Prhub

#38861 Make the remaining DeepSeek-V4.1 NVIDIA cells start

原始 PR 作者 zijiexia 合并时间 2026-09-11 02:04 文件变更 1 提交数 1 评论 0 代码增减 +31 / -14

执行摘要

为 DeepSeek-V4.1 cookbook 剩余 NVIDIA cell 补齐 DSpark decode CUDA graph 启动上限

PR 描述明确回答了 #38839 留下的疑问:B300 的失败「既不是 B300 特有,也不是镜像/PYTHONPATH 的 artifact」。作者在页面自带的 lmsysorg/sglang:dev-dsv41 镜像上重跑其余三个平台,结论是「every DSpark cell fails to start, and on H200 both cells do」,日志为 Exception: Capture cuda graph failed: CUDA out of memory.,且这是启动失败而非负载下才出现的问题。改成修复而非写文档的两条理由被直接点名:(1) GB300 Low-Latency cell 已被页面标为 verified 且是参考平台,徽标今天无法复现;(2) MI350X Low-Latency cell 早已带上等价的 --cuda-graph-max-bs 64,说明 ROCm 作者先踩过同样的坑,只是 NVIDIA 侧漏了。

值得精读的是「为什么」,不必精读「改了什么」——单文件、31 行新增、纯配置。建议关注三点:(1) verified 徽标的可信度机制靠人工实测表格而非 CI,可以思考是否要为 cookbook 关键 cell 增加最小启动冒烟测试;(2) DSpark 下 decode CUDA graph 捕获显存与 --cuda-graph-max-bs-decode 的耦合关系,以及 H200 为何必须额外压低 --mem-fraction-static,这直接影响自建部署的显存规划;(3) 若你要部署 DeepSeek-V4.1,请整段复制对应 cell 的 flags,不要把 Low-Latency 的 cap 与 High-Throughput 的 --max-running-requests 256 混搭——后者是刻意不加 cap 的。另外注意本 PR 的 CI 中 PR Test (Extra) 失败、AMD 未跑,人工实测结论是主要依据。

讨论亮点

本 PR 的评审极其轻量:唯一一条评审来自 @wisclmy0611,状态 APPROVED,正文为空,review_comments_count = 0;PR 由作者 @zijiexia 以单 commit 自行合并,没有行内往返讨论。真正的「讨论」发生在 PR 描述里,它用逐平台实测表替代了争论,并把 #38839 的遗留疑问正面结案:

It is neither. Running the other three platforms on the page's own image settles it: every DSpark cell fails to start, and on H200 both cells do.

The GB300 Low-Latency cell is already marked verified and is the page's reference platform, so the badge is not reproducible today. The MI350X Low-Latency cell already carries the equivalent --cuda-graph-max-bs 64 — the ROCm author hit this and capped it. Only the NVIDIA cells were missing it.

取舍也被自述清楚,没有引发质疑但是最值得读者记住的一句:

64 is a startup-feasibility value rather than a tuned one; it is ample for the interactive batch sizes these recipes target, and the three High-Throughput cells that start without a cap are deliberately left uncapped.

