More bits for keys, fewer for values, at the same total? Simulated KV cache, 4B model, 64K
At the same 4.5 bits per value, giving keys 5 bits and rotated values 3 bits beat plain 4-bit keys and values in 5 of 6 spans, and the reversed split lost in 6 of 6, so the pre-set bar was met. But simply rotating both keys and values at 4 bits did better still (mean KL 0.0173 vs 0.0194), so most of the gain comes from rotation, not from the uneven split.
| Experiment | E22K |
| Date | 2026-10-30 |
| Benchmark | Next-token KL against the same model with an unquantized cache, plus top-1 agreement. Six WikiText-2 test spans (the 4,096 tokens ending at token 72K, 108K, 144K, 180K, 216K and 252K of the Hugging Face tokenization), each scored with 65,536 tokens of context before it, chunked prefill. |
| Model | Qwen3.5-4B in Hugging Face transformers, NF4 weights (bitsandbytes), bf16 compute. Reference is the same model with an unquantized bf16 cache. |
| Hardware | One of my dedicated test rigs: RTX 3080 10 GB, 128 GB system RAM |
| Verdict | PASS |
What I tested
Quantize then dequantize post-RoPE keys and values as they enter the cache, on the 8 full-attention layers only. Absmax group-32 quantization with an fp16 scale per group; 'rotated' means a 256-wide Hadamard rotation before quantizing. Arms with uneven bits for keys and values: 5-bit keys plus rotated 3-bit values (with and without key rotation), the reversed split (rotated 3-bit keys plus 5-bit values) as a control, rotated 4-bit for both, plus two off-budget arms: rotated 4-bit keys with rotated 3-bit values (4.0 bits) and 6-bit keys with rotated 3-bit values (5.0 bits).
Pass bar, set before the run
Set before the run: PASS if 5-bit keys plus rotated 3-bit values (either key variant) has lower mean KL than plain 4-bit keys and values in at least 5 of 6 spans at the same 4.5 bits per value, AND the reversed control (rotated 3-bit keys, 5-bit values) is worse than that winning arm in at least 5 of 6 spans. Secondary: report whether rotated 4-bit keys plus rotated 3-bit values (4.0 bits) is at or below plain 4-bit in at least 5 of 6 spans.
Result
| Arm | Bits per value | Mean KL | Top-1 agreement | Better than plain 4-bit | Per-span KL (72K to 252K) |
|---|---|---|---|---|---|
| Plain 4-bit keys and values | 4.5 | 0.0251 | 95.86% | - | 0.0302 / 0.0460 / 0.0272 / 0.0137 / 0.0074 / 0.0263 |
| Rotated 4-bit keys and values | 4.5 | 0.0173 | 96.34% | 5 of 6 | 0.0222 / 0.0257 / 0.0183 / 0.0103 / 0.0093 / 0.0184 |
| 5-bit keys, rotated 3-bit values | 4.5 | 0.0200 | 95.30% | 4 of 6 | 0.0170 / 0.0354 / 0.0280 / 0.0125 / 0.0098 / 0.0172 |
| Rotated 5-bit keys, rotated 3-bit values | 4.5 | 0.0194 | 95.41% | 5 of 6 | 0.0145 / 0.0418 / 0.0221 / 0.0118 / 0.0092 / 0.0168 |
| Reversed: rotated 3-bit keys, 5-bit values | 4.5 | 0.0332 | 94.31% | 1 of 6 | 0.0352 / 0.0436 / 0.0460 / 0.0236 / 0.0115 / 0.0391 |
| Rotated 4-bit keys, rotated 3-bit values | 4.0 | 0.0236 | 94.97% | 3 of 6 | 0.0228 / 0.0349 / 0.0273 / 0.0156 / 0.0157 / 0.0252 |
| 6-bit keys, rotated 3-bit values | 5.0 | 0.0167 | 95.57% | 5 of 6 | 0.0143 / 0.0274 / 0.0191 / 0.0101 / 0.0103 / 0.0189 |
Main bar: rotated 5-bit keys plus rotated 3-bit values beat plain 4-bit in 5 of 6 spans (it lost only on the 216K span), and the reversed split was worse than it in 6 of 6. PASS as pre-registered.
The fair comparison the bar did not include is rotated 4-bit for both at the same 4.5 bits. It has the lowest mean KL of the equal-budget arms (0.0173) and the best top-1 agreement (96.34%). The uneven rotated split beat it in only 3 of 6 spans. So rotation is doing most of the work here, and spending extra bits on keys adds little on top of it.
The uneven splits have lower top-1 agreement than plain 4-bit (95.3% to 95.4% vs 95.86%) even though their mean KL is lower, because 3-bit values add small errors on many tokens.
Secondary reading: rotated 4-bit keys plus rotated 3-bit values (4.0 bits, 11% fewer than 4.5) was at or below plain 4-bit in only 3 of 6 spans, so it did not meet the secondary bar, though its mean KL (0.0236) is slightly lower.
The plain 4-bit arm reproduces E22i and E22j exactly (0.0251), so the harness is stable between runs.
This is a simulation in Hugging Face transformers, not llama.cpp, so it says nothing yet about speed or real memory use.
Per-span numbers for every arm, with p99 KL, top-1 agreement, perplexity and timing, are in results.csv in the code folder.
What happened
Seven arms over six spans at 64K took about 31 minutes. E22j showed keys are about twice as sensitive as values, so this run moved a bit from values to keys while keeping the same 4.5 bits per value. That split beat plain 4-bit and the reversed split clearly lost, which confirms the direction. The more useful finding is that the gain is mostly from the Hadamard rotation: rotating both keys and values at 4 bits did better than any uneven split at the same budget. For the 1M-token goal the budget has to fall to about 3.1 bits per value, so the next run tests rotated 4-bit keys with rotated 2-bit values and larger groups.
How to rerun
python e22k.py smoke
python e22k.py
Code
All code for E22K: e22k.py, results.csv.
Prior work
No novelty claim. This is a supporting measurement; uneven key and value bit widths (for example KIVI and mixed-precision KV cache papers) and Hadamard rotation before quantization are both known.
Written by Andrew Rose with help from AI tools. Every number comes from the run logs.
Questions or ideas? me@andrewroseit.com or @AndrewRoseIT.