背景问题:长上下文上线后,瓶颈经常不在权重,而在 KV Cache
很多团队优化大模型推理时,第一反应是做权重量化:把 BF16/FP16 权重改成 INT8、INT4、FP8 或混合精度格式,以便让更大的模型塞进单卡或更少 GPU。这个方向当然重要,但在长上下文服务里,另一个更容易被低估的瓶颈是 KV Cache。
Transformer 解码时,每生成一个 token,都需要访问历史 token 的 Key 和 Value。为了避免每一步重复计算历史上下文,推理框架会把历史 token 对应的 Key/Value 缓存在显存中。问题在于:KV Cache 的大小会随着 batch size、上下文长度、层数、KV head 数量、head dimension、数据精度 线性增长。
当上下文从 4K 扩展到 32K、128K,甚至更长时,KV Cache 会从”运行时缓存”变成真正的显存主角。NVIDIA TensorRT-LLM 技术博客明确指出,KV Cache 会随模型规模、批处理请求数和上下文长度增长,造成越来越高的内存需求;TensorRT-LLM 因此提供 paged KV cache、quantized KV cache、circular buffer KV cache 和 KV cache reuse 等多种优化。
这就是 KV Cache Quantization 的切入点:不是压缩模型本身,而是压缩每个请求运行时产生的历史注意力缓存。
核心原理:量化的是注意力历史,不是模型权重
KV Cache 在哪里消耗显存
以常见 decoder-only LLM 为例,单个请求的 KV Cache 大致可以理解为:
KV Cache Memory ≈ num_layers × 2 × num_kv_heads × head_dim × sequence_length × bytes_per_element
这里的 2 来自 Key 和 Value 两份缓存。bytes_per_element 在 BF16/FP16 下通常是 2 字节,如果改成 FP8 则约为 1 字节。如果从 BF16 KV Cache 改成 FP8 KV Cache,理论上 KV 部分显存可以接近减半;如果再进一步做 4bit、3bit、2bit,压缩比会更高,但精度与内核实现难度也会明显上升。
为什么不能把 KV Cache 当普通 activation 随便量化
KV Cache 的特殊性在于它会在整个解码阶段反复被读取。普通激活值通常是一次性中间结果,而 KV Cache 是每生成一个 token 都要被 attention kernel 访问的历史状态。量化误差如果影响 Key/Value 的分布,会通过 attention score、softmax 和 Value 聚合继续放大。
KIVI 论文对 KV Cache 分布做了专门分析,并提出 Key cache 和 Value cache 不应采用完全相同的量化维度:Key 更适合按 channel 量化,Value 更适合按 token 量化。这说明 KV Cache 量化不是简单把 dtype 从 BF16 改成 INT8 —— 它需要理解 Key/Value 的统计分布和 attention 计算路径。
量化层级对比:FP8 → INT8 → 极低比特
生产环境里可以把 KV Cache 量化分成三个层级:
| 层级 | 典型方案 | 精度影响 | 框架成熟度 | 适用阶段 |
|---|---|---|---|---|
| 工程起步层 | FP8 / INT8 | 低 | 高(vLLM、TensorRT-LLM 原生支持) | 首选方案,建立基线 |
| 研究专项层 | 4bit / 3bit / 2bit(KIVI、KVQuant、TurboQuant) | 中-高 | 低(需自定义内核) | 专项验证,非默认基础设施 |
| 框架集成层 | 极低比特 + continuous batching + paged KV | 取决于实现 | 极低 | 前沿探索 |
FP8 / INT8:工程起步层
这是当前主流推理框架最容易落地的方案。vLLM 文档说明,FP8 KV Cache 可以显著降低 KV Cache 内存占用,让内存中存储更多 token,从而提升吞吐并支持更长上下文。TensorRT-LLM 也提供 INT8 和 FP8 KV Cache,并在其量化文档中指出,在 Hopper 与 Ada GPU 上通常更推荐 FP8 KV Cache,因为多数测试中它比 INT8 精度影响更低。
4bit / 3bit / 2bit:研究与专项优化层
- KIVI(ICML 2024)提出 tuning-free asymmetric 2bit KV Cache quantization
- KVQuant 面向更长上下文,结合 per-channel key quantization、pre-RoPE key quantization、非均匀量化和 outlier 处理来降低低比特量化误差
- TurboQuant(Google Research, 2026)进一步把问题放到在线向量量化和内积失真控制上,目标是让 KV Cache 压缩在更低 bit budget 下仍保持注意力语义
极低比特方案能不能用于生产,不只取决于论文指标,还取决于推理框架是否有稳定内核、是否支持 continuous batching、prefix caching、paged KV、KV offloading、TP/EP 并行,以及是否能和模型结构兼容。没有内核和调度配合,理论压缩率未必能变成线上吞吐。
工程落地四步法:从 FP8 基线到极低比特评估
第一步:判断是否真的是 KV Cache 瓶颈
上 KV Cache 量化前,先看这些指标:
- GPU 显存是否主要被 KV Cache 占用,而不是权重占用
- 长上下文请求是否导致并发上不去
- decode 阶段是否 memory-bound
- TTFT 是否由 prefill 主导,还是 TPOT/ITL 被 decode 阶段拖慢
- 开启 prefix caching、chunked prefill、paged KV 后,瓶颈是否仍在 KV 读取与显存容量
如果服务主要是短输入、短输出、小 batch,那么 KV Cache 量化未必带来明显收益。反过来,如果服务是代码仓库问答、长文档分析、多轮 Agent、长对话客服、RAG 大上下文拼接,那么 KV Cache 往往很快变成核心约束。
第二步:用真实业务数据做精度基线
不要只用通用 benchmark 判断 KV Cache 量化是否可用。更稳妥的做法是准备四类评估集:
| 评估集类型 | 内容示例 | 关注指标 |
|---|---|---|
| 短上下文回归集 | 日常问答、分类、抽取 | 基础能力不退化 |
| 长上下文检索集 | 多 needle retrieval、跨段引用、长文摘要 | 检索准确率、引用精度 |
| 业务格式集 | JSON、工具调用、SQL、代码补全、合规话术 | 格式错误率、参数正确率 |
| 边界压力集 | 接近最大上下文长度、混合中英文、长表格、重复片段、低温输出 | 极端场景鲁棒性 |
评估指标不能只看平均分,还要看长上下文分桶、失败样例类型、格式错误率、工具调用参数错误率和安全策略误判率。
第三步:先上可回退的 FP8
vLLM 最新文档支持 FP8 KV Cache,并提供 per-tensor 与 per-attention-head 等量化尺度策略;vLLM 2026 年关于 FP8 KV Cache 的工程博客也给出一个实用结论:FP8 KV Cache 已经可以作为很多长上下文 vLLM 部署的默认起点,但需要注意 prefill-heavy、特殊 attention backend、混合模型小 sliding-window 层以及未校准损失等例外情况。
生产上推荐这样的上线顺序:
phase_0_baseline:
kv_cache_dtype: bf16
collect:
- gpu_memory_usage
- max_concurrent_requests
- ttft
- itl
- output_quality_samples
phase_1_shadow:
kv_cache_dtype: fp8
traffic: shadow_only
compare:
- exact_format_error_rate
- business_eval_score
- long_context_retrieval_score
- latency_percentiles
phase_2_canary:
kv_cache_dtype: fp8
traffic: 1_percent_to_5_percent
rollback_when:
- p95_itl_regression_gt_10_percent
- format_error_rate_regression_gt_0_5_percent
- safety_or_policy_regression_detected
phase_3_full_rollout:
kv_cache_dtype: fp8
keep_fallback: bf16
第四步:再评估更低比特方案
如果 FP8 已经解决容量问题,就不必急着上 4bit、3bit、2bit。更低比特适合以下场景:
- 上下文长度继续扩大,FP8 仍不够
- 单卡或边缘设备显存极其有限
- 业务对长上下文吞吐非常敏感
- 团队能维护自定义 kernel、校准流程和模型级回归测试
如果没有这些条件,极低比特方案更适合作为专项优化,而不是默认基础设施。
适用场景
适合使用 KV Cache 量化的场景
- 长上下文问答:文档、代码库、合同、日志分析
- 多轮 Agent:系统提示词长,工具上下文长,历史状态多
- 高并发在线服务:显存容量限制了 batch 或并发请求数
- decode-heavy 工作负载:输出较长,KV 读取频繁
- 多租户推理平台:需要在同一套 GPU 上承载更多活跃会话
不适合一开始就使用的场景
- 极短上下文、短输出、低并发服务
- 质量容错很低的任务,例如严格合规生成、金融风控解释、关键代码生成
- 模型结构或 attention backend 未被框架充分验证
- 团队没有离线评估集,也没有线上回滚能力
常见误区
误区一:KV Cache 量化等于推理一定变快
KV Cache 量化首先减少显存占用,其次减少访存带宽压力。它是否加速,取决于 workload 是否 memory-bound,以及量化/反量化是否被 attention kernel 高效融合。某些 prefill-heavy 场景里,收益可能不明显。
误区二:权重量化后就不需要 KV Cache 量化
权重量化解决的是模型参数占用;KV Cache 量化解决的是运行时状态占用。长上下文、多并发时,KV Cache 可能超过权重成为主要显存压力。两者不是替代关系,而是互补关系。
误区三:只测困惑度就够了
KV Cache 量化可能对不同任务产生不同影响。长上下文检索、结构化输出、代码生成、工具调用参数、RAG 引用准确率都需要单独评估。平均困惑度稳定不代表业务指标稳定。
误区四:低比特越低越好
2bit、3bit 方案在论文中很有吸引力,但生产系统还要考虑内核成熟度、GPU 架构、框架支持、校准流程、出错回退、部署复杂度。对于多数团队,FP8 是更稳妥的第一阶段。
上线检查清单
模型与框架
- 确认推理框架明确支持目标 KV Cache dtype
- 确认当前模型、attention backend、GPU 架构在支持矩阵内
- 确认量化方式是否需要 calibration scale
- 确认是否和 prefix caching、chunked prefill、continuous batching、paged KV 同时启用
评估与回归
- 建立 BF16/FP16 KV Cache 基线
- 建立 FP8/INT8 对照组
- 覆盖短上下文、长上下文、业务格式、边界压力样例
- 统计格式错误、工具调用错误、安全策略误判,而不只看文本相似度
监控与回滚
- 监控 KV Cache 使用量、GPU 显存碎片、cache hit/miss、eviction、OOM
- 监控 TTFT、TPOT、ITL、吞吐、排队时间、decode step 时间
- 保留 BF16/FP16 回退配置
- 对高价值租户或关键任务提供按路由禁用 KV Cache 量化的能力
参考资料
- vLLM Documentation — Quantized KV Cache
- vLLM Blog — The State of FP8 KV-Cache and Attention Quantization in vLLM
- NVIDIA TensorRT-LLM Blog — Quantization in TensorRT-LLM
- NVIDIA Technical Blog — Introducing New KV Cache Reuse Optimizations in NVIDIA TensorRT-LLM
- KIVI — A Tuning-Free Asymmetric 2bit Quantization for KV Cache (ICML 2024)
- KVQuant — Towards 10 Million Context Length LLM Inference with KV Cache Quantization
- LLM Compressor Docs — FP8 Weight, Activation, and KV Cache Quantization
- Google Research — TurboQuant: Redefining AI efficiency with extreme compression