模型量化:INT8/INT4 推理加速
FreeGuideOnline
最新
2026-07-02
r = S * (q - Z)
其中:
- **r**:原始浮点值
- **q**:量化后的整数值(如 INT8)
- **S**:缩放因子(scale),浮点数
- **Z**:零点(zero-point),整数值,用于对齐浮点 0
这个映射将浮点范围 `[r_min, r_max]` 线性映射到整数范围 `[q_min, q_max]`。INT8 的 `q_min = -128`,`q_max = 127`(有符号)或 `[0, 255]`(无符号)。
量化分为两种主要策略:
- **训练后量化**:无需重新训练,直接对预训练模型进行校准得到 S 和 Z,然后执行推理。
- **量化感知训练**:在训练过程中模拟量化误差,让模型学会适应低精度,从而保持更高的精度。
## INT8 量化
INT8 量化是目前工业界应用最广泛的方案。它将 32 位浮点权重和激活值都转换为 8 位整数,计算时使用整数矩阵乘法,结果再反量化为浮点。
### 对称量化与非对称量化
- **对称量化**:假设浮点值关于 0 对称分布,将零点 Z 固定为 0,仅使用一个缩放因子 S。计算效率更高。
- **非对称量化**:充分利用整数表示范围,允许零点偏移,能更好地覆盖偏置型分布(如 ReLU 激活输出均大于 0 的情况)。
大多数推理框架默认使用**对称量化**进行权重转换,激活值采用**非对称量化**以覆盖动态范围。
### 逐通道量化与逐张量量化
- **逐张量量化**:整个张量使用同一个 scale 和 zero-point。实现简单但容易因为通道间数值范围差异大而引入误差。
- **逐通道量化**:每个输出通道单独计算 scale 和 zero-point。尤其适用于卷积层的权重,能显著提升精度,几乎不影响推理速度。
### INT8 的校准过程
训练后量化需要一个小型校准数据集(通常几百张代表性图片或句子)来统计激活值的动态范围。常见方法:
- **Max-Min**:直接取 `[min, max]` 作为范围,对异常值敏感。
- **MovingAverageMinMax**:运行多个 batch,滑动统计 min/max,更鲁棒。
- **KL 散度**:收集激活值的直方图,选择能最小化原始分布与量化分布之间 KL 散度的阈值,能有效剪裁长尾离群点。
- **均方误差**:搜索阈值使得量化前后张量的 L2 误差最小。
以 TensorRT 为例,它内置了上述多种校准器,用户只需提供校准集即可自动完成 INT8 量化。
### INT8 推理加速原理
现代 CPU 支持 AVX-512 VNNI 指令,GPU 有 Tensor Core 的 INT8 模式,移动端有 ARM NEON、Hexagon DSP 等。这些硬件单元可以直接完成 8 位整数的乘加运算,一个时钟周期内处理多路数据,理论峰值算力远高于 FP32。例如 NVIDIA A100 的 INT8 Tensor Core 算力可达 624 TOPS,而 FP32 仅有 19.5 TFLOPS。
## INT4 量化
INT4 进一步将位宽减半,能带来更极致的压缩和可能更高的计算吞吐量,但精度损失风险也更大。
### INT4 的两种形式
- **纯 INT4 权重**:权重以 4 位整数存储,但计算时往往需要解压为 INT8 甚至 FP16 进行运算。目前大部分硬件没有原生 INT4 矩阵乘法单元,因此 INT4 主要用于减少内存占用和传输带宽。
- **INT4 矩阵乘法**:部分下一代芯片(如 NVIDIA H100 的 FP8/INT4 Tensor Core)开始支持 INT4 计算。软件层面,一些定制库也通过 bit-serial 计算实现 INT4 加速。
### 分组量化
为了在低位宽下保持精度,INT4 量化几乎必须采用更细粒度的分组策略。比如将权重矩阵的每 128 个元素分为一组,每组有独立的 scale 和 zero-point。这增加了额外存储,但可以显著抑制量化噪声。
### 常见 INT4 量化方案
- **GPTQ**:针对大语言模型的训练后量化方法,基于 OBQ 的近似算法,一次性使用权重的 Hessian 信息进行逐列量化。
- **AWQ**:观察到权重中少量“显著通道”对精度影响巨大,通过按比例缩放这些通道来减小量化误差,计算效率很高。
- **GGUF/GGML**:在 llama.cpp 生态中广泛应用,支持多种位宽(包括 INT4)的分块量化,使得大模型能在消费级硬件上运行。
### INT4 部署实践
对于大语言模型,使用 INT4 量化可以在保持可接受性能的情况下将 7B 模型压缩到 4GB 以下,从而在笔记本电脑甚至手机端侧运行。常用工具链:
```python
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
model_id = "meta-llama/Llama-2-7b-chat-hf"
quantization_config = BitsAndBytesConfig(load_in_4bit=True,
bnb_4bit_compute_dtype=torch.float16)
model = AutoModelForCausalLM.from_pretrained(model_id,
quantization_config=quantization_config,
device_map="auto")