per-token、per-channel 和 per-tensor 量化的区别。这三种是模型量化中常见的不同粒度策略,主要区别在于它们应用量化的维度不同。以下是它们的详细对比:
1. 定义与核心区别
量化类型 | 量化维度 | 主要应用对象 | 计算粒度 | 典型场景 |
---|---|---|---|---|
Per-Tensor | 整个张量 | 权重/激活 | 所有数据共享一组 (scale, zero_point) | 简单硬件支持(如早期移动端) |
Per-Channel | 张量的每个通道 | 权重(如卷积/线性层) | 每个通道独立量化 | 卷积神经网络(CNN) |
Per-Token | 输入序列的每个token | 激活(如Transformer层) | 每个token位置独立量化 | Transformer/NLP模型 |
2. 详细说明
(1) Per-Tensor 量化
- 定义:
整个张量(tensor)使用同一组量化参数(scale和zero-point),是最粗粒度的量化方式。- 例如:一个
[B, C, H, W]
的权重张量,所有元素共用一组参数。
- 例如:一个
- 优点:
- 计算简单,硬件兼容性好(几乎所有设备支持)。
- 缺点:
- 若张量内数据分布差异大(如某些通道值范围远大于其他通道),量化误差显著。
- 用途:
- 早期移动端模型(如TensorFlow Lite的默认选项)。
(2) Per-Channel 量化
- 定义:
对张量的每个通道(channel)独立量化,常见于权重张量。- 例如:卷积权重
[out_c, in_c, kH, kW]
,每个输出通道(out_c
)有独立的(scale, zero_point)
。
- 例如:卷积权重
- 优点:
- 适应不同通道的数据分布,显著减少量化误差(尤其对CNN)。
- 缺点:
- 需要存储更多量化参数(每通道一组)。
- 部分低端硬件不支持(需特定加速器)。
- 用途:
- 卷积层(如PyTorch的
torch.quantize_per_channel
)。
- 卷积层(如PyTorch的
(3) Per-Token 量化
- 定义:
对输入序列的每个token(或时间步)独立量化,主要用于动态量化的激活值。- 例如:Transformer输入
[batch, seq_len, hidden_dim]
,每个seq_len
位置独立计算量化参数。
- 例如:Transformer输入
- 优点:
- 适应输入数据的动态变化(如不同token的激活范围差异大)。
- 缺点:
- 实时计算开销大(推理时需动态计算每token的参数量化)。
- 用途:
- Transformer激活值(如LLM推理时的INT8量化)。
3. 关键对比总结
特性 | Per-Tensor | Per-Channel | Per-Token |
---|---|---|---|
粒度 | 整个张量 | 每个通道 | 每个token |
适用对象 | 权重/激活 | 权重(静态) | 激活(动态) |
硬件支持 | 广泛支持 | 需专用支持 | 依赖框架优化 |
计算开销 | 低 | 中 | 高 |
典型误差 | 高 | 低 | 极低 |
4. 组合使用示例
实际部署中,这三种量化常结合使用:
- 权重:Per-channel静态量化(减少通道间分布差异)。
- 激活:Per-token动态量化(适应输入变化)。
- 兼容性:Per-tensor作为保底方案(老旧硬件)。
例如,在LLM(大语言模型)中:
- 线性层权重用 per-channel INT8量化。
- 注意力层的激活用 per-token INT8动态量化。
- 若硬件限制,回退到 per-tensor。
5. 选择建议
- 追求精度:Per-channel(权重) + Per-token(激活)。
- 追求速度:Per-tensor(兼容性优先)。
- 平衡方案:Per-group量化(折中粒度)。
通过合理选择量化粒度,可以在模型大小、推理速度和精度之间取得最佳平衡。