Universal FP8 / NVFP4 Quantizer
Roll your own NVFP4 model — no waiting for the pre-quant to drop
- output_path
- log
The thing nobody warns you about when a new model drops is the wait. BF16 ships, then you sit refreshing HuggingFace while the community converts it to fp8, then NVFP4, then GGUF - each one slower to appear and easier to get wrong. This node is that wait, gone. Point it at any diffusion model you already have and it writes a mixed FP8/NVFP4 .safetensors next to it, in place, no uploads, no scripts. It's thepororo's ComfyUI-NVFP4-Quantizer, and it does its one trick properly.
What it is
It's an output node under model/quantization - you don't wire it into a generation graph, it's a self-contained converter that sits off to the side. Drop it on the canvas, pick a model from your models/diffusion_models folder, and run it. It reads the file, quantizes the weights, and saves a new .safetensors beside the source, defaulting to <source>_nvfp4.safetensors.
Why NVFP4 at all? It's 4-bit, but unlike GGUF's 4-bit it's hardware-accelerated on Blackwell (RTX 50-series), so it's fast, not just small. The KB's notes are the honest summary: on a 5090 running Z-Image Base it measured ~26% faster than BF16 at the cost of visible loss in fine detail like eyes, and BFL claims up to 2.7x faster with 55% less VRAM for the Klein models. FP8 stays the near-free default; if you're on a 50-series and the model barely fits, NVFP4 is the step below it.
How it works
Under the hood the node shells out to the pack's own quantizer.py CLI, which even walks up to your ComfyUI root to import comfy.quant_ops - the actual FP8/NVFP4 kernels live in your ComfyUI install, not in this pack. It opens the safetensors, sniffs the tensor-key names to detect the architecture (SDXL, Wan 2.2, Qwen Image/Edit, Z-Image, FLUX/FLUX.2, or a generic transformer fallback), then classifies every weight as attention, FFN, other linear, sensitive, or nonquant:
- Sensitive layers (patch embed, time/text embedders, final projection, AdaLN/modulation) stay at bf16 by default - these are where quantization visibly breaks output.
- Nonquant covers everything these formats can't touch: convolutions, norms, biases. SDXL's conv weights in particular can't go NVFP4 because this implementation only handles 2D Linear weights.
- Small tensors under
min_elements(default 65,536) get bumped up to the sensitive format too - no point NVFP4-ing a tiny matrix.
Each chosen weight goes through ComfyUI's TensorCoreFP8E4M3Layout or TensorCoreNVFP4Layout on GPU, and the result saves with a _quantization_metadata block recording per-layer formats, plus the detected architecture and preset.
The inputs that matter
Most of the node is preset machinery you'll touch rarely. The ones a beginner actually sets:
- preset -
balanced(attention FP8, FFN NVFP4, other linear FP8) is a sane default.qualitykeeps more layers at bf16 for a quality-first pass.aggressiveputs attention and FFN both on NVFP4.fp8_allis the safe pick on non-Blackwell cards. - estimate_only - run it once with this on before you commit. It prints the detected architecture plus an input/output GiB estimate and reduction % into the log, and saves nothing. It's the "am I about to wreck this file" button.
- min_elements - leave it unless you're chasing every last MB.
- output_filename - leave empty for
<source>_nvfp4.safetensors. Filename only: the output has to live in the same folder as the source, and the node raises if you type a path.
The two outputs are both strings: output_path (where the file landed) and log (the full conversion report). Being an output node, you don't chain it into a sampler - copy the path and load it with your normal Load Diffusion Model node afterward.
Install
ComfyUI Manager (search "ComfyUI-NVFP4-Quantizer"), or:
cd ComfyUI/custom_nodes
git clone https://github.com/thepororo/ComfyUI-NVFP4-Quantizer.git
then restart ComfyUI. Nice part: the pack ships no requirements.txt and nothing to pip install - it leans on the torch and safetensors already in your ComfyUI plus the comfy.quant_ops kernels. The real prerequisites are CUDA and a ComfyUI/comfy-kitchen build that contains TensorCoreNVFP4Layout (current desktop builds do).
Where people get burned
- NVFP4 is Blackwell-only. On older cards the kernels either won't run or buy you nothing. Use
fp8_allthere and skip the nvfp4 option. - The node looks frozen. It runs the conversion in a subprocess and only hands the log back at the end, so a 12GB model means minutes of "nothing happening". It's working.
- Start from an original BF16/FP16 model. Feeding it an already-quantized file just compounds the loss, and there's no way back. Keep the source.
- Trust
estimate_onlyfirst. Auto-detection is solid on the named architectures but derivatives can misclassify; forcearchitectureif the log shows the wrong one.
The README is upfront that quantization is lossy and to test before production use. It is - so keep the original, and remember the KB's rule of thumb: only quantize what genuinely doesn't fit.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| model_name | COMBO | 0 options: | |
| output_filename | STRING | — | |
| architecture | COMBO | auto | 9 options: auto, sdxl, wan22, qwen_image, qwen_image_edit, z_image, +3 |
| preset | COMBO | balanced | 5 options: balanced, quality, aggressive, fp8_all, custom |
| attention | COMBO | fp8 | 6 options: keep, bf16, fp16, fp32, fp8, nvfp4 |
| ffn | COMBO | nvfp4 | 6 options: keep, bf16, fp16, fp32, fp8, nvfp4 |
| other_linear | COMBO | fp8 | 6 options: keep, bf16, fp16, fp32, fp8, nvfp4 |
| sensitive | COMBO | bf16 | 4 options: keep, bf16, fp16, fp32 |
| nonquant | COMBO | bf16 | 4 options: keep, bf16, fp16, fp32 |
| min_elements | INT | 655360–100000000 | — |
| estimate_only | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| output_path | STRING | — |
| log | STRING | — |