diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fcecd1aae..f1677f0ff 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -80,6 +80,9 @@ jobs: with: node-version: "20" + - name: Check cookbook configs + run: node docs/scripts/check_cookbook_configs.mjs + # Hard gate: docs internal links/anchors/redirects must resolve. # mint is pinned for reproducibility (its heading-slug rules are # version-sensitive); bump deliberately after re-verifying locally. diff --git a/docs/cookbook/autoregressive/DeepSeek/DeepSeek-V4.mdx b/docs/cookbook/autoregressive/DeepSeek/DeepSeek-V4.mdx index 8188dbf18..d9eadf09e 100644 --- a/docs/cookbook/autoregressive/DeepSeek/DeepSeek-V4.mdx +++ b/docs/cookbook/autoregressive/DeepSeek/DeepSeek-V4.mdx @@ -602,4 +602,4 @@ Larger blocks can improve decode latency when acceptance stays high, but they al For every candidate, compare with the same recipe without `--speculative-algorithm DSPARK`. Restart the server between the DSpark and non-speculative legs, keep the request corpus, sampling, concurrency, and warmup identical, and give each `bench_serving` leg its own `--flush-cache`. Leave `--speculative-draft-attention-backend` unset unless a separate profiling run justifies an override. -DSpark currently requires CUDA, `pp_size == 1`, and DP Attention disabled. It is not compatible with PD disaggregation on current SGLang releases; turn DSpark off before selecting a prefill or decode role. The DP-Attention and MI355X Flash Official recipes therefore run target-only. If a larger draft block or concurrency causes graph-capture OOM, lower `--mem-fraction-static`, the draft block size, or the configured maximum running requests, then rerun both performance and accuracy gates. +DSpark currently requires CUDA, `pp_size == 1`, and DP Attention disabled. It is not compatible with PD disaggregation on current SGLang releases; selecting a prefill or decode role in the Playground automatically removes the inherited DSpark flags. The DP-Attention and MI355X Flash Official recipes therefore run target-only. If a larger draft block or concurrency causes graph-capture OOM, lower `--mem-fraction-static`, the draft block size, or the configured maximum running requests, then rerun both performance and accuracy gates. diff --git a/docs/scripts/check_cookbook_configs.mjs b/docs/scripts/check_cookbook_configs.mjs index acba44071..aa3a7b8bb 100755 --- a/docs/scripts/check_cookbook_configs.mjs +++ b/docs/scripts/check_cookbook_configs.mjs @@ -16,6 +16,9 @@ // declares silently stops matching; the panel just shows a different cell. // 4. Predicate safety. showWhen / disabled / flags run against selections the // author never clicked through; a throw there blanks the whole widget. +// 5. PD/speculation reachability. A PD card must stay reachable when a base +// cell inherits an algorithm it declares incompatible, so choosing a PD +// role can remove that algorithm from the generated command. import { readFileSync, readdirSync } from "node:fs"; import { dirname, join, relative } from "node:path"; @@ -193,6 +196,25 @@ for (const path of walk(CONFIGS)) { } }, "curl"); } + + const pd = (config.playgroundFeatures || {}).pdDisagg; + if (pd && typeof pd.showWhen === "function") { + const incompatible = (pd.incompatibleSpeculativeAlgorithms || []) + .map((name) => String(name).toUpperCase()); + for (const [i, cell] of (config.cells || []).entries()) { + const algorithmFlag = (cell.flags || []).find((flag) => + flag.split(/[\s=]/)[0] === "--speculative-algorithm"); + const algorithm = algorithmFlag + ? algorithmFlag.split(/[\s=]/).filter(Boolean)[1]?.toUpperCase() + : null; + if (!algorithm || !incompatible.includes(algorithm)) continue; + const selection = { ...(cell.match || {}), specAlgorithm: algorithm }; + if (!pd.showWhen(selection)) { + fail(where, `cells[${i}] hides PD Disagg for incompatible ${algorithm}; ` + + "the card must remain reachable so a PD role can disable speculation"); + } + } + } } if (failures.length) { diff --git a/docs/src/snippets/_playground.jsx b/docs/src/snippets/_playground.jsx index 69e49d14a..5fe304d5e 100644 --- a/docs/src/snippets/_playground.jsx +++ b/docs/src/snippets/_playground.jsx @@ -909,10 +909,6 @@ export const Playground = ({ config }) => { "--disaggregation-mode", "--disaggregation-transfer-backend", "--disaggregation-ib-device", "--disaggregation-bootstrap-port", ]); - const specAlgorithm = (h.findFlagArg(flags, "--speculative-algorithm") || "").toUpperCase(); - if ((fc.incompatibleSpeculativeAlgorithms || []).includes(specAlgorithm)) { - return { flags, env }; - } const backends = fc.transferBackends || []; // A config that omits `modes` has the role on the Deploy panel instead; // this card then only tunes the transport for whatever role is selected. @@ -921,6 +917,16 @@ export const Playground = ({ config }) => { : ((sel && sel.pdMode) || "off"); if (mode === "prefill" || mode === "decode") { + // PD and some speculative algorithms cannot run together. Keep the + // PD card reachable for a speculative base recipe, then make the + // user's explicit PD-role selection win by removing the whole + // speculative flag family before composing the role command. + const specAlgorithm = (h.findFlagArg( + flags, "--speculative-algorithm") || "").toUpperCase(); + if ((fc.incompatibleSpeculativeAlgorithms || []).includes(specAlgorithm)) { + flags = flags.filter((flag) => + !flag.split(/[\s=]/)[0].startsWith("--speculative-")); + } const backend = value.transferBackend || (backends[0] || {}).id || "mooncake"; const adds = [ `--disaggregation-mode ${mode}`, diff --git a/docs/src/snippets/configs/deepseek-ai/deepseek-v4.jsx b/docs/src/snippets/configs/deepseek-ai/deepseek-v4.jsx index c5a500542..13622017e 100644 --- a/docs/src/snippets/configs/deepseek-ai/deepseek-v4.jsx +++ b/docs/src/snippets/configs/deepseek-ai/deepseek-v4.jsx @@ -319,7 +319,6 @@ sgl-eval run aime25 \\ // ----- Card 5: "PD Disaggregation" ----- pdDisagg: { - showWhen: (base) => base.specAlgorithm !== "DSPARK", incompatibleSpeculativeAlgorithms: ["DSPARK"], modes: [ { id: "off", label: "Off" },