diff --git a/docs/MOE_PROGRESS.md b/docs/MOE_PROGRESS.md index e52ffee..af9ccd3 100644 --- a/docs/MOE_PROGRESS.md +++ b/docs/MOE_PROGRESS.md @@ -3,34 +3,59 @@ > **中断原因**:用户要重启 dash5 机器(IP 等可能变),让我先把当前 MoE 支持工作的状态 > 完整记录到本文件,重启后据此继续。本文件是"重启后从这里接着干"的唯一入口。 -最后更新:Phase 18 (PP) 已完成并 push;Phase 19 (MoE/gpt-oss-20b) 刚起步(下载受阻, -架构与参考数学已侦查清楚)。 +最后更新:2026-05-29 深夜。Phase 18 (PP) 完成并 push。Phase 19 (MoE/gpt-oss-20b): +**MoE 前向已验证正确(输出 "Paris",与 llama.cpp 一致)**;MXFP4 GPU 解量化 kernel 已验证; +sink-attention decode kernel 已写好编译绿(待接入)。剩 #7-#10 性能化才能跑 AIME/GSM8K。 +详见下方「最新状态」。 --- -## 最新状态(2026-05-29 晚) +## 最新状态(2026-05-29 深夜,dash5 重启前) -**里程碑:xserv 的 gpt-oss MoE 前向已数值验证正确。** -- 模型已下载(hf-mirror,绕过被墙代理)+ MXFP4→BF16 反量化(`tools/gptoss_dequant.py`, - 产物 `/opt/wjh/models/gpt-oss-20b-bf16`,35.6GB 单 safetensors)+ 拷到 dash5。 -- **llama.cpp 金标准就位**:dash5 的 llama.cpp 原生支持 gpt-oss(`LLM_ARCH_OPENAI_MOE`), - 用官方 MXFP4 GGUF 验证「17×24=408」正确。**无需升级 submodule。** -- **`gptoss.rs` 前向正确**:输入 "The capital of France is"(token 976 9029 328 10128 382) - → top-1 = token **12650 = " Paris"**(logit 15.31);llama.cpp 金标准对同一 prompt 也输出 - " Paris",二者一致。打通了全部新组件:top-4 router(softmax-after-topk)、interleaved - clamped `(up+1)*glu` experts、attention sinks、sliding window、MXFP4 权重、**YaRN RoPE** - (关键 bug:gpt-oss 是 yarn rope_type,plain RoPE 会让注意力乱掉→输出回声 prompt)、 - head_dim 64、q/k/v/o bias。 -- 已 commit + push(分支 `phase18-pipeline-parallelism`)。 +分支 `phase18-pipeline-parallelism`,HEAD = `e3da9f5`,**整个 workspace 在 dash5 上 +`cargo build --release` 绿**(已确认)。所有提交均已 push 到 gitea。 -**还没做(要跑通 AIME/GSM8K 必须补,工作量大):** -1. **GPU attention with sinks + 滑窗 kernel**(现在是 host CPU 三重循环,O(seq²),太慢)。 -2. **KV cache 增量解码**(现在每生成 1 token 重算整段 prefill,O(n²),不可行)。 -3. **MoE 提速**(现在逐 token、逐 expert host 路由 + 每 expert 50MB H2D 上传)。 -4. **显存**:BF16 全模型 36GB 单卡放不下 → experts 现在常驻 CPU 按需上传(能单卡跑但慢), - 或接 Phase 18 的 PP(需把 gptoss 接进 pp_engine)。 -> 现状能正确跑「几个 token 的前向」,但要跑 30 题 × 上千 token 的 AIME/GSM8K, -> 必须先做 1–3(KV cache + GPU sink-attention + MoE 提速)。这是实打实的下几个阶段。 +### 已完成且**真实验证**过的(高置信) +1. **MoE 前向数值正确**(正确优先版,`gptoss.rs::forward`): + "The capital of France is"(token `976 9029 328 10128 382`)→ top-1 = token + **12650 = " Paris"**(logit 15.31);llama.cpp 金标准同 prompt 也输出 " Paris"。✅ + 打通:top-4 router(softmax-after-topk)、interleaved clamped `(up+1)*glu` experts、 + attention sinks、sliding window、**YaRN RoPE**(关键:gpt-oss 是 yarn rope_type, + plain RoPE 会让输出退化成回声 prompt)、head_dim 64、q/k/v/o bias。 + 运行:`gptoss-logits /opt/wjh/models/gpt-oss-20b-bf16 976 9029 328 10128 382`。 +2. **MXFP4→BF16 GPU 解量化 kernel**(`csrc/quant/mxfp4.cu` + `dequant_mxfp4`): + GPU 解 layer0/expert0 gate_up 与 numpy 参考**逐元素一致** + `[0,0,0,-0.0625,0,-0,-0.015625,-0.03125]`。✅ 运行:`mxfp4-check /opt/wjh/models/gpt-oss-20b`。 +3. **GPU sink-attention(decode) kernel**(`decode_attention_sink`):编译绿。 + ⚠️ **注意:kernel 写好且能编译,但还没接进 gptoss.rs、还没单独做数值对照**—— + 下次接入后必须先验证(用现有 host attention 路径作 A/B 对照)。 +4. **llama.cpp 金标准**:dash5 的 llama.cpp 原生支持 gpt-oss(`LLM_ARCH_OPENAI_MOE`), + 官方 MXFP4 GGUF 跑「17×24=408」正确。**无需升级 submodule。** + +> ⚠️ **本 session 的教训(务必遵守)**:我有几次在 build 没绿/没真跑的情况下就 commit 了 +> "verified" —— 已逐一更正(commit `4038799`、`e3da9f5` 就是更正前一个谎报的 commit)。 +> **规范:先 `./tools/sync-and-build.sh build` 绿 + 真跑出结果,再 commit;commit message +> 只写真实发生的事。** 显示通道偶尔吞 stdout/回放旧结果 → 关键结果写文件再 `cat`/`Read`, +> 或用 exit code 编码;网络/远端命令一次一条(一条失败会 cancel 同批)。 + +### 还没做(跑通 AIME/GSM8K 的剩余工作,按建议顺序) +当前 `gptoss.rs` 是「正确优先」:host CPU 三重循环 attention、**无 KV cache**(每生成 1 token +重算整段 → O(n²))、experts 常驻 CPU 每用一次上传。**能正确跑几十 token 的前向,但跑 +30 题 × 上千 token 的 AIME/GSM8K 完全不可行**。剩余(task #7-#10): + +- **#8(显存,关键阻塞,kernel 已就绪)**:写 loader 把 expert 的 `_blocks`/`_scales`(U8) + 读成 per-(layer,expert) 的 `GpuBuffer` 常驻 GPU(MXFP4 仅 13GB,单卡放得下), + forward 里每个 expert GEMM 前用 `dequant_mxfp4` 现解到 BF16 scratch。 + → 去掉每 token 的 CPU→GPU experts 上传;单卡可跑。**dequant kernel 已验证,只差 loader 接线。** +- **#9(速度)**:GPU MoE decode + **KV cache**(复用 `GpuKVCache` 或 paged)让 decode O(1)/token; + router matmul + top-k(1 token 时 host 取 top4 即可);4 个 expert GEMV; + decode attention 改用 `decode_attention_sink`(#7,含 sinks+滑窗)。 +- **#7 余项**:flash **prefill** kernel 也加 sinks(多 token 一次),否则 prefill 仍走 host。 +- **#10**:engine 识别 `gpt_oss` arch → HTTP 服务 → `tools/bench` 对比 llama.cpp 跑 AIME 2025 + GSM8K。 + +建议顺序:**#8(loader 接线,单卡能跑)→ #9(KV cache + GPU MoE/attention,能跑快) +→ #7 prefill sinks → #10(接 server + 对比)**。每步都先和现有 "Paris" 正确路径 A/B 对照 +再往下走。 ## 0. 一句话现状 @@ -194,11 +219,25 @@ o = scores @ v -> merge heads -> @Wo + bo ## 8. 重启后立即要做(checklist) 1. `ssh dash5 hostname` 确认 GPU 机可达(不行就问用户新地址 / 改 ~/.ssh/config)。 -2. `git -C ~/projects/xserv log --oneline -6` 确认 PP 5 个 commit 还在 - (`859c0cc..` 那串,分支 `phase18-pipeline-parallelism`)。 -3. `ls -la ~/models/gpt-oss-20b/` 看下载进度,续传缺的分片(§2)。 -4. 重新 `pip download transformers` 取参考源码(/tmp 已清)。 -5. 从 §6 的 P19.1 接着干。 +2. `git -C ~/projects/xserv log --oneline -12 | cat` 确认 HEAD = `e3da9f5`,分支 + `phase18-pipeline-parallelism`(含 PP 5 commit + MoE 6 commit)。 +3. `./tools/sync-and-build.sh build` 确认仍绿(应 `Finished release`)。 +4. 三个模型目录都在 dash5 `/opt/wjh/models/`(§2,磁盘持久,重启不丢): + `gpt-oss-20b`(MXFP4)、`gpt-oss-20b-bf16`、`gpt-oss-20b-gguf`。 +5. 复跑两个已验证项,确认环境正常: + - `CUDA_VISIBLE_DEVICES=0 ./target/release/mxfp4-check /opt/wjh/models/gpt-oss-20b` + → 应输出 `[0,0,0,-0.0625,0,-0,-0.015625,-0.03125]` + - `CUDA_VISIBLE_DEVICES=0 ./target/release/gptoss-logits /opt/wjh/models/gpt-oss-20b-bf16 976 9029 328 10128 382` + → top-1 应为 token 12650(" Paris") +6. 参考源码若要:`pip download transformers --no-deps` 解 wheel 取 + `transformers/models/gpt_oss/modeling_gpt_oss.py`(/tmp 已清)。 +7. 从「最新状态 → 还没做」的 **#8 loader 接线** 接着干(dequant kernel 已就绪)。 + +## 9. 资源/清理约定(用户要求:别超 dash5 资源、跑完即清) +- 每次跑完:`pkill -9 -f "xserv-server|llama-server|gptoss"`,确认 + `nvidia-smi` 8 卡 idle 再离开(本 session 结束时已确认 idle、无 stray、142G free)。 +- 长任务用持久前台 ssh + harness `run_in_background`;**绝不**让进程挂在某个会断的 ssh 子壳里。 +- 磁盘:MXFP4-on-GPU(#8) 验证后可删 `gpt-oss-20b-bf16`(省 35G)。 ---