什么是量化
量化是使用线性或非线性缩放技术,将连续的值转换为离散值集合的过程
为什么要量化
在深度模型的训练过程中,高精度的模型是必要的,但是在模型部署的过程中,高精度通常并不是主要的
因为高精度必然有着更加细粒度的参数,这种参数对于模型部署落是极为不友好的
通常我们将模型的参数量化成计算成本更低,内存占用更少的INT8类型
这样能够保证模型的性能相似,并且拥有更快的推理速度
量化基础
详细内容可参考:https://arxiv.org/pdf/2004.09602.pdf
设置 [ β , α ] [β, α] [β,α] 为量化选择的可表示实际值的范围
b b b 代表有符号整型形式的位宽
量化的目标,就是将目前参数映射到 [ β , α ] [β, α] [β,α] 内的实数: [ − 2 b − 1 , 2 b − 1 − 1 ] [-2^{b-1}, 2^{b-1}-1] [−2b−1,2b−1−1]
如果目标参数映射到 [ − 2 b − 1 , 2 b − 1 − 1 ] [-2^{b-1}, 2^{b-1}-1] [−2b−1,2b−1−1]范围外,将会采取裁剪的方式,映射到最近边界
量化公式
考虑 8 b i t 8bit 8bit量化,因此,实数 [ β , α ] [ β,α ] [β,α]将被量化为位于 [ − 128 , 127 ] [-128, 127] [−128,127]量化范围内
x q = c l a m p ( r o u n d ( x / s c a l e ) + z e r o P t ) x_q = clamp(round(x / scale) + zeroPt) xq=clamp(round(x/scale)+zeroPt)
其中:
- s c a l e = ( α − β ) / ( 2 b − 1 ) scale = (α-β)/(2^b-1) scale=(α−β)/(2b−1)
- z e r o P t = − r o u n d ( β ∗ s c a l e ) − 2 b − 1 zeroPt = - round(β * scale) - 2^{b-1} zeroPt=−round(β∗scale)−2b−1
round
是四舍五入函数clamp
是裁剪函数,将数值裁剪到 − 128 -128 −128到 127 127 127之间
反量化
反量化就是量化的反过程
x = ( x q − z e r o P t ) ∗ s c a l e x = (x_q - zeroPt) * scale x=(xq−zeroPt)∗scale
TensorRT中的量化
TensorRT仅支持对称的均匀量化,这也就意味这,zeroPt 的值恒为0
对于8bit量化,其实际值范围 [ m i n f l o a t , m a x f l o a t ] [min_{float}, max_{float}] [minfloat,maxfloat] 被量化映射到 [ − 127 , 127 ] [-127, 127] [−127,127], 选择不使用-128来保持对称
值得注意的是,在对称量化表示中,我们失去了一个值,但这一个值的价值微不足道
TensorRT量化方法
对称量化公式: x q = c l a m p ( r o u n d ( x / s c a l e ) ) x_q = clamp(round(x / scale)) xq=clamp(round(x/scale))
因为TensorRT仅仅支持对称范围, 量化参数将会使用最大的绝对值:max(abs(min_float), abs(max_float))
设
α = max(abs(min_float), abs(max_float))
s c a l e = α / ( 2 b − 1 − 1 ) scale = α / (2^{b-1} -1) scale=α/(2b−1−1)
然后进行四舍五入,将量化值裁剪到-127到127之间
反量化: x = x q ∗ s c a l e x = x_q * scale x=xq∗scale
量化算子说明
量化算子将给定范围的实值划分为若干个分区
以3位量化为例,说明量化算子公式背后的原理
非对称量化例子
Real values range: [ β , α ] [β, α] [β,α]
量化值范围: [ -2{3-1}, 2{3-1}-1]
i.e. [-4, -3, -2, -1, 0, 1, 2, 3]
正如预期的那样,对于3位量化,有8个量化(2^3)值
缩放将范围划分为多个分区
也就是说,对于3量化,有7个分区
因此: s c a l e = ( α − β ) / ( 2 3 − 1 ) scale = (α-β)/(2^3-1) scale=(α−β)/(23−1)
对称量化
对称量化有两个变化
- 实数不是自由的而是受限的
- 量子化范围中的一个值被降低,有利于对称性导致一个新的范围 [ − 3 , − 2 , − 1 , 0 , 1 , 2 , 3 ] [-3,-2,-1,0,1,2,3] [−3,−2,−1,0,1,2,3]
现在有6个(2^3-2)分区(不同于非称量子化的7个)
缩放将范围划分为多个分区
s c a l e = 2 ∗ α / ( 2 3 − 2 ) = α / ( 2 3 − 1 − 1 ) scale = 2*α /(2^3 - 2) = α/(2^3-1-1) scale=2∗α/(23−2)=α/(23−1−1)
参考:
- https://github.com/NVIDIA/TensorRT/blob/b55c4710ce01f076c26710a48879fcb2661be4a9/tools/tensorflow-quantization/docs/source/docs/intro_to_quantization.md