阅读笔记:Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference

模型量化 同时被 2 个专栏收录
2 篇文章 0 订阅
3 篇文章 0 订阅

论文pdf:https://arxiv.org/abs/1712.05877
github:https://github.com/google/gemmlowp

1、论文中提出的问题即所解决的问题

  尽管已经有很多量化方法,但在做到高准确率的同时还能权衡推理延时的非常欠缺。

  • 以前的方法没有在合理基准的网络架构上评估,之前都是在过参数化严重的网络例如AlexNet等等。

  • 许多方法在实际硬件上并不能提升效率。(The rising popularity of intelligent mobile devices and the daunting computational cost of deep learning-based models call for efficient and accurate on-device inference schemes)这句话没理解,什么叫操作数比较宽的时候,乘法消失是啥意思。

2、创新点

  • 提出一种量化方案,只有整数计算,既量化权重也量化激活值。

  • 提出了一个量化推理框架,可以高效地部署到只有整数计算的硬件设备上,例如高通Hexagon。

  • 提出了一个量化训练的方案,基于最小化acc的损失。

3、重要的相关论文

  灵感的来源:

  • S. Gupta, A. Agrawal, K. Gopalakrishnan, and P. Narayanan. Deep learning with limited numerical precision. In Proceedings of the 32nd International Conference on Machine Learning (ICML-15), pages 1737–1746, 2015.

  • V. Vanhoucke, A. Senior, and M. Z. Mao. Improving the speed of neural networks on cpus. In Proc. Deep Learning and Unsupervised Feature Learning NIPS Workshop, volume 1, page 4, 2011

4、具体实现

4.1 量化推理

4.1.1量化方案

r = S ( q − Z ) (1) r = S(q-Z) \tag{1} r=S(qZ)(1)
  bias vectors是量化到32bit的整型值。S是浮点值,Z是整型值,和q同数据类型,是实数0对应的量化值。

4.1.2只包含整形运算的矩阵乘

  将两个矩阵的乘法表示为 r 3 = r 1 r 2 r_3=r_1r_2 r3=r1r2(忽略了bias,有BN层的网络conv的bias一般都是false),则可以将矩阵乘表示成如下公式:
S 3 ( q 3 ( i , k ) − Z 3 ) = ∑ j = 1 N S 1 ( q 1 ( i , j ) − Z 1 ) S 2 ( q 2 ( j , k ) − Z 2 ) (2) S_3(q_3^{(i,k)} - Z_3) = \sum_{j=1}^N S_1(q_1^{(i,j)} - Z_1)S_2(q_2^{(j,k)} - Z_2) \tag{2} S3(q3(i,k)Z3)=j=1NS1(q1(i,j)Z1)S2(q2(j,k)Z2)(2)
  进一步整理为:
q 3 ( i , k ) = Z 3 + M ∑ j = 1 N ( q 1 ( i , j ) − Z 1 ) ( q 2 ( j , k ) − Z 2 ) (3) q_3^{(i,k)} = Z_3 + M\sum_{j=1}^N (q_1^{(i,j)} - Z_1)(q_2^{(j,k)} - Z_2)\tag{3} q3(i,k)=Z3+Mj=1N(q1(i,j)Z1)(q2(j,k)Z2)(3)
  其中M为:
M : = S 1 S 2 S 3 (4) M:=\frac{S_1S_2}{S_3}\tag{4} M:=S3S1S2(4)
  到目前为止,除了M其他都是整型。作者发现M总是在0到1之间的数。于是将M表示为如下形式:
M = 2 − n M 0 (5) M = 2^{-n}M_0\tag{5} M=2nM0(5)
  个人理解这个 M 0 M_0 M0类似于计算机组成原理中的归一化定点小数(根据具体硬件可以是32位或16位)。其实这个定点小数就是用整型表示,到时还是整型运算,结合移位运算(这种移位操作涉及到四舍五入),这样就把关于M的运算变成了整型。

4.1.3对零点的高效处理

  观察公式(3)可以发现一次计算需要2N次减法,那么对于两个N*N的矩阵相乘则要 2 N 3 2N^3 2N3次,为此可以将(3)式中的乘法展开,即:
q 3 ( i , k ) = Z 3 + M ( N Z 1 Z 2 − Z 1 a 2 ( k ) − Z 2 a ˉ 2 ( i ) + ∑ j = 1 N q 1 ( i , j ) q 2 ( j , k ) ) (6) q_3^{(i,k)} = Z_3 + M(NZ_1Z_2-Z_1a_2^{(k)}-Z_2\bar{a}_2^{(i)}+\sum_{j=1}^N q_1^{(i,j)}q_2^{(j,k)})\tag{6} q3(i,k)=Z3+M(NZ1Z2Z1a2(k)Z2aˉ2(i)+j=1Nq1(i,j)q2(j,k))(6)
  其中,:
a 2 ( k ) : = ∑ j = 1 N q 2 ( j , k ) , a ˉ 1 ( i ) : = ∑ j = 1 N q 1 ( i , j ) . (7) a_2^{(k)}:=\sum_{j=1}^Nq_2^{(j,k)},\bar{a}_1^{(i)}:=\sum_{j=1}^Nq_1^{(i,j)}.\tag{7} a2(k):=j=1Nq2(j,k),aˉ1(i):=j=1Nq1(i,j).(7)
  这样下面部分就和无零点的量化方式类似了。