B300 两行数据被明确标注来源差异(#38839 的 stock 镜像 + PYTHONPATH 挂 #38798 树,而非页面镜像),作者以「included for completeness」的方式披露,避免读者把不同测量条件混为一谈。

实现拆解

  1. 规则统一到文件头注释:docs/src/snippets/configs/deepseek-ai/deepseek-v4_1.jsx 顶部原先把规则拆散在各 cell 附近,本次合并为一段 header 注释,声明「每个 DSpark cell 都要限制 --cuda-graph-max-bs-decode,派生的 batch 列表在捕获 DSpark decode 图时放不下」,并补充 MI350X 已有等价 --cuda-graph-max-bs、H200 需要「上限 + 更低显存占比」、另外三个 High-Throughput cell 不带这两项也能启动。这样维护者读一处即可解释全部差异,也顺手修掉了 #38839 把 GB300 的注释误写成 verify graphs 的问题。
  2. GB300 Low-Latency cell 补 cap:在 match: { hw: "gb300", strategy: "low-latency" } 的 flags 中、--speculative-dspark-block-size 5 之后插入 --cuda-graph-max-bs-decode 64。该 cell 是页面参考平台且已标 verified,实测在 4x GB300(aarch64,276.62 GiB)上「5.82 GiB wanted,2.15 GiB free」OOM,徽标此前不可复现。
  3. B200 Low-Latency cell 补 cap:match: { hw: "b200", strategy: "low-latency" } 同样只加 --cuda-graph-max-bs-decode 64(已有 --mem-fraction-static 0.8),对应 4x B200(178.35 GiB)上 6.00 GiB 需求 vs 1.48 GiB 可用的捕获失败。
  4. H200 两个 cell 补「cap + 显存占比」:Low-Latency 与 High-Throughput 都新增 --cuda-graph-max-bs-decode 64 和 --mem-fraction-static 0.8。原因是 8x H200(139.80 GiB)只加 cap 后仍有 1.89 GiB 可用、小于 2.00 GiB 的分配请求而继续 OOM,两 flag 同时生效后捕获时有 19.3 GiB 余量。
  5. 状态与注释收敛:H200 ×2、B200 ×2 四个 verificationStatus: "in-progress" 改成 verified: true;B200 区块去掉「verification round open」,B300 区块去掉「比 GB300 多一个内存 knob」的差异化描述(现在所有 DSpark cell 都要 cap,该差异不再成立)。MI350X 按 PR 说明保持不动(本次未测)。
  6. 配套改动:无运行时源码、无单测、无部署脚本变化;校验依赖 node docs/scripts/check_cookbook_configs.mjs(PR 勾选项显示 cookbook config check: OK)。CI 侧 PR Test (Base) 通过,PR Test (Extra) 失败,AMD 侧无对应 run。
文件 模块 状态 重要度
docs/src/snippets/configs/deepseek-ai/deepseek-v4_1.jsx 文档配置 modified 5.84

关键符号

config.cells[].flags config.cells[].verified

关键源码片段

docs/src/snippets/configs/deepseek-ai/deepseek-v4_1.jsx configuration

唯一改动文件,承载 DeepSeek-V4.1 cookbook 的全部按硬件 / 策略分片的启动命令;本 PR 在此为 GB300、B200、H200 的 5 个 cell 补上 decode CUDA graph batch 上限与 H200 显存占比,并把 4 个 in-progress cell 提升为 verified,是「配方可复现性」这一承诺的直接载体。

// docs/src/snippets/configs/deepseek-ai/deepseek-v4_1.jsx
// 单文件 export const config 字面量 —— 不用展开 / 函数 /IIFE(Mintlify 在 hydration 时会重新求值)。
//
// 标记 verified 的 cell 都抄录自对应硬件上、用真实权重跑通的记录。
//
// 每个 DSpark cell 都要限制 --cuda-graph-max-bs-decode:派生的 batch 列表
// 在捕获 DSpark decode 图时放不下,所有 NVIDIA 平台都一样。
// MI350X cell 早已带上等价的 --cuda-graph-max-bs;H200 是这里最紧的板卡(140 GiB),
// 两个 cell 需要该上限再加更低的显存占比;另外三个 High-Throughput cell 不带也能启动。
export const config = {
  // ... modelName / matchDims / modelNames / placeholders / options 保持不变 ...
​
  cells: [
    // ---------- GB300:4x GB300(SM103),TP4 + EP4。页面参考平台。 ----------
    {
      match: { hw: "gb300", strategy: "low-latency" },
      nnodes: 1,
      verified: true, // 参考平台的徽标此前不可复现,本 PR 修复
      flags: [
        "--trust-remote-code",
        "--model-path {{MODEL_NAME}}",
        "--tp 4",
        "--ep-size 4",
        // 派生值在 128K 形状下捕获 verify 图会 OOM。
        "--mem-fraction-static 0.8",
        "--speculative-algorithm DSPARK",
        "--speculative-dspark-block-size 5",
        // 【本 PR 新增】Decode CUDA graph:派生 batch 列表在这里放不下,
        // 实测 5.82 GiB wanted vs 2.15 GiB free(共 276.62 GiB),服务永远不 ready。
        "--cuda-graph-max-bs-decode 64",
        "--reasoning-parser auto",
        "--tool-call-parser auto",
        "--host {{HOST_IP}}",
        "--port {{PORT}}",
      ],
    },
​
    // ---------- H200:8x H200,TP8 + EP8。Hopper 上没有 MXFP8 dense 路径。
    // 这里是显存最紧的板卡(139.80 GiB):只加 cap 仍只余 1.89 GiB,
    // 小于 2.00 GiB 的分配请求,所以两个 cell 还要把显存占比压到 0.8。 ----------
    {
      match: { hw: "h200", strategy: "low-latency" },
      nnodes: 1,
      verified: true, // 由 verificationStatus: "in-progress" 提升而来
      flags: [
        "--trust-remote-code",
        "--model-path {{MODEL_NAME}}",
        "--tp 8",
        "--ep-size 8",
        // 【本 PR 新增】cap 之外再压低显存占比,两项一起才能在捕获时留下 19.3 GiB。
        "--mem-fraction-static 0.8",
        "--attention-backend dsv4",
        "--moe-runner-backend flashinfer_mxfp4",
        "--enable-decoder-swa-bounded-replay",
        // 【本 PR 新增】Decode CUDA graph:派生 batch 列表在这里放不下。
        "--cuda-graph-max-bs-decode 64",
        "--reasoning-parser auto",
        "--tool-call-parser auto",
        "--host {{HOST_IP}}",
        "--port {{PORT}}",
      ],
    },
    // 同平台的 high-throughput cell 走完全相同的两项,只是把
    // --enable-decoder-swa-bounded-replay 换成 --max-running-requests 256。
  ],
};

评论区精华

B300 的启动失败是平台特性还是测量 setup 的 artifact question

#38839 在给 B300 Low-Latency 加 cap 时留下 caveat:B300 是在 stock 镜像上把 #38798 树挂到 PYTHONPATH 测的,没有跑页面自带的 lmsysorg/sglang:dev-dsv41。本 PR 在页面镜像上重跑其余三个平台,确认 GB300 / B200 / H200 的 DSpark cell 乃至 H200 两个 cell 都以 `Capture cuda graph failed: CUDA out of memory` 启动失败,从而排除平台特性与 setup 两种解释。

结论:失败是 DSpark decode 图捕获阶段的普遍问题,与镜像、PYTHONPATH 无关;NVIDIA 侧统一补 --cuda-graph-max-bs-decode(H200 再加 --mem-fraction-static),并把 B300 行以「#38839 来源」标注后并入同一张对照表。 · 已解决

唯一评审:直接批准,无行内讨论 other

@wisclmy0611 给出 APPROVED,评审正文为空,仓库侧记录的 review_comments 为 0;作者 @zijiexia 同时是合并者,单 commit 进入 main。评审注意力主要被 PR 描述中逐平台实测表(as published vs with this PR's flags)承接,而不是逐行 diff 讨论。

结论:无争议、无未决修改项;但也意味着 --cuda-graph-max-bs-decode 取值 64 的取舍没有经过第二人复核,只有「能启动」这一条证据。 · approved

风险与影响

  1. 取值 64 是启动可行性值而非调优值:--cuda-graph-max-bs-decode 64 会把 decode CUDA graph 覆盖的最大 batch 从派生值(正文提到 B300 派生值为 256)压到 64,超出部分走非 graph 路径,可能在较大并发下有吞吐损失。PR 自述面向交互 batch 场景足够,且 High-Throughput cell 刻意不加 cap,但文档读者若把 Low-Latency 配方用于高并发服务,会与预期不符。
  2. verified 徽标缺乏回归保护:verified: true 的语义是「抄录自对应硬件上用真实权重跑通的记录」,但仓库里唯一的自动校验是 docs/scripts/check_cookbook_configs.mjs(只做配置结构/静态检查),无法发现启动期 OOM 回归。历史上 #38839 已经因为 GB300 默认派生值变化出现过一次「徽标不可复现」,本次把 4 个 cell 一次性提升为 verified,未来 sglang 默认 batch 列表或 DSpark 图显存占用变化时可能再次失真。
  3. 结论与特定镜像强绑定:GB300 / B200 / H200 的实测都跑在 lmsysorg/sglang:dev-dsv41 上,B300 行来自 #38839 的另一套 setup,MI350X 完全未测。若页面镜像更新,或用户使用 nightly/自建镜像,显存余量(如 H200 捕获时 19.3 GiB)可能不再成立。
  4. H200 的显存取舍影响 KV 池容量:--mem-fraction-static 0.8 在 H200 上是被迫加的,两个 flag 一起把模型/图捕获的预算压下来,代价是可用于 KV cache 的显存减少;文档只承诺「starts, serves」,没有给出长上下文或高并发下的表现,用户读到 verified 容易误读为「全场景可用」。
  5. 无运行时风险:改动只落在文档配置数据,不涉及 decode_cuda_graph_runner 等源码,因此不存在服务端行为回归或兼容性风险。
  6. CI 信号不完整:本次 commit 的 Latest PR Test (Extra) 为失败、AMD ROCm 无对应 run;这类失败难以由纯文档改动触发,但也没有专门验证 cookbook 配方可启动的测试,等于所有「starts, serves」结论都只有人工证据。

对用户:直接复制的 8 个 NVIDIA cell 从 5 个起不来变为全部可启动,「verified」徽标重新可信,避免读者在 8x H200 或 4x GB300 上照抄命令后卡在 Capture cuda graph failed: CUDA out of memory 且服务永不 ready。对系统:不触碰 serving 路径,--cuda-graph-max-bs-decode 只在用户实际启动时生效,单机 batch 上限由用户自身 flag 决定,框架默认行为不变。对团队:cookbook 作为对外承诺的「配方 + 徽标」体系需要人工实测支撑,本 PR 让 NVIDIA 侧与 ROCm 侧(MI350X 早已带 cap)保持一致,也把「为什么带这些 knob」的理由集中写进文件头,降低后续维护成本。影响面限定在文档与用户启动配置,属于中等偏低的实际影响。

文档配置变更 verified 徽标缺少 CI 回归保护 结论与 dev-dsv41 镜像强绑定 H200 KV 池余量被压缩 64 为启动可行性值非调优值

关联 Issue

#38839 Fix the DeepSeek-V4.1 reasoning example and make every NVIDIA cell start

完整报告

参与讨论