{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2026-07-23-bringing-nunchaku-4-bit-diffusion-inference-to-diffusers/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "Large diffusion transformers can create stunning images (or even videos, audio snippets, and now text), but loading a modern text-to-image model in BF16 precision often requires 20-30 GB of VRAM, which puts these models out of reach of most consumer GPUs. Quantization is a powerful solution to this problem, and Diffusers already integrates several quantization backends such as bitsandbytes, GGUF, torchao, and Quanto, which we covered in [Exploring Quantization Backends in Diffusers](https://huggingface.co/blog/diffusers-quantization).\n\nMost of these backends are *weight-only*. This means that they store the weights in low precision and dequantize them back to high precision at compute time. This reduces memory usage significantly, but it usually does not make inference faster, and can even add a small latency overhead.\n\n[SVDQuant](https://arxiv.org/abs/2411.05007), the quantization method behind the popular [Nunchaku](https://github.com/nunchaku-tech/nunchaku) inference engine, takes a different approach. It runs the main transformer layers with 4-bit weights and activations (W4A4), reducing memory while also speeding up the denoising loop. The details are covered below, but until now, using these checkpoints required a separate inference library.\n\nWith current Diffusers, loading a Nunchaku checkpoint is as simple as calling `from_pretrained()`, with no local CUDA compilation required thanks to the [`kernels`](https://github.com/huggingface/kernels) package. In addition, the companion [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor) toolkit lets you quantize new architectures yourself and publish them as regular Diffusers repositories.\n\n![Nunchaku Lite image quality and performance comparison](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/contact_sheet_top3_metrics_bold.png)\n\n## Table of Contents\n\n- [Getting started with Nunchaku Lite](https://huggingface.co/blog/nunchaku-diffusers#getting-started-with-nunchaku-lite)\n- [Background: SVDQuant and Nunchaku](https://huggingface.co/blog/nunchaku-diffusers#background-svdquant-and-nunchaku)\n- [Introducing Nunchaku Lite](https://huggingface.co/blog/nunchaku-diffusers#introducing-nunchaku-lite)\n- [Native loading in Diffusers](https://huggingface.co/blog/nunchaku-diffusers#native-loading-in-diffusers)\n- [Getting more speed and lower memory](https://huggingface.co/blog/nunchaku-diffusers#getting-more-speed-and-lower-memory)\n- [Benchmarks](https://huggingface.co/blog/nunchaku-diffusers#benchmarks)\n- [Quantizing your own model](https://huggingface.co/blog/nunchaku-diffusers#quantizing-your-own-model)\n- [Ready-to-use checkpoints](https://huggingface.co/blog/nunchaku-diffusers#ready-to-use-checkpoints)\n- [Conclusion](https://huggingface.co/blog/nunchaku-diffusers#conclusion)\n- [Acknowledgements](https://huggingface.co/blog/nunchaku-diffusers#acknowledgements)\n\n## Getting started with Nunchaku Lite\n\nFirst, install the requirements. You need a recent version of Diffusers and the Hugging Face `kernels` package:\n\n```bash\npip install -U diffusers transformers accelerate kernels bitsandbytes\n```\n\nThen load a pre-quantized pipeline like any other Diffusers model:\n\n```python\nimport torch\nfrom diffusers import ErnieImagePipeline\n\npipe = ErnieImagePipeline.from_pretrained(\n    \"lite-infer/ERNIE-Image-Turbo-nunchaku-lite-nvfp4_r32-bnb4-text-encoder\",\n    torch_dtype=torch.bfloat16,\n).to(\"cuda\")\n\nimage = pipe(\n    prompt=\"A cinematic portrait of a red fox in a misty forest at sunrise, \"\n           \"detailed fur, volumetric light\",\n    height=1024,\n    width=1024,\n    num_inference_steps=8,\n    guidance_scale=1.0,\n    generator=torch.Generator(\"cuda\").manual_seed(42),\n).images[0]\nimage.save(\"output.png\")\n```\n\n![BF16 and Nunchaku Lite outputs for a red fox prompt](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/fox_bf16_vs_nunchaku_no_metrics.png)\n\nNo custom pipeline class or separate inference engine is needed, and there is nothing to compile locally. The NVFP4 kernels are downloaded from the Hub through the [Nunchaku Lite kernels page](https://huggingface.co/kernels/rootonchair/nunchaku-lite-kernels) the first time they are used. This checkpoint pairs a Nunchaku NVFP4 transformer with a bitsandbytes NF4 text encoder, and generates a 1024x1024 image in about 1.7 seconds on an RTX 5090 with a peak memory usage of about 12 GB, compared with about 24 GB for the BF16 pipeline. You can find more details about the Nunchaku Lite checkpoint format in the [official Diffusers documentation](https://huggingface.co/docs/diffusers/main/en/quantization/nunchaku).\n\n> NVFP4 checkpoints require an NVIDIA Blackwell GPU (RTX 50 series, RTX PRO 6000, B200). For earlier generations, use the INT4 variants. See the [hardware support](https://huggingface.co/blog/nunchaku-diffusers#hardware-support) table below for details.\n\n## Background: SVDQuant and Nunchaku\n\n**SVDQuant** is the quantization method behind **Nunchaku**, its reference CUDA inference engine. Standard 4-bit quantization is difficult for diffusion transformers because both weights and activations contain large outliers. SVDQuant handles this by moving activation outliers into the weights, representing the hardest part of each weight matrix with a small 16-bit low-rank branch, and quantizing the remaining residual to 4 bits. Nunchaku makes this fast with fused kernels for the 4-bit path and the low-rank branch.\n\n![Nunchaku kernel fusion: the low-rank down projection is fused with input quantization, and the low-rank up projection is fused with the 4-bit matmul](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/svdquant_kernel_fusion.png)\\\nNunchaku fuses the low-rank down projection with the quantization kernel and the low-rank up projection with the 4-bit compute kernel, eliminating the memory access overhead of the 16-bit branch. Figure from the [SVDQuant paper](https://arxiv.org/abs/2411.05007).\n\n## Introducing Nunchaku Lite\n\nThe original [Nunchaku engine](https://github.com/nunchaku-ai/nunchaku) gets much of its speed from [model-specific fused execution paths](https://huggingface.co/blog/nunchaku-diffusers#quantizing-models-with-structural-rewrites), such as fused QKV projections and fused GELU/MLP kernels. Those optimizations are tied to each architecture's module layout and checkpoint format, so supporting a new model family usually requires model-specific integration work.\n\n**Nunchaku Lite** is the new integration path in Diffusers. With it, Diffusers can load Nunchaku-style checkpoints without a custom pipeline or a separate inference engine. Under the hood, Nunchaku Lite patches the relevant `nn.Linear` modules of a stock Diffusers model with runtime SVDQ/AWQ linear layers before the checkpoint is loaded. The CUDA kernels come from the Hub through the `kernels` package. Two kernel families are used:\n\n- **`svdq_w4a4`**: 4-bit weights and activations with the SVDQuant low-rank correction. This layer is used for the transformer's attention and MLP projections, where nearly all of the compute is spent, and is available in INT4 and NVFP4 variants.\n- **`awq_w4a16`**: 4-bit weights with 16-bit activations, used for adaptive normalization and modulation projections such as FLUX `adanorm_single` / `adanorm_zero` or Qwen-Image modulation layers. These layers are memory-bound and precision-sensitive, making AWQ a good fit to preserve precision while still saving memory and space.\n\nThe trade-off is that, without architecture-specific fused kernels and modules, Nunchaku Lite cannot match the speedup of the original Nunchaku engine. However, the bare-bones implementation still delivers around **30% speedup** while retaining the same level of **VRAM reduction**.\n\n## Native loading in Diffusers\n\nIf you have used bitsandbytes or torchao in Diffusers, the mechanics will feel familiar. A Nunchaku Lite model repository is an ordinary Diffusers repository. The only special part is a `quantization_config` block inside the transformer's `config.json`:\n\n```json\n\"quantization_config\": {\n    \"quant_method\": \"nunchaku_lite\",\n    \"compute_dtype\": \"bfloat16\",\n    \"svdq_w4a4\": {\n        \"precision\": \"nvfp4\",\n        \"group_size\": 16,\n        \"rank\": 32,\n        \"targets\": [\n            \"layers.0.self_attention.to_q\",\n            \"layers.0.self_attention.to_k\",\n            \"...\"\n        ]\n    },\n    \"awq_w4a16\": {\n        \"precision\": \"int4\",\n        \"group_size\": 64,\n        \"targets\": [\n            \"adaLN_modulation.1\",\n            \"...\"\n        ]\n    }\n}\n```\n\nThis config tells Diffusers which modules were quantized, which scheme they use, and which Nunchaku Lite runtime layer to instantiate (`SVDQW4A4Linear` or `AWQW4A16Linear`).\n\nBecause the quantized model keeps the exact module structure of the dense one, everything downstream (schedulers, LoRA loading hooks, offloading, `torch.compile`) sees a normal Diffusers model.\n\n### Hardware support\n\nNunchaku Lite uses different kernel variants depending on the GPU generation and checkpoint precision:\n\n| Scheme      | Precision | Supported GPUs                                         |\n| ----------- | --------- | ------------------------------------------------------ |\n| `svdq_w4a4` | `nvfp4`   | Blackwell (RTX 50 series, RTX PRO 6000, B200)          |\n| `svdq_w4a4` | `int4`    | Turing / Ampere / Ada (RTX 30 & 40 series, A100, L40S) |\n| `awq_w4a16` | `int4`    | Turing / Ampere / Ada (RTX 30 & 40 series, A100, L40S) |\n\n> Volta and Hopper GPUs are currently not supported by the 4-bit kernels. The quantizer validates the GPU's CUDA capability at load time and raises a clear error instead of producing incorrect outputs.\n\n## Getting more speed and lower memory\n\nNunchaku Lite can be combined with other Diffusers memory and speed optimizations.\n\n**`torch.compile`.** Compiling the transformer improves the end-to-end speedup from 1.35x to 1.8x:\n\n```python\npipe.transformer.compile(fullgraph=True)\n\n# or compile_repeated_blocks() for faster compilation\n\npipe.transformer.compile_repeated_blocks(fullgraph=True)\n```\n\n**Quantized text encoders.** The transformer is not the only component with a large memory footprint. Text encoders such as T5 or Qwen3 can occupy several gigabytes on their own. Further quantizing the text encoder with bitsandbytes NF4 reduces peak VRAM by about 22% in our benchmark.\n\n**Offloading.** Diffusers offloading helpers such as `enable_model_cpu_offload()` and `enable_sequential_cpu_offload()` work as usual if you need to fit the pipeline onto a smaller GPU.\n\n## Benchmarks\n\nAll numbers below were measured on an NVIDIA RTX PRO 6000 (Blackwell) at 1024x1024 using [rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder](https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder).\n\n### End-to-end latency and memory\n\n| Configuration                          | Full pipeline | Denoise loop | Peak VRAM | Speedup |\n| -------------------------------------- | ------------- | ------------ | --------- | ------- |\n| BF16 baseline                          | 3.00 s        | 2.86 s       | 31.1 GB   | 1.0x    |\n| Nunchaku Lite NVFP4                    | 2.27 s        | 2.13 s       | 20.6 GB   | 1.35x   |\n| Nunchaku Lite NVFP4 + `torch.compile`  | 1.68 s        | 1.53 s       | 20.6 GB   | 1.8x    |\n| Nunchaku Lite NVFP4 + NF4 text encoder | 2.29 s        | 2.13 s       | 16.0 GB   | 1.35x   |\n\nAs shown above, Nunchaku reduces peak VRAM by up to 50% while still improving latency by roughly 30%. The remaining overhead comes largely from extra kernel launches, which `torch.compile` can mitigate, bringing the full pipeline down to 1.68 s, or 1.8x faster than the BF16 baseline.\n\n### Image quality\n\n![Quality comparison grid](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/quality_grid.png)\\\nBF16 vs 4-bit outputs with identical seeds and settings.\n\n## Quantizing your own model\n\nNunchaku Lite support in Diffusers is architecture-agnostic, and the [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor) toolkit provides an end-to-end SVDQuant workflow for Diffusers models: calibrate, quantize, package, and publish.\n\nBelow, we walk through quantizing FLUX.2 Klein 4B as an example. It covers the main steps: inspect the model, calibrate and quantize the transformer, package the result as a Diffusers pipeline, then verify and push it to the Hub. The [full tutorial](https://github.com/rootonchair/diffuse-compressor/blob/main/docs/quantize_new_hf_model.md) covers every flag in detail.\n\n### 1. Inspect what will be quantized\n\nThe generic scanner walks the model and decides what to target: compatible linears inside the repeated transformer-block stack become SVDQ W4A4 targets, recognized modulation linears become AWQ W4A16 targets, and everything else stays dense.\n\n```bash\npython examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \\\n  --precision int4 --rank 32 --inspect-config\n```\n\nAlways read this report before quantizing. For FLUX.2 Klein 4B, the expected result is 100 SVDQ targets, 3 AWQ targets, and 6 dense outer linears, with no missing patterns or duplicate names.\n\n### 2. Run quantization\n\nThe following command runs SVDQuant on the transformer and writes the quantized checkpoint to `outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors`:\n\n```bash\npython examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \\\n  --precision int4 \\\n  --output outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors\n```\n\nReplace `--precision int4` with `nvfp4` to build Blackwell-native weights.\n\n### 3. Package a Diffusers pipeline\n\nThe converter combines the quantized transformer with the base pipeline's other components, writes the compact `nunchaku_lite` configuration into `transformer/config.json`, and can optionally convert text encoders to NF4:\n\n```bash\npython examples/convert_nunchaku_lite_diffusers.py \\\n  --checkpoint outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors \\\n  --model-id black-forest-labs/FLUX.2-klein-4B \\\n  --bnb4-text-encoder text_encoder \\\n  --compute-dtype bfloat16 \\\n  --output-dir outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder\n```\n\n### 4. Load, verify, and push to the Hub\n\n```python\nimport torch\nfrom diffusers import DiffusionPipeline\n\npipe = DiffusionPipeline.from_pretrained(\n    \"outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder\",\n    device_map=\"cuda\",\n)\nimage = pipe(\n    \"A glass robot in a greenhouse, cinematic lighting\",\n    num_inference_steps=4, guidance_scale=1.0,\n    generator=torch.Generator(\"cuda\").manual_seed(12345),\n).images[0]\n```\n\nOnce the outputs look good, run `pipe.push_to_hub(\"your-name/your-model-nunchaku-lite-int4\")`. Other users can then load it with the same `from_pretrained()` pattern shown above.\n\n### Quantizing models with structural rewrites\n\nNote that the generic path assumes the architecture can be quantized without structural rewrites. For additional speedup, the original Nunchaku engine rewrites groups of Diffusers layers as fused modules. The generic path cannot infer these changes on its own, such as combining separate Q, K, and V projections into one module or splitting a fused projection across several modules.\n\nFLUX.1-dev's QKV projection is a concrete example. [Diffusers defines three separate modules](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py#L313-L329):\n\n```python\nself.to_q = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)\nself.to_k = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)\nself.to_v = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)\n```\n\nThe [Nunchaku FLUX module combines those layers](https://github.com/nunchaku-ai/nunchaku/blob/main/nunchaku/models/transformers/transformer_flux_v2.py#L63-L79) into one quantized `to_qkv` module:\n\n```python\nto_qkv = fuse_linears([other.to_q, other.to_k, other.to_v])\nself.to_qkv = SVDQW4A4Linear.from_linear(to_qkv, **kwargs)\n```\n\nThis grouped module is required because Nunchaku's fused operator consumes the QKV projection, Q/K normalization, and rotary embeddings together. By comparison, the [default Diffusers path](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py#L45-L116) executes them separately:\n\n```python\nquery = attn.to_q(hidden_states)\nkey = attn.to_k(hidden_states)\nvalue = attn.to_v(hidden_states)\n\nquery = query.unflatten(-1, (attn.heads, -1))\nkey = key.unflatten(-1, (attn.heads, -1))\nvalue = value.unflatten(-1, (attn.heads, -1))\n\nquery = attn.norm_q(query)\nkey = attn.norm_k(key)\n\nif image_rotary_emb is not None:\n    query = apply_rotary_emb(query, image_rotary_emb, sequence_dim=1)\n    key = apply_rotary_emb(key, image_rotary_emb, sequence_dim=1)\n```\n\nThe [Nunchaku path](https://github.com/nunchaku-ai/nunchaku/blob/main/nunchaku/models/attention_processors/flux.py#L69-L93) supplies the grouped projection, normalization modules, and rotary embeddings to one fused operator:\n\n```python\nqkv = fused_qkv_norm_rottary(\n    hidden_states, attn.to_qkv, attn.norm_q, attn.norm_k, image_rotary_emb\n)\n```\n\nThis is the structural rewrite that the generic path cannot infer. Diffusers has three destination modules with `to_q`, `to_k`, and `to_v` parameter prefixes, while Nunchaku has one grouped module under `to_qkv`. A model-specific target config or adapter must state that the Q, K, and V parameters should be concatenated along the output dimension, in that order, and loaded into `to_qkv`.\n\nStructural rewrites like these are described by a model-specific target config during quantization and handled by a small runtime adapter when the checkpoint is loaded. The [FLUX.2 Klein 4B quantization script](https://github.com/rootonchair/diffuse-compressor/blob/main/examples/text_to_image/quantize_flux2_klein_4b.py) provides a concrete target-config example for producing a structurally rewritten checkpoint, while [rootonchair/nunchaku-lite](https://github.com/rootonchair/nunchaku-lite) provides the runtime adapters needed to load grouped QKV tensors, split fused projections, and other fused operations. For the complete workflow, you can check the [Adding A New Model](https://github.com/rootonchair/diffuse-compressor/blob/main/docs/adding_new_model.md) guide.\n\n## Ready-to-use checkpoints\n\nTo get started right away, check out the following repositories:\n\n- [rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder](https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder): INT4 ERNIE-Image-Turbo with a bitsandbytes NF4 text encoder\n- [rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4-bnb4-text-encoder](https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4-bnb4-text-encoder): NVFP4 ERNIE-Image-Turbo with a bitsandbytes NF4 text encoder\n- [OzzyGT/Krea\\_2\\_Turbo\\_nunchaku\\_lite\\_nvfp4](https://huggingface.co/OzzyGT/Krea_2_Turbo_nunchaku_lite_nvfp4): NVFP4 Krea 2 Turbo checkpoint\n- [lite-infer](https://huggingface.co/lite-infer): more Nunchaku Lite checkpoints and collections\n\n## Conclusion\n\nNunchaku's SVDQuant kernels are one of the most effective ways to run diffusion transformers efficiently on consumer hardware, and they are now natively supported in Diffusers. Pre-quantized checkpoints load with `from_pretrained()`, and the diffuse-compressor toolkit makes it possible to quantize new architectures without waiting for engine support. By quantizing both weights and activations, the W4A4 path lowers memory use while improving denoising latency, keeping image quality close to the BF16 original.\n\nIf you quantize and publish a new model, we would love to hear about it. Share it on the Hub and let us know! If you have any questions about this feature, feel free to join our [Discord](https://discord.gg/G7tWnz98XR).\n\nTo learn more, check out the following resources:\n\n- [Diffusers Nunchaku documentation](https://huggingface.co/docs/diffusers/quantization/nunchaku)\n- [The integration PR (huggingface/diffusers#14100)](https://github.com/huggingface/diffusers/pull/14100)\n- [SVDQuant paper](https://arxiv.org/abs/2411.05007) and the [Nunchaku engine](https://github.com/nunchaku-tech/nunchaku)\n- [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor)\n- Previous posts: [Exploring Quantization Backends in Diffusers](https://huggingface.co/blog/diffusers-quantization) and [Memory-efficient Diffusion Transformers with Quanto and Diffusers](https://huggingface.co/blog/quanto-diffusers)\n\n## Acknowledgements\n\nThanks to the Diffusers maintainers for reviews and guidance throughout the integration, and to the MIT HAN Lab / Nunchaku team for the original SVDQuant work. Thanks to Marc Sun for providing feedback on the blog post. Thanks to Álvaro Somoza for trying out `nunchaku-lite` and for providing feedback.\n\n`rootonchair` is also grateful to SilverAI for supporting this work and providing the environment in which much of this development took place.\n",
  "authors": [],
  "captured_at": "2026-10-19T01:26:53.998049939+00:00",
  "category": "ai",
  "content_html": "<p>Large diffusion transformers can create stunning images (or even videos, audio snippets, and now text), but loading a modern text-to-image model in BF16 precision often requires 20-30 GB of VRAM, which puts these models out of reach of most consumer GPUs. Quantization is a powerful solution to this problem, and Diffusers already integrates several quantization backends such as bitsandbytes, GGUF, torchao, and Quanto, which we covered in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/diffusers-quantization\">Exploring Quantization Backends in Diffusers</a>.</p>\n<p>Most of these backends are <em>weight-only</em>. This means that they store the weights in low precision and dequantize them back to high precision at compute time. This reduces memory usage significantly, but it usually does not make inference faster, and can even add a small latency overhead.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://arxiv.org/abs/2411.05007\">SVDQuant</a>, the quantization method behind the popular <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/nunchaku-tech/nunchaku\">Nunchaku</a> inference engine, takes a different approach. It runs the main transformer layers with 4-bit weights and activations (W4A4), reducing memory while also speeding up the denoising loop. The details are covered below, but until now, using these checkpoints required a separate inference library.</p>\n<p>With current Diffusers, loading a Nunchaku checkpoint is as simple as calling <code>from_pretrained()</code>, with no local CUDA compilation required thanks to the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/kernels\"><code>kernels</code></a> package. In addition, the companion <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/rootonchair/diffuse-compressor\">diffuse-compressor</a> toolkit lets you quantize new architectures yourself and publish them as regular Diffusers repositories.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/contact_sheet_top3_metrics_bold.png\" alt=\"Nunchaku Lite image quality and performance comparison\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<h2>Table of Contents</h2>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#getting-started-with-nunchaku-lite\">Getting started with Nunchaku Lite</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#background-svdquant-and-nunchaku\">Background: SVDQuant and Nunchaku</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#introducing-nunchaku-lite\">Introducing Nunchaku Lite</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#native-loading-in-diffusers\">Native loading in Diffusers</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#getting-more-speed-and-lower-memory\">Getting more speed and lower memory</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#benchmarks\">Benchmarks</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#quantizing-your-own-model\">Quantizing your own model</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#ready-to-use-checkpoints\">Ready-to-use checkpoints</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#conclusion\">Conclusion</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#acknowledgements\">Acknowledgements</a></li>\n</ul>\n<h2>Getting started with Nunchaku Lite</h2>\n<p>First, install the requirements. You need a recent version of Diffusers and the Hugging Face <code>kernels</code> package:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">pip</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> install<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>U</span> diffusers transformers accelerate kernels bitsandbytes</span>\n</span></span></code></pre>\n<p>Then load a pre-quantized pipeline like any other Diffusers model:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span></span></span>\n<span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">diffusers</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">ErnieImagePipeline</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pipe</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ErnieImagePipeline</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">lite-infer/ERNIE-Image-Turbo-nunchaku-lite-nvfp4_r32-bnb4-text-encoder<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">torch_dtype</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">bfloat16</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">to</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">cuda<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">pipe</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n    <span class=\"syntax-variable syntax-parameter syntax-python\">prompt</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">A cinematic portrait of a red fox in a misty forest at sunrise, <span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n           <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">detailed fur, volumetric light<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">height</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1024</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">width</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1024</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">num_inference_steps</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">8</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">guidance_scale</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">1<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>0</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">generator</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">Generator</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">cuda<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">manual_seed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">42</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">images</span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">0</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">save</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">output.png<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/fox_bf16_vs_nunchaku_no_metrics.png\" alt=\"BF16 and Nunchaku Lite outputs for a red fox prompt\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>No custom pipeline class or separate inference engine is needed, and there is nothing to compile locally. The NVFP4 kernels are downloaded from the Hub through the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/kernels/rootonchair/nunchaku-lite-kernels\">Nunchaku Lite kernels page</a> the first time they are used. This checkpoint pairs a Nunchaku NVFP4 transformer with a bitsandbytes NF4 text encoder, and generates a 1024x1024 image in about 1.7 seconds on an RTX 5090 with a peak memory usage of about 12 GB, compared with about 24 GB for the BF16 pipeline. You can find more details about the Nunchaku Lite checkpoint format in the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/docs/diffusers/main/en/quantization/nunchaku\">official Diffusers documentation</a>.</p>\n<blockquote>\n<p>NVFP4 checkpoints require an NVIDIA Blackwell GPU (RTX 50 series, RTX PRO 6000, B200). For earlier generations, use the INT4 variants. See the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#hardware-support\">hardware support</a> table below for details.</p>\n</blockquote>\n<h2>Background: SVDQuant and Nunchaku</h2>\n<p><strong>SVDQuant</strong> is the quantization method behind <strong>Nunchaku</strong>, its reference CUDA inference engine. Standard 4-bit quantization is difficult for diffusion transformers because both weights and activations contain large outliers. SVDQuant handles this by moving activation outliers into the weights, representing the hardest part of each weight matrix with a small 16-bit low-rank branch, and quantizing the remaining residual to 4 bits. Nunchaku makes this fast with fused kernels for the 4-bit path and the low-rank branch.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/svdquant_kernel_fusion.png\" alt=\"Nunchaku kernel fusion: the low-rank down projection is fused with input quantization, and the low-rank up projection is fused with the 4-bit matmul\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>Nunchaku fuses the low-rank down projection with the quantization kernel and the low-rank up projection with the 4-bit compute kernel, eliminating the memory access overhead of the 16-bit branch. Figure from the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://arxiv.org/abs/2411.05007\">SVDQuant paper</a>.</figcaption></figure>\n<h2>Introducing Nunchaku Lite</h2>\n<p>The original <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/nunchaku-ai/nunchaku\">Nunchaku engine</a> gets much of its speed from <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/nunchaku-diffusers#quantizing-models-with-structural-rewrites\">model-specific fused execution paths</a>, such as fused QKV projections and fused GELU/MLP kernels. Those optimizations are tied to each architecture's module layout and checkpoint format, so supporting a new model family usually requires model-specific integration work.</p>\n<p><strong>Nunchaku Lite</strong> is the new integration path in Diffusers. With it, Diffusers can load Nunchaku-style checkpoints without a custom pipeline or a separate inference engine. Under the hood, Nunchaku Lite patches the relevant <code>nn.Linear</code> modules of a stock Diffusers model with runtime SVDQ/AWQ linear layers before the checkpoint is loaded. The CUDA kernels come from the Hub through the <code>kernels</code> package. Two kernel families are used:</p>\n<ul>\n<li><strong><code>svdq_w4a4</code></strong>: 4-bit weights and activations with the SVDQuant low-rank correction. This layer is used for the transformer's attention and MLP projections, where nearly all of the compute is spent, and is available in INT4 and NVFP4 variants.</li>\n<li><strong><code>awq_w4a16</code></strong>: 4-bit weights with 16-bit activations, used for adaptive normalization and modulation projections such as FLUX <code>adanorm_single</code> / <code>adanorm_zero</code> or Qwen-Image modulation layers. These layers are memory-bound and precision-sensitive, making AWQ a good fit to preserve precision while still saving memory and space.</li>\n</ul>\n<p>The trade-off is that, without architecture-specific fused kernels and modules, Nunchaku Lite cannot match the speedup of the original Nunchaku engine. However, the bare-bones implementation still delivers around <strong>30% speedup</strong> while retaining the same level of <strong>VRAM reduction</strong>.</p>\n<h2>Native loading in Diffusers</h2>\n<p>If you have used bitsandbytes or torchao in Diffusers, the mechanics will feel familiar. A Nunchaku Lite model repository is an ordinary Diffusers repository. The only special part is a <code>quantization_config</code> block inside the transformer's <code>config.json</code>:</p>\n<pre><code class=\"language-json\"><span class=\"code-snippet\" data-language=\"JSON\"><span class=\"syntax-source syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>quantization_config<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span>: <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-json\"><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-begin syntax-json\">{</span>\n    <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>quant_method<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>nunchaku_lite<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n    <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>compute_dtype<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>bfloat16<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n    <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>svdq_w4a4<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-json\"><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-begin syntax-json\">{</span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>precision<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>nvfp4<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>group_size<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-constant syntax-numeric syntax-json\">16</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>rank<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-constant syntax-numeric syntax-json\">32</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>targets<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-meta syntax-structure syntax-array syntax-json\"><span class=\"syntax-punctuation syntax-section syntax-array syntax-begin syntax-json\">[</span>\n            <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>layers.0.self_attention.to_q<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-array syntax-json\">,</span>\n            <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>layers.0.self_attention.to_k<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-array syntax-json\">,</span>\n            <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>...<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span>\n        <span class=\"syntax-punctuation syntax-section syntax-array syntax-end syntax-json\">]</span></span>\n    </span><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-end syntax-json\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n    <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>awq_w4a16<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-json\"><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-begin syntax-json\">{</span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>precision<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>int4<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>group_size<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-constant syntax-numeric syntax-json\">64</span><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-pair syntax-json\">,</span></span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary syntax-key syntax-json\"><span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>targets<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span></span><span class=\"syntax-meta syntax-structure syntax-dictionary syntax-value syntax-json\"><span class=\"syntax-punctuation syntax-separator syntax-dictionary syntax-key-value syntax-json\">:</span> <span class=\"syntax-meta syntax-structure syntax-array syntax-json\"><span class=\"syntax-punctuation syntax-section syntax-array syntax-begin syntax-json\">[</span>\n            <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>adaLN_modulation.1<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span><span class=\"syntax-punctuation syntax-separator syntax-array syntax-json\">,</span>\n            <span class=\"syntax-string syntax-quoted syntax-double syntax-json\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-json\">&quot;</span>...<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-json\">&quot;</span></span>\n        <span class=\"syntax-punctuation syntax-section syntax-array syntax-end syntax-json\">]</span></span>\n    </span><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-end syntax-json\">}</span></span>\n</span><span class=\"syntax-punctuation syntax-section syntax-dictionary syntax-end syntax-json\">}</span></span>\n</span></span></code></pre>\n<p>This config tells Diffusers which modules were quantized, which scheme they use, and which Nunchaku Lite runtime layer to instantiate (<code>SVDQW4A4Linear</code> or <code>AWQW4A16Linear</code>).</p>\n<p>Because the quantized model keeps the exact module structure of the dense one, everything downstream (schedulers, LoRA loading hooks, offloading, <code>torch.compile</code>) sees a normal Diffusers model.</p>\n<h3>Hardware support</h3>\n<p>Nunchaku Lite uses different kernel variants depending on the GPU generation and checkpoint precision:</p>\n<table>\n<thead>\n<tr>\n<th>Scheme</th>\n<th>Precision</th>\n<th>Supported GPUs</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>svdq_w4a4</code></td>\n<td><code>nvfp4</code></td>\n<td>Blackwell (RTX 50 series, RTX PRO 6000, B200)</td>\n</tr>\n<tr>\n<td><code>svdq_w4a4</code></td>\n<td><code>int4</code></td>\n<td>Turing / Ampere / Ada (RTX 30 &amp; 40 series, A100, L40S)</td>\n</tr>\n<tr>\n<td><code>awq_w4a16</code></td>\n<td><code>int4</code></td>\n<td>Turing / Ampere / Ada (RTX 30 &amp; 40 series, A100, L40S)</td>\n</tr>\n</tbody>\n</table>\n<blockquote>\n<p>Volta and Hopper GPUs are currently not supported by the 4-bit kernels. The quantizer validates the GPU's CUDA capability at load time and raises a clear error instead of producing incorrect outputs.</p>\n</blockquote>\n<h2>Getting more speed and lower memory</h2>\n<p>Nunchaku Lite can be combined with other Diffusers memory and speed optimizations.</p>\n<p><strong><code>torch.compile</code>.</strong> Compiling the transformer improves the end-to-end speedup from 1.35x to 1.8x:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pipe</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">transformer</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">compile</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">fullgraph</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">True</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> or compile_repeated_blocks() for faster compilation\n</span>\n<span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pipe</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">transformer</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">compile_repeated_blocks</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">fullgraph</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-language syntax-python\">True</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p><strong>Quantized text encoders.</strong> The transformer is not the only component with a large memory footprint. Text encoders such as T5 or Qwen3 can occupy several gigabytes on their own. Further quantizing the text encoder with bitsandbytes NF4 reduces peak VRAM by about 22% in our benchmark.</p>\n<p><strong>Offloading.</strong> Diffusers offloading helpers such as <code>enable_model_cpu_offload()</code> and <code>enable_sequential_cpu_offload()</code> work as usual if you need to fit the pipeline onto a smaller GPU.</p>\n<h2>Benchmarks</h2>\n<p>All numbers below were measured on an NVIDIA RTX PRO 6000 (Blackwell) at 1024x1024 using <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder\">rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder</a>.</p>\n<h3>End-to-end latency and memory</h3>\n<table>\n<thead>\n<tr>\n<th>Configuration</th>\n<th>Full pipeline</th>\n<th>Denoise loop</th>\n<th>Peak VRAM</th>\n<th>Speedup</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>BF16 baseline</td>\n<td>3.00 s</td>\n<td>2.86 s</td>\n<td>31.1 GB</td>\n<td>1.0x</td>\n</tr>\n<tr>\n<td>Nunchaku Lite NVFP4</td>\n<td>2.27 s</td>\n<td>2.13 s</td>\n<td>20.6 GB</td>\n<td>1.35x</td>\n</tr>\n<tr>\n<td>Nunchaku Lite NVFP4 + <code>torch.compile</code></td>\n<td>1.68 s</td>\n<td>1.53 s</td>\n<td>20.6 GB</td>\n<td>1.8x</td>\n</tr>\n<tr>\n<td>Nunchaku Lite NVFP4 + NF4 text encoder</td>\n<td>2.29 s</td>\n<td>2.13 s</td>\n<td>16.0 GB</td>\n<td>1.35x</td>\n</tr>\n</tbody>\n</table>\n<p>As shown above, Nunchaku reduces peak VRAM by up to 50% while still improving latency by roughly 30%. The remaining overhead comes largely from extra kernel launches, which <code>torch.compile</code> can mitigate, bringing the full pipeline down to 1.68 s, or 1.8x faster than the BF16 baseline.</p>\n<h3>Image quality</h3>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/quality_grid.png\" alt=\"Quality comparison grid\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>BF16 vs 4-bit outputs with identical seeds and settings.</figcaption></figure>\n<h2>Quantizing your own model</h2>\n<p>Nunchaku Lite support in Diffusers is architecture-agnostic, and the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/rootonchair/diffuse-compressor\">diffuse-compressor</a> toolkit provides an end-to-end SVDQuant workflow for Diffusers models: calibrate, quantize, package, and publish.</p>\n<p>Below, we walk through quantizing FLUX.2 Klein 4B as an example. It covers the main steps: inspect the model, calibrate and quantize the transformer, package the result as a Diffusers pipeline, then verify and push it to the Hub. The <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/rootonchair/diffuse-compressor/blob/main/docs/quantize_new_hf_model.md\">full tutorial</a> covers every flag in detail.</p>\n<h3>1. Inspect what will be quantized</h3>\n<p>The generic scanner walks the model and decides what to target: compatible linears inside the repeated transformer-block stack become SVDQ W4A4 targets, recognized modulation linears become AWQ W4A16 targets, and everything else stays dense.</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>precision</span> int4<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>rank</span> 32<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>inspect-config</span></span>\n</span></span></code></pre>\n<p>Always read this report before quantizing. For FLUX.2 Klein 4B, the expected result is 100 SVDQ targets, 3 AWQ targets, and 6 dense outer linears, with no missing patterns or duplicate names.</p>\n<h3>2. Run quantization</h3>\n<p>The following command runs SVDQuant on the transformer and writes the quantized checkpoint to <code>outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors</code>:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>precision</span> int4 <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>output</span> outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors</span>\n</span></span></code></pre>\n<p>Replace <code>--precision int4</code> with <code>nvfp4</code> to build Blackwell-native weights.</p>\n<h3>3. Package a Diffusers pipeline</h3>\n<p>The converter combines the quantized transformer with the base pipeline's other components, writes the compact <code>nunchaku_lite</code> configuration into <code>transformer/config.json</code>, and can optionally convert text encoders to NF4:</p>\n<pre><code class=\"language-bash\"><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">python</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> examples/convert_nunchaku_lite_diffusers.py <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>checkpoint</span> outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>model-id</span> black-forest-labs/FLUX.2-klein-4B <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>bnb4-text-encoder</span> text_encoder <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>compute-dtype</span> bfloat16 <span class=\"syntax-punctuation syntax-separator syntax-continuation syntax-line syntax-shell\">\\\n</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\">  --</span>output-dir</span> outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder</span>\n</span></span></code></pre>\n<h3>4. Load, verify, and push to the Hub</h3>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span></span></span>\n<span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-from syntax-python\">from</span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-meta syntax-import-source syntax-python\"> <span class=\"syntax-meta syntax-import-path syntax-python\"><span class=\"syntax-meta syntax-import-name syntax-python\">diffusers</span></span> <span class=\"syntax-meta syntax-statement syntax-import syntax-python\"><span class=\"syntax-keyword syntax-control syntax-import syntax-python\">import</span></span></span></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"></span><span class=\"syntax-meta syntax-statement syntax-import syntax-python\"> <span class=\"syntax-meta syntax-generic-name syntax-python\">DiffusionPipeline</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pipe</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">DiffusionPipeline</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_pretrained</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">device_map</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">cuda<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">pipe</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n    <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">A glass robot in a greenhouse, cinematic lighting<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">num_inference_steps</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">4</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">guidance_scale</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-float syntax-python\">1<span class=\"syntax-punctuation syntax-separator syntax-decimal syntax-python\">.</span>0</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n    <span class=\"syntax-variable syntax-parameter syntax-python\">generator</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">Generator</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">cuda<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">manual_seed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">12345</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span>\n</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">images</span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">0</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n</span></span></code></pre>\n<p>Once the outputs look good, run <code>pipe.push_to_hub(&quot;your-name/your-model-nunchaku-lite-int4&quot;)</code>. Other users can then load it with the same <code>from_pretrained()</code> pattern shown above.</p>\n<h3>Quantizing models with structural rewrites</h3>\n<p>Note that the generic path assumes the architecture can be quantized without structural rewrites. For additional speedup, the original Nunchaku engine rewrites groups of Diffusers layers as fused modules. The generic path cannot infer these changes on its own, such as combining separate Q, K, and V projections into one module or splitting a fused projection across several modules.</p>\n<p>FLUX.1-dev's QKV projection is a concrete example. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py#L313-L329\">Diffusers defines three separate modules</a>:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_q</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">nn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">Linear</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query_dim</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">inner_dim</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">bias</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">bias</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_k</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">nn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">Linear</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query_dim</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">inner_dim</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">bias</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">bias</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_v</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">torch</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">nn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">Linear</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query_dim</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">inner_dim</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">bias</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">bias</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p>The <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/nunchaku-ai/nunchaku/blob/main/nunchaku/models/transformers/transformer_flux_v2.py#L63-L79\">Nunchaku FLUX module combines those layers</a> into one quantized <code>to_qkv</code> module:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">to_qkv</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fuse_linears</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">other</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_q</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">other</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_k</span></span><span class=\"syntax-punctuation syntax-separator syntax-list syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">other</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_v</span></span><span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_qkv</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">SVDQW4A4Linear</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">from_linear</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">to_qkv</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-keyword syntax-operator syntax-unpacking syntax-mapping syntax-python\">**</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">kwargs</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p>This grouped module is required because Nunchaku's fused operator consumes the QKV projection, Q/K normalization, and rotary embeddings together. By comparison, the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py#L45-L116\">default Diffusers path</a> executes them separately:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">to_q</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">hidden_states</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">key</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">to_k</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">hidden_states</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">value</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">to_v</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">hidden_states</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">unflatten</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">heads</span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">key</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">key</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">unflatten</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">heads</span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">value</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">value</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">unflatten</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">heads</span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">norm_q</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">key</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">norm_k</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">key</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_rotary_emb</span></span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">is</span> <span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">not</span> <span class=\"syntax-constant syntax-language syntax-python\">None</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">apply_rotary_emb</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">query</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_rotary_emb</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">sequence_dim</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">key</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">apply_rotary_emb</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">key</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_rotary_emb</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">sequence_dim</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p>The <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/nunchaku-ai/nunchaku/blob/main/nunchaku/models/attention_processors/flux.py#L69-L93\">Nunchaku path</a> supplies the grouped projection, normalization modules, and rotary embeddings to one fused operator:</p>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">qkv</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fused_qkv_norm_rottary</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">hidden_states</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">to_qkv</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">norm_q</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">attn</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">norm_k</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">image_rotary_emb</span></span>\n</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p>This is the structural rewrite that the generic path cannot infer. Diffusers has three destination modules with <code>to_q</code>, <code>to_k</code>, and <code>to_v</code> parameter prefixes, while Nunchaku has one grouped module under <code>to_qkv</code>. A model-specific target config or adapter must state that the Q, K, and V parameters should be concatenated along the output dimension, in that order, and loaded into <code>to_qkv</code>.</p>\n<p>Structural rewrites like these are described by a model-specific target config during quantization and handled by a small runtime adapter when the checkpoint is loaded. The <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/rootonchair/diffuse-compressor/blob/main/examples/text_to_image/quantize_flux2_klein_4b.py\">FLUX.2 Klein 4B quantization script</a> provides a concrete target-config example for producing a structurally rewritten checkpoint, while <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/rootonchair/nunchaku-lite\">rootonchair/nunchaku-lite</a> provides the runtime adapters needed to load grouped QKV tensors, split fused projections, and other fused operations. For the complete workflow, you can check the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/rootonchair/diffuse-compressor/blob/main/docs/adding_new_model.md\">Adding A New Model</a> guide.</p>\n<h2>Ready-to-use checkpoints</h2>\n<p>To get started right away, check out the following repositories:</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder\">rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder</a>: INT4 ERNIE-Image-Turbo with a bitsandbytes NF4 text encoder</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4-bnb4-text-encoder\">rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4-bnb4-text-encoder</a>: NVFP4 ERNIE-Image-Turbo with a bitsandbytes NF4 text encoder</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/OzzyGT/Krea_2_Turbo_nunchaku_lite_nvfp4\">OzzyGT/Krea_2_Turbo_nunchaku_lite_nvfp4</a>: NVFP4 Krea 2 Turbo checkpoint</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/lite-infer\">lite-infer</a>: more Nunchaku Lite checkpoints and collections</li>\n</ul>\n<h2>Conclusion</h2>\n<p>Nunchaku's SVDQuant kernels are one of the most effective ways to run diffusion transformers efficiently on consumer hardware, and they are now natively supported in Diffusers. Pre-quantized checkpoints load with <code>from_pretrained()</code>, and the diffuse-compressor toolkit makes it possible to quantize new architectures without waiting for engine support. By quantizing both weights and activations, the W4A4 path lowers memory use while improving denoising latency, keeping image quality close to the BF16 original.</p>\n<p>If you quantize and publish a new model, we would love to hear about it. Share it on the Hub and let us know! If you have any questions about this feature, feel free to join our <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://discord.gg/G7tWnz98XR\">Discord</a>.</p>\n<p>To learn more, check out the following resources:</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/docs/diffusers/quantization/nunchaku\">Diffusers Nunchaku documentation</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/huggingface/diffusers/pull/14100\">The integration PR (huggingface/diffusers#14100)</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://arxiv.org/abs/2411.05007\">SVDQuant paper</a> and the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/nunchaku-tech/nunchaku\">Nunchaku engine</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/rootonchair/diffuse-compressor\">diffuse-compressor</a></li>\n<li>Previous posts: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/diffusers-quantization\">Exploring Quantization Backends in Diffusers</a> and <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://huggingface.co/blog/quanto-diffusers\">Memory-efficient Diffusion Transformers with Quanto and Diffusers</a></li>\n</ul>\n<h2>Acknowledgements</h2>\n<p>Thanks to the Diffusers maintainers for reviews and guidance throughout the integration, and to the MIT HAN Lab / Nunchaku team for the original SVDQuant work. Thanks to Marc Sun for providing feedback on the blog post. Thanks to Álvaro Somoza for trying out <code>nunchaku-lite</code> and for providing feedback.</p>\n<p><code>rootonchair</code> is also grateful to SilverAI for supporting this work and providing the environment in which much of this development took place.</p>\n",
  "content_markdown": "Large diffusion transformers can create stunning images (or even videos, audio snippets, and now text), but loading a modern text-to-image model in BF16 precision often requires 20-30 GB of VRAM, which puts these models out of reach of most consumer GPUs. Quantization is a powerful solution to this problem, and Diffusers already integrates several quantization backends such as bitsandbytes, GGUF, torchao, and Quanto, which we covered in [Exploring Quantization Backends in Diffusers](https://huggingface.co/blog/diffusers-quantization).\n\nMost of these backends are *weight-only*. This means that they store the weights in low precision and dequantize them back to high precision at compute time. This reduces memory usage significantly, but it usually does not make inference faster, and can even add a small latency overhead.\n\n[SVDQuant](https://arxiv.org/abs/2411.05007), the quantization method behind the popular [Nunchaku](https://github.com/nunchaku-tech/nunchaku) inference engine, takes a different approach. It runs the main transformer layers with 4-bit weights and activations (W4A4), reducing memory while also speeding up the denoising loop. The details are covered below, but until now, using these checkpoints required a separate inference library.\n\nWith current Diffusers, loading a Nunchaku checkpoint is as simple as calling `from_pretrained()`, with no local CUDA compilation required thanks to the [`kernels`](https://github.com/huggingface/kernels) package. In addition, the companion [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor) toolkit lets you quantize new architectures yourself and publish them as regular Diffusers repositories.\n\n![Nunchaku Lite image quality and performance comparison](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/contact_sheet_top3_metrics_bold.png)\n\n## Table of Contents\n\n- [Getting started with Nunchaku Lite](https://huggingface.co/blog/nunchaku-diffusers#getting-started-with-nunchaku-lite)\n- [Background: SVDQuant and Nunchaku](https://huggingface.co/blog/nunchaku-diffusers#background-svdquant-and-nunchaku)\n- [Introducing Nunchaku Lite](https://huggingface.co/blog/nunchaku-diffusers#introducing-nunchaku-lite)\n- [Native loading in Diffusers](https://huggingface.co/blog/nunchaku-diffusers#native-loading-in-diffusers)\n- [Getting more speed and lower memory](https://huggingface.co/blog/nunchaku-diffusers#getting-more-speed-and-lower-memory)\n- [Benchmarks](https://huggingface.co/blog/nunchaku-diffusers#benchmarks)\n- [Quantizing your own model](https://huggingface.co/blog/nunchaku-diffusers#quantizing-your-own-model)\n- [Ready-to-use checkpoints](https://huggingface.co/blog/nunchaku-diffusers#ready-to-use-checkpoints)\n- [Conclusion](https://huggingface.co/blog/nunchaku-diffusers#conclusion)\n- [Acknowledgements](https://huggingface.co/blog/nunchaku-diffusers#acknowledgements)\n\n## Getting started with Nunchaku Lite\n\nFirst, install the requirements. You need a recent version of Diffusers and the Hugging Face `kernels` package:\n\n```bash\npip install -U diffusers transformers accelerate kernels bitsandbytes\n```\n\nThen load a pre-quantized pipeline like any other Diffusers model:\n\n```python\nimport torch\nfrom diffusers import ErnieImagePipeline\n\npipe = ErnieImagePipeline.from_pretrained(\n    \"lite-infer/ERNIE-Image-Turbo-nunchaku-lite-nvfp4_r32-bnb4-text-encoder\",\n    torch_dtype=torch.bfloat16,\n).to(\"cuda\")\n\nimage = pipe(\n    prompt=\"A cinematic portrait of a red fox in a misty forest at sunrise, \"\n           \"detailed fur, volumetric light\",\n    height=1024,\n    width=1024,\n    num_inference_steps=8,\n    guidance_scale=1.0,\n    generator=torch.Generator(\"cuda\").manual_seed(42),\n).images[0]\nimage.save(\"output.png\")\n```\n\n![BF16 and Nunchaku Lite outputs for a red fox prompt](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/fox_bf16_vs_nunchaku_no_metrics.png)\n\nNo custom pipeline class or separate inference engine is needed, and there is nothing to compile locally. The NVFP4 kernels are downloaded from the Hub through the [Nunchaku Lite kernels page](https://huggingface.co/kernels/rootonchair/nunchaku-lite-kernels) the first time they are used. This checkpoint pairs a Nunchaku NVFP4 transformer with a bitsandbytes NF4 text encoder, and generates a 1024x1024 image in about 1.7 seconds on an RTX 5090 with a peak memory usage of about 12 GB, compared with about 24 GB for the BF16 pipeline. You can find more details about the Nunchaku Lite checkpoint format in the [official Diffusers documentation](https://huggingface.co/docs/diffusers/main/en/quantization/nunchaku).\n\n> NVFP4 checkpoints require an NVIDIA Blackwell GPU (RTX 50 series, RTX PRO 6000, B200). For earlier generations, use the INT4 variants. See the [hardware support](https://huggingface.co/blog/nunchaku-diffusers#hardware-support) table below for details.\n\n## Background: SVDQuant and Nunchaku\n\n**SVDQuant** is the quantization method behind **Nunchaku**, its reference CUDA inference engine. Standard 4-bit quantization is difficult for diffusion transformers because both weights and activations contain large outliers. SVDQuant handles this by moving activation outliers into the weights, representing the hardest part of each weight matrix with a small 16-bit low-rank branch, and quantizing the remaining residual to 4 bits. Nunchaku makes this fast with fused kernels for the 4-bit path and the low-rank branch.\n\n![Nunchaku kernel fusion: the low-rank down projection is fused with input quantization, and the low-rank up projection is fused with the 4-bit matmul](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/svdquant_kernel_fusion.png)\\\nNunchaku fuses the low-rank down projection with the quantization kernel and the low-rank up projection with the 4-bit compute kernel, eliminating the memory access overhead of the 16-bit branch. Figure from the [SVDQuant paper](https://arxiv.org/abs/2411.05007).\n\n## Introducing Nunchaku Lite\n\nThe original [Nunchaku engine](https://github.com/nunchaku-ai/nunchaku) gets much of its speed from [model-specific fused execution paths](https://huggingface.co/blog/nunchaku-diffusers#quantizing-models-with-structural-rewrites), such as fused QKV projections and fused GELU/MLP kernels. Those optimizations are tied to each architecture's module layout and checkpoint format, so supporting a new model family usually requires model-specific integration work.\n\n**Nunchaku Lite** is the new integration path in Diffusers. With it, Diffusers can load Nunchaku-style checkpoints without a custom pipeline or a separate inference engine. Under the hood, Nunchaku Lite patches the relevant `nn.Linear` modules of a stock Diffusers model with runtime SVDQ/AWQ linear layers before the checkpoint is loaded. The CUDA kernels come from the Hub through the `kernels` package. Two kernel families are used:\n\n- **`svdq_w4a4`**: 4-bit weights and activations with the SVDQuant low-rank correction. This layer is used for the transformer's attention and MLP projections, where nearly all of the compute is spent, and is available in INT4 and NVFP4 variants.\n- **`awq_w4a16`**: 4-bit weights with 16-bit activations, used for adaptive normalization and modulation projections such as FLUX `adanorm_single` / `adanorm_zero` or Qwen-Image modulation layers. These layers are memory-bound and precision-sensitive, making AWQ a good fit to preserve precision while still saving memory and space.\n\nThe trade-off is that, without architecture-specific fused kernels and modules, Nunchaku Lite cannot match the speedup of the original Nunchaku engine. However, the bare-bones implementation still delivers around **30% speedup** while retaining the same level of **VRAM reduction**.\n\n## Native loading in Diffusers\n\nIf you have used bitsandbytes or torchao in Diffusers, the mechanics will feel familiar. A Nunchaku Lite model repository is an ordinary Diffusers repository. The only special part is a `quantization_config` block inside the transformer's `config.json`:\n\n```json\n\"quantization_config\": {\n    \"quant_method\": \"nunchaku_lite\",\n    \"compute_dtype\": \"bfloat16\",\n    \"svdq_w4a4\": {\n        \"precision\": \"nvfp4\",\n        \"group_size\": 16,\n        \"rank\": 32,\n        \"targets\": [\n            \"layers.0.self_attention.to_q\",\n            \"layers.0.self_attention.to_k\",\n            \"...\"\n        ]\n    },\n    \"awq_w4a16\": {\n        \"precision\": \"int4\",\n        \"group_size\": 64,\n        \"targets\": [\n            \"adaLN_modulation.1\",\n            \"...\"\n        ]\n    }\n}\n```\n\nThis config tells Diffusers which modules were quantized, which scheme they use, and which Nunchaku Lite runtime layer to instantiate (`SVDQW4A4Linear` or `AWQW4A16Linear`).\n\nBecause the quantized model keeps the exact module structure of the dense one, everything downstream (schedulers, LoRA loading hooks, offloading, `torch.compile`) sees a normal Diffusers model.\n\n### Hardware support\n\nNunchaku Lite uses different kernel variants depending on the GPU generation and checkpoint precision:\n\n| Scheme      | Precision | Supported GPUs                                         |\n| ----------- | --------- | ------------------------------------------------------ |\n| `svdq_w4a4` | `nvfp4`   | Blackwell (RTX 50 series, RTX PRO 6000, B200)          |\n| `svdq_w4a4` | `int4`    | Turing / Ampere / Ada (RTX 30 & 40 series, A100, L40S) |\n| `awq_w4a16` | `int4`    | Turing / Ampere / Ada (RTX 30 & 40 series, A100, L40S) |\n\n> Volta and Hopper GPUs are currently not supported by the 4-bit kernels. The quantizer validates the GPU's CUDA capability at load time and raises a clear error instead of producing incorrect outputs.\n\n## Getting more speed and lower memory\n\nNunchaku Lite can be combined with other Diffusers memory and speed optimizations.\n\n**`torch.compile`.** Compiling the transformer improves the end-to-end speedup from 1.35x to 1.8x:\n\n```python\npipe.transformer.compile(fullgraph=True)\n\n# or compile_repeated_blocks() for faster compilation\n\npipe.transformer.compile_repeated_blocks(fullgraph=True)\n```\n\n**Quantized text encoders.** The transformer is not the only component with a large memory footprint. Text encoders such as T5 or Qwen3 can occupy several gigabytes on their own. Further quantizing the text encoder with bitsandbytes NF4 reduces peak VRAM by about 22% in our benchmark.\n\n**Offloading.** Diffusers offloading helpers such as `enable_model_cpu_offload()` and `enable_sequential_cpu_offload()` work as usual if you need to fit the pipeline onto a smaller GPU.\n\n## Benchmarks\n\nAll numbers below were measured on an NVIDIA RTX PRO 6000 (Blackwell) at 1024x1024 using [rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder](https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder).\n\n### End-to-end latency and memory\n\n| Configuration                          | Full pipeline | Denoise loop | Peak VRAM | Speedup |\n| -------------------------------------- | ------------- | ------------ | --------- | ------- |\n| BF16 baseline                          | 3.00 s        | 2.86 s       | 31.1 GB   | 1.0x    |\n| Nunchaku Lite NVFP4                    | 2.27 s        | 2.13 s       | 20.6 GB   | 1.35x   |\n| Nunchaku Lite NVFP4 + `torch.compile`  | 1.68 s        | 1.53 s       | 20.6 GB   | 1.8x    |\n| Nunchaku Lite NVFP4 + NF4 text encoder | 2.29 s        | 2.13 s       | 16.0 GB   | 1.35x   |\n\nAs shown above, Nunchaku reduces peak VRAM by up to 50% while still improving latency by roughly 30%. The remaining overhead comes largely from extra kernel launches, which `torch.compile` can mitigate, bringing the full pipeline down to 1.68 s, or 1.8x faster than the BF16 baseline.\n\n### Image quality\n\n![Quality comparison grid](https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/nunchaku-diffusers/quality_grid.png)\\\nBF16 vs 4-bit outputs with identical seeds and settings.\n\n## Quantizing your own model\n\nNunchaku Lite support in Diffusers is architecture-agnostic, and the [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor) toolkit provides an end-to-end SVDQuant workflow for Diffusers models: calibrate, quantize, package, and publish.\n\nBelow, we walk through quantizing FLUX.2 Klein 4B as an example. It covers the main steps: inspect the model, calibrate and quantize the transformer, package the result as a Diffusers pipeline, then verify and push it to the Hub. The [full tutorial](https://github.com/rootonchair/diffuse-compressor/blob/main/docs/quantize_new_hf_model.md) covers every flag in detail.\n\n### 1. Inspect what will be quantized\n\nThe generic scanner walks the model and decides what to target: compatible linears inside the repeated transformer-block stack become SVDQ W4A4 targets, recognized modulation linears become AWQ W4A16 targets, and everything else stays dense.\n\n```bash\npython examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \\\n  --precision int4 --rank 32 --inspect-config\n```\n\nAlways read this report before quantizing. For FLUX.2 Klein 4B, the expected result is 100 SVDQ targets, 3 AWQ targets, and 6 dense outer linears, with no missing patterns or duplicate names.\n\n### 2. Run quantization\n\nThe following command runs SVDQuant on the transformer and writes the quantized checkpoint to `outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors`:\n\n```bash\npython examples/text_to_image/quantize_hf.py black-forest-labs/FLUX.2-klein-4B \\\n  --precision int4 \\\n  --output outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors\n```\n\nReplace `--precision int4` with `nvfp4` to build Blackwell-native weights.\n\n### 3. Package a Diffusers pipeline\n\nThe converter combines the quantized transformer with the base pipeline's other components, writes the compact `nunchaku_lite` configuration into `transformer/config.json`, and can optionally convert text encoders to NF4:\n\n```bash\npython examples/convert_nunchaku_lite_diffusers.py \\\n  --checkpoint outputs/checkpoints/svdq-int4_r32-flux-2-klein-4b.safetensors \\\n  --model-id black-forest-labs/FLUX.2-klein-4B \\\n  --bnb4-text-encoder text_encoder \\\n  --compute-dtype bfloat16 \\\n  --output-dir outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder\n```\n\n### 4. Load, verify, and push to the Hub\n\n```python\nimport torch\nfrom diffusers import DiffusionPipeline\n\npipe = DiffusionPipeline.from_pretrained(\n    \"outputs/diffusers/FLUX.2-klein-4B-nunchaku-lite-int4-bnb4-text-encoder\",\n    device_map=\"cuda\",\n)\nimage = pipe(\n    \"A glass robot in a greenhouse, cinematic lighting\",\n    num_inference_steps=4, guidance_scale=1.0,\n    generator=torch.Generator(\"cuda\").manual_seed(12345),\n).images[0]\n```\n\nOnce the outputs look good, run `pipe.push_to_hub(\"your-name/your-model-nunchaku-lite-int4\")`. Other users can then load it with the same `from_pretrained()` pattern shown above.\n\n### Quantizing models with structural rewrites\n\nNote that the generic path assumes the architecture can be quantized without structural rewrites. For additional speedup, the original Nunchaku engine rewrites groups of Diffusers layers as fused modules. The generic path cannot infer these changes on its own, such as combining separate Q, K, and V projections into one module or splitting a fused projection across several modules.\n\nFLUX.1-dev's QKV projection is a concrete example. [Diffusers defines three separate modules](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py#L313-L329):\n\n```python\nself.to_q = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)\nself.to_k = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)\nself.to_v = torch.nn.Linear(query_dim, self.inner_dim, bias=bias)\n```\n\nThe [Nunchaku FLUX module combines those layers](https://github.com/nunchaku-ai/nunchaku/blob/main/nunchaku/models/transformers/transformer_flux_v2.py#L63-L79) into one quantized `to_qkv` module:\n\n```python\nto_qkv = fuse_linears([other.to_q, other.to_k, other.to_v])\nself.to_qkv = SVDQW4A4Linear.from_linear(to_qkv, **kwargs)\n```\n\nThis grouped module is required because Nunchaku's fused operator consumes the QKV projection, Q/K normalization, and rotary embeddings together. By comparison, the [default Diffusers path](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py#L45-L116) executes them separately:\n\n```python\nquery = attn.to_q(hidden_states)\nkey = attn.to_k(hidden_states)\nvalue = attn.to_v(hidden_states)\n\nquery = query.unflatten(-1, (attn.heads, -1))\nkey = key.unflatten(-1, (attn.heads, -1))\nvalue = value.unflatten(-1, (attn.heads, -1))\n\nquery = attn.norm_q(query)\nkey = attn.norm_k(key)\n\nif image_rotary_emb is not None:\n    query = apply_rotary_emb(query, image_rotary_emb, sequence_dim=1)\n    key = apply_rotary_emb(key, image_rotary_emb, sequence_dim=1)\n```\n\nThe [Nunchaku path](https://github.com/nunchaku-ai/nunchaku/blob/main/nunchaku/models/attention_processors/flux.py#L69-L93) supplies the grouped projection, normalization modules, and rotary embeddings to one fused operator:\n\n```python\nqkv = fused_qkv_norm_rottary(\n    hidden_states, attn.to_qkv, attn.norm_q, attn.norm_k, image_rotary_emb\n)\n```\n\nThis is the structural rewrite that the generic path cannot infer. Diffusers has three destination modules with `to_q`, `to_k`, and `to_v` parameter prefixes, while Nunchaku has one grouped module under `to_qkv`. A model-specific target config or adapter must state that the Q, K, and V parameters should be concatenated along the output dimension, in that order, and loaded into `to_qkv`.\n\nStructural rewrites like these are described by a model-specific target config during quantization and handled by a small runtime adapter when the checkpoint is loaded. The [FLUX.2 Klein 4B quantization script](https://github.com/rootonchair/diffuse-compressor/blob/main/examples/text_to_image/quantize_flux2_klein_4b.py) provides a concrete target-config example for producing a structurally rewritten checkpoint, while [rootonchair/nunchaku-lite](https://github.com/rootonchair/nunchaku-lite) provides the runtime adapters needed to load grouped QKV tensors, split fused projections, and other fused operations. For the complete workflow, you can check the [Adding A New Model](https://github.com/rootonchair/diffuse-compressor/blob/main/docs/adding_new_model.md) guide.\n\n## Ready-to-use checkpoints\n\nTo get started right away, check out the following repositories:\n\n- [rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder](https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-int4-bnb4-text-encoder): INT4 ERNIE-Image-Turbo with a bitsandbytes NF4 text encoder\n- [rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4-bnb4-text-encoder](https://huggingface.co/rootonchair/ERNIE-Image-Turbo-nunchaku-lite-nvfp4-bnb4-text-encoder): NVFP4 ERNIE-Image-Turbo with a bitsandbytes NF4 text encoder\n- [OzzyGT/Krea\\_2\\_Turbo\\_nunchaku\\_lite\\_nvfp4](https://huggingface.co/OzzyGT/Krea_2_Turbo_nunchaku_lite_nvfp4): NVFP4 Krea 2 Turbo checkpoint\n- [lite-infer](https://huggingface.co/lite-infer): more Nunchaku Lite checkpoints and collections\n\n## Conclusion\n\nNunchaku's SVDQuant kernels are one of the most effective ways to run diffusion transformers efficiently on consumer hardware, and they are now natively supported in Diffusers. Pre-quantized checkpoints load with `from_pretrained()`, and the diffuse-compressor toolkit makes it possible to quantize new architectures without waiting for engine support. By quantizing both weights and activations, the W4A4 path lowers memory use while improving denoising latency, keeping image quality close to the BF16 original.\n\nIf you quantize and publish a new model, we would love to hear about it. Share it on the Hub and let us know! If you have any questions about this feature, feel free to join our [Discord](https://discord.gg/G7tWnz98XR).\n\nTo learn more, check out the following resources:\n\n- [Diffusers Nunchaku documentation](https://huggingface.co/docs/diffusers/quantization/nunchaku)\n- [The integration PR (huggingface/diffusers#14100)](https://github.com/huggingface/diffusers/pull/14100)\n- [SVDQuant paper](https://arxiv.org/abs/2411.05007) and the [Nunchaku engine](https://github.com/nunchaku-tech/nunchaku)\n- [diffuse-compressor](https://github.com/rootonchair/diffuse-compressor)\n- Previous posts: [Exploring Quantization Backends in Diffusers](https://huggingface.co/blog/diffusers-quantization) and [Memory-efficient Diffusion Transformers with Quanto and Diffusers](https://huggingface.co/blog/quanto-diffusers)\n\n## Acknowledgements\n\nThanks to the Diffusers maintainers for reviews and guidance throughout the integration, and to the MIT HAN Lab / Nunchaku team for the original SVDQuant work. Thanks to Marc Sun for providing feedback on the blog post. Thanks to Álvaro Somoza for trying out `nunchaku-lite` and for providing feedback.\n\n`rootonchair` is also grateful to SilverAI for supporting this work and providing the environment in which much of this development took place.\n",
  "dateCreated": "2026-10-19T01:26:53.998049939+00:00",
  "date_created": "2026-07-23T00:00:00+00:00",
  "date_modified": "2026-07-23T00:00:00+00:00",
  "date_published": "2026-07-23T00:00:00+00:00",
  "description": "Large diffusion transformers can create stunning images (or even videos, audio snippets, and now text), but loading a modern text-to-image model in BF16 precision often requires 20-30 GB of VRAM, which puts these models out of reach of…",
  "external_url": "https://huggingface.co/blog/nunchaku-diffusers",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/huggingface-co/2026/07/2026-07-23-bringing-nunchaku-4-bit-diffusion-inference-to-diffusers.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/huggingface-co/2026/07/2026-07-23-bringing-nunchaku-4-bit-diffusion-inference-to-diffusers.md"
  },
  "id": "urn:aggr:item:aca977f6944f64fdbf535e14c4d2b5a7dbca5103",
  "isBasedOn": {
    "@id": "https://huggingface.co/blog/nunchaku-diffusers"
  },
  "mainEntity": {
    "@id": "https://huggingface.co/blog/nunchaku-diffusers",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/huggingface-co/2026-07-23-bringing-nunchaku-4-bit-diffusion-inference-to-diffusers/#webpage"
    },
    "dateModified": "2026-07-23T00:00:00+00:00",
    "datePublished": "2026-07-23T00:00:00+00:00",
    "headline": "Bringing Nunchaku 4-bit Diffusion Inference to Diffusers",
    "image": {
      "@type": "ImageObject",
      "caption": null,
      "height": 90,
      "url": "https://huggingface.co/blog/assets/nunchaku-diffusers/thumbnail.png",
      "width": 160
    },
    "timeRequired": "PT11M",
    "url": "https://huggingface.co/blog/nunchaku-diffusers",
    "wordCount": 2336
  },
  "name": "Archived snapshot: Bringing Nunchaku 4-bit Diffusion Inference to Diffusers",
  "preview": {
    "alt": null,
    "color": null,
    "height": 90,
    "placeholder": {
      "data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=",
      "hash": ""
    },
    "url": "https://huggingface.co/blog/assets/nunchaku-diffusers/thumbnail.png",
    "width": 160
  },
  "reading_minutes": 11,
  "replicated_at": null,
  "source": "huggingface-co",
  "source_name": "Hugging Face - Blog",
  "summary": null,
  "tags": [],
  "temporalCoverage": "2026-10-19T01:26:53.998049939+00:00",
  "title": "Bringing Nunchaku 4-bit Diffusion Inference to Diffusers",
  "url": "https://aggr.aymericbeaumet.com/items/huggingface-co/2026-07-23-bringing-nunchaku-4-bit-diffusion-inference-to-diffusers/",
  "word_count": 2336
}