∑ j = 1 N q 1 ( i , j ) q 2 ( j , k ) (8) \sum_{j=1}^Nq_1^{(i,j)}q_2^{(j,k)}\tag{8} j=1Nq1(i,j)q2(j,k)(8)

4.1.4层的融合

  主要讲融合偏置和激活函数(不是单纯的融合,要考虑到训练和推理的一致性)。代码参见(https://github.com/google/gemmlowp)[gemmlowp]

  首先是偏置的融合,公式(8)中的累加采用一个有符号的32整数来保存累加的值。对于偏置则采用的也是有符号32位整数,假设偏置为 q 4 q_4 q4,则可表示为如下:
∑ j = 1 N q 1 ( i , j ) q 2 ( j , k ) + q 4 (9) \sum_{j=1}^Nq_1^{(i,j)}q_2^{(j,k)} + q_4\tag{9} j=1Nq1(i,j)q2(j,k)+q4(9)

  逆推回去,也就相当于是bias采用的如下量化:
r 4 = S 1 S 2 ( q 4 − 0 ) (10) r_4 = S_1S_2(q_4-0)\tag{10} r4=S1S2(q40)(10)

  bias采用32bit的量化,其一是bias在网络中占比很小,其二是bias将加在所有输出上,bias上的量化误差将带来整体误差,对精度不好。

  完成公式(9)的计算后就得到了一个32位的整型,然后通过参数M又转换到uint8,这里的saturating cast to uint8还不是非常理解。

  随后是融合激活函数,这里只讲了单纯是截取的这类激活函数。前面已经saturate到了 [ 0 , 255 ] [0,255] [0,255],那么激活函数就是在 [ 0 , 255 ] [0,255] [0,255]上取个子区间。而实际量化训练中,网络倾向于保留整个 [ 0 , 255 ] [0,255] [0,255],也就是说激活函数不起作用了,已经包含在前面saturate到 [ 0 , 255 ] [0,255] [0,255]上了。

4.2模拟量化训练

  PTQ训练有两个不好的地方,第一点就是不同的channel因为权重范围的不一样(而上一章中说道所有channel都使用一样的分辨率,因此小range的channel会有较高的相对误差)。第二就是离群值使得表示精度低。于是这里采用的QAT的方法,前向模拟量化的过程,反向则按正常的方式。

  量化的位置:

  • 权重量化发生在卷积前,如果有bn层则先进行融合再量化。

  • 激活值则在激活函数之后或者是concat之后。

  量化的公式:
c l a m p ( r ; a , b ) : = m i n ( m a x ( x , a ) , b ) s ( a , b , n ) : = b − a n − 1 q ( r ; a , b , n ) : = ⌊ c l a m p ( r ; a , b ) − a s ( a , b , n ) ⌉ s ( a , b , n ) + a , (11) clamp(r;a,b):=min(max(x,a),b)\\s(a,b,n):=\frac{b-a}{n-1}\\q(r;a,b,n):=\lfloor\frac{clamp(r;a,b)-a}{s(a,b,n)}\rceil s(a,b,n)+a,\tag{11} clamp(r;a,b):=min(max(x,a),b)s(a,b,n):=n1baq(r;a,b,n):=s(a,b,n)clamp(r;a,b)as(a,b,n)+a,(11)

4.2.1量化参数的学习:

  • 对于权重,取 a : = min ⁡ w , b : = max ⁡ w . a:=\min w,b:=\max w. a:=minw,b:=maxw.还采用了个小技巧,也就是对称量化,量化到 [ − 127 , 127 ] [-127,127] [127,127],不取-128这个值,在附加材料B中有说明。bias不进行量化,因为作者认为bias由浮点值量化到32位整型值损失不大,这个可以不用模拟量化。

  • 对于激活值,则采用EMA(指数移动平均)来更新a和b。前期先禁用激活量(例如50,000到2,000,000个steps),后面稳定了再开启。

    对于这两种方式,都要满足能够将数值0.0非常精确地表示为一个整型值。

4.2.2bn层的折叠

w f o l d : = γ w E M A ( σ B 2 ) + ϵ (12) w_{fold} := \frac{\gamma w}{\sqrt{EMA(\sigma_B^2)+\epsilon}}\tag{12} wfold:=EMA(σB2)+ϵ γw(12)
  这里比较重要的一点就是在训练的过程中,得先卷积然后统计得到均值方差才能得到折叠后的权重,然后再量化并使用折叠卷积进行前向,也就是附加材料中的图C.8。

在这里插入图片描述

4.3附加材料

4.3.1 分层的细节

  激活层,tanh sigmoid softmax这些函数都在gemmlowp中用定点运算来重新实现了。

  addition和concat,都面临要rescale的问题。为此提出这样的要求,假如需要这个操作,那么在训练时让他们的sacale一样。

4.3.2 arm neon的细节

  round操作在arm neon上没有对应的指令,这里还提了-128不使用的好处。

5. 总结

  这篇论文解释清了我对于量化在推理过程中具体是什么样子的疑惑。文中多次提到gemmlowp这个库,应该是具体结合了卷积优化的。

  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值