-
Notifications
You must be signed in to change notification settings - Fork 553
Restructure recipes: split per-model_type recipes from model-hub checkpoint recipes #2219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c5ecf78
bf056a0
001e93d
0f33429
49489d3
574376f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| # Recipes for specific model-hub checkpoints | ||
|
|
||
| This folder holds model-optimization recipes (e.g. PTQ recipes) tuned for a | ||
| **specific published model instance** — one checkpoint released on a model hub | ||
| such as the [Hugging Face Hub](https://huggingface.co/), | ||
| [ModelScope](https://modelscope.cn/), or similar. Unlike | ||
| [`../huggingface/`](../huggingface/), which keys recipes by a transformers | ||
| `model_type` (an architecture shared by many checkpoints), a recipe here mirrors | ||
| **one checkpoint's** quantization scheme verbatim. | ||
|
|
||
| ## Folder structure | ||
|
|
||
| Each instance is keyed by its **model-hub path** — the same `<org>/<model_id>` | ||
| you pass to `from_pretrained(...)` or find in the hub URL. The on-disk path | ||
| mirrors the hub path exactly: | ||
|
|
||
| ```text | ||
| modelopt_recipes/models/ | ||
| <org>/ # hub namespace / organization, e.g. nvidia, mistralai | ||
| <model_id>/ # hub model id, e.g. Nemotron-3-Nano-4B-BF16 | ||
| <task>/ # optimization workflow, e.g. ptq | ||
| <recipe>.yaml | ||
| [<recipe>.<aux>.yaml] # optional $import snippet helpers (see below) | ||
| [README.md] # optional; describes what's checkpoint-specific | ||
| ``` | ||
|
|
||
| For example, the recipe for the hub checkpoint `nvidia/Nemotron-3-Nano-4B-BF16` | ||
| (`https://huggingface.co/nvidia/Nemotron-3-Nano-4B-BF16`) lives at | ||
| `models/nvidia/Nemotron-3-Nano-4B-BF16/ptq/`. Because the folder path *is* the | ||
| hub path, you can go straight from a checkpoint id to its recipe — and back — | ||
| with no lookup table. | ||
|
|
||
| `<task>` is the optimization workflow the recipe targets (e.g. `ptq` for | ||
| post-training quantization). | ||
|
|
||
| ### Naming the `<org>/<model_id>` folders | ||
|
|
||
| Use the checkpoint's exact hub `<org>/<model_id>`, including casing. When the | ||
| same weights are published on more than one hub (e.g. the Hugging Face Hub and | ||
| ModelScope) under the same `<org>/<model_id>`, a single folder serves them all. | ||
| When a recipe was tuned against one **canonical / base** checkpoint but also | ||
| applies to its mirrors, key it by that base model's id. | ||
|
|
||
| ## Choosing a recipe | ||
|
|
||
| Prefer the most specific entry that applies to your model: | ||
|
|
||
| 1. **`models/<org>/<model_id>/`** — if there is an entry for your **exact** | ||
| checkpoint. It reproduces a validated, often per-component mixed-precision | ||
| scheme for that release; use it to match a published quantized checkpoint. | ||
| 2. **[`huggingface/<model_type>/`](../huggingface/)** — an architecture-level | ||
| recipe that applies to every checkpoint of that `model_type`. | ||
| 3. **[`general/`](../general/)** — model-agnostic recipes; a good starting point | ||
| for any model without a more specific entry. | ||
|
|
||
| ## Selecting a recipe at runtime | ||
|
|
||
| Use the path relative to `modelopt_recipes/`: | ||
|
|
||
| ```text | ||
| --recipe models/<org>/<model_id>/<task>/<recipe> | ||
| ``` | ||
|
|
||
| or from Python: | ||
|
|
||
| ```python | ||
| from modelopt.recipe import load_recipe | ||
|
|
||
| recipe = load_recipe("models/nvidia/Nemotron-3-Nano-4B-BF16/ptq/nvfp4_w4a16") | ||
| ``` | ||
|
|
||
| ## What belongs here | ||
|
|
||
| A recipe earns a place here only when it mirrors **one specific released (or | ||
| planned) checkpoint** — a hand-mapped, usually per-layer or per-component | ||
| precision scheme tuned to match that exact release. If the tuning generalizes to | ||
| every checkpoint of an architecture, it belongs under | ||
| [`../huggingface/<model_type>/`](../huggingface/) instead; if it is | ||
| model-agnostic, it belongs under [`../general/`](../general/). See | ||
| [`../ptq.md`](../ptq.md) for what each checkpoint mirror does and how it compares | ||
| to its general baseline. | ||
|
|
||
| ## Sharing content across recipes | ||
|
|
||
| When several recipes reuse the same body, extract it into a sibling **snippet** | ||
| file with a `# modelopt-schema:` header and `$import` it, keeping each recipe | ||
| wrapper thin. Name snippets so they are obviously not runnable recipes (e.g. | ||
| `<recipe>.<field>.yaml`), and reference them by their path relative to | ||
| `modelopt_recipes/`. | ||
|
|
||
| ## Per-folder READMEs | ||
|
|
||
| Each `<task>/` folder may contain a short `README.md` describing exactly what is | ||
| checkpoint-specific — which layers deviate, the calibration used, and the | ||
| reference checkpoint it mirrors — so reviewers and users don't have to diff the | ||
| YAML against the generic presets to see the intent. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,10 +3,9 @@ | |
| This doc walks through the **PTQ quantization schemes** in two parts: the | ||
| model-agnostic recipes under [`general/ptq/`](general/ptq/) (the recommended | ||
| starting point for any model), and then the | ||
| [model-specific recipes](#model-specific-recipes-huggingface) under | ||
| `huggingface/` — per-`model_type` folders plus the | ||
| `huggingface/models/<org>/<checkpoint>/` tier — comparing each to its general | ||
| baseline and explaining why it deviates. | ||
| [model-specific recipes](#model-specific-recipes) — per-`model_type` folders | ||
| under `huggingface/` plus the checkpoint-mirror `models/<org>/<checkpoint>/` | ||
| tier — comparing each to its general baseline and explaining why it deviates. | ||
|
|
||
| --- | ||
|
|
||
|
|
@@ -227,14 +226,14 @@ These can also be **stacked** when a single method isn't enough — e.g. `mse` + | |
|
|
||
| --- | ||
|
|
||
| ## Model-specific recipes (`huggingface/`) | ||
| ## Model-specific recipes | ||
|
|
||
| The general recipes above are **model-agnostic**: they select layers by wildcard | ||
| (`*mlp*`, `*self_attn*`, `*[kv]_bmm_quantizer`) and lean on the shared | ||
| `default_disabled_quantizers` exclusions, so the same file works on any | ||
| architecture whose module names follow the usual conventions. A recipe only | ||
| earns a place under `huggingface/<model_type>/` or | ||
| `huggingface/models/<org>/<checkpoint>/` when a model has to **deviate** from | ||
| `models/<org>/<checkpoint>/` when a model has to **deviate** from | ||
| that baseline. The deviations come in four kinds: | ||
|
|
||
| | Kind | What changes vs. the general recipe | Examples | | ||
|
|
@@ -297,7 +296,7 @@ general recipes never enable output quantizers, and the pattern must stay scoped | |
| to GEMM outputs — a `DynamicQuantize` on non-GEMM outputs (embedding lookup, | ||
| pooling) fails to compile in TensorRT. | ||
|
|
||
| A lighter case: **`step3p5/Step3.5-Flash/ptq/nvfp4-mlp-only`** is close to | ||
| A lighter case: **`models/stepfun-ai/Step-3.5-Flash/ptq/nvfp4-mlp-only`** is close to | ||
| `general/ptq/nvfp4_mlp_only` (NVFP4 on MoE/MLP weights+inputs, FP8 KV) but pinned | ||
| to one released checkpoint and carrying instance-specific disables | ||
| (`share_expert`, `moe.gate`, the conv1d branches). | ||
|
|
@@ -344,14 +343,14 @@ everything else matches the general recipe. | |
|
|
||
| ### Checkpoint mirrors — `models/<org>/<checkpoint>` | ||
|
|
||
| The `huggingface/models/` tier reproduces a **single published (or planned) | ||
| The `models/` tier reproduces a **single published (or planned) | ||
| checkpoint's** quant config verbatim: | ||
|
|
||
| - **`models/mistralai/Mistral-Medium-3.5-128B/ptq/nvfp4-max-calib`** mirrors | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [SUGGESTION] Within this section, only the Mistral bullet carries the full tier path — the five Nemotron bullets below (lines 353, 364, 370, 374) are still written bare, e.g. That was harmless when the prefix was the awkward Suggest prefixing each with - **`models/nvidia/Nemotron-3-Super-120B-A12B-BF16/ptq/nvfp4-mse`** mirrors
- **`models/nvidia/Nemotron-3-Ultra-550B-A55B-BF16/ptq/nvfp4-4o6`** follows the same Super-style
- **`models/nvidia/Nemotron-3.5-Lightning-30B-A3B-BF16/ptq/w4a16_nvfp4_4o6`** applies
- **`models/nvidia/Nemotron-3-Nano-4B-BF16/ptq/nvfp4_w4a16`** mirrors the GGUF **Q4_K_M** bitNote this is safe with respect to
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in 0f33429 — prefixed all four bare Nemotron bullets (Super / Ultra / Lightning / Nano) with |
||
| `nvidia/Mistral-Medium-3.5-128B-NVFP4`: decoder MLP layers 4–86 use NVFP4 | ||
| W4A4, edge MLP layers 0–3 and 87 use FP8 W8A8, and all attention projections | ||
| and the KV cache use FP8. It uses max calibration. | ||
| - **`Nemotron-3-Super-120B-A12B-BF16/ptq/nvfp4-mse`** mirrors | ||
| - **`models/nvidia/Nemotron-3-Super-120B-A12B-BF16/ptq/nvfp4-mse`** mirrors | ||
| `nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4` exactly — a hybrid | ||
| **Mamba-MoE** with a hand-mapped, **per-component** precision scheme: | ||
| - MoE routed experts → NVFP4 W4A4, `group_size 16`, **static** weight scales | ||
|
|
@@ -362,17 +361,17 @@ checkpoint's** quant config verbatim: | |
| `nvfp4-mse.yaml` uses MSE calibration with an FP8-scale sweep (matches the | ||
| release); `nvfp4-max-calib.yaml` is the identical layer map under plain `max` | ||
| calibration, kept for comparison. | ||
| - **`Nemotron-3-Ultra-550B-A55B-BF16/ptq/nvfp4-4o6`** follows the same Super-style | ||
| - **`models/nvidia/Nemotron-3-Ultra-550B-A55B-BF16/ptq/nvfp4-4o6`** follows the same Super-style | ||
| component map (routed experts NVFP4 W4A4 block-16; shared experts + Mamba | ||
| `in/out_proj` + KV cache FP8; everything else BF16), but the routed-expert | ||
| weights use **Four-over-Six (4/6)** NVFP4: an MSE search picks each weight's | ||
| amax multiplier from `[1.0, 1.5]` (M=6 vs. M=4). Activations stay dynamic | ||
| NVFP4 (not MSE-calibrated). | ||
| - **`Nemotron-3.5-Lightning-30B-A3B-BF16/ptq/w4a16_nvfp4_4o6`** applies | ||
| - **`models/nvidia/Nemotron-3.5-Lightning-30B-A3B-BF16/ptq/w4a16_nvfp4_4o6`** applies | ||
| Four-over-Six NVFP4 W4A16 to routed experts, shared experts, and the language | ||
| model head; Mamba `in/out_proj` weights and inputs plus the KV cache use FP8, | ||
| while attention remains BF16. | ||
| - **`Nemotron-3-Nano-4B-BF16/ptq/nvfp4_w4a16`** mirrors the GGUF **Q4_K_M** bit | ||
| - **`models/nvidia/Nemotron-3-Nano-4B-BF16/ptq/nvfp4_w4a16`** mirrors the GGUF **Q4_K_M** bit | ||
| allocation of the Nemotron-H hybrid, mapped onto NVFP4/FP8 **per layer**: | ||
| Q4_K/Q5_0 linears → NVFP4 W4A4 (attention q/k/v/o kept uniform so export can | ||
| fuse them), the Q6_K MLP `down_proj` layers → FP8 W8A8, embeddings → NVFP4 | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.