Prhub

#26885 Cookbook renovation

原始 PR 作者 zijiexia 合并时间 2026-06-08 13:04 文件变更 16 提交数 45 评论 7 代码增减 +6692 / -1693

执行摘要

迁移部署 cookbook 为配置驱动模板,消除跨模型代码重复

每个模型 cookbook 都是自包含的部署代码生成器,导致数百行重复React代码,难以同步,新增模型需要从头编写。PR body 指出:'Each model cookbook today is a self-contained deployment-snippet generator (docs_new/src/snippets/autoregressive/<model>-deployment.jsx) — every page re-implements its own hardware/variant/quant UI, command builder, styling, and dark-mode handling. That's hundreds of lines of duplicated React per model, drifts out of sync, and every new model is a from-scratch write.'

值得精读,尤其是 _playground.jsx 中纯数据与视图分离的设计模式,以及如何通过 URL hash 实现状态持久化和分享。review 中关于 PD 端口处理的 bug 修复过程也值得关注。

讨论亮点

Review 由 JustinTong0323 主导,核心讨论包括:

  • PD端口冲突:Playground为 PD 分离角色生成的 serve 端口和分布式初始化端口存在冲突,decode 角色默认使用 30001 但 Docker 命令仍绑定 30000,多节点场景下两个角色的 --dist-init-addr 使用相同端口导致碰撞。作者随后修复了角色特定端口,但 Docker 端口映射尚未完全覆盖。
  • MegaMoE env 清理:切换 MegaMoE 子选项时,旧配置的环境变量(如 FP4 激活相关)未被完全剥离,会导致 W4A8 命令仍携带 W4A4 设置。作者同意并已修复。
  • RTX 6000 Docker 镜像:RTX PRO 6000 有已验证 cell 但未配置专用 Docker 镜像,回退到 dev 镜像。作者回应 SM120 支持尚未进入 release cut,故意使用 dev 镜像,后续再更新。

实现拆解

  1. 设计配置驱动数据契约:在 docs_new/src/snippets/configs/deepseek-ai/deepseek-v4.jsx 中定义5维验证矩阵的 cells,包括模型名、占位符、cURL模板、基准命令、默认精度等,配置为纯数据对象。
  2. 实现共享部署引擎:新增 _deployment.jsx(+1277行),内部维护硬件目录(HARDWARE_CATALOG)和暗色模式样式工厂(makeStyles),通过 findCell 定位匹配的 cell 生成命令行和 cURL 命令,支持 Docker 模式、多节点注入、环境变量持久化、基准重现弹窗。
  3. 实现交互式 Playground:新增 _playground.jsx(+2048行),实现差分覆盖沙箱,用户可在已验证组合基础上调整并行策略、MoE配置等轴,利用 findMatchingCell 检测覆盖后是否命中另一已验证 cell,并展示即时 diff。
  4. 旧组件删除:删除 deepseek-v4-deployment.jsx(-1263行),该组件是之前为 DeepSeek-V4 独立编写的完整UI。
  5. Claude Code 技能与模板:新增 .claude/skills/cookbook-add-model/ 目录,包含配置模板 config.jsx.tmpl(374行)、MDX 页面模板、作者指南和引擎轴参考文档;新增 Issue Template 3-playground-verified-cell.yml 用于用户提交已验证 cell。
  6. 文档页面适配:修改 docs_new/cookbook/autoregressive/DeepSeek/DeepSeek-V4.mdx,由之前直接引用旧组件改为导入新引擎并传递 config 和 benchmarks 属性。
文件 模块 状态 重要度
docs_new/src/snippets/_playground.jsx Playground 引擎 added 9.25
docs_new/src/snippets/_deployment.jsx 部署引擎 added 9.25
docs_new/src/snippets/configs/deepseek-ai/deepseek-v4.jsx 配置数据 added 7.82
docs_new/src/snippets/configs/deepseek-ai/deepseek-v4-benchmarks.jsx 基准数据 added 7.58
docs_new/src/snippets/autoregressive/deepseek-v4-deployment.jsx 旧组件 removed 9.25
.claude/skills/cookbook-add-model/templates/config.jsx.tmpl 配置模板 added 6.1

