Add Nunchaku Lite single-file quantization (#14100) · huggingface/diffusers@60ec6f7 · GitHub
Skip to content

Commit 60ec6f7

Browse files
rootonchairsergereview[bot]sayakpaulgithub-actions[bot]stevhliu
authored
Add Nunchaku Lite single-file quantization (#14100)
* Add Nunchaku Lite single-file quantization * Support config-backed Nunchaku Lite loading * Remove Nunchaku runtime manifest metadata loading * Simplify Nunchaku compact config loading * Add Nunchaku Lite quantization tests * Document Nunchaku Lite checkpoint loading * Refine Nunchaku Lite quantization docs * Remove unused Nunchaku smooth factor original weights * Update docs/source/en/quantization/nunchaku.md Co-authored-by: sergereview[bot] <283583894+sergereview[bot]@users.noreply.github.com> * Update src/diffusers/quantizers/nunchaku/utils.py Co-authored-by: sergereview[bot] <283583894+sergereview[bot]@users.noreply.github.com> * Update src/diffusers/quantizers/nunchaku/nunchaku_quantizer.py Co-authored-by: sergereview[bot] <283583894+sergereview[bot]@users.noreply.github.com> * Address Nunchaku Lite review feedback * Update Nunchaku Lite quantizer * Rename Nunchaku Lite fp4 precision to nvfp4 * Allow torch_dtype to override Nunchaku compute dtype * Keep Nunchaku replacement modules on meta during loading * Require kernels when importing Nunchaku runtime utils * Use kernels requirement decorators for Nunchaku tests * Validate Nunchaku CUDA capability requirements * Apply suggestions from code review Co-authored-by: Sayak Paul <spsayakpaul@gmail.com> * docs: update nunchaku quantization guide * test: remove nunchaku quantization tests * fix: reject hopper for nunchaku lite * Apply suggestion from @rootonchair * docs: update nunchaku lite compile example * Apply style fixes * Apply suggestions from code review Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com> Co-authored-by: Vinh H. Pham <phamvinh257@gmail.com> * update doc to be more reasonable * fix import that requires kernels --------- Co-authored-by: sergereview[bot] <283583894+sergereview[bot]@users.noreply.github.com> Co-authored-by: Sayak Paul <spsayakpaul@gmail.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Steven Liu <59462357+stevhliu@users.noreply.github.com>
1 parent deb1738 commit 60ec6f7

13 files changed

Lines changed: 879 additions & 0 deletions

File tree

‎docs/source/en/_toctree.yml‎

Lines changed: 2 additions & 0 deletions

‎docs/source/en/api/quantization.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ Quantization techniques reduce memory and computational costs by representing we
3030

3131
[[autodoc]] quantizers.quantization_config.GGUFQuantizationConfig
3232

33+
## NunchakuLiteQuantizationConfig
34+
35+
[[autodoc]] quantizers.quantization_config.NunchakuLiteQuantizationConfig
36+
3337
## QuantoConfig
3438

3539
[[autodoc]] quantizers.quantization_config.QuantoConfig
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<!--Copyright 2026 The HuggingFace Team. All rights reserved.
2+
3+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
4+
the License. You may obtain a copy of the License at
5+
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
8+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
9+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
10+
specific language governing permissions and limitations under the License.
11+
12+
-->
13+
14+
# Nunchaku Lite
15+
16+
Nunchaku Lite is a quantization backend for loading prequantized checkpoints in Diffusers. Create compatible checkpoints with [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor). It quantizes and exports a transformer, then packages it as a Diffusers pipeline.
17+
18+
Nunchaku Lite builds on the original [Nunchaku](https://github.com/nunchaku-ai/nunchaku) inference engine,
19+
[DeepCompressor](https://github.com/nunchaku-ai/deepcompressor) quantization library, and
20+
[SVDQuant paper](https://arxiv.org/abs/2411.05007).
21+
22+
## Install the CUDA kernels
23+
24+
The kernels package supplies the optimized CUDA kernels, which load automatically. Install it first.
25+
26+
```bash
27+
pip install -U kernels
28+
```
29+
30+
## Load a quantized pipeline
31+
32+
Load the prequantized pipeline with [`~DiffusionPipeline.from_pretrained`], which reads the quantization
33+
config from `config.json`.
34+
35+
```python
36+
import torch
37+
from diffusers import DiffusionPipeline
38+
39+
model_id = "rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4"
40+
41+
pipe = DiffusionPipeline.from_pretrained(
42+
model_id, torch_dtype=torch.bfloat16,
43+
).to("cuda")
44+
45+
prompt = "A modern red armchair in a quiet studio, soft window light, realistic product photography"
46+
image = pipe(
47+
prompt=prompt,
48+
height=1024,
49+
width=1024,
50+
num_inference_steps=8,
51+
guidance_scale=1.0,
52+
).images[0]
53+
image.save("ernie-image-turbo-nunchaku-lite.png")
54+
```
55+
56+
> [!NOTE]
57+
> The exported state dict must match the target Diffusers model architecture exactly. For example, a checkpoint
58+
> quantized with fused QKV projections won't load into a model config that expects separate Q, K, and V projection
59+
> modules.
60+
61+
## Supported quantization types
62+
63+
Nunchaku Lite supports the following quantized linear layer formats.
64+
65+
> [!TIP]
66+
> Use `nvfp4` on Blackwell GPUs. Running `int4` checkpoints on Blackwell can be slower than `nvfp4`.
67+
68+
The CUDA kernels currently support the following NVIDIA GPU architectures:
69+
70+
- `sm_75` (Turing, for example RTX 2080)
71+
- `sm_80` (Ampere, for example A100)
72+
- `sm_86` (Ampere, for example RTX 3090 and RTX A6000)
73+
- `sm_89` (Ada, for example RTX 4090)
74+
- `sm_120` (Blackwell, for example RTX 5090)
75+
76+
> [!NOTE]
77+
> Hopper GPUs, such as `sm_90` H100 and H200, are not currently supported.
78+
79+
`nvfp4` checkpoints require a Blackwell or newer NVIDIA GPU. On Blackwell GPUs, use PyTorch >= 2.7 with CUDA >= 12.8.
80+
`int4` checkpoints require a Turing or newer NVIDIA GPU.
81+
82+
| Method | Precision | Group size | Notes |
83+
|---|---:|---:|---|
84+
| `svdq_w4a4` | `nvfp4` | 16 | Uses NVFP4 runtime kernels with SVDQ low-rank correction. |
85+
| `svdq_w4a4` | `int4` | 64 | Uses INT4 W4A4 kernels with SVDQ low-rank correction. |
86+
| `awq_w4a16` | `int4` | 64 | Uses INT4 weight-only AWQ-style kernels. |
87+
88+
## NunchakuLiteQuantizationConfig
89+
90+
The `config.json` file must include a [`NunchakuLiteQuantizationConfig`]. It defines the runtime
91+
`compute_dtype` and the target modules for each Nunchaku Lite quantization method.
92+
93+
- `compute_dtype`: runtime dtype for floating-point buffers in quantized modules, typically `torch.bfloat16`.
94+
- `svdq_w4a4`: SVDQ W4A4 target config with `precision`, `group_size`, `rank`, and `targets`.
95+
- `awq_w4a16`: AWQ W4A16 target config with `precision`, `group_size`, and `targets`.
96+
97+
Each entry in `targets` must point to a linear layer. Diffusers swaps each `svdq_w4a4` target for an SVDQ W4A4 layer and each `awq_w4a16` target for an AWQ W4A16 layer. The example below shows the
98+
expected shape with shortened target lists.
99+
100+
List each module you want to quantize under `svdq_w4a4` or `awq_w4a16`. A module can only use one method, so don't list the same target under both.
101+
102+
```json
103+
{
104+
"_class_name": "ErnieImageTransformer2DModel",
105+
"quantization_config": {
106+
"quant_method": "nunchaku_lite",
107+
"compute_dtype": "bfloat16",
108+
"svdq_w4a4": {
109+
"precision": "nvfp4",
110+
"group_size": 16,
111+
"rank": 32,
112+
"targets": ["layers.0.self_attention.to_q"]
113+
},
114+
"awq_w4a16": {
115+
"precision": "int4",
116+
"group_size": 64,
117+
"targets": ["final_linear"]
118+
}
119+
}
120+
}
121+
```
122+
123+
## torch.compile
124+
125+
Nunchaku Lite kernels and quantized linear layers are compatible with [`torch.compile`](../optimization/fp16#torchcompile).
126+
Compile the quantized transformer after loading the pipeline for faster inference.
127+
128+
```python
129+
pipe.transformer = torch.compile(pipe.transformer, mode="default", fullgraph=True)
130+
```
131+
132+
The compiled Nunchaku Lite NVFP4 pipeline runs 1.8x faster than the original BF16 pipeline (2.271s → 1.675s on an RTX PRO 6000).
133+
134+
## Resources
135+
136+
- [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor)
137+
- [Nunchaku installation requirements](https://nunchaku.tech/docs/nunchaku/installation/installation.html)

‎docs/source/en/quantization/overview.md‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,30 @@ pipe = DiffusionPipeline.from_pretrained(
125125
image = pipe("photo of a cute dog").images[0]
126126
```
127127

128+
## Loading prequantized checkpoints
129+
130+
Some quantization backends support loading checkpoints that were already quantized and uploaded to the Hub. In this case, the quantization configuration is stored in the model's `config.json` and is read automatically — you do not need to create a [`~quantizers.PipelineQuantizationConfig`] or pass a `quantization_config` argument.
131+
132+
```py
133+
import torch
134+
from diffusers import DiffusionPipeline
135+
136+
pipe = DiffusionPipeline.from_pretrained(
137+
"rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4",
138+
torch_dtype=torch.bfloat16,
139+
).to("cuda")
140+
```
141+
142+
The following backends support loading prequantized checkpoints out of the box.
143+
144+
| Backend | Notes |
145+
|---|---|
146+
| [bitsandbytes](./bitsandbytes) | Config is saved in `config.json`; no extra arguments needed. |
147+
| [GGUF](./gguf) | Uses `from_single_file` with Model classes; pipeline-level loading is not supported. |
148+
| [AutoRound](./autoround) | Only loading is supported; quantize first with the AutoRound CLI or Python API. |
149+
| [Nunchaku Lite](./nunchaku) | Config is saved in `config.json`; requires the `kernels` package. |
150+
| [ModelOpt](./modelopt) | Supports both quantizing on the fly and loading prequantized models. |
151+
128152
## Resources
129153

130154
Check out the resources below to learn more about quantization.

‎src/diffusers/__init__.py‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@
124124
else:
125125
_import_structure["quantizers.quantization_config"].append("NVIDIAModelOptConfig")
126126

127+
try:
128+
if not is_torch_available():
129+
raise OptionalDependencyNotAvailable()
130+
except OptionalDependencyNotAvailable:
131+
from .utils import dummy_nunchaku_lite_objects
132+
133+
_import_structure["utils.dummy_nunchaku_lite_objects"] = [
134+
name for name in dir(dummy_nunchaku_lite_objects) if not name.startswith("_")
135+
]
136+
else:
137+
_import_structure["quantizers.quantization_config"].append("NunchakuLiteQuantizationConfig")
138+
127139
try:
128140
if not is_auto_round_available():
129141
raise OptionalDependencyNotAvailable()
@@ -1014,6 +1026,14 @@
10141026
else:
10151027
from .quantizers.quantization_config import NVIDIAModelOptConfig
10161028

1029+
try:
1030+
if not is_torch_available():
1031+
raise OptionalDependencyNotAvailable()
1032+
except OptionalDependencyNotAvailable:
1033+
from .utils.dummy_nunchaku_lite_objects import *
1034+
else:
1035+
from .quantizers.quantization_config import NunchakuLiteQuantizationConfig
1036+
10171037
try:
10181038
if not is_auto_round_available():
10191039
raise OptionalDependencyNotAvailable()

‎src/diffusers/quantizers/auto.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
from .bitsandbytes import BnB4BitDiffusersQuantizer, BnB8BitDiffusersQuantizer
2323
from .gguf import GGUFQuantizer
2424
from .modelopt import NVIDIAModelOptQuantizer
25+
from .nunchaku import NunchakuLiteQuantizer
2526
from .quantization_config import (
2627
AutoRoundConfig,
2728
BitsAndBytesConfig,
2829
GGUFQuantizationConfig,
30+
NunchakuLiteQuantizationConfig,
2931
NVIDIAModelOptConfig,
3032
QuantizationConfigMixin,
3133
QuantizationMethod,
@@ -44,6 +46,7 @@
4446
"torchao": TorchAoHfQuantizer,
4547
"modelopt": NVIDIAModelOptQuantizer,
4648
"auto-round": AutoRoundQuantizer,
49+
"nunchaku_lite": NunchakuLiteQuantizer,
4750
}
4851

4952
AUTO_QUANTIZATION_CONFIG_MAPPING = {
@@ -54,6 +57,7 @@
5457
"torchao": TorchAoConfig,
5558
"modelopt": NVIDIAModelOptConfig,
5659
"auto-round": AutoRoundConfig,
60+
"nunchaku_lite": NunchakuLiteQuantizationConfig,
5761
}
5862

5963

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .nunchaku_quantizer import NunchakuLiteQuantizer
Lines changed: 89 additions & 0 deletions

0 commit comments

Comments
 (0)