Skip to content

Follow-up: TurboQuant upstream landscape + independent implementation feasibility #101

Description

@dogkeeper886

Context

Follow-up to #99 (survey merged in #100, see `docs/research/google-kv-survey.md`). Before committing to a prototype, we need to understand the state of upstream llama.cpp work and decide whether to port an existing PR or implement independently from the paper.

Upstream PR landscape (as of 2026-04-18)

Three TurboQuant PRs were opened against `ggml-org/llama.cpp`:

PR Scope State Notes
#21089 CPU-only, TBQ3_0 + TBQ4_0 Open, stalled Only PR that followed the contribution guidelines (CPU-first, disclosed AI usage, used template). Author: elusznik.
#21062 Full CUDA, TBQ2/3/4 Closed Closed for AI-generated content policy violation. Also had bad merge + multi-backend-in-one-PR policy violations. Targets SM 12.1 (GB10). Segfaults on CUDA 13.2.
#21010 Vulkan, TQ3_0 Closed Also closed for AI policy violation.

Maintainer sentiment on #21089

  • ggerganov (project lead): called the PR "pure slop" on 2026-04-03. Tone later softened but skepticism remained.
  • JohannesGaessler (core maintainer): "tbq4_0 isn't even really better than the existing naive q4_0 type... we should not invest maintainer time here."
  • CISC (core maintainer): pointed out the speed is half of q4_0 and that latest master should be retested.
  • pwilkin, ericcurtin: supportive, note the PR follows guidelines properly.
  • Overall: the PR is not moving. Author (elusznik) expressed frustration at the reception.

The landscape-changing finding

"Master now already applies rotations on the KV cache before quantization, improving the quality of all the regular quantization types. And since TurboQuant is barely any better than the regular quants without rotation, latest master might actually show better performance with the regular quants." — Mushoz, 2026-04-03

This substantially changes our calculus. After upstream's pre-rotation change:

Cache type PPL (Qwen3.5-4B, post-rotation master) Gen t/s Compression
f16 9.027 14.22 1.00×
q4_0 9.047 (+0.22%) 14.09 3.56×
tbq4_0 9.046 (+0.21%) 6.68 3.94×
tbq3_0 9.178 (+1.67%) 6.74 5.19×

tbq4_0 is now quality-equivalent to q4_0 with only ~10% more compression, at half the speed. tbq3_0 remains the only compelling option (5.2× compression, +1.67% PPL).

Community extensions not in any upstream PR

From TheTom (TurboQuant+) and animehacker:

  • Asymmetric K/V quantization is critical — symmetric turbo3 on Qwen2.5-7B Q4_K_M yields catastrophic PPL (3,556). Asymmetric q8_0-K / turbo3-V gives 6.71 (+2.0%).
  • V compression is near-free; K compression stacks badly with weight quantization on sensitive models.
  • Asymmetric WHT normalization: 1/√32 on K-side, unnormalized on Q-side. Using symmetric 1/32 produces plausible but broken output.
  • QJL residual correction hurts attention workloads in practice — implementations are dropping it.

None of the open/closed PRs include these findings, and the paper doesn't cover Q4_K_M-weighted models.

Can we implement without porting a PR?

Yes — and it's arguably the better path. The algorithm is published (arXiv:2504.19874), the implementation patterns from open PRs are in the public record for reference (GGML type registration, block layouts, KV cache integration points), and we have no incentive to chase upstream compatibility since ollama37 is a fork.

Three concrete paths, in order of cost:

Path A — Adopt upstream's pre-rotation only (cheapest, biggest ROI)

  • Cherry-pick llama.cpp master's "apply rotations on KV cache before quantization" change (the one Mushoz cited).
  • Use existing q4_0/q8_0 KV types, now with rotation.
  • Result: most of TurboQuant's quality benefit with zero new kernels, zero new types, zero K80-specific kernel work.
  • This may be sufficient for the K80 use case.

Path B — Implement tbq3_0 only, from the paper, for K80 vec path (medium)

  • Skip tbq4_0 entirely (now pointless per upstream numbers).
  • Implement TBQ3_0 directly from arXiv:2504.19874, following the integration patterns observed in #21089 (type registration in `ggml.c`, block layout in `ggml-common.h`, CPU from_float + vec_dot for correctness reference, CUDA fattn-vec template instance for K80).
  • Include asymmetric K/V support from day one (community finding, not paper).
  • Skip QJL residual correction.
  • No code copied from #21062 (closed/AI-violation) or #21089 (upstream attribution cleaner if we re-derive).

Path C — Port #21089 CPU code as attribution-disclosed baseline, add CUDA ourselves (highest risk)

  • Take #21089 as upstream reference under its license, disclose attribution in commit messages.
  • Add our own sm_37 CUDA kernels.
  • Risk: if #21089 never merges, we inherit a stale base.

Recommendation

Prototype Path A first as a baseline. If the upstream pre-rotation change (now in llama.cpp master) gives ollama37 most of the quality win with existing q4_0/q8_0 on K80, we ship that and revisit tbq3_0 later. If not, proceed to Path B (independent tbq3_0 implementation) — Path C is the worst of both worlds.

Tasks

  • Identify the specific upstream commit(s) that introduced "rotation before KV quantization" in llama.cpp master
  • Assess whether ollama37's current `ml/backend/ggml/` vendor tree is ahead of or behind that commit
  • Benchmark q4_0 KV with and without pre-rotation on K80 (existing infra, minimal work)
  • Only if Path A is insufficient: open a prototype issue for Path B (independent tbq3_0)

Out of scope

  • Path C (porting #21089 verbatim). Rejected.
  • tbq4_0 / TBQ2. No longer compelling given upstream's rotation change.
  • QJL residual correction. Community evidence is against it.

References

Related to #99.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions