Prhub

#35861 docs: add DSPARK speculative decoding option to Ling-3.0-flash cookbook

原始 PR 作者 JustinTong0323 合并时间 2026-08-22 02:50 文件变更 4 提交数 8 评论 1 代码增减 +153 / -62

执行摘要

Ling-3.0-flash cookbook 新增 DSPARK 投机解码选项

PR body 明确提出将投机解码提升为一等公民选择器:"Promotes speculative decoding on the Ling-3.0-flash cookbook to a first-class Spec Decode selector in the Deploy panel — NEXTN (built-in MTP) / DSPARK (external draft) / Off"。动机之一是 DSPARK 带来的显著吞吐收益:B200 BF16 上 c1 吞吐 1902 vs 886 tok/s/GPU(约 2.1×),c16 为 8025 vs 5936(约 1.35×),而 GSM8K 精度几乎持平(96.59% vs 96.66%)。另一个直接触发点是配方可运行性:草稿 block size 8 使验证窗口为 9 tokens,KDA ReplaySSM ring 必须是 2 的幂且不小于 2× 窗口,默认 16 会在启动校验时失败——该问题是在实际运行组合命令时发现的。

值得精读 ling-3.0-flash.jsx 的 IIFE 组织方式与 _playground.jsx 的 flag 生命周期管理:前者展示了在受限的 snippet 编译环境里做代码生成的技巧,后者说明了多选项轴的"识别—剥离—插入"三段式设计。若团队计划为其他模型补充 DSPARK 或其他外部草稿选项,可直接复用这个模式;引擎开发者无需关注本 PR。

讨论亮点

本 PR 几乎没有人工 review 讨论:唯一的 review 是 zijiexia 的 APPROVED(空 body),唯一的 PR 评论来自 mintlify[bot] 的 preview 部署通知,不涉及技术内容。真正有价值的"讨论"隐藏在 8 个 commit 的演进里:commit 255df4a "fix Ling cookbook render — keep snippet config free of top-level code" 揭示了关键实现约束——Mintlify snippet 编译器只求值导出表达式、顶层模块代码会被丢弃,因此 cells 必须迁入 IIFE;commit ec31e57 "drop stray semicolon" 则清理了残留分号。这些是对渲染器约束的适配过程,也解释了为何 dsparkTwin 必须写在 IIFE 内部。

实现拆解

  1. 新增 spec 匹配维度(docs/src/snippets/configs/inclusionAI/ling-3.0-flash.jsx):引入 matchDims 中的 spec 维度(nextn / dspark / off),Deploy 面板呈现 Spec Decode 选择器;既有 low-latency 配方标记为 spec: "nextn",high-throughput 配方标记为 spec: "off"(饱和场景下 draft/verify 开销不划算)。
  2. 用 IIFE + dsparkTwin 自动生成 DSPARK twin cells:由于 Mintlify snippet 编译器只求值导出的表达式、顶层模块代码会被丢弃,cells 整体迁入 IIFE。dsparkTwin 从每个 NEXTN low-latency cell 复制出 twin,把 --speculative-algorithm NEXTN 替换为 DSPARK_FLAGS(含 --speculative-algorithm DSPARK--speculative-draft-model-path--enable-linear-replayssm-spec--linear-replayssm-cache-len 32),并只在 b200 + bf16 组合上标 verified: true
  3. 共享 Playground 组件对齐(docs/src/snippets/_playground.jsx):speculative 轴的 deriveFromBase 识别列表与 stripFlagsByFirstToken 剥离列表都补上 --enable-linear-replayssm-spec--linear-replayssm-cache-len,保证从 DSPARK 切换到 NEXTN / Off 时不残留 ReplaySSM flag;该组件被所有模型页面共享,改动对其他模型页面无行为影响。
  4. 基准数据按 spec 键化(ling-3.0-flash-benchmarks.jsx):每条 match 补充 spec 字段,形成与 cells 一致的数据契约;B200 BF16 low-latency 用 PR #33561 head 0e5e40d8f(dev-Ling-3.0-flash 镜像)重新测量,新增 NEXTN 与 DSPARK 两套速度/精度数据(80 条等长随机请求,ISL 8192 / OSL 1024)。
  5. 文档正文配套(Ling-3.0-flash.mdx):Available Models 增加 DSPARK draft checkpoint 链接;Configuration Tips 说明 ReplaySSM ring 大小推导(block size 8 → 9-token 验证窗口 → 2 的幂且 ≥ 18 → 32),并给出验证环境与数据(BF16、4×B200 TP4、GSM8K 96.66% / stop rate 99.77%,NEXTN 对照 96.44% / 99.62%)。

