测试版本:Qwen3.8-27B-Cold-Fusion-GAIN-V1.1-NM-DAU-NEO-MAX-MTP-GGUF
由于Qwen3.8-27B原版的思考时间过长,这个魔改版号称能在不降低输出质量的情况下减少一半以上的思考时间,某种程度上来说,也算变向提高了token生成速度,以下所有测试均在xhigh模式下进行。
运行命令
docker run --gpus all -v ./:/models -p 8000:8080 ghcr.io/ggml-org/llama.cpp:server-cuda -m /models/Qwen3.8-27B-Cold-Fusion-GAIN-V1.1-NM-DAU-NEO-MAX-NEO-MTP-Q4_K_M.gguf --mmproj /models/mmproj-F16.gguf --port 8080 --host 0.0.0.0 -c 200000 -fa on --spec-type draft-mtp,ngram-mod,ngram-map-k4v --spec-draft-n-max 3 --cache-type-k q8_0 --cache-type-v q8_0 --fit off -ctkd q8_0 -ctvd q8_0 --ctx-checkpoints 32 --checkpoint-min-step 8192 --cache-reuse 256 --cache-idle-slots --no-kv-unified --no-context-shift --load-mode none -cram 16384运行环境:双卡4090
速度:50-60tokens/s,接近200K上下文时降至30-40tokens/s
测试项目:局域网P2P文件传输应用
这一版本使用局域网P2P文件传输应用作为测试项目,可以更好地反映模型在面对真实开发工程任务时编写代码的真实能力。测试环境为opencode+superpowers。以下是设计文档:
# P2P 局域网传输系统设计文档(Phase 1)
日期:2026-08-21
状态:已评审(分节确认通过)
## 1. 目标与范围
在纯内网互信环境下,实现桌面端文件点对点传输,采用 Rust(Tauri 2)后端引擎 + Vue 3 前端,
跨 Windows / Linux 双平台,核心诉求:千兆/万兆局域网下的零拷贝高速传输、受控内存足迹、
断点续传与进度实时同步。
### Phase 1(本规格)
- Tauri 2 + Vue 3 单页应用
- 原生 TCP 传输引擎 + OS 级零拷贝(TransmitFile / sendfile(2))
- BLAKE3 完整性校验 + 位图断点续传(跨平台兼容的 .part 方案)
- 滑动窗口 + 背压控制
- IPC 事件流 + 双层节流进度渲染
- 验收:两台实例、单文件、端到端传输(含暂停/恢复/续传),BLAKE3 校验通过
### Phase 2(后续规格,本文档仅占位)
- QUIC(quinn)+ memmap2 传输模式
- UDP 双向心跳保活
- 单连接多路复用(大量小文件并发)
- Linux io_uring 集成验证
### 明确不做(YAGNI)
- 无 NAT 穿透 / 中继 / 打洞
- 无 mDNS 自动发现(手动输入 IP:port)
- 无传输认证(互信内网前提;QUIC 自带 TLS 属传输层加密,非认证)
- 无目录批量传输(Phase 1 仅单文件)
## 2. 技术选型
| 项 | 选择 | 说明 |
|---|---|---|
| 桌面框架 | Tauri 2 | 原生窗口 + IPC |
| 异步运行时 | tokio | 全引擎统一异步 |
| TCP 零拷贝 | TransmitFile(win)/ sendfile(2)(linux) | `#[cfg(target_os)]` 分支编译 |
| 哈希 | blake3 | 流式计算,>2GB/s |
| 前端 | Vue 3 + Vite + Pinia + TypeScript | 单页、组合式 API |
| QUIC(P2) | quinn | 预留 |
## 3. 架构与目录结构
```
p2p/
├── src-tauri/ # Rust 引擎(Tauri 2)
│ ├── Cargo.toml
│ ├── tauri.conf.json
│ └── src/
│ ├── main.rs # Tauri 入口,注册 state/commands
│ ├── lib.rs # 库根(引擎可脱离 GUI 单测)
│ ├── commands.rs # #[tauri::command] IPC 门面
│ ├── platform.rs # 路径/权限/隐藏属性等 OS 差异隔离
│ ├── error.rs
│ └── engine/
│ ├── mod.rs
│ ├── protocol.rs # 二进制帧格式:handshake/chunk/ack/bitmap
│ ├── server.rs # TCP listener,入站传输
│ ├── client.rs # 出站连接,发送传输
│ ├── transfer.rs # 状态机:切片、滑动窗口、背压
│ ├── zcopy.rs # #[cfg] TransmitFile / sendfile(2)
│ ├── resume.rs # .part/.part.meta 读写、位图持久化
│ └── hash.rs # 流式 BLAKE3
├── src/ # Vue 3 前端
│ ├── main.ts
│ ├── App.vue
│ ├── lib/ipc.ts # invoke/event 封装 + rAF 节流
│ ├── stores/transfer.ts # Pinia(UI 唯一数据源)
│ └── components/
│ ├── ConnectBar.vue # 服务状态 + 对端 IP:port + 连接
│ ├── TransferList.vue
│ ├── TransferItem.vue# 进度条/速度/状态 chip/操作按钮
│ └── Toast.vue # 消息浮窗
├── index.html
├── package.json
├── vite.config.ts
└── tsconfig.json
```
### 模块边界
- `engine/` **零 Tauri 依赖**:纯库,通过事件回调对外暴露状态,可进程内单测/集成测试。
- `commands.rs` 是唯一桥接层:持有 `Arc<AppState>`(session 表),引擎事件 → Tauri event。
- Phase 2 的 QUIC 传输作为 engine 内新增 transport 实现,不动 GUI 与协议语义层。
## 4. 传输协议(Phase 1,TCP)
### 连接模型
- 一端运行 listener(默认端口 9876,可配置);另一端 connect。
- 任一侧均可作为发送方(发起 `send_file`)。
- 受信内网:接收方对 `SEND_REQ` 自动接受。
### 帧格式
所有整数 big-endian。通用帧:`[u8 type][u32 payload_len][payload]`。
- 握手顺序:连接建立后,客户端先发 HELLO,服务端回 HELLO,随后进入传输阶段。
| type | 方向 | payload |
|---|---|---|
| HELLO | 双方 | version(u16), nonce(8B)(回显校验) |
| SEND_REQ | 发送→接收 | name_len(u32)+name, size(u64), chunk_size(u32=4MB), file_blake3(32B) |
| SEND_ACK | 接收→发送 | ok(1B), bitmap_len(u32), bitmap(bytes,仅存在 .part 续传时) |
| CHUNK | 发送→接收 | chunk_id(u32), data_len(u32), data |
| CHUNK_ACK | 接收→发送 | chunk_id(u32) |
| DONE | 发送→接收 | — |
| VERIFY_OK / VERIFY_FAIL | 接收→发送 | — |
| CANCEL | 任一方 | reason(u8) |
- 分块:`chunk_size = 4MB`(可配置),最后一块可不足 4MB。
- CHUNK 按 chunk_id 递增顺序发送;续传时跳过位图中已置位的块。
- **拒绝规则**:若接收端目标路径已存在同名最终文件(非 .part),`SEND_ACK.ok=0`
拒绝传输,UI 提示「目标文件已存在」,不静默覆盖。
### 暂停/恢复语义
- `pause`:发送端停止下发新块(保留连接与已发状态),接收端保留 `.part` 与位图。
- `resume`:等价于「重连续传」——重新 connect、重走握手,由位图决定缺失块,
无需任何额外状态迁移(传输状态全部来自磁盘上的 .part.meta)。
### 断点续传(跨平台兼容方案)
- 接收端写入 `<name>.part`(预分配至完整大小)+ 伴随文件 `<name>.part.meta`:
`version(u16), orig_name, size(u64), chunk_size(u32), bitmap`(bit=该块已写入并落盘)。
- **Windows**:额外对 `.part` 设置隐藏属性(cfg 分支调用);**Linux**:同一套
`.part` 命名 + meta 文件头标识。两端读写同一磁盘格式 → 互操作兼容。
- 重连时 `SEND_ACK` 携带位图 → 发送端仅流式发送缺失块。
- 应用重启后通过扫描接收目录的 `.part.meta` 恢复可续传列表(`list_transfers`)。
### 完整性校验
- 发送端在握手前流式计算整文件 BLAKE3,随 `SEND_REQ` 下发。
- 接收端收完全部块、收到 DONE 后,对 `.part` 流式计算 BLAKE3 比对:
- 一致 → 重命名为最终文件名,删除 meta → VERIFY_OK
- 不一致 → 保留 `.part` 供续传 → VERIFY_FAIL(UI 报错,可 resume 重传)
## 5. 零拷贝、内存与背压
### 发送端
- 每连接一个 `Transfer` 任务:文件句柄 + `next_chunk` 游标。
- 滑动窗口:**在途块上限 4**(4×4MB=16MB,可配置)。
- 每个在途块通过 OS 零拷贝下发:
- Windows:`TransmitFile`(`#[cfg(target_os = "windows")]`)
- Linux:`sendfile(2)`(`#[cfg(target_os = "linux")]`)
- 有界 `tokio::sync::mpsc`(容量=窗口大小)传递 `chunk_id → (offset, len)` 描述符;
ACK 释放槽位后发送循环才拉取下一个描述符 → 网络慢于磁盘时生产者自然挂起(背压)。
- 数据不进应用堆:内核 page-cache → 网卡。
### 接收端
- read task → 有界 channel(容量 4)→ write task;channel 满则 read 挂起(背压传导)。
- write task 按 `chunk_id * chunk_size` 偏移写入 `.part`,置位图位,
每 N 块(默认 16)同步一次 meta 文件(兼顾持久性与吞吐)。
### 内存足迹
- 发送端驻留:窗口×(描述符 + 内核缓冲);接收端:≤4×4MB 接收缓冲。
- 100GB 镜像传输,应用层内存约 32MB 量级,不随文件大小增长。
### OS 差异隔离点(cfg 面)
- `zcopy.rs`:TransmitFile vs sendfile(2)
- `platform.rs`:隐藏属性(仅 win)、路径分隔符、权限掩码
- 其余引擎代码保持 OS 无关
## 6. IPC 与前端
### Tauri commands
| command | 说明 |
|---|---|
| `server_start(port)` / `server_stop()` | 监听控制 |
| `connect(ip, port)` | 建立客户端连接,返回 session id |
| `send_file(session_id, path)` | 发起出站传输 |
| `pause(id)` / `resume_transfer(id)` / `cancel(id)` | 传输控制 |
| `list_transfers()` | 恢复 UI(含扫描 .part.meta 的待续传项) |
### 事件
- `transfer-update`: `{id, phase, sent, total, speed_bps, error?}`
- phase: `connecting | transferring | paused | interrupted | done | error`
- **双层节流**:Rust 侧每传输至多 100ms 一条;前端 `requestAnimationFrame`
批量写入 Pinia → UI 更新 ≤60Hz,进度平滑。
### UI 布局(单页)
- 顶部:服务状态 chip(端口/监听中)+ 对端 `IP:port` 输入 + 连接按钮
- 中部:「发送文件」按钮(Tauri file dialog);对端发起传输时的接收卡片(名称/大小)
- 传输列表项:名称、进度条、速度、phase chip、操作按钮(暂停/继续/取消)
- Toast 浮窗:连接被拒、磁盘错误、哈希不匹配等;
气泡文本用 flex 居中 + 行高对齐,保证 DirectWrite/FreeType 下视觉一致
### 错误处理
- 连接被拒/超时 → toast,session 标记 failed
- 传输中对端断开 → phase=interrupted,保留 .part,可 resume 重连续传
- 磁盘 IO 错误(写满等)→ 暂停并显示错误横幅,可 resume
- 哈希不匹配 → error 状态,保留 .part 供续传
## 7. 测试策略
### Rust 单元测试(engine/ 内,无 GUI)
- protocol:帧编解码往返、截断/畸形输入拒绝
- bitmap:置位/读取/序列化/跨版本兼容
- 分块数学:偏移计算、末块处理
### Rust 集成测试(tests/engine_test.rs,127.0.0.1 进程内双实例)
1. 正常路径:64MB 随机文件 → 字节级一致 + VERIFY_OK
2. 断点续传:中途 kill 发送端 → 重启 → 位图下发 → 仅传缺失块(计数器断言)→ 文件完整
3. 取消:流中 cancel → 无僵尸任务、socket 关闭、.part 保留
4. 背压:小窗口 + 慢消费者 → 在途计数永不超窗
### E2E(手动,README 记录)
- `cargo tauri dev` × 2 实例,1GB 文件传输,观察进度/暂停/续传/哈希校验
### Phase 1 完成定义(DoD)
- [ ] `cargo test` 全绿(单元 + 集成)
- [ ] `cargo tauri dev` 可构建;双实例端到端传输成功(含续传)
- [ ] `cargo check --target x86_64-unknown-linux-gnu` 通过(cfg 分支可编译)
## 8. Phase 2 占位(不在本计划实现)
- QUIC 模式:quinn + memmap2 读文件;TLS 证书自签
- UDP 双向心跳保活:`tokio::time::timeout` 判定超时断开并释放写句柄
- 多路复用:单物理连接多数据流,小文件并发
- Linux io_uring 高吞吐读取验证
本次编码过程中,除了一开始的需求设计,以及中途一次网络问题,以及一些需要读取其它文件的权限问题人工介入之外,其余均由模型独自完成。本次开发共计花费约7小时完成。
观察到的现象
模型具备已具备很强的独立思考能力,例如,当发现某个库中的API调用和自己记忆中的数据中不一致时,不会一直死磕,而是会请求读取库的版本号,源代码等相关内容,通过实际资料修改代码。当然,这部分也许也有TDD开发范式的功劳。
虽然说这个版本的千问模型确实减少了思考,但是相较于其它同类别的参数模型,思考程度依然偏多。在实现过程中,有一个windows系统的文件权限写入问题,光是这一个问题就使用了20万token,当然,这里有一部分原因是陷入了循环思考。有趣的是,在陷入循环思考后,这个模型会自己提醒自己已经陷入了循环思考,但是这部分提醒很快也变成了循环思考的一部分,隔这套娃呢。不过这种情况只出现了一次,而且实在15万上下文之后才出现,随着记忆的压缩,在外围工具的强制干涉下,模型大概率能逃脱这个循环。
软件效果

看起来还挺像那么一回事的,整体界面简洁,交互也符合预期。对于一些基本的软件开发,感觉配合上TDD开发范式,它应当能胜任大部分中低复杂度的任务,感觉每个月可以省下来至少小100的token费用了。
不过,我还是更期待D佬的fable fusion版本的qwen3.8-27B,上一个3.6的魔改版据评测就已经好评如潮,如果能够在3.8的基础上更上一层楼,也许真的可以实现本地token自由了。
Qwen3.8-27B 测试(2)
https://556799.xyz/archives/qwen3.8-27b-ce-shi-2
Comments