Nodes/Skoogeer-Noise/Model (TurboQuant Attention)
ComfyUI Node

Model (TurboQuant Attention)

An LLM-Serving Trick, Transplanted to Diffusion

By ttulttul·Created 9 months ago·Updated 3 months ago· 14
Model (TurboQuant Attention)
  • model
  • MODEL
bits8
qjl_dim64
use_qjl
quantize_values
min_token_product65536
max_token_product262144
attention_scope
layer_start-1
layer_end-1
rotation_seed0
max_head_dim256
force_fp32
memory_margin_mb1024
log_every50
log_fallbacks

Here's the honest summary before you get excited: this node clones your model and installs an approximate attention implementation inspired by the TurboQuant paper - random orthogonal rotation of q/k/v plus coordinate-wise scalar quantization. It is not KV-cache compression, it is not a memory-savings hack that fell out of an LLM inference engine, and the defaults are deliberately conservative because aggressive settings can damage image quality and run slower than baseline. If that still sounds interesting, read on.

It's an experiment, and the pack is upfront about that. The idea is the same one TurboQuant used to make attention cheaper in LLM serving: rotate the key/query space with a random orthogonal matrix (which makes the values spread more evenly), then quantize to fewer bits per coordinate, trading a little accuracy for speed or memory. In ComfyUI this is done as an attention override you slot between your model loader and a normal KSampler - no core patching, no special sampler.

How it works

At runtime the node rotates q, k, and v, quantizes k (and optionally v), then passes the transformed tensors back into ComfyUI's original optimized attention kernel. That last bit matters: it deliberately avoids materializing dense logits in Python, which is what made earlier prototypes OOM on diffusion-sized layers. The QJL residual-correction stage exists in the config but is forced off in the runtime path for the same reason. Guards (min_token_product/max_token_product, memory_margin_mb, max_head_dim) decide which attention calls actually get patched - most won't, which is by design.

The inputs that matter

You're not going to touch most of these, and that's fine. The ones that matter:

  • bits - bits per coordinate (1–8, default 8). Lower is more aggressive and more dangerous.
  • quantize_values - keep disable. Quantizing values as well as keys is the fastest route to wrecked output.
  • attention_scope - self is the usual target for diffusion latent attention.
  • log_every - set to 1 (and log_fallbacks to enable) to actually see whether your attention calls are being patched at all.

Output is a MODEL you feed into a KSampler.

Installing it

Part of the Skoogeer-Noise pack. Manager → search "Skoogeer-Noise", or:

cd ComfyUI/custom_nodes
git clone https://github.com/ttulttul/Skoogeer-Noise

Restart ComfyUI. Only torch, numpy>=1.26, einops, pyyaml>=6.0.3 - no model downloads.

Common gotchas

The biggest one is expectations. People hear "TurboQuant" and expect LLM-serving-style speedups and VRAM savings; this is an attention approximation for diffusion, with quality tradeoffs baked in. If output looks subtly off and you can't tell why, the patch is probably active and degrading things. If nothing changes at all, that's also likely - the token-product thresholds skip most layers. Use the logging knobs to find out which. And treat bits <= 4 as "here there be dragons": the changelog itself warns these settings can be slower than baseline while also hurting quality. This is a tinkerer's node, not a daily-driver.

Categorymodel/patch

Inputs (16)

NameTypeDefaultDescription
modelMODELModel to clone and patch with a TurboQuant-inspired attention approximation.
bitsINT81–8Bits per rotated coordinate for the scalar quantizer. Higher is safer for image quality; lower is more aggressive.
qjl_dimINT641–4096Projection width for the QJL-style residual correction on logits.
use_qjlCOMBOEnable the 1-bit residual correction term for key logits. Currently forced off in the runtime path.
quantize_valuesCOMBOQuantize values as well as keys. Disable is safer for image quality and is the default.
min_token_productINT655360–1073741824Only patch attention calls where query_tokens * key_tokens meets this threshold.
max_token_productINT2621440–1073741824Skip attention calls above this query_tokens * key_tokens threshold. Conservative default avoids the largest, most memory-sensitive layers.
attention_scopeCOMBOWhich attention calls to patch.
layer_startINT-1-1–4096First transformer block index to patch. -1 disables the lower bound.
layer_endINT-1-1–4096Last transformer block index to patch. -1 disables the upper bound.
rotation_seedINT00–18446744073709550000Seed used for the random orthogonal rotation and Gaussian residual projection.
max_head_dimINT2561–4096Skip heads larger than this to avoid excessive projection overhead.
force_fp32COMBOCast q/k/v to fp32 inside the override for extra numerical stability.
memory_margin_mbINT10240–65536Keep this much free CUDA memory in reserve before allowing the TurboQuant workspace allocation.
log_everyINT500–1000000Emit a TurboQuant runtime summary every N attention calls. Set 1 for per-call summaries, 0 to disable periodic summaries.
log_fallbacksCOMBOLog individual skip/fallback reasons when TurboQuant does not activate.

Outputs (1)

NameTypeDescription
MODELMODEL