Prhub

#35064 docs: fix Qwen3.8-27B mamba ratio calculator for speculative decoding

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

执行摘要

修复 Qwen3.8-27B mamba 缓存比例计算器四个行为偏差,对齐 K3

PR body 明确指出计算器 was derived from the Kimi K3 one but lost four behaviours along the way, so it emitted the wrong --mamba-full-memory-ratio and --max-mamba-cache-size for every speculative configuration。四个缺陷中,ReplaySSM 场景 D 应为 0 却按 4 计算导致 2 倍过度预留状态池、挤压 KV 池;DSPARK 不做 --speculative-num-draft-tokens,验证窗口应为 gamma + 1(实际 8 而非 4)导致状态池欠配;pin 重复计入 D;S 硬编码忽略 skip-lock 与 overlap 调制。PR body 特别指出缺陷 1 与 2 误差方向相反,which is why no single spot-check surfaced them

值得精读。该 PR 展示了文档交互工具如何与服务端运行时语义严格对齐:从引擎实现 _calculate_mamba_ratio() 推导用户可见参数公式,以及对'两个方向相反的错误相互掩盖'的归因分析很有教学价值。zijiexia 对'当前无 observable 差异但语义错误'的坚持也是高质量 review 的范例。若团队维护类似的交互式配置器,可借鉴其以服务端为 truth 的推导方式与多路验证手法。

讨论亮点

review 中 zijiexia 提出两条高质量意见:(1) DSPARK 缺省 block_size 应为 7 而非 5,指向默认 checkpoint RadixArk/Qwen3.8-27B-DSparkconfig.json;Jiminator 以三方面确认后修正(checkpoint 配置、服务端 boot log gamma=7, verify_num_draft_tokens=8、K3 计算器一致性)。(2) cfg.baseEnv.length ? cfg.baseEnv : cfg.env 与 K3 的 cfg.baseFlags.length ? cfg.baseEnv : cfg.env 不一致,there's no observable difference today — but the semantics are wrong, and this is the one line where the body claims K3 parity,Jiminator 随后修正。zijiexia 还要求同步更新 mdx 中 --max-mamba-cache-size 的说明并清理注释,最终 APPROVED。

实现拆解

  1. 定位问题入口:核心改动集中在 docs/src/snippets/_qwen38_mamba_ratio_calculator.jsxderive() 函数,它是页面实时计算 --mamba-full-memory-ratio 与等价 pin 值的核心逻辑,输出会直接进入用户复制的部署命令。
  2. 重写 S 槽位计算:将硬编码 5/4/3/1 改为镜像服务端 kv_cache_configurator._calculate_mamba_ratio() 的表达式——基线 3,SGLANG_OPT_MAMBA_SKIP_DECODE_LOCK=1 时减 1,叠加 ping-pong track buffer(overlap 调度开启时 +2,extra_buffer_lazy 或 overlap 关闭时 +1),no_buffer 恒为 3,radix cache 禁用时 S 退化为 1。derive() 签名新增 env 参数以读取环境变量,调用处 effbs 分别传入所属命令的 env,避免 base 命令继承 Playground 的 overlay env。
  3. 重写 D 槽位计算:按 spec 算法分派——--enable-linear-replayssm-spec 时 D 恒为 0(验证中间态移入固定 ring);DSPARK 时 D = --speculative-dspark-block-size + 1,缺省 fallback 为 7(RadixArk/Qwen3.8-27B-DSpark 默认 checkpoint 的 block_size);其他 EAGLE/MTP 场景沿用 --speculative-num-draft-tokens(缺省 4)。
  4. 修正 pin 公式与 env 传递:pin 从 C * (S + D) 改为 C * S,依据是引擎 kv_cache_configurator.pymamba_cap = max_mamba_cache_size // _calculate_mamba_ratio() 只按 S 划分主状态池、spec 缓冲独立分配;base 命令 env 选择改为 cfg.baseFlags.length ? cfg.baseEnv : cfg.env,与 K3 计算器语义一致。
  5. 配套文档与验证:同步更新 Qwen3.8-27B.mdx 中 Accordion 的 S/D 语义、pin 公式与 DSPARK/ReplaySSM 说明,并重写 jsx 注释只描述当前语义。作者在 RTX 5090 上复现了 10 个 servable 配置的比率,并验证 no_buffer、radix-off、skip-lock、overlap-off 与显式 --speculative-dspark-block-size 7 各分支。
文件 模块 状态 重要度
docs/src/snippets/_qwen38_mamba_ratio_calculator.jsx 配置计算器 modified 6.8
docs/cookbook/autoregressive/Qwen/Qwen3.8-27B.mdx 使用文档 modified 3.25

关键符号

derive

关键源码片段

docs/src/snippets/_qwen38_mamba_ratio_calculator.jsx core-logic

核心改动文件,重写 derive() 的 S 与 D 计算、修正 pin 公式并新增 env 参数传递,直接影响用户从页面复制的部署参数准确性。