测试与配套说明:无引擎测试变更;验证手段为 docs 自身的 check_cookbook_configs.mjsmint validatemint broken-links,以及作者在 4×B200 上对组合命令的端到端 serving、smoke、bench 与全量 GSM8K 跑分。

文件 模块 状态 重要度
docs/src/snippets/configs/inclusionAI/ling-3.0-flash.jsx 文档配置 modified 7.33
docs/src/snippets/configs/inclusionAI/ling-3.0-flash-benchmarks.jsx 基准数据 modified 6.31
docs/src/snippets/_playground.jsx 共享组件 modified 4.96
docs/cookbook/autoregressive/InclusionAI/Ling-3.0-flash.mdx 文档正文 modified 2.84

关键符号

dsparkTwin deriveFromBase apply

关键源码片段

docs/src/snippets/configs/inclusionAI/ling-3.0-flash.jsx core-logic

本 PR 的核心实现文件:新增 spec 匹配维度与 DSPARK 选项,cells 迁移到 IIFE 并用 dsparkTwin 自动生成 DSPARK twin 配方。

// Mintlify 的 snippet 编译器只求值导出的表达式,顶层模块代码会被整体丢弃,
// 因此 cells 必须放进 IIFE,flatMap 生成 DSPARK twin 的逻辑才能被执行。
cells: (() => {
  // DSPARK 外部草稿路径由 4 个 flag 联动:
  // --speculative-algorithm DSPARK 切到外部草稿算法;
  // --enable-linear-replayssm-spec 启用 KDA ReplaySSM 线性验证路径;
  // --linear-replayssm-cache-len 32 是推导值:草稿 block size 8 使 verify
  // 窗口为 9 tokens,ReplaySSM ring 必须是 2 的幂且 >= 2× 窗口,
  // 默认 16 过小,服务会在启动校验时拒绝。
  const DSPARK_FLAGS = [
    "--speculative-algorithm DSPARK",
    "--speculative-draft-model-path inclusionAI/Ling-3.0-flash-dspark",
    "--enable-linear-replayssm-spec",
    "--linear-replayssm-cache-len 32",
  ];  // 从 NEXTN low-latency cell 复制出 DSPARK twin:
  // match 键改为 spec: "dspark",flags 中出现的 NEXTN 整体替换为 DSPARK_FLAGS。
  const dsparkTwin = (cell, verified) => ({
    ...cell,
    verified,
    match: { ...cell.match, spec: "dspark" },
    flags: cell.flags.flatMap((f) =>
      f === "--speculative-algorithm NEXTN" ? DSPARK_FLAGS : [f]),
  });  // 原有 low-latency 配方补上 spec: "nextn" 字段,flags 不变;
  // 下面仅保留 b200 + bf16 的完整 cell 作示例,其余硬件同构。
  const lowLatencyCells = [
    {
      match: { hw: "b200", variant: "default", quant: "bf16",
               strategy: "low-latency", spec: "nextn", nodes: "single" },
      verified: true,
      flags: [
        "--model-path {{MODEL_NAME}}",
        "--tp 4",
        "--speculative-algorithm NEXTN",
        "--mem-fraction-static 0.8",
        "--host {{HOST_IP}}",
        "--port {{PORT}}",
      ],
    },
    // ...h20-3e / h200 / h800 / h100 / gb300 以及 fp8 系列同构
  ];  // 每个 low-latency cell 后紧跟其 DSPARK twin;
  // 只有 b200 + bf16 组合在 4×B200 上做过完整验证,标 verified。
  return [
    ...lowLatencyCells.flatMap((c) => [
      c,
      dsparkTwin(c, c.match.hw === "b200" && c.match.quant === "bf16"),
    ]),
    // ...high-throughput(spec: "off")与 hicache(spec: "nextn")系列 cell
  ];
})(),
docs/src/snippets/_playground.jsx core-logic

共享的 Playground 组件:speculative 轴的 flag 识别与剥离列表新增 ReplaySSM 参数,保证切换 spec 时不留过期 flag,是所有模型页面共用的交互引擎。

