【模型优化】量化
量化简介
你看原始信号就是模拟信号,如声音,但是我们要把真实世界的信号带到数字处理领域来,于是就得采样!所谓采样就是把握信号的主要部分,丢掉高频细节部分,真实世界可是一个超高精度的程序空间呀,因此我们要放到我们的计算机中来的话,就得降低精度存储进来了!对应的硬件电路如上图所示,就是高维现实空间跟低维程序空间的一个最底层最硬核的接口了!这些我们在大一就都学过的应该好理解的吧!总之,简单来说量化就是在原信号上的采样而已了!
就是把你一个layer的激活值范围的给圈出来,然后按照绝对值最大值作为阀值(因此当正负分布不均匀的时候,是有一部分是空缺的,也就是一部分- 值域被浪费了;这里有个小坑就是,假如我的激活址全是正的,没有负值,那么你怎么映射呢?),然后把这个范围直接按比例给映射到正负128的范围内来。
上面是简单的max-max 映射,这是针对均匀分布的,很明显的可以知道,只要数据分布的不是很均匀,那么精度损失是很大很明显的
举个极限的例子就是量化后原本int8的动态范围只剩1bit了(就是正的样本没有,负的全部扎堆在一个很小的值附近),就是上面说到的满屏马赛克~这种情况下。。。那还表示个毛的原信息啊!
于是很多情况下是这么干的:
像上图这样,先找一个阀值T,然后低于最低阀值的就全部都饱和映射到-127上,如上图的左边的三个红色的点就是这么处理的。
怎么寻找T
NVIDIA选择的是KL-divergence,其实就是相对熵,那为什么要选择相对熵呢?而不是其他的别的什么呢?因为相对熵表述的就是两个分布的差异程度,放到我们的情境里面来就是量化前后两个分布的差异程度,差异最小就是最好的了~因此问题转换为求相对熵的最小值!
对于模型的每一层来说:
- 第一步就是得到该layer激活值的直方分布图。
- 在不同的截断阀值下产生许多的量化分布。
- 然后选择KL距离最小的阀值。
- 获取分布
我们只能采用有限的采样率,这里TensorRT取的2048bins,而maxnet则取的是4000bins(仅正半轴),bins越多,优点是找到的饱和阀值更好,但是缺陷是在迭代搜索饱和阀址时计算更慢
- 获取截断阈值
英伟达只考虑正半轴的分布,因为用relu函数激活,输出肯定大于0,

查看26道真题和解析