Files
sglang/.claude/skills/cookbook-review-pr/SKILL.md
T

269 lines
17 KiB
Markdown
Raw 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.
---
name: cookbook-review-pr
description: Review a pull request against the SGLang Cookbook (docs/, Mintlify) contribution checklist — the config-driven format (per-model config + benchmarks JSX consumed by the shared _deployment.jsx / _playground.jsx engines). Run with /cookbook-review-pr <PR number>.
---
# Cookbook Review PR
Fetch the diff, run the checklist, report what you find. The cookbook is **config-driven**:
shared engines (`_deployment.jsx`, `_playground.jsx`) with NO model-specific code; each
model is a data `config` (+ optional `benchmarks`) under `src/snippets/configs/<vendor>/`
plus an MDX page. This checklist targets that layout. Field-schema detail lives in
`.claude/skills/cookbook-add-model/references/authoring-reference.md` — defer to it rather
than restating.
## Usage
```
/cookbook-review-pr <PR number>
```
## Steps
1. `gh pr view <N> --repo sgl-project/sglang --json title,body,files,author,baseRefName,headRefName,commits,reviews`
2. `gh pr diff <N> --repo sgl-project/sglang`
3. `gh pr list --repo sgl-project/sglang --state open --search "<model name>"` (duplicate check)
4. Run every checklist item against the diff.
5. Output per-file verdicts + overall recommendation.
## Checklist
### 1. File hygiene
- A cookbook PR should only touch: `docs/src/snippets/configs/<vendor>/*.jsx`
(config + benchmarks), `docs/cookbook/**/*.mdx`, `docs/docs.json`,
`docs/cookbook/<category>/intro.mdx` (vendor card), `docs/cards/logos/<vendor>.png`
(new vendor only). Flag stray files (`settings.local.json`, lockfiles, IDE configs).
- Pages must be `.mdx`, not `.md`. Files end with a trailing newline. Check commit history
for unrelated commits accidentally included.
- **Engines untouched**: `_deployment.jsx` / `_playground.jsx` should NOT change in a
model-add PR (adding a model is data-only). Engine edits = a separate axis/feature PR
(see `cookbook-add-model/references/engine-axis.md`); review them against that checklist.
### 2. Config quality (the per-model `config`)
- Single `export const config = { ... }` literal — **no** function calls, spreads,
fragment refs, or IIFE (Mintlify re-evals at hydration → `ReferenceError`).
- No `!(x in y)` anywhere (Mintlify AST walker crashes) — use `obj.key === undefined`.
- `supportedHardware``HARDWARE_CATALOG` (in `_deployment.jsx`) `config.hardware`. A
model-specific GPU the shared catalog lacks must be declared in `config.hardware`
(`{id,label,vram,vendor}`), **not** added to the engine catalog — unless the platform is
genuinely shared, which is an engine change the PR body has to argue (and the
`cookbook-add-model` hardware table moves with it). A new catalog entry is inert for
other pages: each filters the catalog by its own `supportedHardware`.
- `placeholders` declares every `{{KEY}}` used in `curl` or any cell.
- `modelNames` covers every cell (by `hw|variant|quant` triple or `variant|quant` pair).
- `strategies` count matches the page's operating points — 1 recipe → a single `balanced`;
2 → `low-latency` + `high-throughput`; 3 → the full trio. Tiers apply per
(hw × variant × quant) combination: a single-recipe combination must park under its
semantically honest tier (clear slant → that tier, e.g. a workstation card under
`low-latency`; no slant → `balanced`, e.g. a CPU platform) — **flag a no-slant recipe
parked under low-latency/high-throughput**. Mixed unions
like [low-latency, balanced, high-throughput] with per-selection greying are fine. Also
flag model-specific ids (e.g. `mtp`), and flag an INVERTED speculative mapping — the
deterministic default is MTP/spec-decoding ON → `low-latency`, OFF → `high-throughput`
(at saturation the draft+verify overhead outweighs the speedup); the reverse needs an
explicit maintainer-confirmed justification in the PR. The MDX strategy bullets describe serving semantics
in the DSv4 style (single-user chat / typical multi-user / batch jobs), not internal
toggles.
- `dockerImages` covers the hw ids that have cells (else users hit the `:dev` fallback); a
`hw|quant` key (resolved before the plain `hw`) is valid when one quant on a shared GPU needs
a different image (e.g. an FP4 dev build) — don't flag those.
- `multiNodeHints` present ONLY for hw whose fabric needs manual NIC env (e.g. `gb200`
NVL72) — NOT every `multi-N` hw (standard-IB DeepEP / Marlin multi-node don't need it).
Hints render above BOTH run modes, so flag one that reads as docker-only ("add these
docker run flags") — `docker run` flags belong in the hardware entry's
`multiNodeDockerFlags`, which the engine emits into the Docker command itself.
- `github.cookbookModel` is set to the model's HF id (`<hf-org>/<model-slug>`). The issue
template's `model` field is a free-form input prefilled from this value; if the config
omits the `github` block, the engine falls back to `deepseek-ai/deepseek-v4` and the
page's submissions get mislabeled.
- `playgroundFeatures` is opt-OUT: the **general axes ship on every cookbook by default**
(`attention` TP/CP/DP-Attn, `moe` backend+EP for MoE models, `parsers`, `speculative`,
`pdDisagg`, `hicache`) — flag a missing general axis unless the model genuinely cannot
use it. Model-specific axes only where applicable (MegaMoE backend + `megamoeQuant`
only on Blackwell MoE, gated by `requiresHw`; `hisparse` only DSA-style). Knobs that are
meaningless for a subset of variants/hw are `disable`d with a reason, not silently live
(e.g. MoE knobs greyed on dense variants). No empty/stub axes.
- **No leftover `__TOKEN__`** — the config was stamped from the template and every
placeholder is filled (`grep -rn '__[A-Z_]*__'` on the new config/benchmarks/MDX returns
nothing).
- **All-hardware considered**: every `supportedHardware` id (from the catalog or `config.hardware`) has ≥1 cell OR is a deliberate
greyed "coming soon"; AMD was pruned or kept on purpose (not a leftover template family).
### 3. Cells / 5-dim matrix
- Every cell `match` has EXACTLY the 5 keys (`hw`, `variant`, `quant`, `strategy`, `nodes`).
- `env` / `flags` are flat literals (only `{{PLACEHOLDER}}` subst) — no shared
`commonFlags` reference (Mintlify won't inline it).
- NO `--nnodes` / `--node-rank` / `--dist-init-addr` literals in multi-node cells
(the renderer injects them from `match.nodes`).
- NO literal `--host` / `--port` — use `{{HOST_IP}}` / `{{PORT}}`.
- NO `--reasoning-parser` / `--tool-call-parser` in any cell — parsers are a
Playground-only feature added on top of the base command (DSv4 convention);
flag any cell that bakes them in.
- Accuracy-degrading flags in cells — runtime quant below the checkpoint
(e.g. MegaMoE W4A4 — DSv4 gates it behind the Playground's `megamoeQuant`)
and lossy `--kv-cache-dtype` (e.g. `fp8_e4m3` over a higher-precision-KV
checkpoint): **flag for explicit maintainer confirmation**. Output quality
should be exactly what the quant chip declares, so absent a recorded
sign-off in the PR (e.g. carried verbatim from a measured legacy recipe's
default command), request the flag move to Playground/tips.
- Flag order: `--model-path` first (an optional `--trust-remote-code` may precede it —
the DSv4 cells do), then parallelism, then MoE, then tuning, `--host`/`--port`
last (the playground's insert anchors assume this).
- TP/memory sanity: `model_weight_GB / (tp × gpu_mem)` fits with ~2030% headroom
(BF16 ≈ params×2 GB, FP8 ≈ ×1, FP4 ≈ ×0.5; MoE uses **total** weight, not active params).
### 4. Benchmarks
- Each `benchmarks[]` entry's `match` tuple corresponds to a real cell.
- `accuracyLabels` is present whenever the benchmarks carry accuracy data — the engine
ships NO default eval set; without it the accuracy rows silently don't render.
`defaultAccuracy` / per-cell `accuracy` / `benchmarkCommands.accuracy` keys all
`config.accuracyLabels`.
- A benchmark's quantization must match a variant actually listed — `(BF16)` on a model
that only released FP8/FP4 is a factual bug.
- `benchmarkCommands.speed` is `python3 -m sglang.bench_serving` (the workload), separate
from the `sglang serve` deploy command, and should carry `--flush-cache`: bench_serving's
`random` prompts are deterministic, so a warm rerun hits the radix cache and inflates
throughput — speed numbers are measured cache-cold.
- `sglang_version` is a real build the author ran (a release, or `dev`/nightly) — not a
guessed/placeholder value (no leftover `0.0.0`).
- **Latency percentile**: `config.latencyPercentile` (default `"P50"`, or `"Mean"`) matches the
percentile the TTFT/TPOT values actually are — the card renders `TTFT (<pct>)`. A benchmarks
entry may carry its own `latencyPercentile` to override the page value per cell
(entry → config → `"P50"`): on a P50 page, kept legacy Mean cells must set it — a
`sglang_version` tag alone doesn't convey the percentile. (`"Mean"` is temporary — legacy
data is being re-measured to P50.)
- **Throughput convention**: `tokens_per_sec_per_gpu` is stored as **total (in+out)/GPU**
= `output tok/s/GPU × (isl+osl)/osl`, shown by the card as-is. Flag output-only values.
- **Consistent accuracy harness across entries**: every value under one `accuracyLabels`
column must be produced by the SAME harness — flag a page that, say, measures one
platform's GSM8K with `few_shot_gsm8k --num-questions 200` and another's with
`run_eval --eval-name gsm8k --num-examples 1319` and shows both as one "GSM8K %"
(the scores aren't comparable). Either standardize on one harness (matching
`benchmarkCommands.accuracy`) or require an explicit per-entry note. Common when folding
a second contributor's measurements (e.g. an AMD/ROCm PR) into the page.
### 5. Doc ↔ config parity (the #1 finding)
- Any `sglang serve` command shown in MDX prose (config tips, benchmark section) must
equal what the engine emits from the corresponding cell — same flags, same order. Drift
here is the most common review miss.
### 5b. ComfyUI section (diffusion pages)
- A diffusion page ends with `## <n>. Run in ComfyUI` rendering `<ComfyUISupport />`. A
reader must not have to guess whether the model is reachable from ComfyUI.
- The `model` prop is a key that exists in `docs/src/snippets/diffusion/comfyui-support.jsx`.
A model-specific key is only correct when the plugin really treats it specially — an entry
in `executor_class_dict`
(`python/sglang/multimodal_gen/apps/ComfyUI_SGLDiffusion/core/generator.py`) or a dedicated
node. Otherwise the generic `image` / `video` key is the honest one; a model-specific key
without matching plugin support makes the page claim support that does not exist.
- Prose describing ComfyUI support inline instead of using the component is a finding: the
facts drift from the plugin.
### 6. Commands / port
- Launch uses `sglang serve` — flag any `python -m sglang.launch_server` /
`python3 -m sglang.launch_server` (deprecated). The engine already emits `sglang serve`;
guard against prose/cells reintroducing the old launcher.
- Port `30000` everywhere (launch, curl, client `base_url`, bench) — flag `8000`.
Launch port must match client/curl port on the same page.
### 7. Frontmatter
- Every new MDX page has `title:` and a **top-level** `description:` (a real one-line value
prop, not copied from another vendor) — NOT `metatags.description` (non-canonical; the
top-level field is what renders as the subtitle and SEO meta — see mintlify-authoring).
- **No `mode: wide` on a model page** — it hides the right-hand "On this page" ToC that every
other model page has. Leave `mode` unset (the Deploy/Playground panels self-cap at 900px, so
the default column holds them fine). `mode: wide` belongs only on category `intro.mdx` grids.
- `tag: NEW` only for genuine new launches; when one is added, stale `tag: NEW` on older
pages should be dropped in the same PR (`grep -RlE "^tag: NEW" docs/cookbook/`).
- MDX imports BOTH `Deployment` and `Playground` from `/src/snippets/...` (absolute).
- Deploy heading slugs to `deployment` (or `deploy`), Playground to `playground` — so
"↑ Switch base" and "Open the Playground →" scroll. No numbered headings for these two.
### 8. Navigation & homepage
- New page → `docs/docs.json` updated: under the right vendor group inside
`navigation` → Cookbook → Autoregressive Models, root-relative, **no `.mdx`**:
`cookbook/<category>/<Vendor>/<Model>`.
- Homepage `<Card href>` in `docs/cookbook/<category>/intro.mdx` points to the vendor's
flagship; new vendors get a new `<Card>` + a logo at `docs/cards/logos/<vendor>.png`
**940×525 RGBA transparent, icon-only (no wordmark)**, lowercase filename, tracked via
`git add -f` (`*.png` is gitignored repo-wide). Card order matches the `docs.json` nav order.
- Don't change `docs/cookbook/intro.mdx` for individual model adds (top-level only).
### 9. Links & factual
- HuggingFace URLs resolve to a real model. License section matches the actual HF license
(don't copy from another model). Docker images from `lmsysorg/sglang`; no `sgl-project-dev`.
The image **tag** is a real build (a release the author ran, or `:dev`/nightly) — not a
guessed version.
- Internal links root-relative, no extension (`/cookbook/.../<Model>`); flag `.md`/`.mdx`
or `../`-relative links. `docs.sglang.io` is canonical.
- No Google-Drive image links (don't render). Shell placeholders are `export VAR=<value>`,
not `${VAR}` (a bash no-op).
- **Parser ids must exist in the code registries** on the PR's target branch: every
`--reasoning-parser X` / `--tool-call-parser Y` named in prose or in
`playgroundFeatures.parsers` flags is a registered key in
`python/sglang/srt/parser/reasoning_parser.py` (DetectorMap) /
`python/sglang/srt/function_call/function_call_parser.py` (ToolCallParserEnum) —
prose naming a near-miss id (e.g. the reasoning id where the tool id differs) is a
factual bug. `--…-parser auto` is acceptable ONLY if the template-detection rules
(`python/sglang/srt/managers/template_detection.py`) actually resolve THIS model's
chat template to the right parser — no rule match means auto silently disables the
parser; when in doubt require explicit ids (the DSv4 page pins explicit ids).
### 9b. MDX authoring (Mintlify) — detail in `cookbook-add-model/references/mintlify-authoring.md`
- **Forbidden syntax**: no Docusaurus admonitions (`:::`), `@site`/`@theme`, GitHub alert
blocks (`> [!NOTE]`), markdown **pipe tables** (use JSX `<table>`), inline `<details>`,
or unknown components. `<CardGroup>`/`<Card>` only on category `intro.mdx`, not model pages.
- Code fences are **labeled** (e.g. `python Example` / `bash Command` / `text Output` after
the opening fence); a fenced block nested inside another uses four backticks outside.
- §3 commands and outputs are **collapsible** (DeepSeek-V4 pattern): every runnable
example wrapped in an `<Accordion>`, its real output in a following
`<Accordion title="Example Output">` (`Pending update...` only with user
acknowledgement). Flag bare/inline example blocks and `**Output Example:**` headings.
- Reasoning-parser example matches the parser's **output shape**: separate-field
(`reasoning_content` + `content`) vs inline `<think>` tags parsed out of `content`.
- No hardcoded sampling params (`temperature` / `top_p`) in sample code (SGLang uses
`generation_config.json` defaults); listing them in §1 informationally is fine.
### 10. Quantization rules
- **NVFP4** checkpoints are Blackwell-only (B200/B300/GB300) — never AMD. An AMD FP4 cell
is legitimate ONLY when the vendor published an **MXFP4** checkpoint for it (e.g.
`amd/Qwen3.5-397B-A17B-MXFP4` on MI355X) — verify the HF repo resolves; otherwise the
AMD FP4 chip must be absent/`disabled`.
- BF16 / FP8 work on NVIDIA and AMD. `--kv-cache-dtype fp8_e4m3` in a cell is an
accuracy-degrading flag — see §3 (needs explicit maintainer sign-off; default
home is Playground/tips).
### 11. Scope
- Changes match the PR title. Flag global changes hiding behind a platform-specific title
(e.g. an "H200 FP8" PR that adds a flag to ALL cells). Unmentioned side-fixes belong in
the PR body.
### 12. Duplicate PRs
- Another open PR for the same model? Flag it; compare completeness; note merge-conflict
risk on `docs.json` + the vendor card; flag a superseded older PR by the same author.
### 13. Build / validate
```bash
cd docs
mint validate
mint broken-links
```
Optional: `mint dev` for a visual smoke test.
### 14. Reviewer feedback
- `gh api repos/sgl-project/sglang/pulls/<N>/comments` — have prior reviewer requests been
addressed? Unresolved requested-changes should be flagged.
### 15. Grammar & spelling
- Check added/changed prose for typos and grammar (e.g. "recommend" vs "recommended").
Flag each with the exact wrong text + correction.
## Output
Per file:
- ✅ PASS
- ⚠️ ISSUE: \<what\>
- 🔴 BLOCK: \<what\>
Overall: **APPROVE** / **REQUEST CHANGES** / **BLOCKED**