背景:长上下文推理的瓶颈正在从权重转向 KV Cache
很多团队第一次优化大模型推理时,会优先盯着模型权重下手——FP16 转 INT8、INT4,上 AWQ、GPTQ、FP8,能不能把更大的模型塞进显卡,能不能压缩一次前向计算的成本。这一步当然重要,但到了长上下文、多轮对话、高并发 serving 阶段,另一个瓶颈会以更快的速度浮出水面:KV Cache。
自回归模型每生成一个 token,都需要使用之前所有 token 的 Key/Value 表示来计算注意力。如果没有缓存,就要不断重复计算历史上下文;有了 KV Cache,模型可以复用历史 Key/Value,只对新 token 做增量计算。问题在于,缓存会随上下文长度、batch 内请求数、层数、KV head 数、head 维度线性增长。
在短 prompt、短输出场景,KV Cache 不显眼;但在 32K、128K 甚至更长上下文,或者在一个 GPU 上并发服务大量请求时,KV Cache 会直接挤占显存,限制 batch size、并发数和最大上下文长度。此时继续只压模型权重,往往解决不了线上吞吐问题。
KV Cache 量化的目标很直接:把缓存中的 Key/Value 从 BF16/FP16 降到 FP8、INT8,甚至更低 bit 表示,减少缓存体积和注意力读取带宽压力,在质量可控的前提下提升长上下文服务能力。
核心原理:量化的不是模型权重,而是生成过程中的历史记忆
在 Transformer 解码阶段,每一层 attention 都会产生历史 token 的 Key 和 Value。单个请求的 KV Cache 规模可以简化为:
KV Cache bytes ≈ layers × sequence_length × kv_heads × head_dim × 2(K,V) × bytes_per_element
其中 bytes_per_element 是优化重点。BF16/FP16 通常是 2 bytes;FP8/INT8 通常是 1 byte。仅从存储宽度看,FP8/INT8 可以把 KV Cache 体积约降到原来的一半。实际收益还要看 kernel、scale 存储、访存模式、量化粒度、模型结构和 workload。
为什么 KV Cache 量化和权重量化不是一回事
| 维度 | 权重量化 | KV Cache 量化 |
|---|---|---|
| 量化对象 | 模型参数(静态) | 每请求运行时缓存(动态增长) |
| 量化时机 | 模型加载/引擎构建 | 推理过程中在线量化 |
| 主要收益 | 降低模型显存、减少前向计算成本 | 降低缓存显存、减少 attention 访存带宽 |
| 典型方案 | AWQ、GPTQ、FP8、INT4 | FP8/INT8 KV Cache |
| 关系 | 可叠加,不可互相替代 | 可叠加,不可互相替代 |
例如,一个模型即使做了 INT4 权重量化,长上下文请求仍然会产生大量 KV Cache。并发上来后,显存可能不是被权重吃满,而是被缓存吃满。此时压权重的边际收益递减,压 KV Cache 才会直接影响最大并发和上下文容量。
FP8、INT8、2-bit:先从生产可用性看,而不是只看压缩率
论文里经常能看到 4-bit、3-bit、2-bit KV Cache 方案,例如 KIVI 提出对 Key 和 Value 采用不同粒度的低比特量化策略;KVQuant、TurboQuant、RotateKV 等工作也在持续探索更低 bit 的缓存压缩。但工程落地要先区分两类目标:
- 线上可用的稳定路径:优先考虑推理框架已支持的 FP8/INT8 KV Cache,并配套成熟 attention kernel。
- 研究或专项优化路径:低于 8-bit 的方案压缩率更高,但需要看模型、kernel、硬件、校准、质量评估和框架支持。
生产上不要只问「能压到几 bit」,更应该问:
- 当前框架是否原生支持?
- 量化后的 attention 是否有高性能 kernel?
- 长上下文准确率是否稳定?
- 是否支持按层跳过、按模型灰度、按路由回退?
- 是否能解释 TTFT、TPOT、吞吐和质量变化?
工程落地:从 vLLM/TensorRT-LLM 的可控路径开始
第一步:判断是否真的需要 KV Cache 量化
建议先用线上或压测数据回答四个问题:
- 平均输入长度和 P95/P99 输入长度是多少?
- 输出长度以短答为主,还是长链路推理/长报告生成?
- GPU 显存瓶颈来自权重、激活、KV Cache,还是 batch 调度碎片?
- 当前瓶颈是 TTFT、TPOT/ITL、吞吐、OOM,还是成本?
如果请求大多是短 prompt、短输出,KV Cache 量化可能不是第一优先级。更可能需要优化 batch、prefix cache、continuous batching、speculative decoding 或权重量化。
以下信号出现时,KV Cache 量化值得优先验证:
- 长上下文请求一多就 OOM
- batch size 无法继续提升
- decode 阶段 TPOT/ITL 随上下文长度明显变差
- prefix cache 命中后仍然显存紧张
- GPU 算力利用不低,但内存带宽或缓存读取成为主要瓶颈
第二步:vLLM——先做最小可复现实验
vLLM 已支持通过 kv_cache_dtype 启用 FP8 KV Cache。最小实验可以从无校准或自动 scale 开始,但正式上线前应补充真实数据集校准和质量评估。
vllm serve meta-llama/Llama-3.1-8B-Instruct \
--kv-cache-dtype fp8
对于部分混合注意力模型,滑动窗口层的 KV Cache 本来就较小,量化开销可能无法被摊薄。此时需要验证是否跳过这些层更合适:
vllm serve <model> \
--kv-cache-dtype fp8 \
--kv-cache-dtype-skip-layers sliding_window
如果模型在无校准 FP8 下出现稳定质量下降,应使用目标域样本做 scale calibration。vLLM 的 llm-compressor 示例中提供了基于校准数据生成 FP8 KV Cache scale 的路径,适合在上线前做更稳妥的验证。
第三步:TensorRT-LLM——结合硬件与引擎能力评估
TensorRT-LLM 提供多种 KV Cache 管理能力,包括 paged KV cache、quantized KV cache、circular buffer、KV cache reuse 等。对于 NVIDIA Hopper、Ada、Blackwell 等硬件,KV Cache 量化是否有收益,取决于引擎版本、attention backend、模型结构和 workload。
落地时不要把「启用 FP8 KV Cache」当成一个孤立开关。它通常要和以下能力一起评估:
- paged KV cache:减少缓存碎片,提高显存管理效率
- KV cache reuse:复用系统提示词、模板上下文或共享前缀
- eviction policy:避免高价值缓存被过早淘汰
- routing:把有缓存命中的请求路由到更合适的 worker
- quantized cache:降低缓存体积和读取带宽
第四步:量化 scale——不要忽视校准策略
KV Cache 量化通常需要 scale 把高精度值映射到低精度表示。不同框架可能支持不同粒度:per-tensor、per-head、per-channel、per-token 等。
一个常见误区是:只要设置 kv_cache_dtype=fp8 就结束了。实际应至少比较三组:
| 组别 | 配置 | 作用 |
|---|---|---|
| 基线 | BF16/FP16 KV Cache | 质量上限参照 |
| 实验一 | FP8 KV Cache,无校准或默认 scale | 快速验证压缩收益 |
| 实验二 | FP8 KV Cache,真实业务数据校准 scale | 上线前质量兜底 |
如果实验二明显优于实验一,说明模型或业务分布对 scale 敏感,上线时就不能只依赖默认配置。
评估指标:不要只看吞吐,也要看长上下文质量
KV Cache 量化最容易被错误评估。只看单轮短 prompt 的平均吞吐,可能完全看不出问题。建议至少覆盖以下指标。
性能指标
| 指标 | 说明 |
|---|---|
| TTFT | 首 token 延迟。长上下文 prefill 重时,FP8 attention 可能引入额外开销,需单独测 |
| TPOT / ITL | 生成阶段每 token 延迟。长上下文 decode-heavy 场景是主要收益点 |
| Throughput | tokens/s、requests/s、有效并发 |
| 显存峰值 | 总显存、KV Cache 占用、碎片率 |
| OOM 率 | 尤其是长上下文与高并发组合下的稳定性 |
质量指标
- 长上下文检索:needle-in-a-haystack、MRCR、RULER 或业务自有长文问答集合
- 事实一致性:引用型问答、RAG 场景的来源匹配
- 推理稳定性:数学、代码、长链路 reasoning
- 输出退化:重复、截断、答非所问、格式漂移
- 分桶评估:按 8K、32K、64K、128K、256K 等上下文长度拆开看
线上监控不能只看平均值。KV Cache 量化的问题常出现在长尾请求、极长上下文、特定模型层或特殊业务文本上。
适用场景分析
更适合使用 KV Cache 量化的场景
- 长上下文问答、长文档总结、代码仓库理解
- 多轮 Agent,历史上下文持续增长
- 高并发在线推理,batch size 受显存限制
- decode-heavy 任务,如长答案、长推理、长报告生成
- GPU 显存紧张,但希望提高并发或上下文长度
需要谨慎的场景
- 短上下文低并发服务,量化开销可能盖过收益
- 对细粒度数值、长链路推理、法律/医疗等高精度文本极敏感的业务
- 使用非标准 attention backend,或框架对该模型支持刚上线
- head_dim 很大且 prefill 延迟是核心 SLA
- 缺乏长上下文测试集,无法判断质量回归
常见误区
误区一:权重量化后就不需要 KV Cache 量化
权重和 KV Cache 是两块不同显存。权重量化能让模型更小,但不会自动减少每个请求生成时增长的 KV Cache。长上下文场景下,两者通常需要组合评估。
误区二:只用短 prompt 压测
短 prompt 看不出 KV Cache 的线性增长,也看不出长上下文 attention 误差。上线前必须按上下文长度分桶评估。
误区三:只看吞吐,不看质量
量化的收益很容易被 tokens/s 放大,但质量退化可能只在极长上下文、特殊任务或特定模型结构下出现。没有质量评估的吞吐提升不应直接上线。
误区四:默认 scale 永远足够
默认 scale 简单、可复现,但不是所有模型都稳。只要发现系统性质量下降,就要引入校准数据,或者在该模型/路由上禁用 KV Cache 量化。
误区五:全层量化一定最好
混合注意力或滑动窗口层的缓存规模有限,全层 FP8 未必最优。部分框架支持跳过特定层,应纳入实验矩阵。
上线检查清单
- 明确优化目标:显存、TPOT、吞吐、上下文长度,不能混在一起
- 建立 BF16/FP16 KV Cache 基线
- 至少比较无校准 FP8、校准 FP8、回退基线三组结果
- 按上下文长度、模型、业务类型、输出长度分桶评估
- 覆盖长上下文检索、推理、代码、摘要、RAG 等关键任务
- 监控 TTFT、TPOT/ITL、tokens/s、requests/s、显存峰值、OOM、错误率
- 支持按模型、租户、路由、请求类型灰度启用
- 准备一键回退到 BF16/FP16 KV Cache
- 记录量化配置、scale 生成方式、校准数据版本和框架版本
- 将异常样例写入回归集,避免后续升级重复踩坑
总结
KV Cache 量化是长上下文 LLM 推理从「能跑」到「能上线跑好」的关键一步。它不是银弹,但在正确的场景下——长上下文、高并发、decode-heavy——可以显著降低显存压力,提升服务容量。核心原则是:以 BF16 基线为锚,以校准数据为尺,以分桶评估为镜,灰度上线,随时可回退。
不要一上来就追 2-bit/4-bit 的论文方案。先把 FP8/INT8 在生产框架里跑稳,理解自己的 workload 特征,建立质量监控体系,再考虑更激进的压缩策略。
参考资料
- vLLM Documentation: Quantized KV Cache
- vLLM Blog: The State of FP8 KV-Cache and Attention Quantization in vLLM (2026-04-22)
- vLLM LLM Compressor Docs: KV Cache Quantization
- NVIDIA TensorRT-LLM: Quantization in TensorRT-LLM
- NVIDIA Technical Blog: Introducing New KV Cache Reuse Optimizations in NVIDIA TensorRT-LLM (2025-01-16)
- KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache (ICML 2024)
- Hugging Face Transformers Documentation: Cache strategies