关键符号

Playground Deployment findMatchingCell makeStyles resolveModelName interpolate findCell flagsEq envEq parseNnodes

关键源码片段

docs_new/src/snippets/_playground.jsx core-logic

新增 Playground 引擎,实现交互式差分覆盖沙箱,核心逻辑包括 findMatchingCell、resolveModelName 等。

// _playground.jsx — 引擎内部的纯数据辅助函数,负责根据配置查找已验证组合
// 这些函数与视图完全分离,便于测试和推理const DIMENSIONS = ["hw", "variant", "quant", "strategy", "nodes"];// 在 cells 数组中精确查找匹配当前选择的 cell
const findCell = (cells, sel) =>
  cells.find((c) => DIMENSIONS.every((d) => c.match[d] === sel[d]));// 比较 flags 数组(有序)
const flagsEq = (a, b) =>
  a.length === b.length && a.every((x, i) => x === b[i]);// 比较 env 数组(无序集合)
const envEq = (a, b) => {
  if (a.length !== b.length) return false;
  const set = new Set(a);
  for (const x of b) if (!set.has(x)) return false;
  return true;
};// 在应用覆盖后,查找是否存在另一个已验证的 cell 与当前 (env, flags) 相同
const findMatchingCell = (cells, sel, pgEnv, pgFlags) => {
  for (const c of cells) {
    if (c.match.hw !== sel.hw) continue;
    if (c.match.variant !== sel.variant) continue;
    if (c.match.quant !== sel.quant) continue;
    if (c.match.nodes !== sel.nodes) continue;
    if (flagsEq(c.flags || [], pgFlags || []) && envEq(c.env || [], pgEnv || [])) {
      return c;
    }
  }
  return null;
};// 解析模型 HF slug:优先 hw|variant|quant,其次 variant|quant
const resolveModelName = (sel) => {
  const triple = `${sel.hw}|${sel.variant}|${sel.quant}`;
  const pair = `${sel.variant}|${sel.quant}`;
  return config.modelNames[triple] ?? config.modelNames[pair] ?? "";
};// 在命令模板中替换 {{PLACEHOLDER}}(MODEL_NAME 特殊处理)
const interpolate = (text, env, modelName) =>
  text.replace(/{{(\w+)}}/g, (_, key) =>
    key === "MODEL_NAME" ? modelName : (env[key] ?? `{{${key}}}`));// 解析节点选项 id,如 "multi-2" -> 2
const parseNnodes = (id) => {
  if (id === "single") return 1;
  const m = /^multi-(\d+)$/.exec(id);
  return m ? parseInt(m[1], 10) : 1;
};
docs_new/src/snippets/_deployment.jsx core-logic

新增部署引擎,读取配置生成命令行和 cURL 命令,支持 Docker 和多节点。

