3、量化核心概念:量化定义、定点与浮点、量化误差、量化粒度(per-tensor/per-channel/per-group)

量化(Quantization)是将高精度数值(通常是 FP32/FP16)映射到低精度数值(如 INT8/INT4)的过程,其本质是用更少的比特位表示神经网络中的权重和激活值。在 vLLM 推理引擎中,量化直接决定了显存占用、吞吐量和输出质量之间的平衡。理解量化定义、定点与浮点差异、误差来源以及粒度选择,是掌握 vLLM 量化推理的第一步。本节将系统拆解这四个核心概念,并结合实际推理场景说明其工程意义。

量化核心概念关系图 量化定义 FP32/FP16 → INT8/INT4 定点与浮点 定点:固定小数位,硬件友好 浮点:动态范围大,计算复杂 量化本质:浮点→定点映射 量化误差 舍入误差:数值精度丢失 截断误差:范围溢出/欠覆盖 影响:模型精度下降 量化粒度 per-tensor:整层一个scale,最粗 per-channel:每通道一个scale,较细 per-group:分组共享scale,最灵活 推理影响 显存占用↓ 吞吐量↑ 延迟↓ 精度可能↓ 需权衡精度与性能 vLLM 量化决策 根据模型/硬件/精度要求 选择合适粒度与校准策略

3.1 量化定义:从连续到离散的映射

量化在数学上定义为一个映射函数:Q(r) = round(r / S) + Z,其中 r 是原始浮点数值,S 是缩放因子(Scale),Z 是零点偏移(Zero Point)。反量化过程为 r ≈ S × (Q(r) - Z)。在 vLLM 中,量化通常应用于权重矩阵和激活张量,将 FP16 的 2 字节数据压缩为 INT8 的 1 字节或 INT4 的半字节,从而减少显存带宽压力。

从信息论角度看,量化是有损压缩。关键在于选择合适的 S 和 Z,使得映射后的分布尽可能接近原始分布。vLLM 支持多种量化方案,包括 GPTQ、AWQ、SqueezeLLM 等,它们的主要区别在于校准策略和误差补偿方式。例如,AWQ 通过观察激活值分布来保护重要权重通道,而 GPTQ 则基于 Hessian 矩阵进行二阶误差补偿。

核心要点:量化不是简单的数值截断,而是基于统计分布的优化映射。vLLM 中的量化配置(如 --quantization 参数)决定了使用哪种映射策略,直接影响最终模型质量。

3.2 定点与浮点:数值表示的本质差异

浮点数(如 FP32/FP16)采用科学计数法表示:(-1)^sign × mantissa × 2^exponent,动态范围大但硬件计算单元复杂。定点数则固定小数点的位置,例如 Q7.8 表示 7 位整数位加 8 位小数位,硬件实现简单但动态范围受限。量化推理的核心思想就是将浮点运算转换为定点运算,利用整数矩阵乘法单元(如 Tensor Core 的 INT8 模式)加速计算。

特性FP32FP16INT8INT4
位宽32 bit16 bit8 bit4 bit
动态范围~1e-38 ~ 3e38~6e-5 ~ 6e4-128 ~ 127-8 ~ 7
相对精度高中低极低
显存占用4 B2 B1 B0.5 B
计算速度慢中快最快

在 vLLM 推理中,权重通常以 FP16 加载,但可以通过量化层转换为 INT8/INT4 存储。激活值在推理过程中动态量化,需要额外的 Scale 和 Zero Point 参数。定点运算的优势在于:INT8 矩阵乘法在 NVIDIA GPU 上的吞吐量是 FP16 的 2~4 倍,而 INT4 配合特殊硬件(如 INT4 Tensor Core)可进一步提升。

注意:定点数表示范围有限,当权重或激活值超出量化范围时会产生截断误差。vLLM 的量化校准过程会统计张量的 min/max 值,但极端离群值(Outlier)会显著影响量化质量,这是实际部署中最常见的问题之一。

3.3 量化误差:来源分析与控制策略

量化误差主要来自三个方面:舍入误差(Rounding Error)、截断误差(Clipping Error)和量化分辨率不足。舍入误差是均匀分布的,期望值为 0,但方差与量化步长相关;截断误差发生在数值超出量化范围时,会导致梯度爆炸或激活值饱和;分辨率不足则表现为小数值被量化为 0,丢失细节信息。

