FP8 KV Cache 生产默认
vLLM 支持 kv_cache_dtype="fp8"、fp8_e4m3、fp8_e5m2,scale 可默认、随机 token 校准或 dataset 校准。TensorRT-LLM 也支持 INT8/FP8 KV cache,并在 attention kernel 中读取时 on-the-fly dequant。
优点是集成成熟、2x 容量提升清晰、性能更稳;缺点是压缩率不如 4bit/2bit。
这份教程把 KV cache 量化拆成三个层次:先理解 cache 为什么吃显存,再理解量化轴和误差来源,最后把 TurboQuant、FP8、KIVI、KVQuant、GEAR、HF QuantizedCache、TensorRT-LLM 和 vLLM 工程实现放到同一张选型地图里。
配套 Excalidraw 图稿可直接打开编辑,适合录课、面试复盘或继续扩展成技术分享。
Transformer decode 阶段每次只生成一个新 token,但这个 token 的 query 需要和所有历史 token 的 key 做 attention score,再用 score 加权所有历史 value。KV cache 的意义是避免重复计算历史 token 的 K/V;代价是历史越长、并发越高,显存和 HBM 读流量越大。
KV bytes = 2 * layers * batch * tokens * kv_heads * head_dim * bytes_per_elem。其中 2 是 K 和 V;GQA/MQA 通过减少 kv_heads 降低 cache 体积;FP16/BF16 的 bytes_per_elem 是 2,FP8 是 1,4bit 理论上是 0.5。
低比特不等于理论比例。scale、zero point、codebook、残差窗口、packing 对齐、block metadata 都会吃掉一部分收益。工程上必须看实际 VRAM 峰值和可服务 token 容量。
| 变量 | 常见选择 | 为什么重要 |
|---|---|---|
| 量化对象 | K、V,或者 Q/K/V 一起 | K 影响 attention score,误差直接改变路由;V 影响加权输出。vLLM 的 FP8 路径在部分后端也会量化 Q 并在 FP8 域执行 attention。 |
| 量化轴 | per-tensor、per-head、per-token、per-channel、group-wise | K 通常有 channel outlier,V 更适合 per-token。KIVI 的核心就是这个不对称观察。 |
| 码型 | FP8、INT8、INT4、INT2、non-uniform、Lloyd-Max centroid | FP8 工程成熟;INT4/INT2 压缩强但需要更细的 scale、outlier 或旋转处理。 |
| 高精度残差 | recent window、first tokens、outlier sparse matrix、QJL residual | 最近 token、特殊 token、outlier 对输出质量影响大,很多方案不会把所有 token 一刀切压到低比特。 |
| 计算路径 | 读取后反量化,或在量化域执行 attention | 省显存不一定省延迟。反量化和 packing/unpacking 可能抵消收益;只有 kernel 配好,才会提高吞吐。 |
TurboQuant 论文的目标不是简单把每个数线性映射到 INT4,而是把高维向量先随机旋转,让坐标分布更容易被逐坐标标量量化;然后针对内积估计的偏差,用 1-bit QJL 对残差做修正。论文报告 KV cache 在 3.5 bit/channel 达到质量中性,在 2.5 bit/channel 只有小幅退化。
turboquant_k8v4、turboquant_4bit_nc、turboquant_k3v4_nc、turboquant_3bit_nc 等 preset。TurboQuant 的本质是“先让向量几何变得好量化,再把内积误差作为一等目标处理”。这比“把 FP16 切成 INT4”更准确。
vLLM 2026-05 的研究结论是:FP8 仍是默认首选;TurboQuant 4bit_nc 可以在显存压力极大时尝试。
k3v4_nc 和 3bit_nc 在长上下文和推理任务上可能有明显质量损失,不能只看 cache 容量提升。
vLLM 支持 kv_cache_dtype="fp8"、fp8_e4m3、fp8_e5m2,scale 可默认、随机 token 校准或 dataset 校准。TensorRT-LLM 也支持 INT8/FP8 KV cache,并在 attention kernel 中读取时 on-the-fly dequant。
优点是集成成熟、2x 容量提升清晰、性能更稳;缺点是压缩率不如 4bit/2bit。
Transformers 的 cache_implementation="quantized" 支持 quanto 和 hqq 后端。文档建议 HQQ 的 key/value axis 设为 1,Quanto 的 key/value axis 设为 0。
它适合快速缓解单机 OOM,但短上下文可能因为量化和反量化开销变慢。
KIVI 的核心观察是 K cache 更适合 per-channel 量化,因为 key 存在 channel-wise outlier;V cache 更适合 per-token 量化。它主打 tuning-free 2bit KV cache,是很多后续方案的基线。
KVQuant 组合了 per-channel key quantization、pre-RoPE key quantization、per-layer sensitivity non-uniform dtype、per-vector dense-and-sparse outlier handling 和 Q-Norm。它更像一条“为了 1M 到 10M context 专门设计系统和 kernel”的路线。
GEAR 先低比特量化大部分元素,再用低秩矩阵和稀疏矩阵补 quantization error。SKVQ 用 channel rearrange、clipped dynamic group quantization 和最近窗口高精度保留。WKVQuant 把权重和 KV cache 放在同一个 PTQ 框架中优化。
论文版强调旋转、MSE 标量量化、QJL 残差修正;vLLM 版强调 Hadamard + Lloyd-Max、value uniform quantization 和 norm correction。工程使用时把 turboquant_4bit_nc 当作显存压力场景候选,而不是无脑默认。
# FP8 KV cache:生产上最值得先测的基线
vllm serve meta-llama/Llama-3.1-8B-Instruct --kv-cache-dtype fp8
# 如果有校准数据,优先用 llm-compressor 生成更好的 KV scales
# vLLM 文档也支持 calculate_kv_scales=True 做 warmup 随机 token 校准
# 显存压力明显、排队严重时再试
vllm serve MiniMaxAI/MiniMax-M2.7 --kv-cache-dtype turboquant_4bit_nc
# 更激进的 3bit preset 只适合实验,必须看目标业务质量
vllm serve MiniMaxAI/MiniMax-M2.7 --kv-cache-dtype turboquant_3bit_nc
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
model_id = "meta-llama/Llama-2-7b-chat-hf"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
dtype=torch.float16,
device_map="auto",
)
inputs = tokenizer("解释 KV cache quantization 的收益:", return_tensors="pt").to(model.device)
out = model.generate(
**inputs,
max_new_tokens=128,
cache_implementation="quantized",
cache_config={"backend": "quanto", "nbits": 4},
)
print(tokenizer.decode(out[0], skip_special_tokens=True))
不要把 AWQ、GPTQ、bitsandbytes 这类权重量化当作 KV cache 量化。权重量化降低模型参数显存,KV cache 量化降低运行时上下文显存,两个瓶颈可能同时存在,也可能只有一个是瓶颈。
K 参与 q dot k,决定 attention 分布;K 的 channel outlier 会直接扭曲路由。V 是被 score 加权求和,分布和敏感性不同。因此 KIVI 才会用 K per-channel、V per-token 的不对称设计,KV-AdaQuant 这类工作也强调 keys deserve more bits。
因为它压缩率虽不极限,但 kernel、scale、硬件路径和质量风险更可控。vLLM 的 2026-05 TurboQuant 研究也建议大多数工作负载先选 FP8。
它把高维向量量化问题转成“旋转后坐标分布更好处理”的问题,并把 attention 依赖的 inner product bias 显式作为目标,而不是只最小化每个数的误差。
3bit 节省更多 cache,但可能需要 unpack、反量化、norm correction 或额外 kernel 逻辑;质量上也可能在长上下文和推理任务退化。最终要看服务吞吐和任务准确率的 Pareto frontier。
选择一个 32 层模型,设 batch、context、kv heads、head dim 和 dtype,分别计算 FP16、FP8、INT4、2bit 的 KV cache 理想显存,再说明 scale、metadata、padding 和 block table 会让真实显存偏离理想值。
设计一个长上下文评测表,至少包含 needle retrieval、MRCR、代码生成、数学推理和业务样本。每个任务记录 FP16 baseline、FP8、低比特方案的准确率和失败样例。
把一次 decode attention 拆成读取 KV、反量化、QK、softmax、PV、写回输出几段,说明量化节省了哪段 HBM 流量,又在哪段引入了额外计算。
为线上 RAG 服务设计一个回滚策略:当长上下文检索准确率、p95 TPOT、OOM 率或用户质量指标越界时,如何从低比特回滚到 FP8 或 FP16,并保留可审计日志。
HTML 用来系统阅读;Excalidraw 用来讲解。录视频时建议顺序是:图 1 讲瓶颈,图 2 讲 TurboQuant,图 3 讲工程选型。