docs(adr): ADR-073 — KV-cache quantization priority (Metal)#725
Conversation
Ranks the open KV-quant levers against what ships. Split verdict (unlike ADR-072's clean ranking): two levers rankable now on measured evidence (f16 default-flip #154, f16 paged-cache port #148), the int8/int4 family (#118/#120/#122/#123) gated behind a minimal int8-K CPU experiment + #491 because zero lattice quality/throughput data exists below f16. Anchor: PR #238 (merged) measured f16 KV decode-NEUTRAL on Qwen3.5-0.8B (71.6 vs 72.8 tok/s @1k, PPL delta 4e-6) — KV is <1% of decode bandwidth because the model is GDN-dominated (only 6 of 24 layers carry a KV cache). Reframes KV-quant as a memory-capacity lever, not a decode-throughput one. Refutes the external survey's central "KV ~16% of decode bytes" premise: it assumes a generic Hkv=8/head_dim=128 shape; lattice is Hkv=2/head_dim=256 with 6-of-24 KV layers, measured <1% at 1k. Causal mechanism (GDN-hybrid) recorded at priority level, per the ADR-072 W4-amendment pattern. Three KV caches documented (MetalKvCache production f32-default; FlatKVCache CPU always-f16; PagedKVCache unwired f32-only) — every lever names its target. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nt8's 24) Codex flagged an internal inconsistency: the P1 (f16 default-flip) memory-win parenthetical used the int8 column for the 0.8B (48->24 MiB) while the 27B half (512->256) correctly used the f32->f16 column. Per KV9/KV10 the 0.8B f32->f16 halving is 96->48 MiB @4096. Corrected + clarified that int8 is the further halving to 24. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ohdearquant
left a comment
There was a problem hiding this comment.
SPEC-GATE: SIGNED + approve press (codex r2 clean, content read end to end). The split-verdict structure is the honest shape for this evidence state: two levers ranked on measured data (P1 #154 default-flip riding KV3's measured neutrality+correctness; P-low #148 correctly roadmap-gated since the paged engine serves zero traffic), and the int8/int4 family gated behind a minimal experiment rather than ranked on data that does not exist. The refutation handling is the standard I asked repeated: the survey's 16%-KV premise refuted with the causal mechanism (GDN-hybrid caps KV to 6-of-24/16-of-64 layers, measured <1% at 1k) while honestly flagging the 8K-vs-1k mismatch and requiring re-derivation from our own long-context point rather than overclaiming. The P2 experiment scope (K-only, int8, full-attn layers only, CPU dequant shim, no rotation, no fused kernel) is exactly minimal, and naming #491 as prerequisite instrument ties the trilogy+1 together correctly. Riders inherited: GPU flock on all benches; the experiment's PPL number and the ≥1 long-context point are the public artifacts. Dependent work may proceed on merge, in P-order.
What
ADR-073 ranks the open KV-cache quantization levers (#154 f16 default-flip, #148 f16 paged-cache,
#118/#120/#122/#123 int8/int4 family) against what already ships. Docs only — one new file under
docs/adr/. Third sequencing ADR in the bundle set (siblings: ADR-071 GDN-state, ADR-072 weight-quant).Why this is a split verdict, not a clean ranking
Source recon (verified against
origin/main @ 454245434) found this lane is not a single yes/nolike weight-quant was:
(PR feat(inference): opt-in f16 KV cache for Metal GQA path (#154) #238, merged — 71.6 vs 72.8 tok/s @1k ctx, PPL Δ≈4e-6 on Qwen3.5-0.8B). It's a memory win, not
a throughput one, because the model is GDN-dominated — only 6 of 24 layers carry a KV cache, so
KV is <1% of decode bandwidth. PR feat(inference): opt-in f16 KV cache for Metal GQA path (#154) #238's own words: "The real decode lever is weight
quantization, not KV dtype."
quality or throughput data. The central open question isn't just quality — it's whether KV bit-width
moves decode throughput at all on a model whose KV is <1% of bandwidth.
Prior-art refutation (the W4-amendment pattern)
The external survey's central premise — "KV ≈ 16% of decode bytes," which drives every expected-speedup
number — is refuted: it assumes a generic
Hkv=8, head_dim=128shape. This engine isHkv=2(0.8B) /
Hkv=4(27B),head_dim=256, 6-of-24 / 16-of-64 KV layers, measured <1% at 1k. Causalmechanism (the GDN-hybrid architecture structurally caps KV's share) recorded at priority level.
Decision
blocker is the CI parity-test gap (test(inference): CI coverage for the f16 KV-cache Metal path (#238 follow-up) #252), an engineering completeness gate, not an empirical question.
roadmap-gated (that engine serves zero production traffic).
bandwidth share vs context). Quantize K-only/int8/full-attn-layers-only, CPU dequant-to-f32
prototype, extend the existing
ppl_metal/eval_perplexityharness. The experiment settles whetherint8-K moves anything worth a fused Metal kernel before any kernel work starts.
validation.
Structure
Measured/source-verified reality (KV1–KV12, each tagged +
origin/mainpointer) is kept separate fromthe external prior-art survey, folded as
[prior, unvalidated on our hardware]. Ordering fixed by themeasured decode profile, not the survey. Apple-GPU no-low-precision-matrix-unit constraint carried
through (KV int8/int4 is storage/bandwidth only, no compute payoff — same as weights in ADR-072).