发表博客之:int8 量化 原理讲解,AI推理工程师必备技能!
fgh431 2024-07-10 17:01:02 阅读 84
文章目录
[发表博客之:int8 量化 原理讲解,AI推理工程师必备技能!](https://cyj666.blog.csdn.net/article/details/138426588)
发表博客之:int8 量化 原理讲解,AI推理工程师必备技能!
如果你在找工作,你必须看我这篇文章!!
模型推理的时候,为了降低时延,通常会采用int8量化。那么为啥int8量化这个技术会带来收益呢?
首先下面这个图是某个模型的matmul op。其中两个输入都是fp32,输出也是fp32。由于是用fp32精度来计算的,因此肯定比较费时间的!
而int8量化时,其实就是在上面图的基础上,分别在matmul的两个输入上面,成对的插入了QDQ算子!变成下面这张图这样!
有人可能疑惑了,你把模型上插入了两对QDQ算子,你怎么保证图2和图1是等价的呢?其实啊,图1和图2未必是完全一样的,
但是只要保证图2和图1最后使得模型总体的效果是一样的就行了,这个不是推理工程师的事情,保证模型效果一样是压缩工程师的事情!压缩工程师会保证插入QDQ之后的模型效果仍然很棒!如果不能保证,那这个就是压缩工程师的锅!
继续看图2。<code>Quantize 算子就是将 fp32 的输入量化到int8,而 DeQuantize
算子就是将int8的输入反量化到fp32。Quantize
算子有两个输入,一个是fp32的输入
x
x
x,另一个就是scale参数,输出是int8类型的数据。
它的作用就是将fp32的输入,按照scale参数,量化到int8。公式是用
x
x
x除以scale参数,然后四舍五入取整,最后clip到-127到127之间当然啦,细节啥的不重要。 那DeQuantize
算子有两个输入,一个是int8的输入
x
x
x,另一个也是scale参数,算子的输出是fp32类型
就是将int8的输入,反量化到fp32。具体公式就是用int8的数字
x
x
x,乘以 scale参数即可!也就是DeQuantize
算子其实就是个乘法而已啊!很平平无奇!
继续看图2。DeQuantize0
和 DeQuantize1
的输出都是fp32数字,从而和MatMul
算子的两个输入都是fp32。那我这个Matmul还是用fp32精度计算啊!这能有个毛线的加速啊!因此需要对图2进行一定的等价变换!
继续看图2。一般而言,Matmul的第1个输入正常是个输入,输入是个
[
M
,
K
]
[M,K]
[M,K]的tensor
另一个输入是权重,是个
[
K
,
N
]
[K,N]
[K,N]的权重tensor 一般而言,Quantize0和Dequantize0的scale参数是个单独的数字,也就是孤零零的一个数字!Quantize1和Dequantize1的scale参数是
N
N
N个数字,也就是每列共同拥有一个scale参数!
不同的列的scale参数是不一样的!哈哈,其实这个专业术语叫做per channel量化! 而矩阵运算中,
M
a
t
m
u
l
O
u
t
[
i
,
j
]
=
∑
k
=
0
K
−
1
E
[
i
,
k
]
F
[
k
,
j
]
MatmulOut[i,j]=\sum_{k=0}^{K-1} E[i,k]F[k,j]
MatmulOut[i,j]=k=0∑K−1E[i,k]F[k,j],也就是
M
a
t
m
u
l
O
u
t
MatmulOut
MatmulOut中的每一个元素,是E的一行和F的一列进行乘加运算得到的!
而E的所有元素共享一个scale参数,F的一列也是共享一个scale参数的,因此可以把
E
E
E的scale参数和
F
F
F的scale都提出来!
这样
M
a
t
m
u
l
O
u
t
[
i
,
j
]
=
D
e
Q
u
a
n
t
i
z
e
0
s
c
a
l
e
∗
D
e
Q
u
a
n
t
i
z
e
1
s
c
a
l
e
[
j
]
∑
k
=
0
K
−
1
C
[
i
,
k
]
D
[
k
,
j
]
MatmulOut[i,j]=DeQuantize0_{scale} * DeQuantize1_{scale}[j] \sum_{k=0}^{K-1} C[i,k]D[k,j]
MatmulOut[i,j]=DeQuantize0scale∗DeQuantize1scale[j]k=0∑K−1C[i,k]D[k,j]
D
e
Q
u
a
n
t
i
z
e
1
s
c
a
l
e
[
j
]
DeQuantize1_{scale}[j]
DeQuantize1scale[j] 表示 DeQuantize1算子的scale参数的第j个元素!
也就是说,matmul的输出结果,完全可以先由
E
E
E和
F
F
F做矩阵乘法,
然后乘以
D
e
Q
u
a
n
t
i
z
e
0
s
c
a
l
e
∗
D
e
Q
u
a
n
t
i
z
e
1
s
c
a
l
e
[
j
]
DeQuantize0_{scale} * DeQuantize1_{scale}[j]
DeQuantize0scale∗DeQuantize1scale[j]得到!由此得到图3
其中 Dequantize2 的scale参数是由 <code>图2中DeQuantize0
和DeQuantize1
的scale参数相乘得到的!并且在图3中我们可以看到此时matmul的输入是int8啦!此时可以调用int8的matmul进行计算!
不过要注意,此时matmul的输出是int32数字哦! 上面这个技术叫做
DQ 下移!欢迎大家点赞我!
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。