---
title: KV Cache 量化教程：TurboQuant 与常用方法
jupyter: python3
---


更新时间：2026-05-25

本目录包含 3 张标准 `.excalidraw` 图稿，配合 `inference/kv_cache_quantization_tutorial_2026.html` 使用。

## 文件

1. `00_kvcache_quant_overview.excalidraw`：KV cache 内存公式、读写路径、量化插入点和常见误区。
2. `01_turboquant_pipeline.excalidraw`：TurboQuant 论文算法和 vLLM 工程实现的差异。
3. `02_kvcache_quant_methods_comparison.excalidraw`：FP8、HF QuantizedCache、KIVI、KVQuant、GEAR/SKVQ/WKVQuant、TurboQuant 的对比和选型。
4. `generate_kvcache_quant_tutorial.py`：重新生成 HTML 与 Excalidraw 的脚本。

## 主要资料源

- TurboQuant paper: https://arxiv.org/abs/2504.19874
- TurboQuant OpenReview PDF: https://openreview.net/pdf?id=tO3ASKZlok
- vLLM TurboQuant study: https://vllm.ai/blog/2026-05-11-turboquant
- vLLM quantized KV cache docs: https://docs.vllm.ai/en/stable/features/quantization/quantized_kvcache/
- vLLM TurboQuant docs: https://docs.vllm.ai/en/latest/api/vllm/model_executor/layers/quantization/turboquant/
- Hugging Face KV cache docs: https://huggingface.co/docs/transformers/kv_cache
- TensorRT-LLM GPT attention docs: https://nvidia.github.io/TensorRT-LLM/advanced/gpt-attention.html
- KIVI: https://arxiv.org/abs/2402.02750
- KVQuant: https://arxiv.org/abs/2401.18079
- GEAR: https://arxiv.org/abs/2403.05527
- SKVQ: https://arxiv.org/abs/2405.06219
- WKVQuant: https://arxiv.org/abs/2402.12065
- Quantize What Counts: https://arxiv.org/abs/2502.15075

## 练习题

1. 手算一个 32 层、batch=8、context=32k、kv_heads=8、head_dim=128 的 FP16 KV cache 显存，再分别估算 FP8、INT4 和 2bit 的理想压缩上限。
2. 设计一个评测表格，同时记录 TTFT、TPOT、peak VRAM、最大上下文、needle retrieval accuracy 和困惑度变化。
3. 选 KIVI、KVQuant、TurboQuant 三种方法，写出它们对 K/V 采用的粒度、scale 保存方式和反量化位置。
4. 给一个长上下文 RAG 服务设计量化回滚策略：什么指标触发回滚，回滚到 FP8 还是 FP16，如何避免请求中断。

## 面试题

1. 为什么 K cache 和 V cache 的量化敏感性不同？请从 attention score 和 value aggregation 两条路径解释。
2. FP8 为什么经常是工程默认起点，而不是直接追求 4bit 或 2bit？
3. TurboQuant 的旋转、norm correction 和 inner-product bias 分别在解决什么误差来源？
4. 如何判断 KV cache 量化收益来自显存容量提升，还是来自 decode kernel 实际更快？

## 图示

