上一篇文章介绍了模型量化的基本概念,
本文主要讲解两种主要的量化方式:均匀量化和非均匀量化。
我们假设我们有训练有素的模型参数θ,以浮点精度存储。在量化中,目标是将参数(θ)和中间激活值的精度降低到低精度,同时尽量减少对模型泛化/准确性的影响。
为了实现这一点,我们需要定义一个量化算子:Q = g(x)
该量化运算符将浮点值x映射到量化值Q。
如图1所示,根据Q值范围分布的均匀性,量化可以分为均匀量化和非均匀量化,以橙色圆点标记。
图1
图 1 的左侧表示均匀量化,因为得到的量化值是均匀分布的。
图 1 的右侧表示非均匀量化,因为量化值不一定是均匀分布的。
均匀量化
令 [β, α] 为量化选择的可表示实值范围,b 为有符号整数表示的位宽。
均匀量化将输入值 x∈[β, α] 变换为位于
范围之外的输入将被限制到最近的边界。
对于均匀变换,变换函数只有两种选择:f(x) = s · x + z 及其特殊情况 f(x) = s · x,其中 x, s, z ∈ R。
如图 1 所示,这两个选择也分别称为仿射和缩放:
仿射量化
仿射量化将实数 x∈R 映射到 b 位有符号整数 Q,
对于仿射变换函数
比例因子s和零点z的定义如下:
其中 [β, α] 表示剪辑范围,即我们用来剪辑实际值的有界范围,b 是量化位宽。
零点的目的是在x的数值范围中找到0的对应位置,这在图1的左侧也可以观察到。
量化操作定义如下:
基于 AffineQuantize 操作,AffineDeQuantize 操作非常清晰,它计算原始实值输入的近似值:
利用上面提供的定义和公式,我编写了以下程序来测试仿射量化:
import numpy as np
def get_s_z(b, beta, alpha):
s = (2 ** b - 1) / (alpha - beta)
z = -np.round(beta * s) - 2**(b-1)
return s, z
def quantization(x, b, beta, alpha):
s, z = get_s_z(b, beta, alpha)
return np.clip(np.round( s * x + z), a_min= -2 ** (b-1), a_max = 2 ** (b-1) - 1)
def dequantization(Q, b, beta, alpha):
s, z = get_s_z(b, beta, alpha)
return (1 / s) * (Q - z)
x = [-1.8, -1.0, 0, 0.5]
Q = [quantization(a, 8, -1.8, 0.5) for a in x]
print(Q)
x_hat = [dequantization(a, 8, -1.8, 0.5) for a in Q]
print(x_hat)
输出为:
(py37) $ python quant.py
[-128.0, -39.0, 72.0, 127.0]
[-1.803921568627451, -1.0011764705882353, 0.0, 0.49607843137254903]
我们可以看到,输入[-1.8, -1.0, 0, 0.5]
被量化为[-128.0, -39.0, 72.0, 127.0]
。然后,[-128.0, -39.0, 72.0, 127.0]
被反量化为[-1.803921568627451, -1.0011764705882353, 0.0, 0.49607843137254903]
。
尺度量化
比例量化仅通过比例变换执行范围映射。它通常被称为对称量化,其中输入范围和整数范围围绕零对称。这意味着对于 int8,我们使用整数范围 [-127, 127],选择不使用值 -128 以支持对称性。图 1b 说明了使用比例量化将实数值映射到 int8。
对于尺度变换函数
尺度因子s及尺度量化算子的定义如下:
对于实数 x,尺度量化选择可表示范围 [−α, α],产生 b 位整数值 Q。
可以看出尺度量化没有零点z,且β=-α,它其实是仿射量化的一个特例,因此例子可以参考仿射量化的例子。
非均匀量化
非均匀量化的正式定义如下:
其中 qi 表示离散量化级别,∆i 表示量化步骤(阈值),具体来说,当实数 x 的值介于量化步骤 ∆i 和 ∆i+1 之间时,量化器 f 会将其投射到相应的量化级别 qi 。请注意,qi 和 ∆i 都不是均匀分布的。
一种典型的基于规则的非均匀量化方法是使用对数分布,其中量化步长和级别呈指数增长而不是线性增长。另一种流行的方法是基于二进制代码的量化。
非均匀量化在固定位长下能够实现更高的精度,因为它能够更好地捕捉重要的值区域或者找到合适的动态范围来更好地捕捉分布。
一般而言,非均匀量化通过非均匀分配比特和离散化参数范围使我们能够更好地捕获信号信息。然而,非均匀量化方案通常难以在 GPU 和 CPU 等通用计算硬件上高效部署。因此,由于其简单性和有效的硬件映射,均匀量化目前是事实上的方法。
结论
本文介绍了两种主要的量化方法:均匀量化(Uniform Quantization)和非均匀量化(non-Uniform Quantization)。
均匀量化可以分为仿射和尺度,其中尺度是仿射的特例。
对于非均匀量化,也有许多相关研究,但均匀量化由于其简单性和有效的硬件映射,是目前事实上的方法。
RA/SD 衍生者AI训练营。发布者:chris,转载请注明出处:https://www.shxcj.com/archives/4226