# GLM-5.3-NVFP4 PP+MTP verify CUDA graph 修复(r37)— 2026-09-08 @ 174.1.60.8 上一个实验(glm53_ppmtp_r36_degloo)判定:PP+MTP eager 模式正确但 MTP 机器开销吃光收益(step 239ms@cc16 vs 净胜拐点 148ms),图模式(r36g)则正确性崩溃(accept 2.85→1.05 + 数字乱码)。本实验继续修复图捕获并兑现 MTP+PP 双优势。**结果:修复成功,killer e2e -40%、TPOT -40%、TTFT 近乎减半,全面胜过在役 A16 配置并留役生产。** ## 环境 - 镜像 lmsysorg/sglang:nightly-dev-cu13-20260901-07c8f729,GLM-5.3-NVFP4,8×RTX 6000D(SM120) - TP4PP2 + EAGLE(3 steps / topk1 / 4 draft tokens),DSA,hicache 3,memfrac 0.88,chunk 8192, --disable-overlap-schedule,SYNC_MASK=127,de-GLOO 中继(r36 遗产) - r36 的 8 个挂载文件全部沿用 + 本实验新增第 9 挂载(decode_cuda_graph_runner) ## 排查过程(按时间序) 1. **:1515 切片修复**(r33 注释的根因猜测):decode runner `execute()` 对非末 stage 的 PPProxyTensors 按 `self.bs`(请求数)切片,截断 TARGET_VERIFY 树行(bs×4)→ 改按 `raw_num_token`。**必要但不充分**: r37 实测 accept 仍 1.02-1.27 + 乱码(bs=1 零 padding 下确定性复现 → 排除竞态/padding)。 2. **按 stage 二分**:把 /root/sglang_patch2/eagle_worker_common.py 的 `_PP_FORCE_EAGER_VERIFY` 门扩展为 1/2/3 模式(全 eager / 仅首 stage eager / 仅末 stage eager)。判决: - 模式 2(PP0 eager + PP1 图)→ 仍乱码;模式 3(PP0 图 + PP1 eager)→ 完全正确。 - **缺陷唯一在末 stage(PP1)的 verify 图**;PP0 图(含 :1515 修复)被实证正确。 3. **遥测**(runner 内置 VRFY-IN/BUF/G/SLOT + xcheck,SGLANG_PP_SPEC_DEBUG=2/3): - 入口 relayed hidden 每轮新鲜正常;返回 hidden_states 新鲜;logits argmax 全是高频英文 token(' of'/' the'/':', tokenizer 解码实证)→ "模型没看到上下文"signature。 - VRFY-SLOT:pp 槽位注册健康(enabled=True copy_from_fb=True buffer=静态张量 data_ptr 一致)。 - **VRFY-BUF:fill_from 之后静态 pp 缓冲仍全零;VRFY-IN needs_init=False** → 真凶。 ## 根因(真·根因,取代 r33 的 :1515 猜测为唯一根因) spec worker 的 plan-stream 在 prepare 阶段预跑 `load_batch`(eagle_prepare_for_verify 的 overlap 设计)——彼时 **PP 中继尚未到达**,`pp_proxy_tensors=None`,`fill_from` 跳过全部 pp 槽位,仅完成常规槽位 + 注意力元数据, batch 被标记 pre-planned(needs_forward_metadata_init()=False)。前向流 `execute()` 于是走 pre-planned 早退路径, **该路径只补拷 input_ids/positions 两个 spec 必需字段** → pp_proxy(hidden_states/residual/topk_indices) 静态缓冲永远是分配时的全零。捕获图内的 clone kernel(run_once 体内,:1212)从静态缓冲拷零 → 末 stage 在零激活上 计算 → logits 为"无上下文"垃圾 → 全拒 + 乱码。 一切旁证自洽: - PP0(首 stage)不吃 pp 输入(input_ids/positions 恰好是早退路径补拷的两个)→ 模式 3 正确; - B'(nomtp+图+PP)无 spec worker plan-stream → 走完整 fill_from 路径 → 正确; - TP8 A16 无 PP → 正确; - 图 logits ≈ eager 参考滞后一轮(xcheck 实测):零 token 嵌入 + 上一轮 KV 历史的注意力产出。 ## 修复(patches/decode_cuda_graph_runner_fix.py,第 9 挂载文件) 两处改动: 1. `execute()` :1515:PPProxyTensors 抽取改按 `self.raw_num_token` 切(原 :bs 截断树行;decode width=1 时二者等价于 raw/padded 行数之差,树行场景必须 raw_num_token)。 2. `load_batch()` pre-planned 早退路径:新增 pp_proxy 补拷——`pp_proxy_tensors` 各 key 拷入静态缓冲 `[:src.shape[0]]`,pad 尾(`self.bs*captured_req_width` 之外)清零保确定性。这是本修复的核心。 生产运行时遥测代码(VRFY-* / xcheck)随文件留存,由 SGLANG_PP_SPEC_DEBUG 门控(0=关闭,无开销)。 ## 验证阶梯(全部通过) - 质量门 7/7 ×2 boot(GSM8K×5/中文推理/tool call); - accept 恢复 3.59-3.75(eager 档); - conc_test ×3 ALL-OK、killer ×6 零崩溃(三个 boot 累计); - 性能见 results/bench_results.md:vs eager -40% e2e;vs A16 在役配置 -40% e2e、TTFT 33s vs 58-61s。 ## 生产终态 60.8 glm53-nvfp4:30000 = r37 胜者配置(verify 图 + draft eager + de-GLOO + mask127), `--restart unless-stopped`,已取代 A16 留役(A16 脚本 deploy_glm53_605.sh 留盘可切回)。 draft 图(DRAFTEAGER=0)实测无增益(噪声带内互有胜负),保持 eager 以少一个变量。 ## 遗产与提醒 - /root/sglang_patch2/eagle_worker_common.py 已被本实验覆盖为 bisect 版(md5 babb6461…):env "1"/"0" 语义与 r36 版完全兼容,新增 "2"/"3" 单侧模式;r36 档案中的旧 md5 以本目录为准。 - 语料池 61,772 token 剩余(< 一次 i8k 262,144),i8k 永久无重跑余量,killer random-ids 为标准口径。 - killer 的 raw bench JSON(/data/hf_models/bs_results/san_cc16_s*.json)被 A16 复测覆盖, 胜者数字以 results/bench_results.md 记录为准。