Krea 2 Turbo — Activation-Aware SVDQuant W4A4 for ComfyUI
Activation-aware INT4 quantization + SVDQuant low-rank correction for Krea 2 Turbo — ~2.4x faster than BF16, about a third the file size of the usual FP8 setup, no calibration dataset needed. Built for GPUs without FP8 tensor cores (Turing/Ampere, RTX 20/30-series), where the standard FP8 advice actually runs slower than plain BF16.
Speed (RTX 3090, 1024x1024, 8 steps, warm):
BF16 (reference): 18.80 s — 1.00x
W4A4, no low-rank branch: 6.49 s — 2.90x
SVDQuant rank 64: 7.16 s — 2.63x
SVDQuant rank 256 / rank 256 actaware: 7.77 s — 2.42x
The low-rank branch (the accuracy correction) costs ~9-10% of step time and barely varies with rank — going from rank 16 to rank 256 is only ~4% slower.
Fidelity, measured, not guessed: LPIPS against a BF16 reference, 16 prompts x 2 seeds, paired stats. The activation-aware objective (branch fit against real per-channel activation energy instead of assuming it's uniform) is the biggest single accuracy win in the whole project and costs nothing at inference — same shapes, same kernels, only different numbers inside the branch.
Links: 🔧 Custom nodes (GitHub): https://github.com/alperktt/Krea-2-SVDQuant-ComfyUI 📦 Checkpoints + full benchmarks + example images (Hugging Face): https://huggingface.co/AlperKTS/Krea-2-SVDQuant-ComfyUI
Setup:
Clone the custom nodes: git clone https://github.com/alperktt/Krea-2-SVDQuant-ComfyUI custom_nodes/krea2-svdquant Restart ComfyUI.
Download a checkpoint from Hugging Face into ComfyUI/models/diffusion_models/. Start with rank256-actaware — closest to BF16 of anything in the sweep, same speed as plain rank 256. rank64 if you want the smaller file and never load a LoRA. W4A4-noLowRank for max speed/min size with no branch at all.
Grab the text encoder (qwen3vl_4b_fp8_scaled.safetensors) and VAE (qwen_image_vae.safetensors) — standard for any Krea 2 Turbo workflow.
Load this workflow, select your checkpoint in the loader node, generate.
Loader node by checkpoint:
W4A4-noLowRank → stock UNETLoader
SVDQuant-W4A4-rank* (16/64/128/256/actaware) → Krea2 SVDQuant W4A4 Loader (this repo)
Using LoRAs? Use Krea2 SVDQuant LoRA Loader. On a quantized checkpoint the stock loader would have to dequantize the weight, add the LoRA, and requantize it — losing the 4-bit format and requantizing the LoRA delta along with it. This repo's node applies the LoRA as a parallel branch instead, so the quantized weight is never touched. If you load LoRAs, use rank 256 — rank 64 loses most of its accuracy advantage under one.
Tested on: RTX 3090 (Ampere) — works on any GPU with INT8/W4A4 tensor cores (Turing and up). Experimental, from-scratch project on ComfyUI's native comfy_kitchen backend. Benchmark reports from other GPUs welcome — open a discussion on the repo.
Description
FAQ
Comments (26)
How does smaller VRAM benchmark? Like 8gb cards - is this set up in such a way to speed up instances where memory swapping kicks in?
Straight answer: it should help a lot there, but I have not benchmarked an 8 GB card - all my numbers are from a 3090 and I don't want to quote a figure I didn't measure. If you run it on one I'd genuinely like the numbers.
The reason it should help is exactly the mechanism you're describing. Weights drop from 24.5 GB to 7.5-9.1 GB, so on a small card you go from swapping constantly to possibly resident, and not swapping is worth far more than the 2.4-2.9x kernel speedup the benchmarks measure.
Worth knowing if you tried an older build: there was a real bug here, now fixed. The low-rank correction factors were attached as non-persistent buffers, which ComfyUI's module_size() - the basis of every VRAM decision including the lowvram split - couldn't see, while .to(device) moved them anyway. About 645 MB unaccounted at rank 64, which is exactly the difference between fitting and not on an 8 GB card. They're published into state_dict() now and staged per call, so they get budgeted and offloaded like any other weight.
For 8 GB I'd start with W4A4-noLowRank (7.5 GB, no branch, fastest) or rank 64 (7.9 GB). The rank 256 files are 9.1 GB and only worth it if you load LoRAs.
One gap remains and it's upstream rather than mine: QuantizedTensor.nbytes reports only the packed weight, so the W4A4 weight_scale (~3 MB/layer) is still invisible to ComfyUI's memory accounting for any w4a4 checkpoint, branch or no branch.
@MaliaTate Wow, thanks for the detailed description. I will try some things today :)
@xFennec777 You're welcome.
I'm getting some kind of video memory error message, but I think the current support and stability are poor.
Fair, and I'd rather fix it than argue about it, but I need the actual error text to do anything. Can you paste it?
Two things to check first, both of which produce exactly "some kind of video memory error":
1. Make sure you're on the current version. There was a genuine VRAM accounting bug where the low-rank factors were invisible to ComfyUI's memory planner, ~645 MB unaccounted at rank 64. Fixed, but if you pulled before that fix you'd hit it.
2. Run the "Krea2 SVDQuant Env Check" node, it needs no model loaded. If the int4 kernel isn't available ComfyUI silently falls back to a pure-Python path that's slower AND heavier than BF16 - that needs a cu130 (CUDA 13) or newer PyTorch build. That one thing is behind most "this is broken/slow" reports.
If neither is it, open an issue with your GPU, which checkpoint you loaded, and the output of the "Krea2 SVDQuant Diagnostics" node - it reports which kernel actually runs plus memory accounting, which is what I need to see.
This is an experimental project built from scratch against ComfyUI's native comfy_kitchen backend and it's been tested on one GPU, a 3090. So you may well be right that it's unstable on yours - which is exactly why I want the report rather than a guess.
So this strictly requires CUDA 13?
While workflows with KJ stil require Python 2.9 because KJ nodes incompatible with new versions of some dependencies.
CUDA 13 requires python above 3.0.
In simple this incompatible with KJ nodes.
Was very slow but upgrade CUDA from 12.8 to 13 fixed it.
Requires a cu130 (CUDA 13) or newer PyTorch build. ComfyUI disables comfy_kitchen's CUDA backend on older torch builds, which silently drops every quantized checkpoint onto a pure-Python fallback that is slower than bf16. If these checkpoints are slower than FP8 for you, this is almost certainly why — see TROUBLESHOOTING.md
This model censored and filter bypass lora have no effect.
Requires heavy NSFW models wich spikes VRAM usage above 12 Gb.
This nulifies effect of speed.
Which loader node did you use? On a quantized checkpoint the stock LoraLoaderModelOnly is the wrong node - use "Krea2 SVDQuant LoRA Loader" from the repo. It prints what it matched to the console, something like "224 quantized layers, 32 normal layers". If yours says 0 quantized layers, that's the bug and I'd like the LoRA name plus that console line so I can reproduce it. If it says 224 and still does nothing, that's a real bug and I'll fix it - drop it in the repo issues with the LoRA file.
On the model being censored: that's Krea 2 itself, not anything I do. Quantization is a numerical format change, it converts the weights that exist - it can't add or remove behaviour. Same complaint applies to the original BF16 release and no quantization method changes it.
On VRAM: this doesn't require any extra model. The checkpoints are 7.5-9.1 GB against BF16's 24.5 GB, that's the entire point. If you're loading a different finetune on top, that finetune's size is what you're measuring, not this. And if that's what you're doing - quantize_krea2.py converts any BF16 Krea 2 checkpoint in about 6 minutes, so you can run your own model through it instead of using mine.
@MaliaTate I used your workflow with your loader
bf16, fp8 models uncensored by custom node. INT8 uncensored by filter bypass lora. Your model censored and listed methods have no effect.
@MaliaTate 12 Gb INT8 model works with 5 loaded loras. Your model getting into overflow and 11s/it slowdown with just 3 loaded loras.
@velanteg Happy to dig into this, but I'd like actual numbers rather than adjectives — at the moment we're comparing a 12 GB INT8 checkpoint against a 7.5–9 GB INT4 one and calling the second one the heavy option. 🙂
Two things would settle it. First, your GPU/VRAM, resolution, and step count. Second, and this is the one I'd bet on:
Are those LoRAs actually LoRAs, or are they LoKr / LoHa / OFT? Check the key names in the file — lokr_w1, hada_w1_a, that sort of thing. It matters enormously here. A plain low-rank LoRA folds into the SVDQuant low-rank branch: one pair of GEMMs for the entire stack, cost essentially zero, no matter how many you load. A Kronecker product isn't low-rank, so it can't fold — the loader's default adapters mode is bypass (exact, slower), which computes it on every forward. Measured on a 3090 with a LoKr on all 224 blocks, that's +1.8 s per model call. Per adapter. Three of them and you get exactly the numbers you're reporting.
The fix is one dropdown. On the Krea2 SVDQuant LoRA Loader, set adapters to bake into the weight (fast, requantizes the delta). It rewrites the weight once at load and costs nothing per step. On a 3090 at 1440×1920 with a rank-256 LoRA plus a LoKr plus a .diff patch: 5.21 s/step on bypass, 3.55 on bake (stock loader is 3.22 for reference — and it requantizes your plain LoRA too, which bake doesn't). The trade is that the LoKr delta goes through 4-bit quantization along with the weight, which is why it isn't the default: I'd rather you opt into a fidelity cost than eat one silently.
If you want it permanently and at better quality, tools/bake_adapter.py merges the delta into the BF16 weight before quantization, so the low-rank branch is fitted against the merged weight instead of the adapter being requantized on top of a finished checkpoint. That's the clean version.
Worth noting that none of this applies if your LoRAs are plain — those are free in either mode. So if switching to bake changes your speed at all, that confirms LoKr, and the checkpoint was never the problem.
For a reference point: a laptop RTX 3050, 4 GB VRAM / 32 GB RAM, 1024×1024, rank-256 LoRA loaded — 8 steps in 32s, 42s with the LoRA active. If 4 GB manages that, 11 s/it on a 12 GB card is a configuration issue, not a checkpoint weight class.
And on censorship, once more: quantization is a change of numerical format. It converts weights that already exist; it cannot add or remove a behaviour in either direction. Whatever BF16 gives you, INT4 gives you.
@MaliaTate this now better
@velanteg Nice to hear!
@MaliaTate still not fixed main trouble - your model not work with dynamic memory which cause memory overflow and slowdown on hitting 12 Gb VRAM.
@velanteg Skill issue.
This model works very well actually, apart from yellowish tints on the resulting image.
Running on my old 3090 greatly, it reminds me DMD2 of SDXL era.
@MOVZX you have reading issue. i said model cant use dynamic VRAM, you writing about 3090 where you never hit VRAM limit.
100%|██████████| 8/8 [00:32<00:00, 4.04s/it]
+ comfykitchenattention
LAPTOP 3050 RTX 4GB VRAM 32 GB RAM
1024x1024 Rank256
https://civitai.red/images/139491197
Tested with 16GB RTX5060Ti, nothing but static image, nothing actually generates.
Are you using the custom nodes?
Use the workflow.
Zooming with 16 rank. Great quality. Thanks. Normal lora loader is faster than SVDQ loader...Each give different results, so good to know for variety.
You're welcome. You can also quantize your own model.
See other ranks:
https://huggingface.co/AlperKTS/Krea-2-SVDQuant-ComfyUI/tree/main/checkpoints
@MaliaTate Thanks. I'll try that actaware.
