[doc] standardize diffusion cookbook model pages (#34247)
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ lacks, and replace the EXAMPLE cells with verified recipes. DeepSeek-V4 is a pop
|
||||
- [references/mintlify-authoring.md](references/mintlify-authoring.md) — MDX rules (forbidden syntax, JSX tables, labeled fences) + invocation-example patterns. Read before writing §1–§3 prose.
|
||||
- [references/engine-axis.md](references/engine-axis.md) — adding a new Playground feature axis (rare engine work).
|
||||
- [references/vendor-logo.md](references/vendor-logo.md) — new-vendor card logo: ask the user for the brand logo, then generate the icon-only 940×525 RGBA PNG (spec + Pillow recipe + `git add -f`).
|
||||
- [references/diffusion-authoring.md](references/diffusion-authoring.md) — required opening, tag, command-picker, and feature-overlay contract for diffusion model pages. Read before editing any `docs/cookbook/diffusion/<Vendor>/<Model>.mdx` page.
|
||||
|
||||
## Architecture at a glance
|
||||
|
||||
@@ -68,9 +69,12 @@ playground reads it), the **`sglang-deploy-sel` custom event** (deploy dispatche
|
||||
every change; playground listens — `replaceState` doesn't fire `hashchange`), and the
|
||||
shared **`sglang-deploy-env` localStorage key** (HOST/PORT placeholders).
|
||||
|
||||
> The template is **autoregressive**. Diffusion / omni pages follow their own category
|
||||
> structure — don't force the config-driven template on them; still obey the Mintlify /
|
||||
> NEW-tag / docs.json / category-card / validation rules below.
|
||||
> The main template is **autoregressive**. Diffusion pages use
|
||||
> `templates/diffusion-page.mdx.tmpl` plus
|
||||
> [references/diffusion-authoring.md](references/diffusion-authoring.md); do not force the
|
||||
> autoregressive deployment matrix on them. Omni pages follow their own category structure.
|
||||
> All categories still obey the Mintlify / NEW-tag / docs.json / category-card / validation
|
||||
> rules below.
|
||||
|
||||
---
|
||||
|
||||
@@ -131,6 +135,15 @@ this table (RTX PRO 6000, GH200, future chips) goes in the model's own `config.h
|
||||
|
||||
## Phase 2 — Instantiate the template
|
||||
|
||||
For a diffusion model, instantiate `templates/diffusion-page.mdx.tmpl` and keep the
|
||||
shared `DiffusionModelTags` component, plus `templates/diffusion-config.jsx.tmpl` for the
|
||||
opt-in scoped command builder. Put the compact install command and builder in §1 Quick
|
||||
start. The first two paragraphs in §2 Model capabilities are not generic filler: they must
|
||||
state the model's capability range, strongest differentiator, when to choose it, and at
|
||||
least one real deployment or capability boundary. Put orthogonal runtime features in
|
||||
`scope: "serve"` or `scope: "request"`, not in the base recipe; use the schema from
|
||||
`references/diffusion-authoring.md`.
|
||||
|
||||
1. **Copy** the three template files to their target paths (above). Note the two
|
||||
vendor-folder conventions: under `configs/` the folder is the **HuggingFace org**
|
||||
(`deepseek-ai`); under `cookbook/` it's the **display vendor** (`DeepSeek`).
|
||||
@@ -206,6 +219,10 @@ user notes: §1 Model Introduction (description, links, params, license, variant
|
||||
Tool-Calling / HiCache — keep only what applies; match the reasoning example to the
|
||||
parser's output shape; each runnable block gets an `**Output Example:**`).
|
||||
|
||||
For diffusion pages, follow the category-specific Quick start and capability contract in
|
||||
`references/diffusion-authoring.md`. Run `node docs/scripts/check_cookbook_configs.mjs` to
|
||||
verify the tag widget and introduction structure before rendering the page.
|
||||
|
||||
## Phase 6 — Review
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
# Diffusion cookbook authoring contract
|
||||
|
||||
Use this contract for every model page under
|
||||
`docs/cookbook/diffusion/<Vendor>/<Model>.mdx`.
|
||||
|
||||
## Opening structure
|
||||
|
||||
Import and render the shared tag widget immediately after frontmatter:
|
||||
|
||||
```mdx
|
||||
import { DiffusionModelTags } from '/src/snippets/diffusion/model-tags.jsx';
|
||||
|
||||
<DiffusionModelTags tags={["video + audio", "text-to-video", "reference control", "4–15 seconds"]} />
|
||||
```
|
||||
|
||||
Use 4–6 tags, ordered from broad to specific:
|
||||
|
||||
1. output modality or product class;
|
||||
2. primary request modes;
|
||||
3. the capability that differentiates the model;
|
||||
4. an important scale, latency, duration, resolution, or architecture fact.
|
||||
|
||||
Do not spend tags on generic claims such as `native`, `fast`, `high quality`, or
|
||||
`SGLang`. Attention backends, Cache-DiT, and online quantization are feature overlays,
|
||||
not model identity, unless a published checkpoint is intrinsically tied to that format.
|
||||
|
||||
The page must start with `## 1. Quick start`: keep installation to one runnable
|
||||
command, add at most one short orientation paragraph, and render the scoped command
|
||||
builder before detailed capability tables or deployment commentary. A reader should
|
||||
reach a generated Serve command without scrolling through model background first.
|
||||
|
||||
Follow it with `## 2. Model capabilities` and 2–3 short paragraphs:
|
||||
|
||||
- paragraph 1: what the model does and where it is genuinely strong;
|
||||
- paragraph 2: when to choose it and the most important limitation or tradeoff;
|
||||
- optional paragraph/table: checkpoint or mode routing that a user must understand before serving.
|
||||
|
||||
Keep the capability lead between roughly 45 and 180 words. Replace marketing superlatives with
|
||||
concrete capabilities. A reader should learn more than “this is a powerful image/video
|
||||
model,” but should not have to read the architecture section to choose the right model.
|
||||
|
||||
## Scoped command builder
|
||||
|
||||
New diffusion pages use `templates/diffusion-config.jsx.tmpl` and opt into the shared
|
||||
`commandBuilder` renderer. Setup, Server, and Request choices share one semantic selection and
|
||||
one command composer; do not create a second command engine or assemble fragments in MDX.
|
||||
|
||||
Classify every dimension by lifecycle:
|
||||
|
||||
- `scope: "base"`: the visible Setup tab—hardware-independent required decisions such as
|
||||
checkpoint weights and request mode. Hardware, Nodes × GPUs/node, and the recommended
|
||||
verified deployment are supplied by the shared builder.
|
||||
- `scope: "serve"`: startup flags such as placement, attention, precision, encoder scheduling,
|
||||
and graph execution. They modify only the complete Serve command.
|
||||
- `scope: "request"`: sampling fields such as quality and outputs. They modify only the complete
|
||||
Request command.
|
||||
|
||||
Keep the topology registry small and honest. `verifiedRecipes` contains only exact end-to-end
|
||||
runs on that hardware and resource shape. `autoTopology(selection)` may construct a legal custom
|
||||
shape, but `resolveDeployment` must mark it `unverified` unless it exactly matches a recipe.
|
||||
`validateTopology` returns static errors for impossible world-size, head, partition, or placement
|
||||
combinations; errors disable both Copy actions. Never silently label a nearby GPU or topology as
|
||||
verified.
|
||||
|
||||
Expose topology-dependent best values explicitly. A Server row may remain `Auto`, but its summary
|
||||
and generated flag must show the effective policy—for example, encoder `auto` resolving to
|
||||
`replicate` across nodes. Reserve `disabled` for combinations that cannot work (a kernel the
|
||||
platform does not ship, a mode the checkpoint cannot serve); an option that runs but has not
|
||||
been through a verification round should declare `soft` instead, which keeps it selectable and
|
||||
labels the pick as unverified. Keep `torch.compile` and similarly narrow experiments in the
|
||||
detailed prose until they have a broadly compatible recipe.
|
||||
|
||||
Each dimension should provide a concise `description`, an optional quality label, and a
|
||||
`learnMore` anchor. Each option should provide at most two lines of decision-relevant explanation,
|
||||
its exact `flags`/`stripPrefixes`/`env`/`hints`, and a `disabled` (with `disableReason`), `soft`
|
||||
(with `softReason`), or `verifiedWhen` predicate when support is conditional — the reason strings
|
||||
are user-facing: blocked options flash theirs under the row on tap and expose it as a tooltip.
|
||||
The builder stores all semantic choices in the URL hash; active scope, expanded state, head
|
||||
address, and node rank stay local.
|
||||
|
||||
Legacy configs without `commandBuilder` continue to use the old matrix renderer. Do not migrate
|
||||
an existing page opportunistically; use the new schema for new diffusion models and deliberate
|
||||
model-by-model migrations.
|
||||
|
||||
## Review checklist
|
||||
|
||||
- tags render before section 1 and describe the model rather than the runtime;
|
||||
- Quick start puts installation and the generated commands before detailed model background;
|
||||
- the capability section explains strength and boundary without marketing filler;
|
||||
- checkpoint variants and request modes are unambiguous;
|
||||
- Setup keeps both commands visible as a deployment overview; Server and Request each show only
|
||||
the command controlled by that scope;
|
||||
- command bodies grow naturally up to their collapsed limit and do not reserve empty height;
|
||||
- topology-dependent recommended defaults are explicit in the setting summary and generated command;
|
||||
- legal custom topologies are Unverified and copyable; statically illegal combinations block Copy;
|
||||
- attention, quantization, caching, compile, and similar orthogonal features have explicit
|
||||
quality contracts and verified scopes;
|
||||
- unverified hardware or performance claims are absent;
|
||||
- `node docs/scripts/check_cookbook_configs.mjs` and Mintlify validation pass.
|
||||
@@ -0,0 +1,173 @@
|
||||
// Diffusion command-builder config template. Replace every __TOKEN__, keep only
|
||||
// verified hardware/features, and adapt the topology divisibility contract to
|
||||
// the model architecture.
|
||||
|
||||
export const config = {
|
||||
modelName: "__MODEL_DISPLAY__",
|
||||
supportedHardware: ["__DEFAULT_HW__"],
|
||||
groupHardware: false,
|
||||
matchDims: [],
|
||||
|
||||
overlayDims: [
|
||||
{
|
||||
id: "weights",
|
||||
title: "Checkpoint weights",
|
||||
scope: "base",
|
||||
description: "Choose the checkpoint partition required by this request mode.",
|
||||
default: "default",
|
||||
options: [{ id: "default", label: "Default", flags: [] }],
|
||||
},
|
||||
{
|
||||
id: "mode",
|
||||
title: "Request mode",
|
||||
scope: "base",
|
||||
default: "text",
|
||||
options: [{ id: "text", label: "Text" }],
|
||||
},
|
||||
{
|
||||
id: "placement",
|
||||
title: "Placement",
|
||||
scope: "serve",
|
||||
description: "Keep weights resident unless a verified capacity path requires sharding or offload.",
|
||||
default: "resident",
|
||||
options: [
|
||||
{ id: "resident", label: "Resident", flags: ["--performance-mode speed"], recommended: true },
|
||||
{ id: "fsdp", label: "FSDP", flags: ["--use-fsdp-inference true"], disabled: true },
|
||||
{ id: "offload", label: "Layerwise offload", disabled: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: "attention",
|
||||
title: "Attention",
|
||||
scope: "serve",
|
||||
description: "Use the platform default unless another backend was measured end to end.",
|
||||
default: "platform",
|
||||
options: [{ id: "platform", label: "Platform default", recommended: true }],
|
||||
},
|
||||
{
|
||||
id: "precision",
|
||||
title: "Precision",
|
||||
scope: "serve",
|
||||
default: "native",
|
||||
options: [{ id: "native", label: "Native mixed precision", recommended: true }],
|
||||
},
|
||||
{
|
||||
id: "encoder",
|
||||
title: "Encoder",
|
||||
scope: "serve",
|
||||
default: "auto",
|
||||
options: [{ id: "auto", label: "Auto", flags: ["--encoder-parallel auto"], recommended: true }],
|
||||
},
|
||||
{
|
||||
id: "execution",
|
||||
title: "Execution",
|
||||
scope: "serve",
|
||||
default: "eager",
|
||||
options: [{ id: "eager", label: "Eager", recommended: true }],
|
||||
},
|
||||
{
|
||||
id: "quality",
|
||||
title: "Quality",
|
||||
scope: "request",
|
||||
default: "lossless",
|
||||
options: [{ id: "lossless", label: "Lossless", recommended: true }],
|
||||
},
|
||||
{
|
||||
id: "outputs",
|
||||
title: "Outputs",
|
||||
scope: "request",
|
||||
kind: "number",
|
||||
min: 1,
|
||||
max: 10,
|
||||
unit: "outputs per prompt",
|
||||
default: 1,
|
||||
options: [],
|
||||
},
|
||||
],
|
||||
|
||||
commandBuilder: {
|
||||
defaultSelection: {
|
||||
hw: "__DEFAULT_HW__",
|
||||
nodes: 1,
|
||||
gpus_per_node: __DEFAULT_GPUS__,
|
||||
topology_mode: "auto",
|
||||
tp_size: 1,
|
||||
ulysses_degree: __DEFAULT_GPUS__,
|
||||
ring_degree: 1,
|
||||
},
|
||||
resource: {
|
||||
limits: {
|
||||
nodes: { min: 1, max: __MAX_NODES__ },
|
||||
gpus_per_node: { min: 1, max: __MAX_GPUS_PER_NODE__ },
|
||||
},
|
||||
verifiedRecipes: [{
|
||||
id: "__DEFAULT_HW__-default",
|
||||
hw: "__DEFAULT_HW__",
|
||||
nodes: 1,
|
||||
gpus_per_node: __DEFAULT_GPUS__,
|
||||
placement: "resident",
|
||||
tp_size: 1,
|
||||
ulysses_degree: __DEFAULT_GPUS__,
|
||||
ring_degree: 1,
|
||||
encoder: "auto",
|
||||
default: true,
|
||||
}],
|
||||
autoTopology: (s) => ({
|
||||
tp_size: 1,
|
||||
ulysses_degree: Number(s.gpus_per_node),
|
||||
ring_degree: Number(s.nodes),
|
||||
}),
|
||||
validateTopology: (s, topology) => {
|
||||
const world = Number(s.nodes) * Number(s.gpus_per_node);
|
||||
const product = Number(topology.tp_size) * Number(topology.ulysses_degree) * Number(topology.ring_degree);
|
||||
return world === product ? [] : [`World size ${world} must equal TP × Ulysses × Ring (${product}).`];
|
||||
},
|
||||
},
|
||||
resolveDeployment: (s) => {
|
||||
const resource = config.commandBuilder.resource;
|
||||
const topology = s.topology_mode === "manual"
|
||||
? { tp_size: Number(s.tp_size), ulysses_degree: Number(s.ulysses_degree), ring_degree: Number(s.ring_degree) }
|
||||
: resource.autoTopology(s);
|
||||
const errors = resource.validateTopology(s, topology);
|
||||
const recipe = resource.verifiedRecipes.find((entry) => entry.hw === s.hw
|
||||
&& entry.nodes === Number(s.nodes)
|
||||
&& entry.gpus_per_node === Number(s.gpus_per_node)
|
||||
&& entry.placement === s.placement
|
||||
&& entry.tp_size === topology.tp_size
|
||||
&& entry.ulysses_degree === topology.ulysses_degree
|
||||
&& entry.ring_degree === topology.ring_degree);
|
||||
const world = Number(s.nodes) * Number(s.gpus_per_node);
|
||||
const flags = ["--model-path {{MODEL_NAME}}", `--num-gpus ${world}`];
|
||||
if (topology.tp_size > 1) flags.push(`--tp-size ${topology.tp_size}`);
|
||||
flags.push(`--ulysses-degree ${topology.ulysses_degree}`);
|
||||
if (topology.ring_degree > 1) flags.push(`--ring-degree ${topology.ring_degree}`);
|
||||
flags.push("--host {{HOST_IP}}", "--port {{PORT}}");
|
||||
const verified = !!recipe && errors.length === 0;
|
||||
return {
|
||||
match: { hw: s.hw },
|
||||
nnodes: Number(s.nodes),
|
||||
verified,
|
||||
flags,
|
||||
builder: {
|
||||
topology,
|
||||
topologySummary: `TP ${topology.tp_size} · Ulysses ${topology.ulysses_degree} · Ring ${topology.ring_degree}`,
|
||||
errors,
|
||||
warnings: verified ? [] : ["Valid custom topology; exact end-to-end verification is pending."],
|
||||
verification: { serve: verified ? "verified" : "unverified", request: verified ? "verified" : "unverified" },
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
|
||||
modelNames: { default: "__MODEL_ID__" },
|
||||
placeholders: {
|
||||
HOST_IP: { target: "command", label: "Bind host", default: "0.0.0.0" },
|
||||
PORT: { target: "command", label: "Bind port", default: "30010" },
|
||||
CURL_HOST: { target: "curl", label: "Server host", default: "localhost" },
|
||||
CURL_PORT: { target: "curl", label: "Server port", default: "30010" },
|
||||
},
|
||||
curl: (s) => `curl -sS -X POST http://{{CURL_HOST}}:{{CURL_PORT}}/__REQUEST_PATH__ \\
|
||||
-H 'Content-Type: application/json' \\
|
||||
-d '${JSON.stringify({ model: "{{MODEL_NAME}}", prompt: "__PROMPT__", quality: s.quality, num_outputs_per_prompt: Number(s.outputs) }, null, 2)}'`,
|
||||
cells: [],
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
---
|
||||
title: __MODEL_DISPLAY__
|
||||
description: "Deploy __MODEL_DISPLAY__ with SGLang Diffusion."
|
||||
metatags:
|
||||
description: "Serve __MODEL_DISPLAY__ for __PRIMARY_CAPABILITY__ with SGLang Diffusion."
|
||||
---
|
||||
|
||||
import { DiffusionModelTags } from '/src/snippets/diffusion/model-tags.jsx';
|
||||
import { Deployment } from '/src/snippets/_deployment.jsx';
|
||||
import { config } from '/src/snippets/configs/__HF_ORG__/__MODEL_SLUG__.jsx';
|
||||
|
||||
<DiffusionModelTags tags={["__MODALITY__", "__PRIMARY_TASK__", "__DIFFERENTIATOR__", "__IMPORTANT_BOUNDARY__"]} />
|
||||
|
||||
## 1. Quick start
|
||||
|
||||
Install with `uv pip install "sglang[diffusion]" --prerelease=allow`, then choose
|
||||
a verified recipe below.
|
||||
|
||||
<Deployment config={config} />
|
||||
|
||||
## 2. Model capabilities
|
||||
|
||||
[__MODEL_DISPLAY__](__MODEL_URL__) is __CONCRETE_MODEL_DESCRIPTION__. Its strongest use case is __MEASURED_OR_DOCUMENTED_STRENGTH__.
|
||||
|
||||
Choose it when __SELECTION_GUIDANCE__. The main tradeoff is __CAPABILITY_OR_DEPLOYMENT_BOUNDARY__.
|
||||
|
||||
| Checkpoint or mode | Best fit | Important boundary |
|
||||
| --- | --- | --- |
|
||||
| `__MODEL_ID__` | __USE_CASE__ | __LIMIT__ |
|
||||
|
||||
## 3. Deployment details
|
||||
|
||||
Document topology-dependent defaults, platform-specific installation details,
|
||||
and only the hardware recipes that need explanation beyond the builder.
|
||||
|
||||
## 4. Request examples
|
||||
|
||||
__REQUEST_EXAMPLES__
|
||||
|
||||
## 5. Feature details
|
||||
|
||||
Document quality contracts, installation requirements, and benchmark scope for
|
||||
the Server and Request choices exposed in the builder. Keep `torch.compile` and
|
||||
other experimental controls here until they have a broadly compatible recipe.
|
||||
Reference in New Issue
Block a user