// _deployment.jsx — 部署命令生成引擎,无模型特定代码export const Deployment = ({ config, benchmarks }) => {
  if (!config) {
    return <div style={{padding: 12, color: "#b91c1c", }}>Deployment: missing <code>config</code> prop</div>;
  }  // 硬件目录(跨 cookbook 共享),config.hardware 在运行时合并
  const HARDWARE_CATALOG = {
    nvidia: [
      { id: "h100", label: "H100", vram: "80GB" },
      { id: "h200", label: "H200", vram: "141GB" },
      { id: "b200", label: "B200", vram: "192GB" },
      { id: "b300", label: "B300", vram: "288GB" },
      { id: "gb200", label: "GB200", vram: "192GB" },
      { id: "gb300", label: "GB300", vram: "288GB" },
    ],
    amd: [
      { id: "mi300x", label: "MI300X", vram: "192GB" },
      { id: "mi325x", label: "MI325X", vram: "256GB" },
      { id: "mi350x", label: "MI350X", vram: "288GB" },
      { id: "mi355x", label: "MI355X", vram: "288GB" },
    ],
  };  // 暗色模式感知的样式工厂
  const makeStyles = (isDark) => ({
    container: { maxWidth: "900px", margin: "0 auto", display: "flex", flexDirection: "column", gap: "3px" },
    card: {
      padding: "5px 10px",
      border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
      borderLeft: `3px solid ${isDark ? "#E85D4D" : "#D45D44"}`,
      borderRadius: "4px",
      display: "flex", alignItems: "center", gap: "10px",
      background: isDark ? "#1f2937" : "#fff",
    },
    itemsGrid: () => ({
      display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(72px, 1fr))",
      gap: "4px", flex: 1,
    }),
  });  // 在 cells 数组中查找匹配当前 5 维选择的 cell
  const DIMENSIONS = ["hw", "variant", "quant", "strategy", "nodes"];
  const findCell = (cells, sel) =>
    cells.find((c) => DIMENSIONS.every((d) => c.match[d] === sel[d]));  // ... 剩余渲染逻辑(生成命令、渲染矩阵等)
};

评论区精华

PD 分离模式端口覆盖不完整 正确性

JustinTong0323 发现 decode 角色 serve 端口和 Docker 端口映射存在冲突:decode 默认使用 30001 但 Docker 命令仍绑定 30000,多节点场景下两个角色的 --dist-init-addr 使用相同端口。

结论:作者修复了角色特定 serve 端口,但 Docker 端口映射仍需修正(后续评论指出未完全修复)。 · 部分解决

切换 MegaMoE 子选项时旧环境变量残留 正确性

JustinTong0323 指出从 W4A4 切换到 W4A8 时,FP4 相关的环境变量(SGLANG_OPT_DEEPGEMM_MEGA_MOE_USE_FP4_ACTS 等)未被剥离,导致命令仍运行在 W4A4 模式下。

结论:作者同意并修复了 env 清理逻辑。 · 已解决

RTX 6000 缺少专用 Docker 镜像 question

JustinTong0323 要求为 RTX PRO 6000 添加专用 Docker 镜像或移除该 cell。

结论:作者回应 SM120 支持尚未进入 release cut,故意使用 dev 镜像,后续更新。 · 待跟进

PD 模式 Docker 端口映射使用角色特定端口 正确性

JustinTong0323 指出 PD 模式 decode 角色改用了 --port 30001,但 Docker 命令仍映射 30000 端口,导致容器端口不通。

结论:需使用角色端口进行 -p 映射或切换到 host 网络模式,尚未修复。 · 未解决

风险与影响

  • 命令生成正确性:新引擎自动注入 --nnodes--node-rank-dist-init-addr--host--port,若配置中某 cell 遗漏或处理有误,可能生成不可用命令。review 已发现 PD 端口问题,但仍可能存在其他未覆盖场景。
  • Mintlify 兼容性:引擎需遵守 Mintlify 的 JSX 限制(无模块级别语句、小写标签等),若 Mintlify 升级可能引入兼容性问题。
  • 配置 schema 演变:配置文件的字段契约与引擎强耦合,新增引擎轴需同时修改引擎和参考文档,缺少版本检查。
  • 基准数据维护:基准数据文件 deepseek-v4-benchmarks.jsx 包含大量硬编码数字,需随模型版本或 SGLang 更新而手动更新。
  • 用户:获得更丰富的交互体验(深链接、Playground、基准重现),操作更直观;但旧书签 URL 可能失效。
  • 团队:新增模型 cookbook 只需编写配置文件和简短的 MDX 页面,不再需要编写 React 组件,大幅降低维护成本;但需学习配置数据契约和引擎工作方式。
  • 系统:文档网站构建时新增约 3.3k JS 代码,加载时间可能略增,但影响有限。
命令生成正确性风险 配置 Schema 耦合 PD Docker 端口映射未修复 基准数据手动维护

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论