Krea2 SVDQuant Quantize
Quantize your own Krea 2 without leaving ComfyUI — no terminal required
- summary
The short version
The pack ships pre-quantized checkpoints, but if you want to quantize your own Krea 2 - a finetune, a merge, a BF16 file you didn't want to download someone else's build of - this is the node that does it from inside ComfyUI. It runs the exact same function as the quantize_krea2.py CLI, so the graph and the terminal can't drift apart. Drag workflows/krea2_quantize.json into the canvas, point source_model at your BF16 checkpoint, press Queue.
The output is a quantized DiT in models/diffusion_models/ (about 8 GB), loadable with the Krea2 SVDQuant W4A4 Loader if you pick svdq, or the stock UNETLoader for w4a4 / int8 / fp8.
The inputs that matter
Mostly you set four things and leave the rest:
- source_model - a BF16 Krea 2 checkpoint (~24 GB). An already-quantized file can't be re-quantized, with one exception: FP8 is unpacked back to BF16 first and works fine.
- format -
svdq(default): 4-bit weights and activations plus a low-rank bf16 correction branch.w4a4: same without the branch - smaller and ~9% faster per step.int8: the most faithful, still ~2x FP8 on Ampere.fp8: storage only, no speed gain on non-FP8 hardware. - rank - the size of the low-rank branch (svdq only). The tooltip's honest framing: with no LoRA, ranks 64/128/256 measure the same, so 64 is enough. With a LoRA loaded, 256 wins clearly. 64 is the sensible default.
- refine_iters - 0 is a single-shot SVD split (~54s); 100 refines the branch against the quantization error and early-stops (~5.7 min). Keep it on if rank > 16 - refinement is what makes rank behave. Without it, raising rank just costs file size.
Worth knowing before you queue: this node blocks the queue for the whole run, unloads whatever model is resident to take the GPU, and writes ~8 GB - refusing to overwrite an existing file unless you tick overwrite. That's not a bug, it's the author being careful with your last run.
The optional act_stats input is the cheapest quality on offer: point it at an activation-statistics file from the Capture nodes and the branch gets fitted against measured per-channel activation energy instead of assuming it's uniform. It's free at inference and the best-measured gain in the whole repo (LPIPS 0.3378 → 0.2825). The seed input (default 0) makes builds reproducible on the same GPU; -1 restores the old unseeded behavior. Same seed on a different GPU still differs slightly - CPU and CUDA don't draw the same numbers.
How to install
cd ComfyUI/custom_nodes && git clone https://github.com/alperktt/Krea-2-SVDQuant-ComfyUI krea-2-svdquant
No extra Python dependencies. If you'd rather run the same thing from a terminal:
cd ComfyUI/custom_nodes/krea-2-svdquant
python quantize_krea2.py /path/to/krea2_bf16.safetensors --format svdq --rank 256 --act-stats krea2_act_stats_turbo.safetensors
Gotchas
- Only the 224 transformer-block linears are quantized; norms, modulation, text-fusion and the final layer stay at full precision. Expect a log line like
quantized 224 layers- a run reporting 0 fails loudly, so you'll know. - If it's slower than FP8 afterwards, you're on a pre-cu130 torch build. The fast kernels only exist on CUDA-13+ PyTorch; below that everything drops to a pure-Python fallback that's slower than bf16. Check
python -c "import torch; print(torch.version.cuda)"first. - The download-table calibration files aren't for your build.
krea2_act_stats_turbo.safetensorsdescribes the stock Turbo weights. Activation statistics describe the weights they came from - a finetune or merge needs its own capture pass (that's what the Capture nodes are for).
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| source_model | COMBO | The BF16 Krea 2 checkpoint to quantize (~24 GB). An already-quantized file cannot be used as a source, except FP8, which is unpacked back to BF16 first. | |
| format | COMBO | svdq | svdq: 4-bit weights and activations plus a low-rank bf16 correction branch. w4a4: the same without the branch - smaller and ~9%% faster per step. int8: the most faithful option and still ~2x fp8 on Ampere. fp8: storage only. |
| rank | INT | 648–1024 | svdq only: size of the low-rank branch. Only pays off with refine_iters > 0. Without a LoRA, 64 / 128 / 256 measure the same, so 64 is enough. With a LoRA loaded, 256 wins clearly and 64 loses most of its advantage - so 256 if you use LoRAs. |
| rank_alloc | COMBO | uniform | svdq only: how the rank budget is spread across the eight projection types. Same file size either way. uniform gives every layer the same rank. gqa moves the budget to attn.wk / attn.wv, which absorb ~2x the quantization error at a third of the branch cost because Krea 2 has only 12 kv heads. Measured and it does not pay: LPIPS 0.3523 vs 0.3403 for uniform, 5 of 10 prompts better, no mean effect. It does halve the spread across prompts and improve the worst one. Leave on uniform unless you are re-testing that. |
| refine_iters | INT | 1000–200 | svdq only. 0 is a single-shot SVD split (~54s); 100 refines the branch against the quantization error and early-stops (~5.7min). Keep this on if rank > 16: refinement is what makes rank behave. Without it, raising rank costs file size and buys nothing measurable. |
| groupsize | INT | 25632–1024 | convrot rotation group size. Unused for fp8. |
| variant | COMBO | unknown | Which Krea 2 release this is. Affects only the output filename and the recorded metadata - quantization is identical; what differs is the sampler settings afterwards. |
| output_name | STRING | Filename inside models/diffusion_models/. Leave empty to derive it from the variant and format. | |
| overwrite | BOOLEAN | false | Off means an existing file of the same name is an error rather than 8 GB written over your last run. |
| act_statsopt | STRING | svdq only: an activation-statistics file from the Capture nodes (a bare filename is looked up in ComfyUI/output/). Fits the low-rank branch against measured per-channel activation energy instead of assuming it is uniform. Free at inference and the best-measured setting here - LPIPS to BF16 0.3378 to 0.2825 with no LoRA. Empty means the plain objective. | |
| seedopt | INT | 0-1–4294967295 | svdq only: seed for the randomized low-rank SVD. Quantizing twice with the same seed on the same GPU now gives identical files; -1 restores the old unseeded behaviour, where it did not. The same seed on a different device still differs (~1e-4 per weight) - CPU and CUDA do not draw the same numbers. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| summary | STRING | Where the checkpoint was written, and what went into it. |