mirror of
https://github.com/NVIDIA/Model-Optimizer.git
synced 2026-10-02 03:14:52 +08:00
[OMNIML-3707] Model-specific PTQ recipes bootstrap (#1506)
### What does this PR do?
Type of change: new feature
Replaces the hardcoded model-type branches in `examples/llm_ptq/` with
opt-in declarative **model-specific recipes** under
`modelopt_recipes/huggingface/<model_type>/ptq/`. Any adjustment
specific to a model type or instance must live in that model's recipe —
there is no implicit model-specific path anymore. Users select a model's
recipe with `--recipe huggingface/<model_type>/ptq/<recipe>`; users on
the plain `--qformat` path get only the generic numerics.
What moved out of Python
(`examples/llm_ptq/example_utils.py::build_quant_cfg` and
`examples/llm_ptq/hf_ptq.py::mono_quantize`):
- **gemma / mpt** `w4a8_awq` → `awq_lite` with `alpha_step=1` (coarser
search to avoid TRT-LLM overflow).
- **gemma** `int8_sq` → SmoothQuant `alpha=0.5` (default `1.0` regresses
Gemma 7B).
- **phi4mm** → disable `*speech*`, `*audio*`, `*image*`, `*vision*`
(quantize only the language model).
- **Nemotron VL** → disable `*vision*`, `*image*`, `*radio*`,
`*visual*`, `*encoder*`, `*model_encoder*` (quantize only the decoder).
What stayed in Python:
- MTP dynamic layer exclusion in `hf_ptq.py` (depends on
runtime-detected layer indices).
- `is_nemotron_vl(full_model)` detection itself, which still drives the
VLM calibration loop and the post-quantize `full_model` update — only
the `quant_cfg` adjustment it triggered moved into the Nemotron VL
recipe.
`multinode_ptq.py` shares the same `build_quant_cfg` call site and was
updated to match the new 2/3-arg signature; multinode users on
`--qformat` get the generic numerics (no `--recipe` plumbing in
multinode yet, so model-specific recipes are only reachable via
`hf_ptq.py`).
Already-YAML recipes that were elsewhere in the tree are relocated into
the same `huggingface/<model_type>/ptq/` layout so all model-specific
recipes live under one convention:
- **Step3.5-Flash** — moved from
`modelopt_recipes/huggingface/step3p5/Step3.5-Flash/` to
`huggingface/step3p5/Step3.5-Flash/ptq/` to match the `<model>/ptq/`
convention.
- **Qwen3.5 / Qwen3.6** — moved from
`modelopt_recipes/models/Qwen3.5-Qwen3.6/w4a16.yaml` to per-model_type
folders, anchored on the HuggingFace `model_type` (verified against
transformers 5.8.1 + HF model hub `config.json` for `Qwen/Qwen3.6-27B`,
`Qwen/Qwen3.6-35B-A3B`, `nvidia/Qwen3.5-397B-A17B-NVFP4`):
- `huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.yaml` —
dense `qwen3_5`
- `huggingface/qwen3_5_moe/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.yaml` —
`qwen3_5_moe`
- Both wrappers `$import` the shared `quant_cfg` snippet
`huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.quant_cfg.yaml`
(one source of truth; the two model_types share the same hybrid
linear-attention + softmax-attention architecture so the rules apply
identically).
Full recipe layout (`modelopt_recipes/huggingface/`):
```
gemma/ptq/{w4a8_awq,int8_sq}-kv_fp8_cast.yaml
mpt/ptq/w4a8_awq-kv_fp8_cast.yaml
phi4mm/ptq/{disabled_quantizers,nvfp4-kv_fp8_cast}.yaml
nemotron_vl/ptq/{disabled_quantizers,nvfp4-kv_fp8_cast}.yaml
qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast{,.quant_cfg}.yaml
qwen3_5_moe/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.yaml
step3p5/Step3.5-Flash/ptq/nvfp4-mlp-only.yaml
```
All recipes ship with FP8 KV-cache cast (`kv_fp8_cast`). For phi4mm and
nemotron_vl, `disabled_quantizers.yaml` is a multi-document list unit
that `$import`s the standard `default_disabled_quantizers` exclusions
and appends the model-specific ones — so each recipe imports a single
disabled-quantizer slot instead of layering two, with no duplication in
YAML. Each `ptq/` folder has a `README.md` describing exactly what is
model-specific.
### Usage
```bash
# Gemma W4A8 AWQ with the Gemma-specific algorithm tuning + FP8 KV cache:
python examples/llm_ptq/hf_ptq.py \
--pyt_ckpt_path google/gemma-7b \
--recipe huggingface/gemma/ptq/w4a8_awq-kv_fp8_cast \
--export_path ./out
# Nemotron VL with vision branches excluded automatically:
python examples/llm_ptq/hf_ptq.py \
--pyt_ckpt_path nvidia/<nemotron-vl-model> \
--recipe huggingface/nemotron_vl/ptq/nvfp4-kv_fp8_cast \
--export_path ./out
```
### Testing
- Pre-commit recipe validator
(`tools/precommit/check_modelopt_recipes.py`) loads every new recipe via
`load_recipe()` — passes for all new YAMLs (gemma/mpt/phi4mm/nemotron_vl
recipes + phi4mm/nemotron_vl `disabled_quantizers` snippets + qwen3_5 /
qwen3_5_moe recipe wrappers + the shared
`w4a16_nvfp4-fp8_attn-kv_fp8_cast.quant_cfg` snippet + Step3.5-Flash
relocation).
- For qwen3_5 / qwen3_5_moe specifically, `load_recipe(...)` on both
wrappers produces an identical 33-entry resolved `quant_cfg`, confirming
the shared snippet is the single source of truth.
- `yamlfmt` + `markdownlint` + `bandit` + license-insertion hooks all
pass.
- No tests reference the removed `build_quant_cfg(qformat, ...,
model_type, ...)` signature; the only call sites (`hf_ptq.py`,
`multinode_ptq.py`) were updated to the new 2/3-arg form.
### Before your PR is "*Ready for review*"
- Is this change backward compatible?: ❌ — users who relied on
**automatic** model-specific quant_cfg behavior via `--qformat`
(gemma/mpt AWQ, gemma SmoothQuant, phi4mm exclusions, Nemotron VL
exclusions) now need to pass `--recipe
huggingface/<model_type>/ptq/<recipe>` to apply the model's recipe. The
flag itself is unchanged; only the implicit behavior was removed.
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: N/A
- Did you write any new necessary tests?: ❌ — relies on the existing
pre-commit recipe validator that loads each new YAML.
- Did you update Changelog?: ✅
- Did you get Claude approval on this PR?: ❌
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added many model-specific PTQ recipes (Gemma, MPT, Nemotron VL,
Phi‑4‑Multimodal, Qwen3.5, Qwen3.5‑MoE) and support for AWQ block-size
and MoE calibration ratio in quantization options.
* **Documentation**
* Expanded READMEs and changelog to document recipe locations, layout,
and how to opt into model-specific PTQ recipes.
* **Refactor**
* Model-specific PTQ tweaks moved to opt‑in recipes; default behavior
uses generic numerics.
<!-- review_stack_entry_start -->
[](https://app.coderabbit.ai/change-stack/NVIDIA/Model-Optimizer/pull/1506?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)
<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Signed-off-by: Shengliang Xu <shengliangx@nvidia.com>
This commit is contained in:
@@ -17,6 +17,10 @@ Changelog
|
||||
|
||||
- Deprecated GradNAS pruning algorithm as it is not actively maintained and supports very limited and old models. It is recommended to use Minitron or Puzzletron pruning for LLM models. Also deprecates related ``examples/chained_optimizations`` directory.
|
||||
|
||||
- Model-specific PTQ ``quant_cfg`` adjustments previously hardcoded in ``examples/llm_ptq/`` (``build_quant_cfg`` / ``mono_quantize``) for gemma, mpt, phi4mm, and Nemotron VL are now opt-in **model-specific recipes** under ``modelopt_recipes/huggingface/<model_type>/ptq/``. Any adjustment specific to a model type or instance must live in that model's recipe; the bare ``--qformat`` path produces only the generic numerics. Pass ``--recipe huggingface/<model_type>/ptq/<recipe>`` to apply the model's recipe. Covers gemma/mpt ``w4a8_awq`` (``awq_lite`` ``alpha_step=1``), gemma ``int8_sq`` (SmoothQuant ``alpha=0.5``), phi4mm speech/audio/image/vision exclusions, and Nemotron VL vision-branch exclusions. All shipped recipes also enable FP8 KV-cache cast. MTP dynamic layer exclusion and ``is_nemotron_vl`` detection remain in Python.
|
||||
|
||||
- The Step3.5-Flash recipe moved from ``modelopt_recipes/models/Step3.5-Flash/nvfp4-mlp-only.yaml`` (0.44) to ``modelopt_recipes/huggingface/step3p5/Step3.5-Flash/ptq/nvfp4-mlp-only.yaml`` to match the ``huggingface/<model_type>/ptq/`` layout convention. Update ``--recipe`` paths accordingly.
|
||||
|
||||
**New Features**
|
||||
|
||||
- Extend Claude Code agent skills for PTQ, deployment, evaluation, monitoring, and baseline-vs-quantized result comparison. Adds evaluation task references for additional benchmarks, stronger PTQ checkpoint validation gates, and session-scoped workspace/job tracking.
|
||||
|
||||
@@ -511,8 +511,11 @@ General PTQ recipes are model-agnostic and apply to any supported architecture:
|
||||
Model-specific recipes
|
||||
----------------------
|
||||
|
||||
Model-specific recipes are tuned for a particular architecture and live under
|
||||
``models/<model_name>/``:
|
||||
Model-specific recipes are tuned for a particular Hugging Face ``model_type``
|
||||
(or a specific released model) and live under
|
||||
``huggingface/<model_type>/[<specific_model>/]<task>/``. See
|
||||
`modelopt_recipes/huggingface/README.md <https://github.com/NVIDIA/Model-Optimizer/blob/main/modelopt_recipes/huggingface/README.md>`_
|
||||
for the layout convention and recipe-lookup order.
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
@@ -520,7 +523,7 @@ Model-specific recipes are tuned for a particular architecture and live under
|
||||
|
||||
* - Recipe path
|
||||
- Description
|
||||
* - ``models/Step3.5-Flash/nvfp4-mlp-only``
|
||||
* - ``huggingface/step3p5/Step3.5-Flash/ptq/nvfp4-mlp-only``
|
||||
- NVFP4 MLP-only for Step 3.5 Flash MoE model
|
||||
|
||||
|
||||
@@ -669,9 +672,10 @@ The ``modelopt_recipes/`` package is organized as follows:
|
||||
| +-- nvfp4_experts_only-kv_fp8.yaml
|
||||
| +-- nvfp4_experts_only-kv_fp8_layerwise.yaml
|
||||
| +-- nvfp4_omlp_only-kv_fp8.yaml
|
||||
+-- models/ # Model-specific recipes
|
||||
| +-- Step3.5-Flash/
|
||||
| +-- nvfp4-mlp-only.yaml
|
||||
+-- huggingface/ # Model-specific recipes
|
||||
| +-- <model_type>/ # see modelopt_recipes/huggingface/README.md
|
||||
| +-- <task>/
|
||||
| +-- <recipe>.yaml
|
||||
+-- configs/ # Reusable config snippets (imported via $import)
|
||||
+-- numerics/ # Numeric format definitions
|
||||
| +-- fp8.yaml
|
||||
|
||||
@@ -183,7 +183,7 @@ python hf_ptq.py \
|
||||
--export_path <quantized_ckpt_path>
|
||||
```
|
||||
|
||||
Built-in recipes are located in `modelopt_recipes/general/ptq/`. You can also provide a path to your own custom YAML recipe file or directory. See the [recipe documentation](https://nvidia.github.io/Model-Optimizer) for details on the YAML schema and available recipes.
|
||||
Built-in recipes are located in `modelopt_recipes/general/ptq/` for model-agnostic recipes and in `modelopt_recipes/huggingface/<model_type>/ptq/` for recipes tuned to a specific Hugging Face `model_type` (see [`modelopt_recipes/huggingface/README.md`](../../modelopt_recipes/huggingface/README.md)). You can also provide a path to your own custom YAML recipe file or directory. See the [recipe documentation](https://nvidia.github.io/Model-Optimizer) for details on the YAML schema and available recipes.
|
||||
|
||||
> *When `--recipe` is specified, `--qformat` and `--kv_cache_qformat` are ignored. The recipe fully defines the quantization configuration.*
|
||||
|
||||
|
||||
@@ -202,10 +202,8 @@ def create_vlm_calibration_loop(full_model, calib_dataloader):
|
||||
|
||||
|
||||
def build_quant_cfg(
|
||||
qformat,
|
||||
quant_cfg,
|
||||
awq_block_size,
|
||||
model_type,
|
||||
moe_calib_experts_ratio: float | None = None,
|
||||
) -> dict[str, Any]:
|
||||
quant_cfg = copy.deepcopy(quant_cfg)
|
||||
@@ -222,10 +220,6 @@ def build_quant_cfg(
|
||||
if awq_block_size:
|
||||
weight_quantizer["block_sizes"][-1] = awq_block_size
|
||||
|
||||
# Coarser optimal scale search seems to resolve the overflow in TRT-LLM for some models
|
||||
if qformat == "w4a8_awq" and model_type in ["gemma", "mpt"]:
|
||||
quant_cfg["algorithm"] = {"method": "awq_lite", "alpha_step": 1}
|
||||
|
||||
if moe_calib_experts_ratio:
|
||||
assert 0 < moe_calib_experts_ratio <= 1, "moe_calib_experts_ratio must be between 0 and 1"
|
||||
if isinstance(quant_cfg["algorithm"], str):
|
||||
@@ -240,17 +234,6 @@ def build_quant_cfg(
|
||||
f"Quantization algorithm: {quant_cfg['algorithm']} does not support setting moe_calib_experts_ratio"
|
||||
)
|
||||
|
||||
# Gemma 7B has accuracy regression using alpha 1. We set 0.5 instead.
|
||||
if model_type == "gemma" and "int8_sq" in qformat:
|
||||
quant_cfg["algorithm"] = {"method": "smoothquant", "alpha": 0.5}
|
||||
|
||||
if model_type == "phi4mm":
|
||||
# Only quantize the language model
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*speech*", "enable": False})
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*audio*", "enable": False})
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*image*", "enable": False})
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*vision*", "enable": False})
|
||||
|
||||
return quant_cfg
|
||||
|
||||
|
||||
|
||||
@@ -631,22 +631,6 @@ def mono_quantize(
|
||||
"Consider reducing calib_size to reduce calibration time.\n####\n"
|
||||
)
|
||||
|
||||
# For Nemotron VL models, disable quantization of vision components
|
||||
if is_nemotron_vl_model:
|
||||
print("Disabling quantization for vision components in Nemotron VL model")
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*vision*", "enable": False})
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*image*", "enable": False})
|
||||
# Also disable radio model components specifically (for Nemotron-Parse)
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*radio*", "enable": False})
|
||||
quant_cfg["quant_cfg"].append({"quantizer_name": "*visual*", "enable": False})
|
||||
quant_cfg["quant_cfg"].append(
|
||||
{"quantizer_name": "*encoder*", "enable": False}
|
||||
) # Disable encoder
|
||||
quant_cfg["quant_cfg"].append(
|
||||
{"quantizer_name": "*model_encoder*", "enable": False}
|
||||
) # Nemotron-Parse specific
|
||||
print("Quantization will only be applied to the decoder (text generation) component")
|
||||
|
||||
if not model_is_already_quantized or calibration_only:
|
||||
# quantize the model
|
||||
|
||||
@@ -1115,10 +1099,8 @@ def quantize_main(
|
||||
quant_cfg = QUANT_CFG_CHOICES[args.qformat]
|
||||
|
||||
quant_cfg = build_quant_cfg(
|
||||
args.qformat,
|
||||
quant_cfg,
|
||||
args.awq_block_size,
|
||||
model_type,
|
||||
args.moe_calib_experts_ratio,
|
||||
)
|
||||
|
||||
@@ -1132,8 +1114,10 @@ def quantize_main(
|
||||
getattr(mtq, KV_QUANT_CFG_CHOICES[args.kv_cache_qformat])["quant_cfg"],
|
||||
)
|
||||
|
||||
# Exclude MTP layers from quantization if detected (e.g., GLM-4.7's layer 92)
|
||||
# These layers are typically speculative decoding layers that should be exported as-is
|
||||
# Exclude MTP layers from quantization if detected (e.g., GLM-4.7's layer 92).
|
||||
# These layers are typically speculative decoding layers that should be exported as-is.
|
||||
# Complementary to recipe `*mtp*` wildcards (name-match); this catches MTP layers
|
||||
# identified by index.
|
||||
mtp_layer_prefixes = getattr(full_model, "_mtp_layer_prefixes", None)
|
||||
if mtp_layer_prefixes:
|
||||
quant_cfg = copy.deepcopy(quant_cfg)
|
||||
|
||||
@@ -330,10 +330,8 @@ def main(args):
|
||||
quant_cfg = QUANT_CFG_CHOICES[args.qformat]
|
||||
|
||||
quant_cfg = build_quant_cfg(
|
||||
args.qformat,
|
||||
quant_cfg,
|
||||
args.awq_block_size,
|
||||
model_type,
|
||||
)
|
||||
|
||||
enable_quant_kv_cache = args.kv_cache_qformat != "none"
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# Model-specific recipes for Hugging Face models
|
||||
|
||||
This folder holds model-optimization recipes (e.g. PTQ recipes) whose
|
||||
behavior is tied to a **specific Hugging Face model architecture or model instance**.
|
||||
|
||||
## Choosing a recipe
|
||||
|
||||
Built-in recipes live in two places: `modelopt_recipes/huggingface/<model_type>/`
|
||||
for model-specific recipes and `modelopt_recipes/general/` for model-agnostic
|
||||
ones. When deciding which to use:
|
||||
|
||||
1. **Look in `huggingface/<model_type>/` first** for the target model's
|
||||
Hugging Face `model_type`, and inside it for a nested
|
||||
`<specific_model>/` folder if the recipe is tuned for one released
|
||||
checkpoint rather than every checkpoint of that `model_type`. The
|
||||
presence of a folder here signals that there is a recommended recipe
|
||||
for that `model_type` or model instance.
|
||||
2. **Fall back to `general/`** if no `<model_type>/` folder applies. The
|
||||
general recipes are a good starting point for any model — and the
|
||||
recommended starting point for a model architecture that does not yet
|
||||
have a model-specific entry.
|
||||
|
||||
## Folder structure
|
||||
|
||||
Recipes are categorized by the Hugging Face `model_type` string — the
|
||||
value of the top-level `model_type` field in the model's `config.json`
|
||||
(or, for multimodal configs, the `text_config.model_type` of the inner
|
||||
language model). Use the exact `model_type` as the directory name:
|
||||
|
||||
```text
|
||||
modelopt_recipes/huggingface/
|
||||
<model_type>/
|
||||
<task>/
|
||||
<recipe>.yaml
|
||||
[<recipe>.<aux>.yaml] # optional snippet helpers (see below)
|
||||
[README.md] # optional; describes what's model-specific
|
||||
```
|
||||
|
||||
`<task>` is the model-optimization workflow the recipe targets (e.g.
|
||||
`ptq` for post-training quantization).
|
||||
|
||||
Selecting a recipe at runtime uses the path relative to
|
||||
`modelopt_recipes/`, e.g.
|
||||
`--recipe huggingface/<model_type>/<task>/<recipe>`.
|
||||
|
||||
### Verifying a model's `model_type`
|
||||
|
||||
The authoritative source for a model's `model_type` is the released
|
||||
checkpoint's `config.json` on the Hugging Face Hub, e.g.
|
||||
`https://huggingface.co/<org>/<model>/raw/main/config.json`. The
|
||||
`transformers` library's per-model `configuration_<name>.py` files also
|
||||
hardcode the `model_type` string. Do not guess — confirm against one of
|
||||
these sources before placing a recipe.
|
||||
|
||||
### Sharing content across recipes
|
||||
|
||||
When the same body is reused by multiple recipes — for example, one
|
||||
recipe that applies to several `model_type`s, or several recipes that
|
||||
share a sub-block — extract the reused portion into a sibling
|
||||
**snippet** file with a `# modelopt-schema:` header and have each
|
||||
recipe `$import` it. The recipe wrappers stay thin; the shared body
|
||||
lives in one place.
|
||||
|
||||
Name snippet files so they are obviously not runnable recipes, e.g.
|
||||
include the field name the snippet represents as a secondary suffix
|
||||
(`<recipe>.<field>.yaml`). The snippet lives next to whichever recipe
|
||||
is its natural canonical home; other importers reference it by the
|
||||
same relative path under `modelopt_recipes/`.
|
||||
|
||||
### Per-family nested layout for specific model variants
|
||||
|
||||
If a recipe is tuned for one specific released model rather than every
|
||||
checkpoint under a `model_type`, nest the model name as an extra level:
|
||||
|
||||
```text
|
||||
<model_type>/
|
||||
<specific_model>/
|
||||
<task>/
|
||||
<recipe>.yaml
|
||||
```
|
||||
|
||||
### Per-folder READMEs
|
||||
|
||||
Each `<task>/` folder may contain a short `README.md` describing exactly
|
||||
what is model-specific about each recipe (the algorithm override, the
|
||||
disabled-quantizer pattern, etc.) so reviewers and users do not have to
|
||||
diff the YAML against the generic presets to see the intent.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Gemma PTQ recipes
|
||||
|
||||
Recipes here override the algorithm defaults that ship in the general PTQ
|
||||
presets because Gemma needs different settings to converge / stay accurate.
|
||||
|
||||
| Recipe | What's model-specific |
|
||||
|--------|-----------------------|
|
||||
| `w4a8_awq-kv_fp8_cast.yaml` | Uses `awq_lite` with `alpha_step: 1` instead of the default AWQ search. The default search overflows in TRT-LLM kernels on Gemma; the coarser sweep avoids it without measurably hurting accuracy. Numerics: INT4 block weights + FP8 inputs + FP8 KV-cache cast (constant amax, no KV calibration). |
|
||||
| `int8_sq-kv_fp8_cast.yaml` | Sets SmoothQuant `alpha: 0.5` instead of the default `1.0`. Gemma 7B regresses with `alpha=1`; `0.5` recovers it. Numerics: INT8 per-channel weights + INT8 inputs + FP8 KV-cache cast. |
|
||||
|
||||
The base numerics units and the standard disabled-quantizer list are inherited
|
||||
from the shared `configs/`; only the algorithm fields are model-specific.
|
||||
@@ -0,0 +1,46 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Gemma-specific INT8 SmoothQuant PTQ recipe with FP8 KV-cache cast. Overrides
|
||||
# the SmoothQuant alpha from the default 1.0 to 0.5 to recover accuracy on
|
||||
# Gemma 7B (default alpha causes a regression).
|
||||
|
||||
imports:
|
||||
base_disable_all: configs/ptq/units/base_disable_all
|
||||
default_disabled_quantizers: configs/ptq/units/default_disabled_quantizers
|
||||
int8: configs/numerics/int8
|
||||
int8_per_channel: configs/numerics/int8_per_channel
|
||||
kv_fp8_cast: configs/ptq/units/kv_fp8_cast
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: >-
|
||||
Gemma INT8 SmoothQuant recipe with FP8 KV-cache cast: alpha=0.5 (instead
|
||||
of the default 1.0) to avoid accuracy regression on Gemma 7B, plus FP8
|
||||
KV-cache using constant amax (no KV calibration).
|
||||
quantize:
|
||||
algorithm:
|
||||
method: smoothquant
|
||||
alpha: 0.5
|
||||
quant_cfg:
|
||||
- $import: base_disable_all
|
||||
- quantizer_name: '*weight_quantizer'
|
||||
cfg:
|
||||
$import: int8_per_channel
|
||||
- quantizer_name: '*input_quantizer'
|
||||
cfg:
|
||||
$import: int8
|
||||
- $import: kv_fp8_cast
|
||||
- $import: default_disabled_quantizers
|
||||
@@ -0,0 +1,47 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Gemma-specific W4A8 AWQ PTQ recipe with FP8 KV-cache cast. Uses a coarser
|
||||
# optimal-scale search (awq_lite with alpha_step=1) to avoid overflow observed
|
||||
# in TRT-LLM kernels when using the default AWQ search on Gemma.
|
||||
|
||||
imports:
|
||||
base_disable_all: configs/ptq/units/base_disable_all
|
||||
default_disabled_quantizers: configs/ptq/units/default_disabled_quantizers
|
||||
fp8: configs/numerics/fp8
|
||||
int4_per_block: configs/numerics/int4_per_block
|
||||
kv_fp8_cast: configs/ptq/units/kv_fp8_cast
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: >-
|
||||
Gemma W4A8 AWQ recipe with FP8 KV-cache cast: INT4 block weights + FP8
|
||||
inputs, awq_lite with alpha_step=1 (coarser search) to avoid TRT-LLM
|
||||
overflow, plus FP8 KV-cache using constant amax (no KV calibration).
|
||||
quantize:
|
||||
algorithm:
|
||||
method: awq_lite
|
||||
alpha_step: 1
|
||||
quant_cfg:
|
||||
- $import: base_disable_all
|
||||
- quantizer_name: '*weight_quantizer'
|
||||
cfg:
|
||||
- $import: int4_per_block
|
||||
- $import: fp8
|
||||
- quantizer_name: '*input_quantizer'
|
||||
cfg:
|
||||
$import: fp8
|
||||
- $import: kv_fp8_cast
|
||||
- $import: default_disabled_quantizers
|
||||
@@ -0,0 +1,8 @@
|
||||
# MPT PTQ recipes
|
||||
|
||||
| Recipe | What's model-specific |
|
||||
|--------|-----------------------|
|
||||
| `w4a8_awq-kv_fp8_cast.yaml` | Uses `awq_lite` with `alpha_step: 1` instead of the default AWQ search. The default search overflows in TRT-LLM kernels on MPT; the coarser sweep avoids it. Numerics: INT4 block weights + FP8 inputs + FP8 KV-cache cast (constant amax, no KV calibration). Same algorithm override applied to Gemma — see `huggingface/gemma/ptq/`. |
|
||||
|
||||
The base numerics units and the standard disabled-quantizer list are inherited
|
||||
from the shared `configs/`; only the AWQ algorithm fields are model-specific.
|
||||
@@ -0,0 +1,47 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# MPT-specific W4A8 AWQ PTQ recipe with FP8 KV-cache cast. Uses a coarser
|
||||
# optimal-scale search (awq_lite with alpha_step=1) to avoid overflow observed
|
||||
# in TRT-LLM kernels when using the default AWQ search on MPT.
|
||||
|
||||
imports:
|
||||
base_disable_all: configs/ptq/units/base_disable_all
|
||||
default_disabled_quantizers: configs/ptq/units/default_disabled_quantizers
|
||||
fp8: configs/numerics/fp8
|
||||
int4_per_block: configs/numerics/int4_per_block
|
||||
kv_fp8_cast: configs/ptq/units/kv_fp8_cast
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: >-
|
||||
MPT W4A8 AWQ recipe with FP8 KV-cache cast: INT4 block weights + FP8
|
||||
inputs, awq_lite with alpha_step=1 (coarser search) to avoid TRT-LLM
|
||||
overflow, plus FP8 KV-cache using constant amax (no KV calibration).
|
||||
quantize:
|
||||
algorithm:
|
||||
method: awq_lite
|
||||
alpha_step: 1
|
||||
quant_cfg:
|
||||
- $import: base_disable_all
|
||||
- quantizer_name: '*weight_quantizer'
|
||||
cfg:
|
||||
- $import: int4_per_block
|
||||
- $import: fp8
|
||||
- quantizer_name: '*input_quantizer'
|
||||
cfg:
|
||||
$import: fp8
|
||||
- $import: kv_fp8_cast
|
||||
- $import: default_disabled_quantizers
|
||||
@@ -0,0 +1,14 @@
|
||||
# Nemotron VL PTQ recipes
|
||||
|
||||
Nemotron VL is a vision-language model family (including Nemotron-Parse).
|
||||
Quantization should be applied only to the decoder (text-generation
|
||||
component); the vision encoder, image encoder, and radio/model_encoder
|
||||
branches stay in full precision.
|
||||
|
||||
| File | What's model-specific |
|
||||
|------|-----------------------|
|
||||
| `disabled_quantizers.yaml` | Reusable unit (`QuantizerCfgListConfig`). Merges the standard `default_disabled_quantizers` exclusions with Nemotron-VL ones (`*vision*`, `*image*`, `*radio*`, `*visual*`, `*encoder*`, `*model_encoder*`). The last two patterns are required for Nemotron-Parse. Imported by recipes below as the single `disabled_quantizers` slot so they don't pull in two disabled-quantizer sets. |
|
||||
| `nvfp4-kv_fp8_cast.yaml` | NVFP4 W4A4 model quantization + FP8 KV-cache cast (constant amax, no KV calibration). Identical numerics to the general `nvfp4` preset / `kv_fp8_cast` unit; what makes it model-specific is that it imports `disabled_quantizers.yaml` from this folder to skip the vision/encoder branches. |
|
||||
|
||||
Additional `<qformat>-kv_fp8_cast.yaml` recipes can be generated for other formats
|
||||
if needed; only `nvfp4-kv_fp8_cast.yaml` is shipped by default.
|
||||
@@ -0,0 +1,39 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# QuantizerCfgList snippet of disabled quantizers for Nemotron VL. Splices in
|
||||
# the standard `default_disabled_quantizers` exclusions and appends
|
||||
# Nemotron-VL-specific ones so that only the decoder (text-generation
|
||||
# component) is quantized; vision/encoder branches, including the
|
||||
# Nemotron-Parse radio/model_encoder modules, are skipped. Recipes that
|
||||
# import this should NOT also import `default_disabled_quantizers`.
|
||||
|
||||
# modelopt-schema: modelopt.torch.quantization.config.QuantizerCfgListConfig
|
||||
imports:
|
||||
default_disabled_quantizers: configs/ptq/units/default_disabled_quantizers
|
||||
---
|
||||
- $import: default_disabled_quantizers
|
||||
- quantizer_name: '*vision*'
|
||||
enable: false
|
||||
- quantizer_name: '*image*'
|
||||
enable: false
|
||||
- quantizer_name: '*radio*'
|
||||
enable: false
|
||||
- quantizer_name: '*visual*'
|
||||
enable: false
|
||||
- quantizer_name: '*encoder*'
|
||||
enable: false
|
||||
- quantizer_name: '*model_encoder*'
|
||||
enable: false
|
||||
@@ -0,0 +1,36 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Nemotron VL-specific PTQ recipe for the `nvfp4` quantization format.
|
||||
# Equivalent to the general `nvfp4` preset with quantization disabled
|
||||
# on non-language branches.
|
||||
|
||||
imports:
|
||||
base_disable_all: configs/ptq/units/base_disable_all
|
||||
w4a4_nvfp4_nvfp4: configs/ptq/units/w4a4_nvfp4_nvfp4
|
||||
disabled_quantizers: huggingface/nemotron_vl/ptq/disabled_quantizers
|
||||
kv_fp8_cast: configs/ptq/units/kv_fp8_cast
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: 'Nemotron VL PTQ recipe (nvfp4): same numerics as the general nvfp4 preset, applied to the decoder (text generation) component only (vision/encoder
|
||||
branches are skipped).'
|
||||
quantize:
|
||||
algorithm: max
|
||||
quant_cfg:
|
||||
- $import: base_disable_all
|
||||
- $import: w4a4_nvfp4_nvfp4
|
||||
- $import: kv_fp8_cast
|
||||
- $import: disabled_quantizers
|
||||
@@ -0,0 +1,13 @@
|
||||
# Phi-4-Multimodal PTQ recipes
|
||||
|
||||
Phi-4-Multimodal is a multimodal model. Quantization should be applied only to
|
||||
the language model; the speech, audio, image, and vision branches are kept in
|
||||
full precision to avoid accuracy regressions on those modalities.
|
||||
|
||||
| File | What's model-specific |
|
||||
|------|-----------------------|
|
||||
| `disabled_quantizers.yaml` | Reusable unit (`QuantizerCfgListConfig`). Merges the standard `default_disabled_quantizers` exclusions with Phi-4-MM ones (`*speech*`, `*audio*`, `*image*`, `*vision*`). Imported by recipes below as the single `disabled_quantizers` slot so they don't pull in two disabled-quantizer sets. |
|
||||
| `nvfp4-kv_fp8_cast.yaml` | NVFP4 W4A4 model quantization + FP8 KV-cache cast (constant amax, no KV calibration). Identical numerics to the general `nvfp4` preset / `kv_fp8_cast` unit; what makes it model-specific is that it imports `disabled_quantizers.yaml` from this folder to skip the non-language branches. |
|
||||
|
||||
Additional `<qformat>-kv_fp8_cast.yaml` recipes can be generated for other formats
|
||||
if needed; only `nvfp4-kv_fp8_cast.yaml` is shipped by default.
|
||||
@@ -0,0 +1,34 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# QuantizerCfgList snippet of disabled quantizers for Phi-4-Multimodal.
|
||||
# Splices in the standard `default_disabled_quantizers` exclusions and appends
|
||||
# Phi-4-MM-specific ones so that only the language model is quantized;
|
||||
# speech/audio/image/vision branches are skipped. Recipes that import this
|
||||
# should NOT also import `default_disabled_quantizers`.
|
||||
|
||||
# modelopt-schema: modelopt.torch.quantization.config.QuantizerCfgListConfig
|
||||
imports:
|
||||
default_disabled_quantizers: configs/ptq/units/default_disabled_quantizers
|
||||
---
|
||||
- $import: default_disabled_quantizers
|
||||
- quantizer_name: '*speech*'
|
||||
enable: false
|
||||
- quantizer_name: '*audio*'
|
||||
enable: false
|
||||
- quantizer_name: '*image*'
|
||||
enable: false
|
||||
- quantizer_name: '*vision*'
|
||||
enable: false
|
||||
@@ -0,0 +1,36 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Phi-4-Multimodal-specific PTQ recipe for the `nvfp4` quantization format.
|
||||
# Equivalent to the general `nvfp4` preset with quantization disabled
|
||||
# on non-language branches.
|
||||
|
||||
imports:
|
||||
base_disable_all: configs/ptq/units/base_disable_all
|
||||
w4a4_nvfp4_nvfp4: configs/ptq/units/w4a4_nvfp4_nvfp4
|
||||
disabled_quantizers: huggingface/phi4mm/ptq/disabled_quantizers
|
||||
kv_fp8_cast: configs/ptq/units/kv_fp8_cast
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: 'Phi-4-Multimodal PTQ recipe (nvfp4): same numerics as the general nvfp4 preset, applied to the language model only (speech, audio, image,
|
||||
and vision branches are skipped).'
|
||||
quantize:
|
||||
algorithm: max
|
||||
quant_cfg:
|
||||
- $import: base_disable_all
|
||||
- $import: w4a4_nvfp4_nvfp4
|
||||
- $import: kv_fp8_cast
|
||||
- $import: disabled_quantizers
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# Shared `quant_cfg` snippet for the Qwen3.5 family's
|
||||
# `w4a16_nvfp4-fp8_attn-kv_fp8_cast` recipe. Imported by both
|
||||
# `huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.yaml` (dense `qwen3_5`)
|
||||
# and `huggingface/qwen3_5_moe/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.yaml` (MoE
|
||||
# `qwen3_5_moe`); the two families share the hybrid linear-attention +
|
||||
# softmax-attention architecture, so the wildcard rules apply identically.
|
||||
# MoE-only patterns inside `default_disabled_quantizers`
|
||||
# (`*block_sparse_moe.gate*`, `*mlp.shared_expert_gate.*`, `*router*`) are
|
||||
# no-ops on dense.
|
||||
|
||||
# modelopt-schema: modelopt.torch.quantization.config.QuantizerCfgListConfig
|
||||
imports:
|
||||
base_disable_all: configs/ptq/units/base_disable_all
|
||||
default_disabled_quantizers: configs/ptq/units/default_disabled_quantizers
|
||||
fp8: configs/numerics/fp8
|
||||
kv_fp8_cast: configs/ptq/units/kv_fp8_cast
|
||||
nvfp4: configs/numerics/nvfp4
|
||||
---
|
||||
- $import: base_disable_all
|
||||
|
||||
# W4A16 NVFP4 on MLP projection targets. The gate/up/down projection patterns
|
||||
# cover dense MLPs, shared experts, and fused MoE expert quantizers
|
||||
# (e.g. gate_up_proj_weight_quantizers.N).
|
||||
- quantizer_name: '*mlp*gate_proj*weight_quantizer*'
|
||||
cfg: {$import: nvfp4}
|
||||
- quantizer_name: '*mlp*up_proj*weight_quantizer*'
|
||||
cfg: {$import: nvfp4}
|
||||
- quantizer_name: '*mlp*down_proj*weight_quantizer*'
|
||||
cfg: {$import: nvfp4}
|
||||
|
||||
# FP8 self-attention projections.
|
||||
- quantizer_name: '*self_attn*weight_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
- quantizer_name: '*self_attn*input_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
|
||||
# FP8 large linear-attention projections. in_proj_a and in_proj_b are
|
||||
# re-disabled explicitly below; conv1d stays disabled via base_disable_all
|
||||
# (no rule re-enables it).
|
||||
- quantizer_name: '*linear_attn.in_proj_qkv*weight_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
- quantizer_name: '*linear_attn.in_proj_qkv*input_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
- quantizer_name: '*linear_attn.in_proj_z*weight_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
- quantizer_name: '*linear_attn.in_proj_z*input_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
- quantizer_name: '*linear_attn.out_proj*weight_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
- quantizer_name: '*linear_attn.out_proj*input_quantizer'
|
||||
cfg: {$import: fp8}
|
||||
|
||||
# FP8 KV cache with constant amax.
|
||||
- $import: kv_fp8_cast
|
||||
|
||||
# Standard exclusions (BatchNorm, LeakyReLU, gates, routers, conv1d, output
|
||||
# heads, etc.). Includes `*lm_head*` disable, which is re-enabled below.
|
||||
- $import: default_disabled_quantizers
|
||||
|
||||
# Qwen-specific exclusions: linear-attention sub-modules that are not in the
|
||||
# reference recipe, and any visual / MTP siblings on multimodal releases.
|
||||
- quantizer_name: '*linear_attn.in_proj_a*'
|
||||
enable: false
|
||||
- quantizer_name: '*linear_attn.in_proj_b*'
|
||||
enable: false
|
||||
- quantizer_name: '*visual*'
|
||||
enable: false
|
||||
- quantizer_name: '*vision_tower*'
|
||||
enable: false
|
||||
# Name-match for "mtp"; complementary runtime path in hf_ptq.py catches
|
||||
# MTP layers identified by index instead.
|
||||
- quantizer_name: '*mtp*'
|
||||
enable: false
|
||||
|
||||
# Re-enable NVFP4 on lm_head weights. Must come after
|
||||
# default_disabled_quantizers, which disables `*lm_head*`.
|
||||
- quantizer_name: '*lm_head*weight_quantizer'
|
||||
cfg: {$import: nvfp4}
|
||||
@@ -0,0 +1,39 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# W4A16 (NVFP4 weights) MLP / FP8 attention / FP8 KV-cast PTQ recipe for
|
||||
# HuggingFace `qwen3_5` (dense) models. Covers Qwen3.5 and Qwen3.6 dense
|
||||
# releases, which share the `qwen3_5` model_type and hybrid linear-attention +
|
||||
# softmax-attention architecture. Shares its `quant_cfg` with the MoE
|
||||
# counterpart at `huggingface/qwen3_5_moe/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.yaml`;
|
||||
# the snippet lives under
|
||||
# `huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.quant_cfg.yaml`.
|
||||
|
||||
imports:
|
||||
shared_quant_cfg: huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.quant_cfg
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: >-
|
||||
W4A16 (NVFP4 weights) MLP / FP8 attention / FP8 KV-cast PTQ recipe for
|
||||
HuggingFace `qwen3_5` (dense) models: NVFP4 for MLP projection weights and
|
||||
lm_head; FP8 for self-attention and the large linear-attention
|
||||
projections; FP8 KV cache with constant amax.
|
||||
quantize:
|
||||
algorithm:
|
||||
method: max
|
||||
layerwise: false
|
||||
quant_cfg:
|
||||
- $import: shared_quant_cfg
|
||||
@@ -0,0 +1,40 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# W4A16 (NVFP4 weights) MLP / FP8 attention / FP8 KV-cast PTQ recipe for
|
||||
# HuggingFace `qwen3_5_moe` models. Covers Qwen3.5-MoE and Qwen3.6-MoE
|
||||
# releases, which share the `qwen3_5_moe` model_type and hybrid
|
||||
# linear-attention + softmax-attention MoE architecture. Shares its
|
||||
# `quant_cfg` with the dense counterpart at
|
||||
# `huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.yaml`; the snippet lives
|
||||
# under `huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.quant_cfg.yaml`.
|
||||
|
||||
imports:
|
||||
shared_quant_cfg: huggingface/qwen3_5/ptq/w4a16_nvfp4-fp8_attn-kv_fp8_cast.quant_cfg
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: >-
|
||||
W4A16 (NVFP4 weights) MLP / FP8 attention / FP8 KV-cast PTQ recipe for
|
||||
HuggingFace `qwen3_5_moe` models (Qwen3.5-MoE and Qwen3.6-MoE releases):
|
||||
NVFP4 for MoE / shared-expert MLP projection weights and lm_head; FP8 for
|
||||
self-attention and the large linear-attention projections; FP8 KV cache
|
||||
with constant amax.
|
||||
quantize:
|
||||
algorithm:
|
||||
method: max
|
||||
layerwise: false
|
||||
quant_cfg:
|
||||
- $import: shared_quant_cfg
|
||||
@@ -1,122 +0,0 @@
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
metadata:
|
||||
recipe_type: ptq
|
||||
description: >
|
||||
W4A16 PTQ recipe for Qwen3.5/Qwen3.6 models: W4A16 NVFP4 for dense MLP,
|
||||
routed MoE, shared-expert MLP projections, and lm_head; FP8 for
|
||||
self-attention and the large linear-attention projections; FP8 KV cache
|
||||
with constant amax (fp8_cast behavior).
|
||||
|
||||
quantize:
|
||||
algorithm:
|
||||
method: max
|
||||
layerwise: false
|
||||
|
||||
quant_cfg:
|
||||
- quantizer_name: '*'
|
||||
enable: false
|
||||
|
||||
# W4A16 NVFP4 MLP projection targets. Matching the gate/up/down projection
|
||||
# names covers dense MLPs, shared experts, and fused MoE expert quantizers
|
||||
# such as gate_up_proj_weight_quantizers.N/down_proj_weight_quantizers.N.
|
||||
- quantizer_name: '*mlp*gate_proj*weight_quantizer*'
|
||||
enable: true
|
||||
cfg: &nvfp4_cfg
|
||||
block_sizes:
|
||||
-1: 16
|
||||
type: dynamic
|
||||
scale_bits: e4m3
|
||||
num_bits: e2m1
|
||||
- quantizer_name: '*mlp*up_proj*weight_quantizer*'
|
||||
enable: true
|
||||
cfg: *nvfp4_cfg
|
||||
- quantizer_name: '*mlp*down_proj*weight_quantizer*'
|
||||
enable: true
|
||||
cfg: *nvfp4_cfg
|
||||
- quantizer_name: '*lm_head*weight_quantizer'
|
||||
enable: true
|
||||
cfg: *nvfp4_cfg
|
||||
|
||||
# FP8 self-attention projections.
|
||||
- quantizer_name: '*self_attn*weight_quantizer'
|
||||
enable: true
|
||||
cfg: &fp8_cfg
|
||||
num_bits: e4m3
|
||||
axis:
|
||||
- quantizer_name: '*self_attn*input_quantizer'
|
||||
enable: true
|
||||
cfg: *fp8_cfg
|
||||
|
||||
# FP8 large linear-attention projections. Keep in_proj_a, in_proj_b, and
|
||||
# conv1d disabled to match the reference checkpoint policy.
|
||||
- quantizer_name: '*linear_attn.in_proj_qkv*weight_quantizer'
|
||||
enable: true
|
||||
cfg: *fp8_cfg
|
||||
- quantizer_name: '*linear_attn.in_proj_qkv*input_quantizer'
|
||||
enable: true
|
||||
cfg: *fp8_cfg
|
||||
- quantizer_name: '*linear_attn.in_proj_z*weight_quantizer'
|
||||
enable: true
|
||||
cfg: *fp8_cfg
|
||||
- quantizer_name: '*linear_attn.in_proj_z*input_quantizer'
|
||||
enable: true
|
||||
cfg: *fp8_cfg
|
||||
- quantizer_name: '*linear_attn.out_proj*weight_quantizer'
|
||||
enable: true
|
||||
cfg: *fp8_cfg
|
||||
- quantizer_name: '*linear_attn.out_proj*input_quantizer'
|
||||
enable: true
|
||||
cfg: *fp8_cfg
|
||||
|
||||
# FP8 KV cache with constant amax. This matches fp8_cast behavior and
|
||||
# avoids exporting per-layer KV scale tensors.
|
||||
- quantizer_name: '*[kv]_bmm_quantizer'
|
||||
enable: true
|
||||
cfg:
|
||||
num_bits: e4m3
|
||||
axis:
|
||||
use_constant_amax: true
|
||||
|
||||
# Explicitly keep non-reference targets unquantized.
|
||||
- quantizer_name: '*linear_attn.conv1d*'
|
||||
enable: false
|
||||
- quantizer_name: '*linear_attn.in_proj_a*'
|
||||
enable: false
|
||||
- quantizer_name: '*linear_attn.in_proj_b*'
|
||||
enable: false
|
||||
- quantizer_name: '*mlp.gate.*'
|
||||
enable: false
|
||||
- quantizer_name: '*mlp.shared_expert_gate.*'
|
||||
enable: false
|
||||
- quantizer_name: '*router*'
|
||||
enable: false
|
||||
- quantizer_name: '*block_sparse_moe.gate*'
|
||||
enable: false
|
||||
- quantizer_name: '*mixer.conv1d*'
|
||||
enable: false
|
||||
- quantizer_name: '*output_layer*'
|
||||
enable: false
|
||||
- quantizer_name: '*proj_out.*'
|
||||
enable: false
|
||||
- quantizer_name: 'output.*'
|
||||
enable: false
|
||||
- quantizer_name: '*visual*'
|
||||
enable: false
|
||||
- quantizer_name: '*vision_tower*'
|
||||
enable: false
|
||||
- quantizer_name: '*mtp*'
|
||||
enable: false
|
||||
- parent_class: 'nn.BatchNorm1d'
|
||||
quantizer_name: '*'
|
||||
enable: false
|
||||
- parent_class: 'nn.BatchNorm2d'
|
||||
quantizer_name: '*'
|
||||
enable: false
|
||||
- parent_class: 'nn.BatchNorm3d'
|
||||
quantizer_name: '*'
|
||||
enable: false
|
||||
- parent_class: 'nn.LeakyReLU'
|
||||
quantizer_name: '*'
|
||||
enable: false
|
||||
Reference in New Issue
Block a user