TurboQuant PyTorch
Skill by ara.so — Daily 2026 Skills collection.
From-scratch PyTorch implementation of Google's TurboQuant (ICLR 2026) for compressing LLM KV caches. Achieves 5x compression at 3-bit with 99.5% attention fidelity via two-stage vector quantization.
What It Does
TurboQuant compresses LLM key-value caches to 2–4 bits per coordinate:
- Stage 1: Random orthogonal rotation + Lloyd-Max scalar quantization (MSE-optimal)
- Stage 2: QJL residual correction — 1-bit sign projection that makes inner product estimates unbiased
Result: attention scores remain accurate even when individual vectors look quite different from originals. The algorithm preserves inner products, not vector fidelity.
Compression ratios at 8K context on Qwen2.5-3B (289 MB FP16 baseline):
- 4-bit → 76 MB (3.8x)
- 3-bit → 58 MB (5.0x) ← practical sweet spot
- 2-bit → 40 MB (7.3x)
Installation
requirements.txt includes:
torch>=2.0scipy(Lloyd-Max codebook computation)transformers,accelerate,bitsandbytes(only for real model validation)
Project Structure
Key Commands
Core API
Lloyd-Max Codebook
Stage 1: MSE Quantization (TurboQuantMSE)
Stage 2: Unbiased Inner Product Estimation (TurboQuantProd)
KV Cache Wrapper (TurboQuantKVCache)
Production Compressors (for real model tensors)
Common Patterns
Pattern 1: Compress a Full Model's KV Cache
Pattern 2: Validate Compression Quality
Pattern 3: Needle-in-Haystack Retrieval Test
Pattern 4: Compute Memory Savings
Algorithm Details
Why Random Rotation?
Rotating by a random orthogonal matrix R maps unit vectors to a space where each coordinate follows N(0, 1/d). This makes coordinates nearly independent with known distribution — enabling optimal per-coordinate scalar quantization (Lloyd-Max).
Why QJL for Keys but Not Values?
- Keys: Used in dot products with queries. Bias in inner product estimates directly corrupts attention weights. QJL correction is essential.
- Values: Used in weighted sums after softmax. Small per-vector MSE errors average out. Stage 1 MSE quantization is sufficient.
Choosing proj_dim (QJL projection dimension)
Higher proj_dim → lower variance in inner product estimates, but more memory:
Bit-width Selection Guide
Troubleshooting
scipy import error when building codebooks:
CUDA out of memory during validate.py:
- Requires ≥6GB VRAM for Qwen2.5-3B in 4-bit
- Reduce
seq_lenin the validation script or use a smaller model
Inner product estimates have high variance:
- Increase
proj_dim(tryhead_diminstead ofhead_dim // 2) - Check that input vectors are normalized before compressing
Codebook build is slow on first run:
- Lloyd-Max uses numerical integration (scipy) — this is expected
- Codebooks are precomputed once per
(dim, bits)combination; cache them:
Attention fidelity lower than expected:
- Ensure vectors are L2-normalized before compressing (
F.normalize(x, dim=-1)) - The compressors in
compressors.pyhandle normalization internally;TurboQuantProdexpects unit vectors
References
- TurboQuant paper — ICLR 2026
- QJL paper — 1-bit residual correction technique
- PolarQuant — Related polar coordinate approach


