Prhub

#35786 [docs] Retune the Qwen3.8-27B RTX 5090 DFLASH2 cells against 1cf2b8c

原始 PR 作者 Jiminator 合并时间 2026-08-21 12:54 文件变更 2 提交数 2 评论 1 代码增减 +71 / -37

执行摘要

按 1cf2b8c 重调 5090 DFLASH2 显存 pin 并置灰不可达项

PR body 指出 #35663 添加的 DFLASH2 格子携带的 RTX 5090 pin 是在“页面从未告诉用户去安装”的构建上测量的;按用户实际被指示的构建(lmsysorg/sglang:qwen38-27b 容器 / 最新 PyPI 发布)复测时,DFLASH2 的 0.90 bf16 pin 在第一个请求即 OOM,0.945 fp32 pin 在 CUDA 图捕获阶段 OOM,而 DSPARK 全部通过。因此需要将 DFLASH2 的 pin 对准文档指定的 commit 1cf2b8c 重新标定,并把确实不可达的 fp32 Low-Latency 组合显式置灰而不是给出必失败的命令。

值得精读,重点不在代码而在 PR body 的实测方法论:先确定用户实际被指示安装的构建,再逐个 pin 复测并记录 pool / slot / accept 数据,最后用 S=5 / S=4 槽位分析解释“为什么 fp32 低延迟不可达”。这种“不可达就置灰而不是硬给 pin”的取舍,以及“文档错误背后往往藏着产品 bug(#33352)”的根因意识,是这份文档 PR 最有借鉴价值的部分。对 sglang 维护者,建议单独跟进作者提出的 CUDA-graph 捕获失败诊断改进。

讨论亮点

本 PR 没有实质性的 review 讨论线程:zijiexia 直接 APPROVED,唯一评论是 Mintlify 机器人贴出的文档预览链接,不涉及技术决策。核心讨论沉淀在 PR body 的“Note for maintainers”里,作者给出了一段值得关注的分析:

The underlying cause of the DFLASH2 retune is #33352, which removed the 4 GiB free-memory gate on automatic prefill CUDA-graph capture that #31204 added. Builds carrying that gate fall back to eager prefill when headroom is short; builds without it attempt the capture and fail with num_active_captures_ > 0 INTERNAL ASSERT FAILED ... please report a bug to PyTorch, which gives no hint that --mem-fraction-static is the knob.

即真正的根因在产品侧(#33352 移除显存余量门槛),文档只是暴露了症状;作者建议独立于本 PR 改善该报错的诊断信息,这一点未被任何维护者回复或行动跟进。

实现拆解

变更入口是 docs/cookbook/autoregressive/Qwen/Qwen3.8-27B.mdx 的安装引导与 docs/src/snippets/configs/Qwen/qwen3.8-27b.jsx 的命令生成器配置,按以下步骤拆解:

  1. 固定构建 commit(mdx):pip 与 Docker 两条安装路径均从“跟踪移动分支”改为显式 git checkout 1cf2b8c54d81802abc15dcf23a29b9cc687bc01e(对应 PR #35496),因为新 pin 是 commit 特定的;同时重写 DFLASH2 警告块,说明缺少 #35496 会在 NVFP4 格子启动时报 requires a dense FP16/BF16/FP32 target lm_head
  2. 重标 bf16 pin(jsx):DFLASH2 的 RTX 5090 bf16 mem-fraction 由 0.90(沿用 DSPARK 的 pin)改为 0.88,原因是在 1cf2b8c 上 0.90 首个请求即 OOM;新 pin 下 pool 27,452 / 29,276,约 7.01 ms,accept 3.01。
  3. 重标 fp32 pin(jsx):fp32 由 0.945 + ratio 10 改为 0.895 + ratio 10。关键分析是:这些格子固定 --max-running-requests 1,balanced 的 mamba ratio 会为从不使用的并发预配 KV,反而让 state pool 缺一个 fp32 slot;只有 High-Throughput(S=4)可容纳,Low-Latency(S=5)无解。
  4. 置灰 fp32 Low-Latency(jsx):在 ssmDtype 的 float32 选项上对 32 GB RTX 5090 + DFLASH2 组合做 disabled,通过既有 reseatHiddenPicks 机制将用户选择自动移到 bf16;stripPrefixes 相应在 fp32 下同时剥离 --mem-fraction-static--mamba-full-memory-ratio
  5. 验证配套:无自动化测试(PR 声明 docs only),验证依赖 PR body 中的 RTX 5090 32GB 实测表格(NVFP4 checkpoint、ISL 8192 / OSL 1024、concurrency 1、exact-shape checks),并对 fp32 Low-Latency 给出了从 0.86 到 0.945 的全区间失败数据。
文件 模块 状态 重要度
docs/src/snippets/configs/Qwen/qwen3.8-27b.jsx 文档脚本 modified 6.22
docs/cookbook/autoregressive/Qwen/Qwen3.8-27B.mdx 部署文档 modified 3.56

关键符号

config.dflash.flags config.dflash.stripPrefixes config.ssmDtype.options

关键源码片段

docs/src/snippets/configs/Qwen/qwen3.8-27b.jsx core-logic

命令生成器的核心配置:重调 RTX 5090 下 DFLASH2 的 mem-fraction 与 mamba ratio pin,并通过 disabled 与 stripPrefixes 组合将 fp32 Low-Latency 置灰。

// 注:以下配置来自 docs/src/snippets/configs/Qwen/qwen3.8-27b.jsx,
// DFLASH2 格子的 RTX 5090 专属 pin 全部按 commit 1cf2b8c(PR #35496)复测。
{
  id: "dflash", label: "DFLASH2",
  // Trained block-diffusion draft, a separate checkpoint. The selector
  // projects through the target lm_head — including quantized heads — so
  // it runs on the NVFP4 checkpoint too.
  disabled: (sel) => sel.hw === "rtx5090" && sel.quant !== "nvfp4",
  disableReason:
    "On the 32GB RTX 5090 the DFlash2 draft model only fits on top of the NVFP4 weights",
  // fp32 是唯一需要覆盖 balanced ratio 的场景,因此该组合要把两个
  // 前缀同时剥离,再在 flags 里重新输出。
  stripPrefixes: (sel) =>
    sel.hw === "rtx5090"
      ? sel.ssmDtype === "float32"
        ? ["--mem-fraction-static", "--mamba-full-memory-ratio"]
        : ["--mem-fraction-static"]
      : [],
  flags: (sel) => [
    "--speculative-algorithm DFLASH",
    "--speculative-draft-model-path incoai/Qwen3.8-27B-DFlash2",
    "--speculative-num-draft-tokens 8",
    // 关键:bf16 用 0.88(0.90 在 1cf2b8c 上首个请求即 OOM);fp32 用 0.895
    // 且必须配合 ratio 10,因为格子固定 --max-running-requests 1,balanced
    // 的 ratio 会把 KV 预配给从不使用的并发,反而饿死 state pool。
    ...(sel.hw === "rtx5090"
      ? sel.ssmDtype === "float32"
        ? ["--mem-fraction-static 0.895", "--mamba-full-memory-ratio 10"]
        : ["--mem-fraction-static 0.88"]
      : []),
  ],
}
docs/cookbook/autoregressive/Qwen/Qwen3.8-27B.mdx documentation

用户实际看到的部署文档:pip 与 Docker 安装路径均改为固定 checkout 1cf2b8c,并更新 DFLASH2 构建警告与 Configuration Tips,确保用户使用的构建与 pin 的测量基准一致。

# For the DFLASH2 cells only — DFlash2 selector support is newer than the
# latest release, so build from the commit those cells were validated on
# instead of the line above:
git clone https://github.com/sgl-project/sglang.git && cd sglang
# 固定 checkout 1cf2b8c(对应 PR #35496),文档里所有 DFLASH2 pin 均以此 commit 为基准
# 之前“跟踪 main”的做法会让 pin 与用户实际构建错位,这正是本 PR 要消除的偏差
# shellcheck disable=SC2046
git checkout 1cf2b8c54d81802abc15dcf23a29b9cc687bc01e
uv pip install -e "python[all]"

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. 固定 commit 的时效性风险:1cf2b8c 会随 main 演进过时,用户按文档构建可能遇到历史 commit 与当前依赖(PyPI 包、CUDA 版本)的兼容问题;若 DFlash2 或量化路径后续有修复,文档不会自动跟进,这与 #35767 改用滚动 dev tag 的做法形成张力。
  2. pin 值依赖实测环境:0.88 / 0.895 / ratio 10 是在 RadixArk/Qwen3.8-27B-NVFP4 checkpoint 与特定引擎内存分配行为下测得的;checkpoint 更新或 PyTorch 图捕获策略变化都可能让这些值再次 OOM。
  3. 置灰逻辑回归风险:jsx 中 disabled / stripPrefixes / reseatHiddenPicks 的组合依赖选择器框架行为,改动无自动化测试,后续若有人整理该 snippet 结构可能破坏置灰与 pin 输出的联动。
  4. 构建成本变化:Docker 路径从 docker pull 改为从源码 docker build,用户需要完整构建工具链和时间,文档未提示镜像构建耗时或失败排查入口。
  5. 根因未修复:#33352 导致的 CUDA-graph 捕获无友好诊断问题仍存在于产品中,其他模型和显卡组合仍可能撞上同类无提示 OOM。

直接影响面是 RTX 5090 32GB 上运行 Qwen3.8-27B NVFP4 + DFLASH2 的用户:此前按文档配置会 OOM 或图捕获失败,现在 bf16 与 fp32 High-Throughput 可获得实测可启动的配置,fp32 Low-Latency 不再给出必失败的命令,而会被自动切换到 bf16。对文档团队的影响是确立了“文档 pin 必须对准文档告诉用户的构建”的实证纪律,并示范了“不可达组合显式置灰”的处理方式。影响范围严格限定在 Qwen3.8-27B cookbook 页面与命令生成器配置,不修改任何运行时代码,因此对线上服务无影响。

文档 pin 依赖固定 commit 无自动化测试 置灰逻辑依赖选择器框架 根因 #33352 诊断缺失

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论