1、基本概念
量化就是将浮点型实数量化为整型数(FP32->INT8)
反量化就是将整型数转化为浮点型实数(INT8->FP32)
2、量化操作
比如有一个FP32的浮点型数字x=5.234,将这个数变为整型。这个数字乘以一个量化系统s,比如s=100,那么量化后的值,然后对这个数字进行四舍五入(round操作)
整型INT8的范围是[-128,127],无符号INT8的范围也才[0,255]。所以需要进行截断,假设INT8范围是,那么上述可以变为:
这样计算方式不对
3、基于线性量化的对称量化和非对称量化
可以看上图,左边是非对称量化,右边是对称量化。对称量化的实数0也对应着整数的0,而非对称量化的实数0不一定对应着整数0,而是z。对称量化实数的范围是对称的[-a,a],而非对称量化的则不对称
。对称量化整数的范围是对称的[-127,127],而非对称量化的则不对称[-128,127]。
需要说明一点,不论是非对称还是对称量化,是基于线性量化的一种。线性量化将FP32映射到INT8数据类型,每个间隔是相等的,而不相等的就称为非线性量化。
4、对称量化
量化系数s需要根据实际数据分布来计算。
a代表当前输入数据分布中的实数最大值,因为是对称,因此实际范围是[-a,a]。对于对称量化,假设当前根据权重分布,选取的a为4,那么s=127/a=127/4=31.75。
在反量化的时候需要反向操作一番,将量化后的结果乘以1/s重新变为浮点型。
一般量化过程中,有pre-tensor和pre-channel两种方式,pre-tensor对于同一块输入(比如某个卷积前的输入tensor)采用一个scale,该层所有的输入数据共享一个scale值;pre-channel一般是作用于权重,比如一个卷积的权重维度[64,3,3,3](输入通道为3,输出通道为64,卷积核3x3),pre-channel会产生64个scale值,分别作用于该卷积权重参数的64个通道。
5、卷积操作量化
矩阵相乘可表示Y=XW,X为输入,W为权重,Y为输出。偏置bias一般可以去掉,对精度影响也不大,所以就先不考虑了。
注意看上图输入X的维度为[m,p],而W的维度为[p,n],因此i的范围为[0,m),k的范围为[0,p)。这里的输入和权重都是FP32精度,也就是实数。把矩阵公式细粒度拆成一个一个计算,也就是行和列每个元素相乘然后求和。
首先是最左边,和
分别代表浮点型的输入和权重,i代表第i行,k代表第k行,因此
代表第i行,第k列的元素,
同理。两者相乘求和可以得到
,可以看到这里求和的范围是p,k从1到p变化。
和
分别代表输入的第i行的scale和权重的第j列的scale值,这样输入的每一行必须共享scale,而权重的每一列也必须共享scale。下图左边的kernel矩阵,每一行代表一个输出通道的kernel集合(这里因为输入图像是三通道的,因此kernel有三个,不同颜色代表一个kernel)