Files

250 lines
23 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Legacy → config-driven dimension mapping
Loaded on demand by the `cookbook-migrate-model` skill. How to translate a
legacy generator's option space into the 5-dim matrix + Playground axes.
Field schemas live in `../../cookbook-add-model/references/authoring-reference.md`;
this file is about the *mapping decisions*.
## 1. Legacy control → new home
| Legacy control | New home | Rule |
|---|---|---|
| hardware radio | `match.hw` | Catalog ids as-is. Off-catalog hardware → `config.hardware` entry — e.g. A100 `{id:"a100", label:"A100", vram:"80GB", vendor:"nvidia"}` (merges into the NVIDIA row), Xeon `{id:"xeon", label:"Xeon", vram:"host RAM", vendor:"intel"}` (engine renders a new INTEL row; any vendor key works). A merged chip like GLM-5's "MI300X/MI325X" splits into two ids with duplicated cells (cells are denormalized by design). |
| model-size / model-name radio | `variants` | One variant per deployable checkpoint family; single `{id:"default"}` when there's no variant axis (then `modelNames` keys drop the variant half). |
| quantization radio | `quantizations` | Real precision ids (`bf16`/`fp8`/`fp4`/`int4`/…). One `fp4` id even when checkpoints differ per vendor — route via `hw\|variant\|quant` triple keys in `modelNames` (NVFP4 on Blackwell vs AMD MXFP4 is the precedent); per-hw greying falls out of which cells exist. |
| toggle that **couples** with other parts of the command (changes TP/mem/EP), OR one the legacy page labels with **operating-point words** | `strategies` | The Playground applies pure flag diffs — it cannot do coupled changes. Example: Qwen3.5's MTP toggle bumps TP on three H100 combos → strategies `low-latency` (MTP on) / `high-throughput` (MTP off). **Naming counts like coupling**: GLM-5.1's / Kimi-K2.6's `dpattention` adds only `--dp N --enable-dp-attention` (uncoupled), but its options are subtitled "Low Latency" / "High Throughput" — the page's own named operating-point split → strategies; a flag-only spec toggle riding alongside it stays a Playground axis and bakes per its legacy default. GPU-count radios (GLM-4.7, MiniMax-M2.5/2.7) → budget-tier strategies with the legacy SUPPORT matrix preserved by which cells exist. Strategy count follows the page's operating points: 1 → `balanced`, 2 → `low-latency`+`high-throughput`, 3 → the full trio (§4). |
| toggle that only adds/removes its own flags | Playground axis (+ bake, EXCEPT parsers and accuracy-degrading flags) | **Parsers (`--reasoning-parser` / `--tool-call-parser`) are NEVER baked into cells** — Deployment commands ship without them regardless of the legacy default or the measured command; the `parsers` axis adds them on top (DSv4 convention; cells mirror the legacy generator's parsers-OFF output). Accuracy-degrading toggles are never baked either — §2 caveats (axis-only, accuracy-safe cells). Other flag-only toggles: legacy default ON → bake into cells AND declare the axis so users can strip (red strikethrough); default OFF → keep cells clean, axis preset only. MTP/EAGLE presets → `speculative` axis; dp-attention → a strategy when the legacy page labels it as the operating-point split or when coupled (see the row above), else `attention.dpAttn`. **EVERY legacy control survives as an interactive control** (a dimension or a Playground axis), never a tips-only mention — but a model-specific control is **config DATA, not engine code**: the axis handler reads options/flags/env/gating straight from `config.playgroundFeatures` (MegaMoE W4A4 is entirely DSv4 config data on the existing `moe` axis — no per-model engine edit). A control that fits an existing axis's data schema is therefore pure config, full stop. A **titled single-select that strips a flag family** (e.g. Nemotron3's "KV Cache DType" `--kv-cache-dtype`) is covered by the merged generic **`flagSelects`** axis → **config-only**: declare a `flagSelects` list of `{ id, title, stripPrefixes, options }` (see the Qwen3.5 mamba example), **no engine PR**. Only a control whose *shape* `flagSelects` still can't express would need a new ONE-TIME generic primitive (never a model-named handler) on a prior engine PR; the backward-compat reasoning (opt-in per key, not in the opt-out set) is in engine-axis.md. |
| per-combo hidden option (e.g. spec hidden on Xeon) | absent cells | Don't create cells for combos the legacy widget couldn't produce; the engine greys them automatically. `# Error:` pseudo-commands → no cell + explanation in §2 tips and/or a chip `disable`/`disableReason`. |
| coupled secondary knob (e.g. mamba cache V1/V2) | cells + Playground axis | Bake the correct value per cell following the legacy coupling (Qwen3.5: MTP ⇒ `--mamba-radix-cache-strategy extra_buffer` on NVIDIA; AMD/Xeon ⇒ V1/no flag) and document the coupling in §2 tips — AND surface the knob as a Playground axis like every other legacy feature (row above; add the axis when none fits). Baking alone is NOT enough — the every-feature rule supersedes the pilot's cells+prose-only treatment of Qwen3.5's mamba knob (retrofit pending). The mamba knob is the same single-select shape as KV Cache DType, so it rides the merged generic **`flagSelects`** axis — Qwen3.6 / Qwen3-Coder-Next declare it purely in config (a `flagSelects` block), **no engine PR**. |
## 2. Command rewrite table (the ONLY allowed normalizations)
| Legacy | New |
|---|---|
| `python(3) -m sglang.launch_server` | (engine emits `sglang serve`; cells hold flags only) |
| `--model X` / `--model-path X` | `--model-path {{MODEL_NAME}}` + `modelNames` key |
| `--tp-size N` | `--tp N` |
| `--speculative-algo X` (abbreviated) | `--speculative-algorithm X` — the Playground spec axis strips/derives by the full first token only; an abbreviated alias would survive toggles and double up |
| `--speculative-algorithm NEXTN` | `--speculative-algorithm EAGLE` — **NEXTN is an alias of EAGLE** (same algorithm). Normalize cells + presets to EAGLE; never expose both NEXTN and EAGLE as separate `speculative` presets (they'd be duplicate chips). Keep a one-line "the bench reported NEXTN, an alias of EAGLE" provenance note where the measured command used it. |
| `--expert-parallel-size N` | `--ep N` — the Playground EP knob recognizes/strips only `--ep`; the long form would survive toggles and double up |
| (absent) | append `--host {{HOST_IP}}`, `--port {{PORT}}` to every cell |
| `--nnodes N --node-rank … --dist-init-addr …` literals | delete; `match.nodes: "multi-N"` + `nodesOptions` entry — the engine injects the trio after the last parallelism anchor plus the multi-node header comment |
| env-var command prefixes | verbatim into `cell.env[]` (never drop/normalize) |
| flag order as emitted | re-sort to canonical: `--trust-remote-code` → `--model-path` → parallelism (`--tp`/`--dp`/`--enable-dp-attention`/EP) → MoE → tuning → `--host`/`--port` (Playground insert anchors assume this). Keep the legacy relative order within the tuning span so commands stay eyeball-diffable. |
Caveats discovered in the pilot:
- The Playground `moe.ep` knob only understands `--ep` — normalize a legacy
`--expert-parallel-size N` to `--ep N` (alias, see table above) so the knob
can recognize/strip it.
- `multiNodeHints` only for hw whose fabric needs manual NIC env (gb200-class);
standard-IB H100 multi-node needs none. Hints show on both run modes, so
`docker run` flags go in the hardware entry's `multiNodeDockerFlags` instead.
- `dockerImages`: only the tags the legacy page pinned. CPU/Xeon stays unmapped
(`:dev` fallback) with a "install from source" tip.
- **Accuracy-degrading flags** (`--kv-cache-dtype fp8_e4m3`, W4A4-style
runtime quant) — deterministic rule, enforced in migration without
asking:
- offered as a legacy **selectable option/toggle** → never select it;
cells mirror the accuracy-safe side (even if the legacy default was the
lossy side). The option itself **must survive as a Playground control**
— the user's choice may not degrade to a tips mention. Express it as
config data on the fitting axis (DSv4 gates W4A4 behind `megamoeQuant`;
a single-select like Nemotron3-Ultra's "KV Cache DType" radio
None/fp8_e4m3/bf16 rides the merged generic **`flagSelects`** axis — declare
a `flagSelects` block, config-only, no engine PR);
- baked into the recipe's **unconditional/default command** → keep it
verbatim. The legacy measurements ran with it, and fp8 KV halves KV
memory — stripping could OOM the recipe. Expect this pattern: legacy
AMD recipes routinely append `--kv-cache-dtype fp8_e4m3` ("for memory
efficiency"), and GLM-5's NVFP4 path ships it too — all keep.
(Only migration gets this auto-keep — faithfulness wins here. On new
pages the same flags are flag-and-confirm with the maintainer:
authoring-reference §2.2 / review checklist.)
## 2b. Playground axes: opt-out, not opt-in
The legacy page's silence about a feature does NOT mean the axis is dropped.
Every cookbook ships the **general axes** by default — `attention`
(TP/CP/DP-Attn), `moe` (backend + EP) for MoE models, `parsers`,
`speculative`, `pdDisagg`, `hicache` — then adds model-specific axes, and
deletes ONLY axes the model genuinely cannot use (`hisparse` is DSA-only;
MegaMoE is DeepSeek-V4 Blackwell-only). Knobs meaningless for a subset of
variants/hw get `disable` + `disableReason` (per-chip constraints), not
removal — e.g. MoE backend/EP greyed out on dense variants.
`speculative` presets must include every algorithm that actually appears on
the page (otherwise a stripped cell's baseline can't be re-applied) — but
**collapse aliases**: NEXTN is an alias of EAGLE (§2 rewrite table), so a page
benchmarked with NEXTN ships a single `eagle` preset, not both. (Pilot history:
Qwen3.5 once shipped both; corrected to EAGLE-only.)
**MTP `--max-running-requests` hint (engine, automatic):** when a cell's
command turns speculative decoding on (`--speculative-algorithm` present)
without `--max-running-requests`, the Deploy panel + Playground auto-render an
amber callout (SGLang otherwise caps it at 48). It is FLAG-driven, not
strategy-driven — nothing to author per page; do NOT duplicate it in §2 prose.
The `parsers` axis is **add-only**: `--reasoning-parser` /
`--tool-call-parser` are never part of any Deployment cell (see §1) — the
axis adds them on top of the base command, so toggling a parser renders a
green addition, never a strikethrough.
## 3. Verified policy mechanics
- Green requires measured data + flag equality with the measured command (see
SKILL.md hard rule 3). Order `cells[]` so the verified flagship cell is
**first** — `cells[0]` is the page's initial selection.
- When the measured command and the generator default disagree (Qwen3.5: bench
ran `NEXTN` + `SGLANG_USE_CUDA_IPC_TRANSPORT=1`, generator emitted `EAGLE` +
fusion flags), the verified cell mirrors the measurement; the generator
default lives on as the not-verified sibling cells. Offer BOTH as Playground
`speculative` presets and explain the split in §2 tips.
- `config.accuracyLabels` is REQUIRED whenever benchmarks carry accuracy data —
the engine ships no default eval set (#27842); without it the accuracy rows
silently don't render. `defaultAccuracy` paints every *entry-bearing* cell of
a variant — under the strict policy prefer per-entry `accuracy` on the
measured cell only.
## 4. Per-family strategy sets (survey sketches — re-derive from the live page)
The family table below was sketched from the 2026-06-10 survey at PAGE level.
At migration time **re-derive it from the live generator**: pages drift
(precedent: Kimi-K2.6's live page has a speculative toggle the survey notes
lack), and the per-combination rule means gated/hidden toggles — typically on
Xeon, AMD, or a single-recipe quant like NVFP4 — produce `balanced` combos the
page-level sketch doesn't show.
**Strategy-set rule — the count follows the page's operating points** (ids
always from the DeepSeek-V4 vocabulary, never model-specific ids like
`mtp`/`no-mtp`):
- **1 operating point** (a single recipe, no performance toggle) → a single
**`balanced`** strategy. Never invent a second recipe just to fill chips.
- **2 operating points** → **`low-latency` + `high-throughput`**. When the
legacy toggle is MTP / speculative decoding, the mapping is a
**deterministic default — apply it without asking**: MTP on →
`low-latency`, MTP off → `high-throughput`. (Why it's near-certain:
speculative decoding cuts per-token latency at low concurrency, but at
saturation the draft+verify overhead costs more than it saves — DSv4's
high-throughput recipes disable MTP for the same reason.) Other toggles
map by the same serving semantics — the two recurring **high-throughput
markers** are **dp-attention ON** (MLA-attention models) and **EP / DP+EP
ON** (MoE models): both shard work across ranks for saturated throughput
at some per-request latency cost. These directions apply to the toggle
CHOSEN as the strategy dimension (§1); a flag-only spec toggle riding
alongside a named operating-point toggle stays a Playground axis and bakes
per its legacy default — GLM-5.1's spec defaults ON, so its flags bake
into BOTH tiers there. Only if a legacy page documents the OPPOSITE slant
(e.g. "enable MTP for high throughput") stop and confirm with the
maintainer.
- **3 operating points** → the **full trio** (the ideal — e.g. GPU-budget
tiers 2/4/8).
**Signal-driven tiers (hard rule).** A cell goes under `low-latency` /
`high-throughput` ONLY on a signal present in the legacy source: an explicit
performance toggle (MTP/speculative, dp-attention, EP, gpuCount, …), a named
recipe/strategy checkbox, option subtitles ("Low Latency" / "High
Throughput"), or prose stating the operating point. Reading such
a signal is SGLang-level serving semantics (MTP favors latency on any
vendor's silicon), so any migrator can tier any vendor's cells without
hardware-specific judgment. **No signal → `balanced`** — legacy silence is
itself information: the page offered that command as the hardware's
general-purpose operating point, and `balanced` transcribes exactly that.
Never derive a slant from your own hardware intuition ("this flag combo
feels throughput-tuned"); re-tiering on measured evidence is the hardware
owner's follow-up PR, not part of a migration. A toggle that maps to no
dimension, or a suspected undocumented slant → stop and ask the maintainer.
The tiers apply **per (hw × variant × quant) combination**, not just per page:
a combination with fewer operating points than the page parks its cells in
the semantically honest tier. A single recipe with a signal-evidenced slant
goes to that tier (DSv4's RTX PRO 6000 → `low-latency`: workstation card,
low-batch Marlin recipe — the recipe's own SGLang-legible content is the
evidence); a general-purpose recipe with no latency/throughput slant goes to
`balanced` (Qwen3.5's Xeon → `balanced`). Never park a no-slant recipe under
`low-latency`/`high-throughput` just because the page's toggle mapping lands
there — that reads as a semantic lie ("CPU = high-throughput?"). The page's
`strategies` list is the union of tiers actually used (a mixed
[low-latency, balanced, high-throughput] page where GPUs use the two ends and
CPU uses the middle is fine); the engine greys unused chips per selection and
auto-snaps, no extra config needed.
Deviations (e.g. how to name pure GPU-budget tiers) need maintainer sign-off.
The MDX strategy bullets describe serving semantics in the DSv4 style
(single-user chat / typical multi-user / batch jobs), with at most a one-line
model-specific note — never toggle-/migration-centric explanations.
| Family | strategies | Notes |
|---|---|---|
| Gemma4 | `low-latency` (MTP on — the legacy toggle's own "Lower Latency" subtitle) / `high-throughput` (MTP off); mi300x hides the toggle → its single recipe → `balanced` (trio union, Qwen3.5 Xeon pattern) | variants = e2b/e4b/12b/31b/26b-a4b; checkpoint radio Standard(BF16)/QAT(q4_0) → quant ids via `modelNames`; §3.3 prose carries AMD recipes beyond the widget's mi300x — maintainer call on cells-from-prose vs tips; vision/audio invocation prose carries over (deployment matrix is text-standard); "gemma4 branch" version → speed drops, MMLU/GSM8K accuracy keeps (mind the few-shot vs run_eval harness footnote); dedicated multi-arch dev images verbatim |
| Nemotron3-Ultra | dpattention carries "Low latency"/"High throughput" subtitles (naming rule) but THREE perf controls stack — multi-value DP-Attention (2/4/8) × MTP × EP — design the tier mapping via the step-2 table; maintainer sign-off required | NVIDIA-only (h100→gb300) with a per-quant verified-hw SUPPORT matrix → absent cells; "Model" radio = the quant dim (BF16 / NVFP4 Blackwell-only); TP radio 8/16 — TP=16 is 2-node → `nodes` dim; **kvcache radio (None/fp8_e4m3/bf16) → `flagSelects` axis, config-only** (the generic primitive merged in #28128 — NO engine PR); `launch_server` + spec-V2 env prefix verbatim; dedicated `dev-nemotron3-ultra(+cu13)` images verbatim ("not in any stable release"); **"main branch" version is non-reproducible → drop the WHOLE measured result (speed AND accuracy)** unless it can be pinned to the support PR/commit (day-0 rule, §hard-rule-2) |
| GLM-4.5, GLM-4.6 | `low-latency` (TP, + MTP from the legacy checkbox) / `high-throughput` (TP+DP+EP) | |
| GLM-4.7 | `low-latency`(2 GPUs) / `balanced`(4) / `high-throughput`(8) — gpus 2/4/8 + SUPPORT matrix; confirm naming, tiers are GPU budgets | measured-best B200 TP=2 NVFP4 → the verified cell |
| GLM-4.7-Flash | `low-latency` (tp1 + MTP from the legacy checkbox) / `high-throughput` (DP) | derive from the legacy dp/mtp checkboxes |
| GLM-5, GLM-5.1 | `low-latency` (dpattention off) / `high-throughput` (dpattention on) — the dpattention radio carries the page's own "Low Latency"/"High Throughput" subtitles (naming rule, §1) | spec is flag-only, default ON, hidden on AMD → bakes into both tiers on NVIDIA + `speculative` axis; NVFP4 hides all toggles → single no-signal recipe → `balanced` (page ships the trio union) |
| Kimi-K2 | `low-latency` (tp8) / `high-throughput` (dp4+ep4) | variants = instruct/thinking; reasoning chip `hide` on instruct |
| Kimi-K2.5, K2.6 | `low-latency` (dpattention off) / `high-throughput` (dpattention on) — same named-subtitle pattern as GLM-5.1 | K2.5 spec preset carries `--speculative-draft-model-path …eagle3-mla`, chip-gated to h200/b300; K2.6's live page has a NVIDIA-only spec toggle, default OFF → `speculative` axis only, no bake (missed by the survey) |
| Qwen3.6, Qwen3-Next | `low-latency` (MTP on, the legacy speculative toggle) / `high-throughput` (MTP off); Xeon hides the toggle → its single recipe → `balanced` (page ships the trio) | same pattern as the Qwen3.5 pilot |
| Kimi-Linear, MiniMax-M2, Qwen3, Qwen3-Coder, Qwen3-Coder-Next | single `balanced` — one recipe, no performance toggle (rule above: 1 operating point → `balanced`) | renders as one chip; Qwen3-Coder-Next has NO speculative dim on the live page (quant × toolcall × mambaCache only — an earlier sketch wrongly lumped it with Qwen3.6) |
| MiniMax-M2.5, M2.7 | `low-latency`(2) / `balanced`(4) / `high-throughput`(8=tp8+ep8) — confirm naming, tiers are GPU budgets | Xeon (M2.7) is a single no-slant recipe (fixed TP=6) → `balanced` (per-combination rule, Qwen3.5 Xeon precedent) |
| Qwen3.5 (DONE — pilot) | `low-latency` (MTP on) / `high-throughput` (MTP off); Xeon's single no-slant recipe → `balanced` (the page ships the full trio) | see §5 |
Qwen3 variant fan-out: variants = deployable checkpoints size-ordered
(`235b-instruct`, `235b-thinking`, `235b`, `30b-*`, `32b`, …); do NOT abuse
strategies for the instruct/thinking category. Trim original-hybrid chips to
the ones the legacy page actually measured.
## 5. Worked example — the Qwen3.5 pilot (PR #27848)
Decisions log, in the order they came up:
1. **Strategy split over Playground toggle** because MTP couples with TP on
three H100 combos (35B/27B BF16: tp2↔tp1+mem0.88; 122B FP8: tp4↔tp2).
Canonical naming: `low-latency` = MTP on (legacy default), `high-throughput`
= MTP off. Xeon has a single operating point (the legacy widget hid the MTP
toggle there) and its recipe has no latency/throughput slant → its 12 cells
park under `balanced` (per-combination placement; parking them under
high-throughput as a toggle-mapping side effect read as a semantic lie).
Result: 186 cells = 87 low-latency + 87 high-throughput + 12 balanced; the
page ships the full trio and the engine greys unused chips per selection.
2. **Verified cell follows the measurement**: H200/397B/BF16/low-latency =
`SGLANG_USE_CUDA_IPC_TRANSPORT=1` env + `--speculative-algorithm EAGLE`
(the bench reported NEXTN, an alias of EAGLE — normalized to EAGLE, §2) +
measured flag set **minus the parser flags** (the measured run had both
parsers on; cells never carry them — noted in the benchmarks header). All
other cells = the generator's parsers-OFF output verbatim. A single `eagle`
spec preset on the speculative axis (the duplicate NEXTN preset was dropped).
3. **FP4 single quant id** with `hw|variant|quant` modelNames keys →
`nvidia/...NVFP4` (b200/b300) vs `amd/...MXFP4` (mi355x).
4. **Xeon** as `config.hardware` `vendor:"intel"`; cells carry
`--device cpu --disable-overlap-schedule`; no docker mapping.
5. **Playground axes**: the full general set per §2b — attention
(TP/CP/DP-Attn), moe (DeepEP backend + EP knob, `disable`+reason on the
dense variants), parsers, speculative (NEXTN + EAGLE — both algorithms
appear on the page), pdDisagg, hicache. Excluded as inapplicable:
hisparse (DSA-only), MegaMoE (DSv4 Blackwell-only). The legacy
`--expert-parallel-size 8` flag is normalized to `--ep 8` for the EP knob.
6. **Benchmarks**: one entry (the measured cell) only — entry-less cells render
"pending" without stubs. The legacy speed numbers were DROPPED: they were
measured on a drifting "main branch" build, which is no version anchor
(speed migrates only under an exact release tag / commit hash — hard rule
2), so the entry carries accuracy only (GSM8K + MMMU via `accuracyLabels`,
sample counts in `notes`) and no `sglang_version`.
7. **Codegen + audit scripts** (adapt per model): a generator-port script that
emits the cells literal, and an independent audit that `git show`s the
ORIGINAL generator, stubs `useState`/`useEffect`, calls its
`generateCommand(values)` per combo via indirect eval, and token-diffs
against the new cells (expected deltas only). Read the legacy source via
`git show main:<path>` — NOT `HEAD:` (the migration branch's HEAD has
already deleted the file, so the audit breaks after the deletion commit).
Re-run the audit after ANY later cells revision (renames included). Pilot
result: 185/185 identical + 1 intentional override. Scripts are archived
in PR #27848's description (collapsed details block).
8. **Inherited-infeasible combos kept verbatim** (e.g. 122B BF16 tp1 on
mi325x: 244 GB weights vs 256 GB VRAM with mem-fraction 0.8) — they stay
yellow and are listed in the PR body for the re-verification track.
9. **Browser-smoke probe pitfall**: multiple programmatic `.click()` calls in
one synchronous eval batch under React 18 — the DOM reads between them are
stale and look like snap-logic bugs. One click per eval, then settle.