## 量化基础知识
一、概述
量化是指将神经网络前向推理过程中浮点数运算量化为整数运算,以达到计算加速的目的。
通常是指将float32转化为int8进行运算,这样做会有更小的模型体积,可将模型大小减少 4 倍;更快的计算速度,与float32计算相比,int8计算速度通常快 2 到 4 倍。
二、量化方法
- 非对称量化
非对称量化是通过收缩因子(scale) 和 零点(zero point) 将实数 [ R m i n , R m a x ] [R_{min},R_{max}] [Rmin,Rmax]分别映射到 [ 0 , 2 b − 1 − 1 0, 2^{b-1}-1 0,2b−1−1]的范围内,b 代表量化数值的bit数。 以int8量化为例, b = 8 b = 8 b=8。
如下图所示,将实数 [ R m i n , R m a x ] [R_{min},R_{max}] [Rmin,Rmax]量化到[0,255]范围内。
假设输入的浮点数范围为 ( R m i n , R m a x ) (R_{min}, R_{max}) (Rmin,Rmax),对8bits量化来说,scale和零点z的计算公式如下:
S = R m a x − R m i n ( 2 b − 1 ) = R m a x − R m i n 255 S= \frac{R_{max}−R_{min}}{(2^{b}-1)} = \frac{R_{max}−R_{min}}{255} S=(2b−1)Rmax−Rmin=255Rmax−Rmin
z
=
r
o
u
n
d
(
−
R
m
i
n
s
c
a
l
e
)
z = round(-\frac{R_{min}}{scale})
z=round(−scaleRmin) 或
z
=
r
o
u
n
d
(
255
−
R
m
a
x
s
c
a
l
e
)
z = round(255-\frac{R_{max}}{scale})
z=round(255−scaleRmax)
得到了scale和零点z后,对于任意的输入r,量化值q为:
q
=
r
s
c
a
l
e
+
z
q = \frac{r}{scale}+z
q=scaler+z
由定点到浮点反量化公式为:
r
=
(
q
−
z
)
∗
s
c
a
l
e
r = (q-z)*scale
r=(q−z)∗scale
- 对称量化
对称量化:通过一个收缩因子(scale)将实数
[
R
m
i
n
,
R
m
a
x
]
[R_{min},R_{max}]
[Rmin,Rmax]量化到[
−
2
b
−
1
,
2
b
−
1
−
1
-2^{b-1}, 2^{b-1}-1
−2b−1,2b−1−1]的范围内。 以int8量化为例,
b
=
8
b = 8
b=8。
如下图所示,将实数
[
R
m
i
n
,
R
m
a
x
]
[R_{min},R_{max}]
[Rmin,Rmax]量化到[−128,127]范围内。与非对称量化相比,对称量化的zero_point = 0。
s
c
a
l
e
=
R
m
a
x
−
R
m
i
n
(
2
b
−
1
−
1
)
−
(
−
2
b
−
1
)
=
R
m
a
x
−
R
m
i
n
255
)
scale =\frac{R_{max}−R_{min}}{(2^{b-1}-1) -(-2^{b-1})} =\frac{R_{max}−R_{min}}{255} )
scale=(2b−1−1)−(−2b−1)Rmax−Rmin=255Rmax−Rmin)
对于任意的输入r,量化值q为:
q
=
r
s
c
a
l
e
q = \frac{r}{scale}
q=scaler
由定点到浮点反量化公式为:
r
=
q
∗
s
c
a
l
e
r = q*scale
r=q∗scale
三、卷积计算过程
卷积运算中,主要是乘累加运算,通常格式是
o
u
t
p
u
t
=
∑
i
n
p
u
t
∗
w
e
i
g
h
t
+
b
i
a
s
output = \sum_{input*weight} + bias
output=∑input∗weight+bias
假设input的定点值为
Q
i
Q_i
Qi,weight为
Q
w
Q_w
Qw,bias为
Q
b
Q_b
Qb,output为
Q
o
Q_o
Qo。scale和zero_point类似。
(
Q
o
−
Z
o
)
∗
S
o
=
(
(
Q
i
−
Z
i
)
∗
S
i
)
∗
(
(
Q
w
−
Z
w
)
∗
S
w
)
+
(
Q
b
−
Z
b
)
∗
S
b
(Q_o-Z_o)*S_o =((Q_i-Z_i)*S_i)*((Q_w-Z_w)*S_w)+(Q_b-Z_b)*S_b
(Qo−Zo)∗So=((Qi−Zi)∗Si)∗((Qw−Zw)∗Sw)+(Qb−Zb)∗Sb
其中S_b =S_i* S_w,若都采用对称量化,即Z_i,Z_b,Z_w,Z_o为0,
则上式变为:
Q
o
∗
S
o
=
(
Q
i
∗
S
i
)
∗
(
Q
w
∗
S
w
)
+
Q
b
∗
S
i
∗
S
w
Q_o*S_o =(Q_i*S_i)*(Q_w*S_w)+Q_b*S_i*S_w
Qo∗So=(Qi∗Si)∗(Qw∗Sw)+Qb∗Si∗Sw
Q o = S i ∗ S w S o ∗ ( Q i ∗ Q w + Q b ) Q_o =\frac{S_i*S_w}{S_o}*(Q_i*Q_w+Q_b) Qo=SoSi∗Sw∗(Qi∗Qw+Qb)
因此提前算出 S i ∗ S w S o \frac{S_i*S_w}{S_o} SoSi∗Sw即可
若input,output 采用非对称量化量化
(
Q
o
−
Z
o
)
∗
S
o
=
(
(
Q
i
−
Z
i
)
∗
S
i
)
∗
(
Q
w
∗
S
w
)
+
Q
b
∗
S
i
∗
S
w
(Q_o-Z_o)*S_o =((Q_i-Z_i)*S_i)*(Q_w*S_w)+Q_b*S_i*S_w
(Qo−Zo)∗So=((Qi−Zi)∗Si)∗(Qw∗Sw)+Qb∗Si∗Sw
Q o = S i ∗ S w S o ∗ ( ( Q i − Z i ) ∗ Q w + Q b ) + Z o Q_o =\frac{S_i*S_w}{S_o}*((Q_i-Z_i)*Q_w+Q_b)+Z_o Qo=SoSi∗Sw∗((Qi−Zi)∗Qw+Qb)+Zo
Q o = S i ∗ S w S o ∗ ( Q i ∗ Q w + Q b − Z i ∗ Q w ) + Z o Q_o =\frac{S_i*S_w}{S_o}*(Q_i*Q_w+Q_b-Z_i*Q_w)+Z_o Qo=SoSi∗Sw∗(Qi∗Qw+Qb−Zi∗Qw)+Zo
因此提前算出 S i ∗ S w S o \frac{S_i*S_w}{S_o} SoSi∗Sw, Z i Z_i Zi, Z o Z_o Zo即可
若input,output ,weight采用非对称量化量化
(
Q
o
−
Z
o
)
∗
S
o
=
(
(
Q
i
−
Z
i
)
∗
S
i
)
∗
(
(
Q
w
−
Z
w
)
∗
S
w
)
+
Q
b
∗
S
i
∗
S
w
(Q_o-Z_o)*S_o =((Q_i-Z_i)*S_i)*((Q_w-Z_w)*S_w)+Q_b*S_i*S_w
(Qo−Zo)∗So=((Qi−Zi)∗Si)∗((Qw−Zw)∗Sw)+Qb∗Si∗Sw
Q o = S i ∗ S w S o ∗ ( ( Q i − Z i ) ∗ ( Q w − Z w ) + Q b ) + Z o Q_o =\frac{S_i*S_w}{S_o}*((Q_i-Z_i)*(Q_w-Z_w)+Q_b)+Z_o Qo=SoSi∗Sw∗((Qi−Zi)∗(Qw−Zw)+Qb)+Zo
Q o = S i ∗ S w S o ∗ ( Q i ∗ ( Q w − Z w ) + Q b − Z i ∗ ( Q w − Z w ) ) + Z o Q_o =\frac{S_i*S_w}{S_o}*(Q_i*(Q_w-Z_w)+Q_b-Z_i*(Q_w-Z_w))+Z_o Qo=SoSi∗Sw∗(Qi∗(Qw−Zw)+Qb−Zi∗(Qw−Zw))+Zo
因此提前算出 S i ∗ S w S o \frac{S_i*S_w}{S_o} SoSi∗Sw, Z i Z_i Zi, Z o Z_o Zo, Z w Z_w Zw即可