// ---- Axis: Speculative Decoding -----------------------------------------
// 单选项轴:value 为 "current" 时保持 base 原样;为 "off" 时剥离全部
// spec flag(greedy);为具体选项时先剥离旧 flag,再插入选中项自己的 flags。
// deriveFromBase:收集 cell 里现有的 --speculative-* flag 集合,
// 与各选项的 flags 做数量 + 内容双重匹配,命中即视为该选项,否则回退 "current"。
deriveFromBase: (cell, fc) => {
  const flags = (cell && cell.flags) || [];
  const baseSpec = flags.filter((f) => {
    const head = f.split(/[\s=]/)[0];
    return head === "--speculative-algorithm"
      || head === "--speculative-num-steps"
      || head === "--speculative-eagle-topk"
      || head === "--speculative-num-draft-tokens"
      || head === "--speculative-dspark-block-size"
      // ReplaySSM 是 DSPARK 外部草稿的配套验证路径,必须纳入识别与剥离,
      // 否则从 DSPARK 切回 NEXTN / Off 时会残留 --linear-replayssm-cache-len。
      || head === "--enable-linear-replayssm-spec"
      || head === "--linear-replayssm-cache-len"
      || head === "--speculative-ngram-max-bfs-breadth";
  });
  if (baseSpec.length === 0) return "off";
  for (const opt of (fc.options || [])) {
    if (!opt.flags || opt.flags.length !== baseSpec.length) continue;
    const ok = opt.flags.every((pf) => baseSpec.includes(pf));
    if (ok) return opt.id;
  }
  return "current";
},// apply:切换选项时按首个 token 剥离全部 spec 相关 flag,
// 再插入目标选项的 preset flags;选择与 base 一致时直接返回以保留 flag 位置。
apply: ({ flags, env, value, fc, sel, h, derived }) => {
  if (value === "current") return { flags, env };
  if (derived && value === derived) return { flags, env };
  const picked = (fc.options || []).find((p) => p.id === value);
  if (picked && h.evaluateChip(picked, {
    ...sel,
    dpAttnOn: h.hasFlag(flags, "--enable-dp-attention"),
  }).disabled) {
    return { flags, env };
  }
  flags = h.stripFlagsByFirstToken(flags, [
    "--speculative-algorithm", "--speculative-num-steps",
    "--speculative-eagle-topk", "--speculative-num-draft-tokens",
    "--speculative-dspark-block-size", "--enable-linear-replayssm-spec",
    "--linear-replayssm-cache-len",
    "--speculative-ngram-max-bfs-breadth",
  ]);
  const preset = (fc.options || []).find((p) => p.id === value);
  if (preset?.flags?.length) flags = h.insertBeforeTail(flags, preset.flags);
  return { flags, env };
},

评论区精华

Mintlify preview 部署确认 other

mintlify[bot] 自动回复:preview 部署就绪,提供 lmsysorg 文档预览链接 View Preview,指向 cookbook/autoregressive/InclusionAI/Ling-3.0-flash 页面。

结论:仅为部署通知,无技术内容;文档渲染链路的适配在提交历史中完成闭环(多次 retrigger、顶层代码迁入 IIFE、清理残留分号)。 · 已解决

风险与影响

  1. 草稿仓库未公开:PR body 明确说明 "the draft repo is currently private — the HF link 404s anonymously until it goes public"。文档发布后用户按配方执行会先遇到 404,属于已知的临时性外部依赖风险。
  2. 文档内数据不一致:PR body 表格中 NEXTN 为 96.66%、DSPARK 为 96.59%,而 mdx 正文写 DSPARK 96.66%、NEXTN 96.44%(且 stop rate 99.77% / 99.62%),两处数字可能来自不同测量轮次,读者对照时容易困惑。
  3. 共享组件匹配逻辑脆弱deriveFromBase 要求 opt.flags.length === baseSpec.length 且逐条相等;若未来引擎给 cell 追加其它 speculative flag(如 --speculative-num-steps),长度不匹配会让选择器回退为 "current",显示异常。
  4. 基准数据易过期:benchmark 锚定 PR #33561 的具体 commit 与 dev-Ling-3.0-flash 镜像,mdx 中已存在 GB300 数据待补的 TODO,后续引擎演进后数值需要重新测量。

用户侧:Ling-3.0-flash 部署页面新增 Spec Decode 维度,可一键切换 NEXTN / DSPARK / Off 并查看各自基准,低延迟场景可直接选用吞吐更高的 DSPARK 路径。系统侧:纯文档与文档站配置变更,无引擎代码改动,不影响运行时行为。团队侧:该模式(matchDims 新维度 + IIFE 生成 twin cells)为其它模型 cookbook 扩展外部草稿投机解码提供了可复制的样板;共享 Playground 的 flag 生命周期管理逻辑得到一次实际扩展验证,后续新增 spec 类 flag 有明确落点。影响程度有限且可控。

草稿模型仓库未公开 PR body 与文档数据不一致 共享组件 flag 匹配逻辑脆弱 基准数据随版本过期

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论