量化 KV 缓存#
量化 KV 缓存通过使用低精度数据类型(FP8 或 FP4)代替默认的 BF16 模型精度,来减少键值(KV)缓存存储的内存占用。在自回归生成过程中,大语言模型(LLM)会缓存先前计算的键值对,以避免冗余计算。KV 缓存通常消耗很大一部分 GPU 内存,尤其是在处理长序列时。
量化 KV 缓存是一种内存优化技术,它通过允许缓存更多标记(tokens)来主要提升吞吐量,但根据所使用的量化格式,可能会引入极小的精度损失。
警告
性能警告:当必须在注意力(attention)操作前对量化 KV 缓存进行反量化时,如果反量化过程没有与注意力算子融合(fused),性能可能会变得非常缓慢。请务必核实您选择的注意力后端是否支持量化 KV 缓存。不支持融合算子的后端可能会出现严重的吞吐量下降,甚至抵消掉内存带来的收益。
后端支持:并非所有注意力后端都支持量化 KV 缓存。请参考 注意力后端 了解哪些后端支持此功能。
支持的格式#
SGLang 支持以下量化 KV 缓存格式
FP8 格式#
OCP (Open Compute Project) 规定了两种通用的 8 位浮点格式
E5M2 (5 位指数,2 位尾数):动态范围更大 (±57344.0),精度较低
E4M3 (4 位指数,3 位尾数):精度更高,动态范围较小 (±240.0)
FP4 格式#
警告
FP4 量化目前处于实验阶段。
OCP (Open Compute Project) 规定了 MXFP4 (Microscaling FP4),这是一种 4 位浮点格式
E2M1 (1 位符号位,2 位指数,1 位尾数):使用基于块的微缩放(microscaling),其中张量被划分为连续元素的块,每个块共享一个 8 位指数缩放因子。虽然 OCP 规定块大小为 32 个元素,但 SGLang 当前在 KV 缓存量化中的实现使用 16 个元素的块。
用法#
启用量化 KV 缓存#
要启用量化 KV 缓存,请在启动服务器时使用 --kv-cache-dtype 参数
# Enable FP8 E5M2 KV cache
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-R1-0528 \
--kv-cache-dtype fp8_e5m2 \
# Enable FP8 E4M3 KV cache
python3 -m sglang.launch_server \
--model-path deepseek-ai/DeepSeek-R1-0528 \
--kv-cache-dtype fp8_e4m3 \
# Enable FP4 E2M1 KV cache
python3 -m sglang.launch_server \
--model-path nvidia/DeepSeek-R1-0528-NVFP4 \
--kv-cache-dtype fp4_e2m1 \
缩放因子#
FP8 量化需要缩放因子来正确地对 KV 缓存进行量化和反量化。
注意
目前仅支持每张量(per-tensor/标量)缩放因子。
缩放因子可以通过以下方式获取:
从检查点(checkpoints)加载:预量化模型(例如 ModelOpt)可能包含会自动加载的
k_scale和v_scale参数通过 JSON 提供:通过
--quantization-param-path提供缩放因子。
JSON 文件应遵循以下格式
{
"kv_cache": {
"dtype": "float8_e4m3fn",
"scaling_factor": {
"0": {
"0": 1.0,
"1": 1.0
}
}
}
}
其中 scaling_factor 的外层键是张量并行(TP)秩,内层键是层索引。
警告
如果未提供缩放因子且在检查点中未找到,将默认使用 1.0,这可能会导致精度问题。
提示
FP4 (MXFP4):与 FP8 不同,FP4 量化在量化和反量化过程中自动实时处理缩放因子。不需要预量化模型或外部缩放因子文件——基于块的缩放因子是根据需要动态计算的。
性能考量#
内存节省#
量化 KV 缓存提供了显著的内存节省
BF16 → FP4:支持比 BF16 多约 3.56 倍的标记(考虑到缩放因子的开销)
注意
FP4 和 FP8 量化需要额外的内存来存储基于块的缩放因子,这与单纯的位宽减少相比,降低了实际的内存节省。块大小为 16 的 FP4 支持的标记数量约为 FP8 的 1.78 倍,约为 BF16 的 3.56 倍。FP8 与 BF16 之间的相对标记容量可以从这些比例中推导出来。
这使得在相同的内存预算下,可以实现更长的上下文长度或更多的并发请求。
精度影响#
FP8 精度#
FP8 E4M3 量化通常引入极小的精度损失。其影响取决于模型架构、序列长度和量化格式(通常 E4M3 的精度优于 E5M2)。
FP4 精度#
FP4 (MXFP4) 量化在显著节省内存的同时,其精度影响因模型大小和数据集复杂度而异。来自 PR #10078 (MLA) 和 PR #12612 (MHA) 的初步精度测试结果显示:
大型模型(例如 Qwen3-235B-A22B, DeepSeek-R1-0528)
在大型模型上,FP4 保持了接近 FP8/BF16 的精度,尤其是在简单的数据集上
模型 |
数据集 |
KV16 |
KV8 (FP8 E4M3) |
KV4 (FP4 E2M1) |
|---|---|---|---|---|
Qwen3-235B-A22B |
gsm8k |
0.9168 |
0.9181 |
0.9186 |
Qwen3-235B-A22B |
aime25 |
0.7733 |
0.7333 |
0.6000 |
Qwen3-235B-A22B |
gpqa_diamond |
0.7010 |
0.6899 |
0.6778 |
DeepSeek-R1-0528 |
gsm8k |
0.9157 |
0.9154 |
0.9124 |
DeepSeek-R1-0528 |
aime25 |
0.5067 |
0.4934 |
0.4000 |
DeepSeek-R1-0528 |
gpqa_diamond |
0.7707 |
0.7697 |
0.7273 |
较小型模型(例如 GPT-OSS-120B)
在较小型模型上,FP4 显示出更明显的精度下降,特别是在具有挑战性的数据集上
模型 |
数据集 |
KV16 |
KV8 (FP8 E4M3) |
KV4 (FP4 E2M1) |
|---|---|---|---|---|
GPT-OSS-120B |
gsm8k |
0.9161 |
0.9163 |
0.9152 |
GPT-OSS-120B |
aime25 |
0.7533 |
0.7667 |
0.3533 |
GPT-OSS-120B |
gpqa_diamond |
0.5081 |
0.5434 |
0.3202 |
关键结论
简单数据集(如 gsm8k):在不同规模的模型中,FP4 均能保持接近 FP8/BF16 的精度
模型大小至关重要:大型模型(200B+ 参数)通常比小型模型更能容忍 FP4 量化
上下文长度:在长上下文场景中,精度下降可能更为明显,因为量化误差的累积可能会变得显著。
提示
请针对您的特定模型和工作负载评估 FP4 的精度。处理简单任务的大型模型通常显示出极小的下降,而小型模型或复杂的推理任务可能需要 FP8 或 BF16 才能获得可接受的精度。
最佳实践#
使用预量化模型:优先选择离线量化且检查点中包含缩放因子的模型。
选择正确的格式:使用
fp8_e4m3以获得更好的精度(推荐),使用fp8_e5m2以获得更大的动态范围,或使用fp4_e2m1以实现最大的内存节省(实验性)检查后端兼容性:核实您选择的注意力后端是否支持量化 KV 缓存