谷歌的量化白皮书(Quantizing deep convolutional networks forefficient inference: A whitepaper)绝对是模型量化入门学习的必读资料,回顾自己在量化工作中踩的一些坑,十分后悔没有提前阅读这个资料,否则对于一个刚做模型量化的小白来说,很多不必要的坑可以规避,而且更能对量化这件事有一个整体的理解。下面一起大致回顾一下这个小编认为的入门必读的文章。(文章只是对一些小编认为比较重要的部分进行介绍,更希望读者能自行再读一下原文)
1、为什么要做模型量化
深度神经网络在终端设备当中的应用越来越广泛。终端设备的硬件条件限制,比如功耗,内存的限制,而且对实时性的要求一般也比较高。这就要求在终端的网络能够在有限的硬件资源下,实现高精度的更快速推理。而模型量化可以大幅度减少模型推理的内存并且大幅度提高推理速度,并且带来更低的功耗。模型量化是端侧模型部署的一个十分重要的手段。
2、量化设计
2.1 Uniform Affine Quantizer
Uniform Affine Quantizer你可以翻译成均匀放射量化,就是把一个浮点的范围区间均匀的映射到一个的整型区间。对于8bit的量化, = 256. 一般也把这种量化叫做均匀非对称量化。有两个量化参数决定这种量化方法,Scale () 我们一般称作缩放系数,或者叫做step size也就是量化步长,还有一个参数叫zero piont(), 零点,或者叫做offset偏置,这个参数代表了对于float的0值,对应的量化整型值;对于卷积中的多数padding操作一般都会进行补零, 这样保证了对于0值的量化不会出错。
a. 量化过程:
当和确定好了,那么量化过程就可以用以下公式表示。
公式(1)是根据量化参数,把float范围的值,线性均匀映射到整型范围。而公式(2)对量化后的整型值进行范围限制。范围限制在。
b. 反量化过程:
反量化过程可以用以下公式表示:
c. 端侧的计算过程:
拿一个简单的Conv2d举个例子:
这里简单解释一下上面的公式,别看的那么一长串觉得很复杂,其实就是中学的数学计算。k, l, m, n是维度参数,weight的shape是(out_channel, out_channel, kernel_size_w, kernel_size_h)。 用符号conv表示卷积操作,括号里面就是多项式的乘法分解。
可以看到上面的公式中,由于零点值,计算量多出了红色部分,和绿色部分。绿色部分还好,因为是提前知道的,可以提前计算好,而红色部分在推理过程中,计算量是会随着通道维度以及feature map的尺寸变大而变大的。虽然这种非对称量化对于8bit的量化精度会保持的不错,但是计算量也比下面的对称量化多出了划线部分。
2.2 Uniform symmetric quantizer
Uniform symmetric quantizer你可以翻译成均匀对称量化。对于对称量化,我们把zero point设置为0。
a. 量化过程:
一般对称量化都是有符号的量化。
b. 反量化过程:
2.3 Stochastic quantizer
Stochastic quantizer可以翻译成随机量化。随机量化其实就是在量化时,先对输入的浮点值加上一个(-0.5, 0.5)之前的随机值,然后再进行去整操作。
a. 量化过程:
反量化过程和公式(3)一样。增加一个随机参数可以防止量化权重产生饱和越界,一般在计算梯度的时候有作用。但是对于推理来说,大多数硬件并不支持。
2.4 Modeling simulated quantization in the backward pass
在训练中模拟量化过程,其实就是 Quantization-aware training,量化感知训练。在训练中插入伪量化节点,用来模拟量化。伪量化节点包括,量化和反量化过程。
因为在量化的过程中,会有取整的操作,而对于取整操作,导数为0. 因此不能直接对量化节点输出的参数求梯度,而是需要采用一种近似的方法求梯度,对输入量化节点的参数求梯度,一般称作“直通估计”(straight through estimato).
如上图所示,上面的是为量化节点的输出,下面的是近似值。
2.5 Granularity of quantization
Granularity of quantization可以叫做量化粒度。对于整个一层的权重只使用一个scale和zero point进行量化的方式,一般叫做per-layer量化或者叫per-tensor量化。如果对于每一个卷积核(以输出通道数衡量, 比如对于权重weight shape (c_out, c_in, kernel_size, kernel_size), 通道数就是c_out),都有对应的scale和zero point,这种量化方式叫做per-channel量化。一般不对激活值做per-channel的量化,因为如果激活值也做per-channel的量化,激活值和权重做卷积操作会非常复杂。
至此,介绍完了量化的基本知识,这也是白皮书中个人认为最重要的部分,了解了这些就基本知道了量化的基础知识。白皮书中剩余的部分包括量化推理和性能和准确率,量化方式,以及一些实验,和量化建议等,将在一篇文章中说明。