
🧠 记忆锚点:KV 量化压的是缓存读写;分组与尺度决定误差,必须用长上下文质量和尾延迟一起验。
💡 答案要点
KV Cache 量化 = 用低精度存储 KV Cache
核心思想: KV Cache 占显存太多,用 INT8/INT4 代替 FP16
精度对比:
| 精度 | 每个值占用 | 4K 上下文占用(7B 模型) |
|---|---|---|
| FP16 | 2 bytes | 2GB |
| INT8 | 1 byte | 1GB(节省 50%) |
| INT4 | 0.5 byte | 0.5GB(节省 75%) |
量化方法:
1. 对称量化(Symmetric Quantization):
python
# 量化
scale = max(abs(tensor)) / 127
quantized = round(tensor / scale).clamp(-128, 127).to(int8)
# 反量化
dequantized = quantized.to(float16) * scale2. 非对称量化(Asymmetric Quantization):
python
# 量化
min_val = tensor.min()
max_val = tensor.max()
scale = (max_val - min_val) / 255
zero_point = round(-min_val / scale)
quantized = round(tensor / scale + zero_point).clamp(0, 255).to(uint8)
# 反量化
dequantized = (quantized.to(float16) - zero_point) * scale3. 分组量化(Group-wise Quantization):
python
# 问题:全局量化精度损失大
# 解决:分组量化,每组独立 scale
# 将 tensor 分成 N 组
groups = tensor.reshape(N, -1)
# 每组独立量化
for i, group in enumerate(groups):
scale[i] = group.abs().max() / 127
quantized[i] = round(group / scale[i])KV Cache 的特殊性:
| 特点 | 影响 | 解决方案 |
|---|---|---|
| 动态性 | 每个 token 都在变 | 动态量化 |
| 异常值 | 某些通道值特别大 | Per-channel 量化 |
| Key vs Value | Key 对精度更敏感 | Key用INT8,Value用INT4 |
实现示例(Per-channel INT8):
python
class KVCacheQuantizer:
def quantize_kv(self, k, v):
# Key: per-channel INT8(精度要求高)
k_scale = k.abs().max(dim=-1, keepdim=True)[0] / 127
k_quant = (k / k_scale).round().clamp(-128, 127).to(torch.int8)
# Value: per-token INT4(可以更激进)
v_scale = v.abs().max(dim=-1, keepdim=True)[0] / 7
v_quant = (v / v_scale).round().clamp(-8, 7).to(torch.int8)
return k_quant, k_scale, v_quant, v_scale
def dequantize_kv(self, k_quant, k_scale, v_quant, v_scale):
k = k_quant.to(torch.float16) * k_scale
v = v_quant.to(torch.float16) * v_scale
return k, v精度损失评估(Llama 7B,MT-Bench):
| 方案 | 显存节省 | 困惑度增加 | 任务准确率下降 |
|---|---|---|---|
| FP16 | 0% | 0 | 0% |
| INT8(全局) | 50% | +5% | -3% |
| INT8(per-channel) | 50% | +1% | -0.5% |
| INT4(per-channel) | 75% | +8% | -2% |
| 混合(K=INT8, V=INT4) | 60% | +2% | -1% |
面试话术:
示例表达(仅在能用本人经历或可复现实验佐证时使用): "KV Cache 量化是推理优化的关键。我在项目中用 per-channel INT8 量化,显存节省 50%,精度损失不到 1%。核心是处理好异常值,用分组/分通道量化代替全局量化。"