TurboQuant Status Check, August 2026 — What Actually Shipped in vLLM, llama.cpp, and Ollama
vLLM shipped it in v0.20 and published a sobering benchmark; llama.cpp upstream rejected it in June; Ollama's implementation is dead. We also correct our own earlier "merged in llama.cpp" claim — with links.

TurboQuant Status Check, August 2026 — What Actually Shipped in vLLM, llama.cpp, and Ollama
Five months after Google Research's TurboQuant paper landed, the "4x KV cache compression for free" story has split into three very different realities depending on which inference engine you run. One engine shipped it and published a sobering benchmark. One engine rejected it. One engine's implementation is dead.
This post is a status check — and a correction. Our earlier posts on TurboQuant repeated a claim that was circulating in March: that llama.cpp had merged tq1_0–tq4_0 cache types. That was wrong. Below is what the repositories actually say as of late August 2026, with links.
This is Part 3 of our TurboQuant series.
- Part 1: TurboQuant Explained — the algorithm (PolarQuant + QJL)
- Part 2: TurboQuant in Practice — llama.cpp forks and the Python package
- Part 3 (this post): What actually shipped, engine by engine
- Part 4: TurboQuant in vLLM on one A100 — measured (coming)
The Short Version
| Engine | Status | How to use it | Verdict |
|---|---|---|---|
| vLLM | Shipped in v0.20.0 (merged Apr 15, 2026) | --kv-cache-dtype turboquant_4bit_nc | Works. vLLM's own study says FP8 is still the better default. |
| llama.cpp (upstream) | Rejected — PR #21089 closed Jun 2, 2026 | Not available | Maintainers: "Hadamard rotations have already been merged"; show demonstrable gains first. |
| llama.cpp (forks) | Working, unmerged | -ctk turbo3 -ctv turbo4 -fa on on a fork | Real, fast, and yours to maintain. |
| Ollama | Dead — PR #15505 closed May 30, 2026 | Not available | Ollama moved GGUF inference to upstream llama-server; the PR can't land. |
| HuggingFace Transformers | No native support | pip install turboquant (independent, not Google) | Fine for experiments; not the official implementation. |
If you only remember one line: the only production engine with TurboQuant is vLLM, and vLLM's own recommendation is to keep using FP8 unless you specifically need the capacity.
1. vLLM: Shipped, Studied, and Honestly Reported
The one place TurboQuant is a first-class feature is vLLM. PR #38479 merged on April 15, 2026 and landed in v0.20.0. It adds a custom Triton-based TurboQuantAttentionBackend with four presets:
vllm serve Qwen/Qwen3-8B --kv-cache-dtype turboquant_k8v4 # FP8 keys, 4-bit values (~2.4x)
vllm serve Qwen/Qwen3-8B --kv-cache-dtype turboquant_4bit_nc # 4-bit K+V, norm correction (~3.4x)
vllm serve Qwen/Qwen3-8B --kv-cache-dtype turboquant_k3v4_nc # 3-bit K, 4-bit V
vllm serve Qwen/Qwen3-8B --kv-cache-dtype turboquant_3bit_nc # 3-bit K+V (~4x+)Two details worth knowing before you try it:
- v0.20.0 supported only full-attention and uniform sliding-window transformers; hybrid Mamba/linear-attention models raised
NotImplementedError. PR #39931 (merged May 5) added Qwen3.5 and Qwen3-Next by quantizing only thefull_attentionlayers and skipping the linear ones — with an open edge case (#41726, chunked-prefill continuation) still being worked. - Ampere GPUs (A100) needed a Triton float8 fallback; Hopper is the primary target.
What vLLM's own benchmark found
On May 11, the vLLM team published "A First Comprehensive Study of TurboQuant" — Llama-3.3-70B, Qwen3-30B-A3B (Instruct and Thinking), and MiniMax-M2.7, evaluated on MRCR long-context retrieval and reasoning benchmarks (AIME25, GPQA Diamond, MATH500, LiveCodeBench). The numbers are the most careful public evaluation to date, and they are not the numbers in the hype cycle.
Accuracy, relative to BF16:
| Variant | Long-context (Llama-70B, MRCR AUC) | Reasoning (Qwen3-30B-Thinking) |
|---|---|---|
| FP8 | ~52% (matches BF16) | >98% recovery |
| TQ k8v4 | ~52% | >98% |
| TQ 4bit-nc | ~52% | ~96% |
| TQ k3v4-nc | 48.6% | ~20-point drop |
| TQ 3bit-nc | 50.3% | ~20-point drop |
On Qwen3-30B at 256K context, the 3-bit variants fell to 31–34% AUC — roughly a 30% relative degradation.
Speed, relative to BF16 (Qwen3-30B):
| Variant | Latency overhead | Throughput |
|---|---|---|
| FP8 | negligible | 100% |
| TQ k8v4 | ~10% | 80% |
| TQ 4bit-nc | ~20% | — |
| TQ 3bit-nc | ~60% | 73% |
Capacity: FP8 2x, k8v4 2.4x, 4bit-nc 3.4x, 3bit-nc 4x+. Under burst load on Llama-70B, that capacity mattered: BF16 hit ~17s P99 TTFT from memory saturation while TurboQuant variants stayed under 3.5s. FP8 was best at 1.3s.
Their conclusion, quoted: *"FP8 remains the best default."* The practical variant is 4bit-nc — "up to 3.4x KV-cache capacity with modest accuracy degradation of 1–4 points" — and the 3-bit variants are explicitly not recommended for production.
What this means
The paper's headline was about distortion on isolated vectors. vLLM measured what happens to end-task accuracy and throughput in a real serving stack. The two are not the same thing: 3-bit keys cost you ~20 points on reasoning benchmarks, and the Triton kernels cost 10–60% latency against FP8's fused paths. TurboQuant in vLLM is a capacity tool for memory-bound long-context serving, not a free lunch.
2. llama.cpp: Rejected Upstream, Alive in Forks
This is where our earlier posts were wrong, so let's be precise.
Upstream ggml-org/llama.cpp has no TurboQuant cache type. The accepted -ctk/-ctv values in common/arg.cpp are f32, f16, bf16, q8_0, q4_0, q4_1, iq4_nl, q5_0, q5_1. No tq3_0, no turbo3.
What happened:
- PR #21010 (Vulkan
TQ3_0) was closed for violating the project's AI-generated-code policy. - PR #21089 added CPU-only
tbq3_0/tbq4_0types. Reported on Qwen3.5-4B:tbq4_03.94x compression with KLD similar toq4_0;tbq3_05.22x with expected quality loss; CPU decode fell from 15.7 to ~8 tok/s. Closed June 2, 2026. The maintainers' reasoning: Hadamard rotations are already merged, and the PR did not demonstrate gains over the existing equal-bit-width types across multiple models, as the contribution guidelines require.
That rejection is defensible. The upstream concern isn't "TurboQuant doesn't work" — it's "show us it beats q4_0 + Hadamard on the same bits, on more than one model." Nobody has yet done that to the maintainers' standard.
Meanwhile the community discussion (#20969) produced a genuinely impressive set of independent implementations:
| Fork | Backend | Types | Notes |
|---|---|---|---|
| TheTom/llama-cpp-turboquant | Metal | turbo3 (3.25b), turbo4 (4.25b) | M5 Max: turbo3 at 98.9% of q8_0 speed, +1.1% PPL |
| spiritbuun/llama-cpp-turboquant-cuda | CUDA + FA | turbo3, turbo4 | RTX 3090: 98.8% of q8_0 prefill |
| Madreag/turbo3-cuda | CUDA + FA | turbo3 | RTX 5090: 700K context, NIAH 6/6 |
| Aaryan-Kapoor (turboquant-tq3_0) | CPU | TQ3_0 (3.5b) | zero speed penalty vs f16 |
| tetherto/qvac-fabric-llm.cpp | Vulkan | mixed K/V | coopmat acceleration |
| atomicmilkshake/llama-cpp-turboquant | CUDA | turbo2/3/4 | + TriAttention KV pruning |
And they converged on the same engineering conclusions — this is the most useful technical output of the whole episode:
- Algorithm 1 (PolarQuant MSE) alone is enough. The QJL residual stage adds overhead without measurable benefit. Every fork dropped it.
- Keys need more bits than values. K/V norm disparities of up to 182x were measured across models; asymmetric
k4/v3-style allocation is the norm now (vLLM'sk8v4preset is the same lesson). - Block size 32 beats the paper's 128 for flash-attention parallelism.
- Norm correction (store
‖x‖ / ‖Q(x)‖and rescale at decode) improves perplexity at zero cost. It's the_ncsuffix in vLLM.
If you run llama.cpp on your own hardware, a fork is a perfectly good way to get 4–5x KV compression today. Just know that you're on a branch that tracks upstream by hand.
3. Ollama: Dead on Arrival
Ollama PR #15505 was the most complete implementation of the lot — nine OLLAMA_KV_CACHE_TYPE presets (tq4/tq3/tq2, K-only and V-only variants), FWHT rotation, Lloyd–Max codebook, outlier splitting, and a fused inline-decode flash-attention path. On Blackwell, tq3k reportedly held ~80% of f16 memory at 60–75% of f16 decode throughput.
It was closed May 30, 2026, by the author, because Ollama's #16031 moved GGUF inference to an external upstream llama-server. Ollama no longer has its own attention path to patch. TurboQuant in Ollama now depends on TurboQuant in upstream llama.cpp — which, see above, was rejected.
So the honest answer to "does Ollama support TurboQuant?" is: no, and not until llama.cpp upstream does.
4. HuggingFace: An Independent Package, Not Google's
pip install turboquant works and gives you TurboQuantCache, a drop-in past_key_values for Transformers, plus a TurboQuantMSE quantizer and an OpenAI-compatible server. It's published by back2matching, Apache-2.0, versions 0.1.0 and 0.2.0 released March 25–27, 2026.
Its README says it plainly: *"This is an independent implementation, not affiliated with Google Research."* Google has not released an official implementation. Treat the package as what it is — a well-made community reimplementation, good for experiments, not a reference.
5. What the Paper Claimed vs. What Shipped
| Claim (paper / March hype) | Reality (August 2026) |
|---|---|
| ~4–6x KV compression | Yes: 3.4x (4bit-nc) to 4.9x (turbo3) in shipped code |
| "Near-lossless" | At 4 bits with norm correction and 8-bit keys: yes. At 3-bit keys: 20-point reasoning drops in vLLM's study |
| No speed penalty | On Metal/CUDA llama.cpp forks with FA: ~99% of q8_0. In vLLM's Triton path: 10–60% latency overhead vs FP8 |
| QJL residual correction matters | Every implementation dropped it |
| "Merged in llama.cpp" | Never happened. Rejected June 2 |
| "Coming to Ollama" | Dead May 30 |
| "Google implementation Q2 2026" | Not released |
6. So What Should You Do?
- Serving with vLLM, memory-bound on long context: try
turboquant_4bit_nc, measure *your* task, keepfp8as the control. Skip the 3-bit variants. - Serving with vLLM, not memory-bound:
fp8. Done. - llama.cpp on a Mac or a single GPU: a fork (
turbo3/turbo4with-fa on) is real and fast. Useturbo4for keys if quality matters. - Ollama: nothing to do. Wait for upstream.
- Research / notebooks:
pip install turboquant, or implement PolarQuant yourself — it's ~60 lines (Part 5 of this series does exactly that on real KV tensors).
In Part 4 we stop reading other people's tables and run vLLM's four presets against FP8 and BF16 on a single A100 with an 8B model — the size vLLM's study didn't cover.
References
- Zandieh et al., TurboQuant: Online Vector Quantization with Near-optimal Distortion Rate, ICLR 2026
- vLLM, A First Comprehensive Study of TurboQuant: Accuracy and Performance (May 11, 2026)
- vLLM PR #38479 (merged Apr 15, 2026) · PR #39931 hybrid models (merged May 5) · Issue #41726
- llama.cpp PR #21089 (closed Jun 2, 2026) · PR #21010 · Discussion #20969
- Ollama PR #15505 (closed May 30, 2026)
- turboquant on PyPI · back2matching/turboquant
Subscribe to Newsletter
Related Posts

Hybrid Mamba-Transformer, Measured: Qwen3.5-9B's Cache Is 4.4x Smaller Than Qwen3-8B's — and Why Our Speed Numbers Don't Count
Cache memory of Qwen3.5-9B (24 linear + 8 attention layers) vs Qwen3-8B measured from 2K to 64K context on one A100: 4.4x smaller at 64K, converging to 4.6x, and it decomposes exactly. Plus why HF eager speed numbers can't judge the architecture.

TurboQuant From Scratch on Real KV Tensors — What 3 Bits Actually Cost, and Why the Forks Beat the Paper's Layout
PolarQuant in 60 lines of PyTorch on real KV from Llama-3.2-1B and Qwen3-8B: 3-bit costs +10% perplexity, k8v4 +0.2%, QJL only pays below 4 bits, and the block-32 layout explains half the forks' edge.

TurboQuant llama.cpp CUDA Fork, Measured on an A100 — turbo4 Matches q4_0, turbo3 Breaks at Long Context
Qwen3-8B Q4_K_M on one A100, six KV types: perplexity, prefill, decode-at-depth, and VRAM measured. turbo4 matches q4_0 quality and beats q8_0 decode 2.5x at depth; turbo3 triples perplexity at 32K context.