多 Batch 量化校准与单 Batch 校准的数值差异
——从 GPU 浮点计算与并行归约谈起
一、量化校准在做什么?
无论是 PTQ 还是 QAT,量化校准阶段的核心目标都是:
统计中间激活值的数值分布
根据统计结果确定量化参数(scale / threshold / zero-point)
常见统计方式包括:
min / max
percentile / KL / MSE
二、单 Batch 与多 Batch 校准的计算路径差异
1. 单 Batch 校准(batch_size = 1)
单 batch 校准的特征是:
每次前向仅包含一个样本
激活值逐样本进入统计逻辑
数值计算顺序相对固定
浮点累加路径简单、稳定
在这种模式下,统计结果通常具有较好的稳定性与可复现性。
2. 多 Batch 校准(batch_size > 1)
同一层的激活值在 batch 维度上同时参与统计
GPU 会对 batch 维度进行并行归约(parallel reduction)
数值的累加顺序不再是线性的
这一变化是理解后续数值差异的关键。
三、一个关键事实:浮点加法不严格满足结合律
1. 数学加法 vs 浮点加法
在数学意义上:
(a + b) + c = a + (b + c)
一个重要事实是:
浮点加法在多项累加时,结果依赖于计算顺序。
2. 一个具体的数值例子
a = 1e20
b = -1e20
c = 1
顺序一:先抵消大数
= 0 + 1
= 1
顺序二:小数先参与累加
≈ a + (-1e20)
= 0
结果不同。
原因在于:
- 1e20 的数量级远大于 1
- 在有限精度浮点表示中,1 已经小到无法影响 1e20 的最低有效位
小数值在与大数相加时会被舍入“吞掉”
四、为什么 GPU 上更容易出现这种差异?
1. 并行归约改变了加法顺序
((x0 + x1) + (x2 + x3)) + ...
而不是严格的顺序累加:
x0 + x1 + x2 + x3 + ...
并行归约的结构会随着以下因素发生变化:
batch_size
block / warp 划分
kernel 调度方式
因此:
即使代码不变,batch 改变也可能导致数值累加顺序发生变化。
2. 混合精度进一步放大数值差异
在实际推理与校准中,GPU 还可能使用:
FP16 / BF16
Tensor Core / FMA
较低的数值精度会使小数值更容易在累加中被舍入,从而进一步放大统计差异。
五、量化 scale 为什么会因此发生变化?
1. 单 Batch 校准中的统计特性
在单 batch 校准中:
- 激活值是逐样本、顺序累加进入统计逻辑的
min / max / 的更新顺序是确定的
浮点舍入行为稳定
因此,统计到的激活分布具有较强的稳定性。
2. 多 Batch 校准中的统计特性
在多 batch 校准中:
- 同一层多个样本的激活值同时参与统计
GPU 通过并行归约完成累加或比较
浮点累加顺序不确定
这会导致:
max / min 可能出现微小差异
histogram 中各 bin 的累计值略有偏移
六、从工程角度如何理解这一现象?
从工程视角看,可以将这一现象归结为:
多 batch 校准改变了浮点统计的并行归约路径,而浮点加法在多项累加中不具备严格的顺序不变性,因此统计结果存在差异是符合预期的。
七、总结
单 batch 与多 batch 校准在逻辑上等价
在数值实现层面并非严格等价
GPU 并行归约会改变浮点累加顺序
浮点计算不严格满足结合律
校准统计结果因此可能发生变化
在数值敏感模型上,这种变化会体现为量化精度差异