梯度量化
参考:
http://on-demand.gputechconf.com/gtc/2017/presentation/s7310-8-bit-inference-with-tensorrt.pdf
目标:将FP32的数据转换为INT8,并且精度不会降低很多
为什么:INT8有更高的吞吐量,更低的内存占用
挑战:INT8精确度低的问题
解决办法:在量化训练好的模型参数和计算的时候最小化信息损失
结果:TensorRT已经搞定了这些
量化 原理
一句话原理
将fp32的卷积(相乘)转换为int8的卷积(相乘)
A = scale_A * QA + bias_A
B = scale_B * QB + bias_B
AB = scale_A scale_B QA\QB +
scale_A *QA+ bias_B +
scale_B *QB + bias_A +
bias_A * bias_B
英伟达通过实验说不要偏置也没有影响
A = scale_A * QA
B = scale_B * QB
AB = scale_A QA*scale_B * QB
线性量化
将FP32的值线性映射到一个-127~127之间的数 ,具体的做法是将参数从小到大排列,然后平均分成255份,最小的那一份的数对应-127,次小的那一份数对应-126…
饱和量化
将fp32过大过小的值去掉,再执行线性映射
如何找到合适的阈值
- 收集不同样本计算下参数的直方图 ,比如某一层resnet_52_conv
- 产生很多阈值,将FP32的值映射到int8
- 让不同阈值的FP32激活值分布和INT8激活值做KL_divergence,选出该最小对应的阈值
如何做KL散度
$$KL = min(H(P)-H(Q))$$,P为参考样本,Q为int8计算之后的样本
LK_divergence具体是怎么做的?
小目标检测中,转tensorrt精度会有很大的损失,原因是系统把红绿灯那一小块卷积后的结果当成噪点处理了,被截断,这是猜想
- 不断阶段参考样本,从128开始
- 将截断外的数值求和
- 将2中得到的值添加到阶段样本P之后
- 求样本P的概率分布
- 创建样本Q,它是从P的INT8量化
- 将样本Q拉伸到和P一样长
- 计算Q的概率分布
- 求P,Q的KL散度,得到T