// 核心:derive() 从配置 flag 列表与运行环境推导缓存比例,语义对齐服务端
// kv_cache_configurator._calculate_mamba_ratio() 与 DSpark/EAGLE 的 spec 行为。
const derive = (flags, env) => {
  const flagArg = (name) => {
    for (const f of flags) {
      const parts = f.split(/\s+/);
      if (parts[0] === name) return parts[1];
    }
    return null;
  };
  const hasFlag = (name) => flags.some((f) => f.split(/[\s=]/)[0] === name);  // S = 每请求占用主状态池的槽位数(镜像引擎实现):
  // 基线 3;SGLANG_OPT_MAMBA_SKIP_DECODE_LOCK=1 时减 1;
  // 叠加 ping-pong track buffer:overlap 调度开启时为 2,
  // extra_buffer_lazy 或 overlap 关闭时为 1,no_buffer 恒为 3,
  // radix cache 禁用时 S 退化为 1。默认组合恰好等于旧硬编码 5/4/3/1。
  const skipLock = env.some((e) =>
    e.startsWith("SGLANG_OPT_MAMBA_SKIP_DECODE_LOCK=1"));
  const overlapOff =
    hasFlag("--disable-overlap-schedule") ||
    (Number(flagArg("--pp-size")) || 1) > 1;
  const slots = radixOff
    ? 1
    : strategy === "no_buffer"
      ? 3
      : 3 - (skipLock ? 1 : 0) +
        (overlapOff || strategy === "extra_buffer_lazy" ? 1 : 2);  // D = 每条请求的 spec 验证中间状态数(不计入主池 pin)。
  const algo = (flagArg("--speculative-algorithm") || "").toUpperCase();
  // ReplaySSM 把验证中间态移到固定 ring 上,D 恒为 0。
  const replaySpec = hasFlag("--enable-linear-replayssm-spec");
  // DSPARK 不读 --speculative-num-draft-tokens:窗口 = gamma + 1,
  // gamma 缺省时为 draft checkpoint 的 block_size(RadixArk 默认 7)。
  const dsparkBlock = Number(flagArg("--speculative-dspark-block-size")) || 7;
  const drafts = !specOn || replaySpec
    ? 0
    : algo === "DSPARK"
      ? dsparkBlock + 1
      : Number(flagArg("--speculative-num-draft-tokens")) || 4;  // 引擎只用 S 划分状态池:
  // mamba_cap = max_mamba_cache_size // _calculate_mamba_ratio(),
  // spec 缓冲独立分配,所以 pin = C x S 而非 C x (S + D)。
  const ratio = ((slots + drafts) * stateBytesPerSlot) / (kvBytesPerToken * L);
  return { ratio, slots, drafts, specOn /* 其余派生几何常量省略 */ };
};// 两处调用:原命令与 base 命令各自携带自己的 env,
// base 命令的 env 不再继承 Playground overlay,语义与 K3 计算器一致。
const eff = derive(cfg.flags, cfg.env);
const bs = derive(
  cfg.baseFlags.length ? cfg.baseFlags : cfg.flags,
  cfg.baseFlags.length ? cfg.baseEnv : cfg.env,
);
const pin = Math.ceil(C * slots);

评论区精华

DSPARK 缺省 block_size 应为 7 而非 5 正确性

zijiexia 指出 fallback 到默认 DSpark checkpoint(RadixArk/Qwen3.8-27B-DSpark)时 block_size 应为 7;Jiminator 确认并以三方面验证:checkpoint 的 config.json、服务端 boot log(gamma=7, verify_num_draft_tokens=8)、K3 计算器一致性。

结论:DSPARK 缺省 fallback 修正为 7,D = 8。 · 已解决

baseEnv 选择语义应与 K3 一致 正确性

zijiexia 指出 `cfg.baseEnv.length ? cfg.baseEnv : cfg.env` 与 K3 的 `cfg.baseFlags.length ? cfg.baseEnv : cfg.env` 不一致,虽然当前 15 个 cell 均 env 为空无可见差异,但语义错误且违反 body 声称的 K3 parity。

结论:改为 `cfg.baseFlags.length ? cfg.baseEnv : cfg.env`,base 命令不再继承 overlay env。 · 已解决

同步更新 mdx 的 pin 说明并清理注释 documentation

zijiexia 在 CHANGES_REQUESTED 中要求更新 mdx 中 --max-mamba-cache-size 的计算说明,并清理 jsx 中不准确的注释。

结论:第二个 commit 全面重写 mdx 说明与 jsx 注释,zijiexia 最终 APPROVED。 · 已解决

风险与影响

本次改动仅涉及文档站点的 2 个文件,无运行时服务端风险。主要风险在于一致性维护:derive() 中的 S 表达式是服务端 kv_cache_configurator._calculate_mamba_ratio() 的手工镜像,DSPARK 的 block_size=7 fallback 是硬编码默认值,若服务端逻辑或未来 checkpoint 的 block_size 变化,计算器需人工同步,当前无自动化测试或跨文件校验防止漂移。另外,修复前用户从页面复制的参数在 spec 场景存在 2 倍偏差(KV 池 -38% 或状态池欠配),修复本身消除了该偏差,但属于事后修正。

影响范围:文档站点 2 个文件,面向 Qwen3.8-27B cookbook 读者;通过生成部署参数间接影响实际部署的 mamba 状态池与 KV 池划分,尤其影响长上下文与并发大于 1 的场景。影响程度中等:修复后 EAGLE+ReplaySSM 场景不再出现 KV 池过度收缩,DSPARK 场景状态池不再欠配。对团队的维护成本体现在 jsx、mdx、服务端 kv_cache_configurator.py 三处需保持一致。

计算逻辑为服务端实现的手工镜像,易漂移 缺少自动化测试覆盖 硬编码 checkpoint 默认值需人工同步 修复前输出参数可致 KV 池 -38%

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论