控制量化误差的常用方法包括:

  1. 对称量化 vs 非对称量化:对称量化假设数据分布关于 0 对称,无需零点偏移;非对称量化更适合 ReLU 后的激活值分布。
  2. 校准数据集:使用少量真实样本统计张量分布,选择最优的 Scale 和 Zero Point。vLLM 支持通过 --calibration-dataset 指定校准数据。
  3. 误差补偿:GPTQ 使用 Hessian 矩阵进行权重更新补偿,AWQ 通过缩放显著通道来减少误差。
  4. 混合精度:对敏感层(如 attention 的 QKV 投影)保留 FP16,对不敏感层(如 FFN 的中间层)使用 INT8。
经验建议:在 vLLM 中部署量化模型时,建议先用小规模校准集(如 128~512 条样本)评估量化误差。如果精度下降超过 1%,可尝试更细粒度的量化(如从 per-tensor 改为 per-channel),或使用 AWQ 等更先进的量化算法。

3.4 量化粒度:per-tensor / per-channel / per-group

量化粒度决定了 Scale 和 Zero Point 的共享范围,是精度与计算复杂度之间的权衡。三种粒度的对比如下:

粒度共享范围额外参数精度计算开销适用场景
per-tensor整个张量1 组 Scale/ZP最低最低小模型、对精度不敏感
per-channel每个输出通道C 组(C 为通道数)中中权重量化,多数场景推荐
per-group每 G 个元素N/G 组高较高激活量化、低比特(INT4)

per-tensor 是最简单的实现,整个权重矩阵共享一个 Scale。对于分布均匀的权重(如经过 LayerNorm 后的值),效果尚可;但若权重存在明显的通道间差异,误差会放大。per-channel 为每个输出通道独立计算 Scale,能更好地适应不同通道的数值范围,是 vLLM 中 GPTQ 和 AWQ 的默认选择。per-group 进一步细化,将通道内的元素按固定大小分组(如 128 个一组),每组独立量化。这在 INT4 量化中尤为重要,因为 4 比特的表示范围极小,必须通过分组来降低误差。

工程实践:在 vLLM 中,--quantization-format 参数可控制量化粒度。例如,使用 gptq 时可通过 --group-size 设置分组大小(常见值为 128 或 64)。较小的 group-size 能提升精度,但会增加存储 Scale 参数的开销(每个组多 2 字节),需根据显存预算权衡。

3.5 案例拆解:LLaMA-7B 的 INT8 量化部署

假设我们要在 vLLM 中部署 LLaMA-7B 模型,目标是将显存占用从 FP16 的 14GB 降至 INT8 的 7GB,同时保持推理精度损失小于 0.5%。初始测试发现,直接使用 per-tensor 量化后,模型在 MMLU 基准上的准确率从 45.2% 降至 42.8%,损失 2.4%,远超预期。

分析过程:通过可视化权重分布,发现 LLaMA-7B 的 FFN 层权重存在明显的通道间方差差异——部分通道的数值范围是其他通道的 10 倍以上。per-tensor 量化使用全局 min/max,导致小数值通道被严重压缩,信息丢失。

解决方案:改用 per-channel 量化,并采用 AWQ 算法保护 1% 的显著权重通道。具体操作如下:

# 使用 AWQ 量化 LLaMA-7B
python -m vllm.entrypoints.llm \
  --model meta-llama/Llama-2-7b-hf \
  --quantization awq \
  --quantization-format per-channel \
  --calibration-dataset c4 \
  --calibration-samples 256 \
  --max-model-len 4096

结果对比:per-channel + AWQ 后,MMLU 准确率恢复至 44.9%,仅下降 0.3%。显存占用降至 7.2GB,推理吞吐量从 850 tokens/s 提升至 2100 tokens/s。代价是量化时间增加了约 15 分钟(校准过程),且模型文件增大了约 200MB(存储额外的 Scale 参数)。

复盘经验:对于 7B 以上模型,per-tensor 量化几乎不可用;per-channel 是精度与性能的最佳平衡点。若需进一步压缩至 INT4,建议使用 group-size=128 的 per-group 量化,并配合 GPTQ 的二阶补偿。

3.6 常见误区与总结

在实际使用 vLLM 量化功能时,以下误区需要特别注意:

  • 误区一:量化后必须微调。实际上,现代量化算法(如 AWQ、GPTQ)在大多数场景下无需微调即可保持精度,微调反而可能引入过拟合。
  • 误区二:校准集越大越好。校准集应具有代表性而非数量多,通常 128~512 条样本即可。过多样本会增加校准时间且可能过拟合到校准分布。
  • 误区三:所有层都适合量化。Attention 的 Softmax 输出和 LayerNorm 的 gamma/beta 参数通常保持 FP16,因为这些层对精度极其敏感。
  • 误区四:忽略零点偏移。对于非对称量化,零点偏移的精度同样重要,使用 INT32 存储零点可避免累积误差。