```{=html}
<!-- xboard:00_kvcache_quant_overview.excalidraw -->
<div class="xboard"><div class="xb-h1" style="--tc:#1e40af" data-a="c">KV Cache 量化总览</div><div class="xb-t" data-a="c">从内存公式、读写路径、量化轴到工程选型，一张图建立心智模型</div><div class="xb-row xb-flow n5"><div class="xb-box" style="--bc:#2563eb;flex-grow:20" data-d="1"><div class="xb-h2" style="--tc:#1e40af">1  生成链路</div><div class="xb-t" data-a="c">Prompt tokens<br>输入序列</div></div><div class="xb-box" style="--bc:#2563eb;flex-grow:20" data-d="1"><div class="xb-t" data-a="c">Prefill<br>并行算全量 Q K V</div></div><div class="xb-box" style="--bc:#2563eb;flex-grow:20" data-d="1"><div class="xb-t" data-a="c">KV Cache<br>逐层保存历史 K V</div></div><div class="xb-box" style="--bc:#2563eb;flex-grow:20" data-d="1"><div class="xb-t" data-a="c">Decode step<br>新 token 查询所有历史 K</div></div><div class="xb-box" style="--bc:#2563eb;flex-grow:20" data-d="1"><div class="xb-t" data-a="c">Output token<br>追加到上下文</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#d97706;flex-grow:49" data-d="1"><div class="xb-h2" style="--tc:#1e40af">2  KV cache 内存公式</div><div class="xb-t" data-a="c">KV bytes = 2 * layers * batch * tokens * kv_heads * head_dim * bytes_per_elem<br>2 表示 K 和 V；GQA/MQA 主要通过减少 kv_heads 降低 cache 体积</div></div><div class="xb-box" style="--bc:#dc2626;flex-grow:51" data-d="1"><div class="xb-t" data-a="c">为什么 decode 容易 memory-bound<br>每生成 1 个 token，都要读过去所有 token 的 K/V<br>长上下文和大 batch 会让 HBM 读流量线性增长</div></div></div><div class="xb-row xb-flow n4"><div class="xb-box" style="--bc:#2563eb;flex-grow:26" data-d="1"><div class="xb-h2" style="--tc:#1e40af">3  量化可以插入的位置</div><div class="xb-t" data-a="c">写入 cache 前<br>K/V 从 FP16/BF16 转为低比特<br>需要 scale、zero point 或 codebook</div></div><div class="xb-box" style="--bc:#16a34a;flex-grow:26" data-d="1"><div class="xb-t" data-a="c">存储形态<br>FP8 / INT8 / INT4 / 2bit<br>packed layout 决定真实压缩率</div></div><div class="xb-box" style="--bc:#7c3aed;flex-grow:26" data-d="1"><div class="xb-t" data-a="c">读取 cache 时<br>反量化到计算域<br>或在 FP8/INT8 域内直接 attention</div></div><div class="xb-box" style="--bc:#ea580c;flex-grow:21" data-d="1"><div class="xb-t" data-a="c">残差窗口<br>最近 token 保持高精度<br>减少短程依赖损伤</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#64748b;flex-grow:25" data-d="1"><div class="xb-h2" style="--tc:#1e40af">4  四个常见误区</div><div class="xb-t" data-a="c">只看 bit 数<br>忽略 scale 与 metadata 开销</div></div><div class="xb-box" style="--bc:#64748b;flex-grow:25" data-d="1"><div class="xb-t" data-a="c">短上下文启用量化<br>可能省显存但拖慢延迟</div></div><div class="xb-box" style="--bc:#64748b;flex-grow:25" data-d="1"><div class="xb-t" data-a="c">把权重量化当 KV 量化<br>AWQ/GPTQ 不自动压 KV</div></div><div class="xb-box" style="--bc:#64748b;flex-grow:25" data-d="1"><div class="xb-t" data-a="c">只测困惑度<br>长检索与推理任务更能暴露损伤</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#0f766e;flex-grow:100" data-d="1"><div class="xb-t" data-a="c">选型口诀<br>先 FP8，再看是否真的被 KV 显存卡住；需要 4bit/3bit 时必须用目标模型、上下文长度、采样参数和业务任务做 A/B。</div></div></div></div>
<!-- /xboard -->
```
<p class="caption">KV cache 内存公式、读写路径、量化插入点和常见误区 · <a href="00_kvcache_quant_overview.excalidraw">Excalidraw 源文件</a></p>

```{=html}
<!-- xboard:01_turboquant_pipeline.excalidraw -->
<div class="xboard"><div class="xb-h1" style="--tc:#1e40af" data-a="c">TurboQuant：论文算法与 vLLM 工程实现</div><div class="xb-t" data-a="c">不要把论文里的 QJL 残差修正和当前 vLLM 的 KV-cache preset 混为一谈</div><div class="xb-row"><div class="xb-box" style="--bc:#64748b;flex-grow:35" data-d="1"><div class="xb-h1" style="--tc:#1e40af" data-a="c">论文 TurboQuant</div><div class="xb-row"><div class="xb-box" style="--bc:#2563eb;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">输入向量 x<br>来自每个 head 的 K 或 V</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#2563eb;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">随机旋转 / Hadamard<br>让坐标分布更集中、更接近独立</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#2563eb;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">逐坐标 MSE 标量量化<br>用少量 centroid 逼近旋转后坐标</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#7c3aed;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">残差 r = x - x_hat<br>MSE 最优不等于内积无偏</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#7c3aed;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">1-bit QJL 残差修正<br>用符号 sketch 修正注意力内积偏差</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#7c3aed;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">目标<br>3.5 bit/channel 质量中性<br>2.5 bit/channel 小幅退化</div></div></div></div><div class="xb-box" style="--bc:#db2777;flex-grow:29" data-d="1"><div class="xb-t" data-a="c">关键直觉<br>Attention score 是 q dot k，K 的方向和内积误差最敏感。<br>TurboQuant 不是普通 per-tensor affine int4，而是先改变几何分布再量化。</div></div><div class="xb-box" style="--bc:#64748b;flex-grow:35" data-d="1"><div class="xb-h1" style="--tc:#1e40af" data-a="c">vLLM TurboQuant KV-cache</div><div class="xb-row"><div class="xb-box" style="--bc:#2563eb;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">命令入口<br>--kv-cache-dtype turboquant_4bit_nc 等 preset</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#2563eb;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">Keys<br>FP8 或 Hadamard + Lloyd-Max MSE 3/4 bit</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#2563eb;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">Values<br>3/4 bit uniform quantization</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#dc2626;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">NC<br>norm correction 修正 centroid norm distortion</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#dc2626;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">当前实现取舍<br>QJL 故意省略，避免 softmax 方差放大</div></div></div><div class="xb-row"><div class="xb-box" style="--bc:#dc2626;flex-grow:100" data-d="2"><div class="xb-t" data-a="c">工程结论<br>FP8 默认更稳；4bit_nc 适合显存压力场景<br>k3v4_nc 和 3bit_nc 要谨慎验证</div></div></div><div class="xb-t" data-a="c">同名不等于同实现<br>读论文看算法保证<br>跑服务看 kernel 和 preset</div></div></div></div>
<!-- /xboard -->
```
<p class="caption">TurboQuant 论文算法和 vLLM 工程实现的差异 · <a href="01_turboquant_pipeline.excalidraw">Excalidraw 源文件</a></p>

