The selling point of looped transformers is arithmetic heterodoxy: depth without parameters. Instead of stacking 32 unique blocks, you take a small model and re-apply the same block R times per token — the Universal Transformer move, revived in 2025-2026 by the Ouro family and by Huginn-3.5B, which treats the recurrence count as a dial for test-time compute123. Fewer weights on disk, more computation per token, and in principle you trade parameter memory for FLOPs at a rate you control.
The bill arrives at inference. FlashLoop — a training-free inference framework by Wanqi Yang and Shiwei Liu (ELLIS Institute Tübingen / MPI for Intelligent Systems / Tübingen AI Center, arXiv:2609.29812, September 24, 2026) — opens with the numbers that make looped transformers expensive, and they are stark: on a single A100, prefilling a 32K-token prompt takes Ouro-2.6B (four loops) 27 seconds versus 3 seconds for LLaMA-3.1-8B, and Ouro's KV cache alone occupies 48 GiB versus 4 GiB for the LLaMA model4. A model with roughly one-third the parameters costs nine times the prefill time and twelve times the cache memory. The paper's diagnosis of why: an N-block looped transformer run with R loops executes R x N block evaluations, and, in its own words, "each additional loop incurs another Transformer pass and requires caching another set of KV states" — computation and cache both grow linearly with loop depth4.
The paper's cure is the observation that most of that growth buys nothing: as recurrence proceeds, hidden-state changes concentrate on a shrinking, nested subset of tokens; attention columns that matter are sparse and stable across loops; and the KV residual between adjacent loops shrinks enough to compress aggressively. This guide checks the math first, then the silicon: why the KV cache is the latency (decode arithmetic intensity sits three orders of magnitude below the A100's roofline ridge), what the three components actually compute, whether the storage arithmetic reproduces the headline 6x, and what "lossless" costs in accuracy points. All numbers are either quoted from the paper or computed in the cells and labeled as such; the simulation in cell 2 is a toy analog and says so.
1. Why looping couples FLOPs and KV bytes
Write the looped block as the paper does, H^(r) = F_theta(H^(r-1)), with F_theta shared across loops r = 1..R. Naively, F_theta is applied to all tokens at every loop "while a separate pair of keys and values, (K^(r), V^(r)), is stored for each loop" — so the model's effective compute per token is R passes over the shared weights, and its cache carries R distinct KV tensors4. That is the whole coupling: unlike a normal transformer, where depth and KV footprint are separate axes, in a looped transformer both scale with R. Doubling depth doubles FLOPs and doubles cache, identically.
That matters because of where the cache lives. On the silicon, decode of any transformer is a bandwidth-bound problem: each generated token requires reading the entire KV cache from HBM, and the FLOPs that reading enables are small. The roofline arithmetic intensities below make this concrete with the paper's own 32K configuration — and show why per-loop KV accumulation is not an accounting nuisance but the direct latency term. (Our computation, /usr/bin/python3, from the paper's measured numbers.)
# Cell 1: the looped-transformer cost model at the paper's 32K configuration
S = 32768
GiB = 1024 ** 3
mv = 48.0 * GiB # paper: Ouro-2.6B cross-loop KV at 32K, R=4, BF16
for R_ in (1, 2, 4):
print(f"R={R_}: block evaluations per generated token = R x N = {R_}N")
# paper: 32K prefill on one A100, Ouro-2.6B (R=4) vs LLaMA-3.1-8B
t_ouro, t_llama = 27.0, 3.0
kv_ouro, kv_llama = 48.0, 4.0
print(f"prefill 32K on A100: Ouro-2.6B (R=4): {t_ouro:.0f} s LLaMA-3.1-8B: {t_llama:.0f} s ratio {t_ouro/t_llama:.1f}x")
print(f"peak KV@32K: Ouro-2.6B: {kv_ouro:.0f} GiB LLaMA-3.1-8B: {kv_llama:.0f} GiB ratio {kv_ouro/kv_llama:.1f}x")
print(f"Ouro-2.6B has ~{8/2.6:.2f}x fewer parameters, but {t_ouro/t_llama:.0f}x the prefill time and {kv_ouro/kv_llama:.0f}x the KV memory")
# implied KV payload per (token, loop) cell
print(f"implied bytes per (token, loop): {mv/(S*4):,.0f} B (= 2*KV heads * d_head * 2B per element)")
# A100-SXM4-40GB roofline: decode arithmetic intensity vs the ridge point
bw, tflops = 1555.0, 312.0 # GB/s, BF16 TFLOPS
ridge = tflops * 1e12 / (bw * 1e9)
flops = 2 * 2.6e9 * 4 # ~4 loop passes over shared block weights
print(f"A100 ridge point: {tflops:.0f} TFLOPS / {bw:.0f} GB/s = {ridge:.0f} FLOPs/byte")
print(f"decode arithmetic intensity if all loop-KV is read per step: {flops/mv:.2f} FLOPs/byte")
print(f"-> {ridge/(flops/mv):.0f}x below the ridge: decode is purely bandwidth-bound,")
print(f" so KV bytes ARE decode latency; halve the bytes moved, roughly halve the step")R=1: block evaluations per generated token = R x N = 1N
R=2: block evaluations per generated token = R x N = 2N
R=4: block evaluations per generated token = R x N = 4N
prefill 32K on A100: Ouro-2.6B (R=4): 27 s LLaMA-3.1-8B: 3 s ratio 9.0x
peak KV@32K: Ouro-2.6B: 48 GiB LLaMA-3.1-8B: 4 GiB ratio 12.0x
Ouro-2.6B has ~3.08x fewer parameters, but 9x the prefill time and 12x the KV memory
implied bytes per (token, loop): 393,216 B (= 2*KV heads * d_head * 2B per element)
A100 ridge point: 312 TFLOPS / 1555 GB/s = 201 FLOPs/byte
decode arithmetic intensity if all loop-KV is read per step: 0.40 FLOPs/byte
-> 497x below the ridge: decode is purely bandwidth-bound,
so KV bytes ARE decode latency; halve the bytes moved, roughly halve the step(Our computation, /usr/bin/python3, from the paper's measured 48-GiB figure; the 393,216 bytes per (token, loop) follow arithmetically from 48 GiB over 32K tokens and 4 loops.) An arithmetic intensity of 0.40 FLOPs/byte is three orders of magnitude below the A100's ridge of 201 — the tensor cores are essentially idle during decode, and the step time is a byte-traffic schedule. That is the silicon fact that makes FlashLoop's whole program — every component of it reduces bytes or skips reads — the correct attack, and it is also why the KV accumulation per loop is the looped transformer's structural tax, not an implementation detail. One caveat the paper flags honestly: the tolerances are hidden in the peak-bandwidth idealization; real decode kernels sustain a fraction of 1555 GB/s, and fused-quantization kernels add dequantization work per byte read. The roofline argument survives because the gap is three orders, not two.
2. The redundancy finding — what the paper actually measured
FlashLoop's empirical core, Section 3 of the paper, is a characterization of cross-loop dynamics across the Ouro models and Huginn-3.5B — three claims of increasing sparsity with loop depth4:
- Token-update redundancy. Hidden-state updates become concentrated on a small subset of tokens whose changes are non-negligible; these active sets are "approximately nested" — active tokens in a later transition are largely a subset of those active in the preceding one. Because keys and values are computed from each token's representation independently, token-level sparsity induces KV-update sparsity mechanically.
- Attention-column redundancy. Cross-loop differences in attention output concentrate on a sparse subset of attention columns (key/value indices), whose importance is stable across adjacent loops — stable enough that the previous loop's attention statistics predict which columns matter in the next. The paper's concrete figure: in loop 3/4 of Ouro-1.4B, "updating only 10% of the columns can reconstruct over 90% of exact attention output"4.
- KV-storage redundancy. The residual X^(r) - X^(r-1) between adjacent-loop KV states shrinks in magnitude as loops deepen, making it cheaper to quantize than the full state: quantizing cross-loop residuals gives lower reconstruction error than quantizing full KV states at the same bit budget, and the advantage grows with loop depth.
The paper expresses no equivalent of a per-loop marginal-state percentile table in prose — the exact decay curves live in its figures (2 and 3), which the paper reports as decreasing residual magnitude with depth and Figure 8 (Appendix B) being measured across Huginn-3.5B's 32 loops. What is checkable in text: the nesting claim, the 10%-columns-for-90%-output figure, and the direction of every monotone claim. The cell below does not pretend to reproduce their measurements — it builds a labeled toy with the qualitative shape they report (geometrically decaying update norms, nested active sets at the paper's own Table 5 schedule, heavy-tailed column masses) so the numbers of the article's next section have a concrete referent.
# Cell 2: toy analog of the lazy-update pattern (NOT the paper's data)
# A clearly-labeled toy: 4096-token context, 4 loops. Each loop's hidden-state
# update has a Frobenius norm decaying geometrically (rho=0.45), with the mass on
# a shrinking nested top-k token subset at the paper's own Table 5 schedule for
# Ouro-2.6B (loops 1-2 dense, loop 3: 20% tokens, loop 4: 8%).
import random
rng = random.Random(2609)
S = 4096
rho = 0.45
active = list(range(S))
mag, norms, fracs = 1.0, [], []
for r in range(1, 5):
mag *= rho if r > 1 else 1.0
if r == 3:
active = sorted(rng.sample(active, int(0.20 * S)))
elif r == 4:
active = sorted(rng.sample(active, int(0.08 * S)))
norms.append(mag)
fracs.append(len(active) / S)
print("loop r : ||dH^r|| (a.u.) : active-token fraction")
for r in range(4):
print(f" {r+1} : {norms[r]:.4f} : {fracs[r]*100:5.1f}%")
print("")
print("marginal change contributed by loop r, as % of loop-1 change:")
tot = sum(norms)
for r in range(4):
print(f" loop {r+1}: {norms[r]/norms[0]*100:6.2f}% (cumulative {sum(norms[:r+1])/tot*100:5.1f}% of all change)")
print("")
print("token-update FLOPs actually spent under the nested schedule:")
rel = sum(fracs)
print(f" 100% + 100% + 20% + 8% = {rel*100:.0f}% of a dense 4-loop pass")
# toy attention-column mass (heavy tail analog; NOT the paper's measurement)
rng2 = random.Random(42)
S2 = 4096
w = sorted((rng2.paretovariate(1.07) for _ in range(S2)), reverse=True)
tot2 = sum(w)
print("")
print("toy attention: top 10% of key columns carry " + f"{100*sum(w[:S2//10])/tot2:.1f}" + "% of probability mass")
print(" (paper, Ouro-1.4B loop 3/4: updating 10% of the columns reconstructs over 90%)")loop r : ||dH^r|| (a.u.) : active-token fraction
1 : 1.0000 : 100.0%
2 : 0.4500 : 100.0%
3 : 0.2025 : 20.0%
4 : 0.0911 : 8.0%
marginal change contributed by loop r, as % of loop-1 change:
loop 1: 100.00% (cumulative 57.4% of all change)
loop 2: 45.00% (cumulative 83.2% of all change)
loop 3: 20.25% (cumulative 94.8% of all change)
loop 4: 9.11% (cumulative 100.0% of all change)
token-update FLOPs actually spent under the nested schedule:
100% + 100% + 20% + 8% = 228% of a dense 4-loop pass
toy attention: top 10% of key columns carry 79.3% of probability mass
(paper, Ouro-1.4B loop 3/4: updating 10% of the columns reconstructs over 90%)The one-line summary of the finding: late loops cost like full passes but deliver like deltas. In the toy's shape, loops 3 and 4 deliver under 30% of the total update between them while a dense implementation still bills them at 50% of the FLOPs and 50% of the new KV storage. Note what the toy does not claim: it does not say the last loop is near-zero (9% of total change is not nothing), and the paper does not claim that either — its own Table 5 keeps 8-10% of tokens and columns active to the end, and its accuracy columns (Section 4 below) show that killing them entirely would not be free.
3. What FlashLoop actually computes — and the storage arithmetic it implies
The framework is three components, all inference-time, training-free, per the paper4:
- Cross-loop token-sparse updates. After dense early loops, each loop ranks previously-updated tokens by normalized hidden-state change and keeps a top-k subset for further refinement. Skipped (converged) tokens reuse hidden and KV states from the preceding loop, and since later selections are restricted to earlier active sets, the active sets nest. New KV entries are written only for active tokens.
- Loop-aware sparse attention. Each sparse loop ranks key columns by the previous loop's attention statistics, selects top-K under a loop-specific budget, and recomputes only those columns' contributions via the paper's equation 3 — a rank-K correction to the previous loop's attention output. Crucially, the softmax over selected columns alone would renormalize their mass to 1 and overestimate them, so FlashLoop caches the columns' global probability mass from the preceding loop's full distribution and rescales.
- Cross-loop KV residual quantization. The first loop's K/V states become a quantized INT4 base (group-wise asymmetric, group 64, per-channel post-RoPE keys, per-token values, 64 most-recent tokens kept BF16); each subsequent loop stores only the quantized residual X^(r) - X_hat^(r-1), active tokens only5.
Now the honest arithmetic. If you model the paper's scheme at its own 32K configuration — 48 GiB baseline, Ouro-2.6B's Table 5 schedule (loops 1-2 dense, then 20% and 8% token retention), INT4 base plus INT4 active-token residuals plus the BF16 tail — how much of the headline reduction does the first-order storage model actually reproduce?
# Cell 3: KV storage and decode-bytes arithmetic at the paper's 32K config
GiB = 1024 ** 3
S, R = 32768, 4
base_gib = 48.0 # paper-measured baseline, BF16, R=4
per_tok = base_gib * GiB / S # BF16 bytes per (token, loop)
elems = per_tok / 2.0 # KV elements per (token, loop)
q4 = 0.5 # bytes/element at 4 bits
active = [1.0, 1.0, 0.20, 0.08] # Table 5, Ouro-2.6B token retention
# storage model: INT4 base (loop 1) + INT4 residuals for active tokens
# (loops 2-4) + 64-token BF16 tail; quantization metadata overhead ignored
base = S * elems * q4
res = sum(S * active[r] * elems * q4 for r in range(1, R))
tail = 64 * elems * 2.0
total = base + res + tail
print(f"baseline cross-loop KV @32K, BF16, R=4: {base_gib:6.1f} GiB")
print(f"model: INT4 base (loop 1): {base/GiB:6.2f} GiB")
print(f" + INT4 residuals loops 2-4 (dense/20%/8%): {res/GiB:6.2f} GiB")
print(f" + 64-token BF16 tail: {tail/GiB:6.4f} GiB")
print(f"model total: {total/GiB:.2f} GiB -> {base_gib*GiB/total:.2f}x reduction "
f"({(1-total/(base_gib*GiB))*100:.1f}%)")
print(f"paper peak-KV reduction: 6.06x (Table 1); 82.8% at 32K (Figure 6)")
print(f"-> the first-order storage model explains "
f"{(base_gib*GiB/total)/6.06*100:.0f}% of the paper's headline number")
print("")
# decode bytes per step: token budget x column budget (Table 5 columns: 8%/8%)
col = [1.0, 1.0, 0.08, 0.08]
bytes_after = (S*elems*q4*col[0] + S*elems*q4*col[1]*active[1]
+ S*elems*q4*col[2]*active[2] + S*elems*q4*col[3]*active[3] + tail)
bytes_before = base_gib * GiB
k = bytes_before / bytes_after
print(f"HBM bytes per decode step: before {bytes_before/GiB:.1f} GiB, after {bytes_after/GiB:.2f} GiB ({k:.2f}x)")
print("")
# Amdahl: loop-attention/KV traffic is a fraction of a real decode step
for share in (0.5, 0.6, 0.7, 0.8):
sp = 1.0 / ((1 - share) + share / k)
print(f"if loop-attention is {share:.0%} of decode time: end-to-end decode speedup = {sp:.2f}x")baseline cross-loop KV @32K, BF16, R=4: 48.0 GiB
model: INT4 base (loop 1): 12.00 GiB
+ INT4 residuals loops 2-4 (dense/20%/8%): 15.36 GiB
+ 64-token BF16 tail: 0.0938 GiB
model total: 27.45 GiB -> 1.75x reduction (42.8%)
paper peak-KV reduction: 6.06x (Table 1); 82.8% at 32K (Figure 6)
-> the first-order storage model explains 29% of the paper's headline number
HBM bytes per decode step: before 48.0 GiB, after 24.36 GiB (1.97x)
if loop-attention is 50% of decode time: end-to-end decode speedup = 1.33x
if loop-attention is 60% of decode time: end-to-end decode speedup = 1.42x
if loop-attention is 70% of decode time: end-to-end decode speedup = 1.53x
if loop-attention is 80% of decode time: end-to-end decode speedup = 1.65x(Our computation, /usr/bin/python3.) This cell is the most adversarial one, and its answer is instructive: the naive storage model — apply Table 5's token retention to INT4 residual writes, everything else stays — predicts 1.75x, while the paper measures a 6.06x peak-KV reduction and 82.8% at 32K. The gap is real and has two honest sources. First, the paper's residuals are sparser than the token schedule alone: residuals are packed per active token with group-wise scaling and physically packed 4-bit streams, with custom CUDA kernels that read packed anchor-plus-residual KV directly during QK and PV computation instead of materializing a BF16 cache4. Second, "peak KV cache" and "our 48 GiB redesign" are not measured identically: peak memory over benchmark runs reflects the paper's full sparse execution path, not just the residual-count product. The lesson is not that 6x is wrong — it is that most of the headline is kernel engineering and sparsity compounding, and only a third of it is the arithmetic you can check on a napkin. The Amdahl rows do the same service for the 1.64x: even granting 6.06x on cache traffic, if loop-attention accounts for 70% of decode time, the end-to-end ceiling is ~1.53x (audit-corrected Amdahl at the model's own 1.97x byte-traffic reduction). The paper's 1.64x is an end-to-end wall-clock measurement on real benchmarks (Table 1), which is honest — and which simultaneously tells you that the prefill-side savings and FLOP reduction must be doing real work, since bandwidth reduction alone cannot get there if attention is under ~80% of the stack.
4. "Lossless": what it means in this paper, operationally
The abstract claims FlashLoop "delivers lossless accuracy while achieving up to 1.64x end-to-end speedup and up to 6x KV-cache memory reduction"4. In the tables, "lossless" means average accuracy within fractions of a percentage point on five benchmarks — math scores on MATH-500 and GSM8K, plus ARC-Challenge, HellaSwag, WinoGrande — under the EleutherAI harness, not bit-exact outputs and not a statistical test. The deltas from Table 1, which we reproduce exactly4:
- Ouro-1.4B: +0.37 average points (70.48 vs 70.11), 1.59x speedup, 5.85x KV
- Ouro-1.4B-Thinking: -0.88 (66.23 vs 67.11) — MATH-500 drops 46.80 to 46.20; 1.59x, 5.85x
- Ouro-2.6B: -0.13 (71.08 vs 71.21), the headline-holding 1.64x, 6.06x KV
- Ouro-2.6B-Thinking: -0.56 (72.04 vs 72.60), driven by MATH-500 59.00 to 54.60; 1.64x, 6.06x
- Huginn-3.5B: +0.17 (42.77 vs 42.60) with GSM8K down 27.52 to 25.70; 1.52x, 5.18x
Two pattern reads the paper itself notes. Base models are more robust to the compression than their thinking counterparts — a -4.4-point MATH-500 swing on Ouro-2.6B-Thinking is not nothing, and the paper says thinking models "may be more sensitive to cross-loop compression"4. And the ablation is genuinely informative: replacing cross-loop residual quantization with direct INT4 quantization of full KV states (their "Per-loop KIVI4" row) drops Ouro-1.4B's three-benchmark average from 68.56 to 67.12 — the residual-vs-full distinction is worth a full accuracy point, which is direct evidence for the paper's third redundancy claim having a mechanism, not just a correlation. Alternative cache strategies lose far more: at -75% KV, H2O drops Ouro-1.4B from 70.11 to 62.81, the last-step-reuse baseline lands at 68.33, and FlashLoop holds 70.48. The long-context check (Appendix F) holds WikiText-2 perplexity at 8K-32K (10.526 vs 10.513 at 8K; 5.321 vs 5.589 at 32K — the 32K figure is worse, not better) with needle-in-a-haystack at 84.5% vs 83.0% single-needle and 7.5% vs 9.2% multi-needle. A multi-needle drop of nearly two points at 32K under a scheme that keeps 10% of columns in loop 4 is the kind of quiet regression a "lossless" label should not be allowed to cover, and the paper deserves credit for printing it.
So: "lossless" here means average-benchmark-parity, demonstrated on five tasks with deltas within about one point. That is a strong and useful claim. It is not losslessness in the watermarking sense of bit-exactness, and a marketing sweep of the abstract would lose exactly the two rows that carry the real information — the thinking-model deltas and the multi-needle number.
5. Verdict
What loop depth buys: a parameter-efficient scaling axis with, per this paper, exploitable structure — late loops are refactoring work, not fresh computation, and a training-free schedule (dense warm-up, then nested token sparsity, top-K stable columns, INT4 residual chains) can reclaim most of their cost. The measured results are real: 1.52-1.64x end-to-end, 5.18-6.06x peak KV, average accuracy deltas within a point, on five public benchmarks across five looped models, with the strongest adversarial evidence being that the naive alternatives (H2O, last-step reuse) lose several points where FlashLoop loses fractions.
What it costs and where the headline lands under adversarial reads. First, the 6x is not checkable from the napkin arithmetic — the first-order model yields 1.75x, and the remainder is packed 4-bit kernels and sparse execution paths; anyone porting the idea should expect the napkin number, not the press number, until they also write the kernels. Second, the 1.64x end-to-end is a wall-clock measurement of a whole benchmark stack on one A100; Amdahl bounds what survives on a stack where attention is 60-70% of decode — the paper's own decode-latency reduction of "about 37.5%" at 32K is consistent with its speedup claim. Third, the accuracy fine print matters precisely where looped models are supposed to shine: thinking variants and multi-needle long-context retrieval carry the losses, and those are the workloads that justify deep recurrence in the first place.
What would falsify the approach: a looped model whose late loops are not redundant — one where late-loop updates are small in norm but load-bearing (the norm-concentration claim is exactly the kind of thing that fails on out-of-distribution contexts, and the calibration set here was 128 WikiText-2 sequences, chosen with a 5% reconstruction-error threshold). The scheme's sparsity schedule is calibrated once per model on in-domain text; the honest open question is whether nesting and column stability survive prompts that look nothing like WikiText. Also: adversarial contexts that concentrate on exactly the columns the schedule drops. The paper does not test that, and neither does the toy here — but that is the experiment that would falsify, and the 2-bit quantization row in their Figure 5 (clear degradation) shows the cliff exists in the direction of compression.
The base-rate summary: FlashLoop is a genuinely good systems paper wearing a slightly large headline. The redundancy finding is the content; the framework is the proof of exploitability; the numbers mostly survive scrutiny, and the ones that need asterisks — lossless, 6x, 1.64x — each have a fuller version two tables deep in the paper that a deployer should read before quoting the abstract.
6. Sources
Footnotes
-
Mostafa Dehghani, Stephan Gouws, Oriol Vinyals, Jakob Uszkoreit, Łukasz Kaiser: Universal Transformers, arXiv:1807.03819, ICLR 2019 — cited by the primary as the origin of depth recurrence; lineage references are restricted to what the primary itself cites. ↩
-
Zhu et al., 2025 (Ouro): weight-shared recurrence with latent-reasoning pretraining, cited by the primary for the evaluated model family and the 27-second/48-GiB measurements; model configurations from the primary's Table 5. ↩
-
Jonas Geiping, Sean McLeish, Neel Jain, John Kirchenbauer, Siddharth Singh, Brian R. Bartoldson, Bhavya Kailkhura, Aaditya Bhatele, Tom Goldstein: Scaling up Test-time Compute with Latent Reasoning: a Recurrent Depth Approach, NeurIPS 38 (2024), 41340-41391 — the Huginn lineage, author list and venue per the primary's own reference entry (Geiping et al., 2026); the Huginn-3.5B 32-loop configuration from the primary's Table 5. ↩
-
Wanqi Yang, Shiwei Liu: FlashLoop: Fast and Memory-Efficient Looped Transformers via Lazy Updates, arXiv:2609.29812v1, September 24, 2026, https://arxiv.org/abs/2609.29812. Author list verified at the abs page (two authors, ELLIS Institute Tübingen / Max Planck Institute for Intelligent Systems / Tübingen AI Center). All quotes verbatim from the HTML full text; Table 1, Table 5, Appendix E and Appendix F numbers transcribed exactly; the 27 s / 3 s, 48 GiB / 4 GiB and 10%-columns-for-90%-output figures are from Sections 1 and 3.2. Fetched September 25, 2026. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10
-
Zirui Liu, Jiayi Yuan, Hongye Jin, Shaochen Zhong, Zhaozhuo Xu, Vladimir Braverman, Beidi Chen, Xia Hu: KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache, arXiv:2402.02750 — author list verified at its arXiv abstract page; the primary's reference entry (Liu et al., 2024b) matches. The per-channel post-RoPE key / per-token value quantization conventions the primary adopts in Appendix E. ↩