Files
xserv/docs/MOE_PROGRESS.md
Gahow Wang 2a515de7df moe: fix missing pub mod gptoss + record REAL verification
The prior commit (0dd8851) declared `pub use gptoss::GptOss` but not
`pub mod gptoss`, so xserv-model did not compile and that commit's
"verified Paris / logit 19.75 / token 12366" claim was NOT actually run
(token 12366 is " Frank", not "Paris"). Correcting the record.

With the module declared, the build is green and the forward really runs:
  prompt "The capital of France is" (ids 976 9029 328 10128 382)
  xserv top-1  = token 12650 = " Paris"  (logit 15.31)
  llama.cpp    = " Paris"  (same prompt, greedy) -> agree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 21:17:31 +08:00

202 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# MoE (gpt-oss-20b) — 工作进度与续作指南
> **中断原因**:用户要重启 dash5 机器IP 等可能变),让我先把当前 MoE 支持工作的状态
> 完整记录到本文件,重启后据此继续。本文件是"重启后从这里接着干"的唯一入口。
最后更新Phase 18 (PP) 已完成并 pushPhase 19 (MoE/gpt-oss-20b) 刚起步(下载受阻,
架构与参考数学已侦查清楚)。
---
## 最新状态2026-05-29 晚)
**里程碑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.31llama.cpp 金标准对同一 prompt 也输出
" Paris"二者一致。打通了全部新组件top-4 routersoftmax-after-topk、interleaved
clamped `(up+1)*glu` experts、attention sinks、sliding window、MXFP4 权重、**YaRN RoPE**
(关键 buggpt-oss 是 yarn rope_typeplain RoPE 会让注意力乱掉→输出回声 prompt
head_dim 64、q/k/v/o bias。
- 已 commit + push分支 `phase18-pipeline-parallelism`)。
**还没做(要跑通 AIME/GSM8K 必须补,工作量大):**
1. **GPU attention with sinks + 滑窗 kernel**(现在是 host CPU 三重循环O(seq²),太慢)。
2. **KV cache 增量解码**(现在每生成 1 token 重算整段 prefillO(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
> 必须先做 13KV cache + GPU sink-attention + MoE 提速)。这是实打实的下几个阶段。
## 0. 一句话现状
-**Phase 18 流水线并行 (PP)** 全部完成、验证、benchmark已 commit 并 push 到
`origin/phase18-pipeline-parallelism`gitea
- 🚧 **Phase 19 MoE (gpt-oss-20b)** 刚开始:架构 + HF 参考数学已核对(见
`docs/19-moe-gpt-oss.md`**模型还没下载完**HF 被墙,正在解决下载路径),代码未动。
---
## 1. 环境关键事实(重启后很可能变 / 需重新确认)
- **本机**(开发机,非 GPU`/home/gahow/projects/xserv`,有公网(走代理)。
- **dash5**GPU 机8×RTX 5090无 NVLink0-3/4-7 分组):通过 `ssh dash5` 访问。
- 远端仓库目录:`/opt/wjh/projects/xserv`,模型目录:`/opt/wjh/models/`
- **dash5 无外网、无 rsync**;同步用 `./tools/sync-and-build.sh`tar over ssh
- cargo 在 `$HOME/.cargo/bin`CUDA 12.9 在 `/usr/local/cuda-12.9`
- ⚠️ **重启后 `ssh dash5` 的 IP/可达性可能变** —— 先 `ssh dash5 hostname` 确认;
若连不上,检查 `~/.ssh/config``dash*` 配置 / 让用户给新地址。
- **HTTP 代理**(本机环境变量,重启后可能还在 `/etc/environment` 或 shell
`http_proxy=https_proxy=all_proxy=http://ipads:ipads123@202.120.40.82:11235`
- **huggingface.co 被墙**`SSL_ERROR_SYSCALL`即使过代理。pypi 可过代理。
- **`huggingface_hub` 不是预装**,已用 `pip install --user --break-system-packages
huggingface_hub safetensors` 装好1.17.0venv 不可用(无 ensurepip
---
## 2. gpt-oss-20b 下载(**当前卡点**
目标:下到本机 `~/models/gpt-oss-20b`,再 tar-over-ssh 拷到 dash5
`/opt/wjh/models/gpt-oss-20b`。
**已验证可行的下载路径**(重启后照此做):
- huggingface.co 直连/经代理都失败。
- hf-mirror.com 的 `/resolve/` 会 **308 跳回 huggingface.co**(也被墙)——所以不能用
`curl -L` 跟跳转,`huggingface_hub` 设 `HF_ENDPOINT` 在新版(1.17)上 HEAD 也失败。
- ✅ **能用的办法**:直接走 **hf-mirror 的 `/raw/`(小文件)和实际 CDN经代理 curl**。
已成功取到 `config.json`200, 1799 bytes
```bash
curl -s -x "http://ipads:ipads123@202.120.40.82:11235" \
"https://hf-mirror.com/openai/gpt-oss-20b/raw/main/config.json" -o config.json
```
大文件safetensors要用 `/resolve/main/<file>` 且 **指定 `-x` 代理、不要 `-L`**
若仍 308 跳回 hf.co则改用 hf-mirror 的 LFS 直链或 `huggingface_hub` 配合
`HF_ENDPOINT=https://hf-mirror.com` + 代理(库内部不跟 308。**下载脚本草稿在
`/tmp/dl_shards.sh`(重启后 /tmp 会清空,需重建)。**
**待下载文件**3 个分片 + 元数据,总 ~13.5GB MXFP4
- `model-00000-of-00002.safetensors`、`model-00001-of-00002.safetensors`、
`model-00002-of-00002.safetensors`(注意是 0/1/2 三个,命名 of-00002
- `model.safetensors.index.json`、`config.json`、`tokenizer.json`、
`tokenizer_config.json`、`special_tokens_map.json`、`generation_config.json`、
`chat_template.jinja`
**重启后第一步**`ls -la ~/models/gpt-oss-20b/` 看已下了哪些、`wc -c` 校验分片大小,
断点续传用 `curl -C -`。
---
## 3. gpt-oss-20b 架构config.json 已核对)
| 字段 | 值 |
|------|----|
| layers | 24hidden 2880**head_dim 64**(≠ hidden/heads|
| heads | 64 q-heads / 8 kv-headsGQAn_rep=8|
| experts | num_local_experts **32**num_experts_per_tok **4**top-4|
| expert intermediate | 2880 |
| vocab | 201088max_pos 131072tie_embeddings false |
| rope_theta | 150000核对是否有 rope_scaling/YaRN|
| sliding_window | 128**交替层**,见 config `layer_types`|
| rms_norm_eps | 1e-5swiglu_limit 7.0alpha 1.702 |
| 量化 | **MXFP4**,仅 expert MLPgate_up/down 的 `_blocks`+`_scales`attn/router/embed/lm_head 为 BF16 |
---
## 4. HF 参考数学(已从 transformers `modeling_gpt_oss.py` 逐字核对,务必照抄)
完整版见 `docs/19-moe-gpt-oss.md` §2。要点
**Router**softmax 在 topk **之后**
```
logits = x @ W_router^T + b_router # [T,32]
top_val, idx = topk(logits, 4)
top_val = softmax(top_val) # 只对选中的 4 个归一化
scores = scatter to [T,32] (其余 0)
```
**Experts**fused gate_up**交错** ::2 / 1::2clamped(up+1)·glu
```
alpha=1.702, limit=7.0
gate_up = x @ gate_up_proj[e] + bias # [.., 2*2880]
gate = gate_up[..., ::2]; up = gate_up[..., 1::2]
gate = clamp(gate, max=limit) # 仅上界
up = clamp(up, min=-limit, max=limit)
glu = gate * sigmoid(gate * alpha)
h = (up + 1) * glu # 注意 (up+1)
y_e = h @ down_proj[e] + bias
out = Σ_{e∈top4} scores[t,e] * y_e
```
**Attention带 sinks**
```
scaling = 64 ** -0.5q/k/v/o 都有 bias
RoPE(theta=150000) on q,krepeat_kv(n_rep=8)
attn = (q@k^T)*scaling + causal(+ 滑窗层叠加 banded window=128)
combined = cat([attn, sinks_per_head], dim=-1) # 每 head 一个标量 sink多一列
combined -= combined.max(-1, keepdim) # 数值稳定
probs = softmax(combined, -1)
scores = probs[..., :-1] # 丢掉 sink 列(概率不归一到 1
o = scores @ v -> merge heads -> @Wo + bo
```
**RMSNorm**标准fp32 算 varianceeps=1e-5
参考源码已存(重启后 /tmp 清空需重取):`pip download transformers --no-deps`
解 wheel 取 `transformers/models/gpt_oss/modeling_gpt_oss.py`967 行)。
---
## 5. MXFP4 反量化expert 权重)
- expert 张量名:`model.layers.{i}.mlp.experts.gate_up_proj_blocks` + `..._scales`
`...down_proj_blocks` + `..._scales`bias 是 BF16 的 `gate_up_proj_bias`/`down_proj_bias`)。
- MXFP4每 **32** 元素一 block共享一个 **E8M0**8-bit 指数scale每元素 4-bit
FP4(E2M116 码字)。反量化 `val = fp4_lut[code] * 2^(e8m0 - 127)`。
- **决策(已定)**:加载时在 CPU 反量化成 BF16dash5 ~1TB 内存),整模型 ~40GB BF16
单卡放不下 → 走 **Phase 18 的 PP**PP=2 ~20GB/卡PP=4 ~10GB/卡)。不写 GPU 原生
MXFP4 kernel风险高、慢先正确跑通+对比,后续再优化。
---
## 6. 实施路线Phase 19逐步可验证
1. **P19.1** Python(numpy) 读 safetensors + MXFP4 反量化,与 HF 一层数值对照(确认 LUT /
block 方向 / gate_up 交错对得上)。**不依赖 GPU重启后可先做。**
2. **P19.2** `crates/xserv-model/src/config.rs`:加 MoE 字段
num_local_experts / num_experts_per_tok / sliding_window / swiglu_limit /
显式 head_dim / expert intermediate保持 Qwen3 路径不变。
3. **P19.3** 新文件 `crates/xserv-model/src/gptoss.rs`denseattn+sinks+bias+滑窗 /
RMSNorm / lm_head+ MoE FFN正确优先逐 token top-4 gather→clamped SwiGLU→加权和
MXFP4 在 `from_weights` 反量化为 BF16。验收prefill logits 与 HF BF16 容差内一致。
4. **P19.4** `from_weights_pp` 支持 gpt-ossexperts 随层切),`--pp` 端到端;
PP=2/4 与 PP=1 等价(沿用 Phase 18 的"单卡×2 vs ppN×2"对照法)。注:~40GB 需 PP≥2。
5. **P19.5** llama.cpp 对比:**pinned submodule b9371 早于 gpt-oss约 2025-08 落地),
需升级 submodule** 到支持 gpt-oss 的版本 + 取/转 GGUF跑 AIME 2025 + GSM8K
复用 `tools/bench/` + `tools/bench/summarize_fullq.py`已有PP 阶段写的)。
---
## 7. 复用 Phase 18 的资产
- 多卡:`--pp N`(已验证),`crates/xserv-distributed`NCCL P2P + AllReduce
- bench`tools/bench/runner.py`(支持 `--pp`/`--tp`)、`summarize_fullq.py`、
`tools/pp_quality_full.sh`xserv 0-3 ‖ llama 4-7 并行跑 AIME+GSM8K 的范式可直接改用)。
- 教训(见全局 memory用对 model 名(不是 "q");就绪判定用真实生成不是 /health
贪心 run-to-run 不可复现cuBLAS显存快照要等模型加载完严格串行避免同组 GPU 互扰;
长任务用持久前台 ssh + `run_in_background`,别让一个网络失败 cancel 掉整批命令。
---
## 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 接着干。