```{=html}
<!-- xboard:02_kvcache_quant_methods_comparison.excalidraw -->
<div class="xboard"><div class="xb-h1">常用 KV Cache 量化方法对比与选型</div><div class="xb-t">按三个层次理解：工程默认、研究低比特、极限长上下文。</div><div class="xb-scroll"><table class="xb-table"><thead><tr><th>方法</th><th>核心做法</th><th>常见比特</th><th>优势</th><th>风险和适用场景</th></tr></thead><tbody><tr><td><b>FP8 KV</b><br>vLLM / TensorRT-LLM</td><td>K/V 用 FP8 存；scale 按 tensor 或按 head；部分后端直接在 FP8 域算 attention</td><td>8</td><td>部署最成熟；cache 容量约 2 倍；延迟可预测</td><td>压缩率有限；校准 scale 更稳；作为生产默认基线</td></tr><tr><td><b>HF QuantizedCache</b><br>Quanto / HQQ</td><td>Transformers generate 中量化 cache；可配 backend、axis、residual length</td><td>2 / 4 / 8</td><td>上手快；适合单机实验和缓解 OOM</td><td>短上下文可能变慢；各 backend 的 axis 不同；要留高精度残差窗口</td></tr><tr><td><b>KIVI</b></td><td>K 按 channel、V 按 token 量化，利用 K 的 channel outlier</td><td>2</td><td>调参少；低比特 KV 量化的经典基线</td><td>依赖专用 kernel；长推理任务要业务验证</td></tr><tr><td><b>KVQuant</b></td><td>Pre-RoPE 量化 K、非均匀 dtype、dense-sparse outlier、Q-Norm</td><td>2 / 3</td><td>面向超长上下文，论文展示 1M–10M context</td><td>实现复杂，要自定义 CUDA；偏研究和专用系统</td></tr><tr><td><b>GEAR / SKVQ / WKVQuant</b></td><td>量化叠加低秩误差、稀疏 outlier、滑动窗口，或权重+KV 联合 PTQ</td><td>约 1.5–4</td><td>更高压缩率或联合优化，思路多</td><td>各有额外假设；迁到 vLLM / SGLang 需要 kernel 和调度配合</td></tr><tr><td><b>TurboQuant</b></td><td>旋转后逐坐标标量量化；论文加 QJL 残差修正；vLLM preset 加 norm correction</td><td>3 / 4，k8v4</td><td>显存紧张时扩大可服务 token 数；算法可解释</td><td>按当前 vLLM 测试 FP8 仍是首选；4bit_nc 可试，3bit 要谨慎</td></tr></tbody></table></div><div class="xb-box" style="--bc:#ea580c" data-d="1"><div class="xb-h2">实战决策</div><div class="xb-t">先确认 KV cache 真的在限制吞吐或上下文，不是就别压 KV。是的话先测 FP8；仍然 OOM 或排队严重，再比较 4bit / KIVI / TurboQuant / KVQuant。</div></div><div class="xb-box" style="--bc:#0891b2" data-d="1"><div class="xb-h2">评测必须覆盖</div><div class="xb-t">VRAM 峰值、TTFT、TPOT、吞吐、cache 命中率、困惑度、长上下文检索、数学 / 代码推理、目标业务样本。</div></div></div>
<!-- /xboard -->
```
<p class="caption">FP8、HF QuantizedCache、KIVI、KVQuant、GEAR/SKVQ/WKVQuant、TurboQuant 的对比和选型 · <a href="02_kvcache_quant_methods_comparison.excalidraw">Excalidraw 源文件</a></p>
