问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

深度学习量化技术详解:从原理到应用

创作时间:
作者:
@小白创作中心

深度学习量化技术详解:从原理到应用

引用
CSDN
1.
https://m.blog.csdn.net/github_37287822/article/details/144520871

深度学习模型量化是提高模型推理效率和降低计算资源消耗的重要技术手段。本文将深入解析深度学习量化的核心概念、方法与应用,从量化映射、量化方法、量化粒度等多个维度进行详细阐述,并提供具体的代码实现和应用场景分析。

1 简介

模型量化一般代表的是深度学习模型中的浮点参数和操作转换为定点表示,如FP32转换为I8,FP32转换为U8等。换句话说,就是将一个高精度数值域转换为近似的低精度数值域表示。

FP32,表示为4个字节,I8或者U8表示为1个字节,从内存占用上呈现4倍降低,其次设备对浮点运算的计算能力要弱于整型运算。

所以很显然,量化能够降低内存占用,实现模型压缩和推理加速,但会造成一定程度的精度损失这句话就不难理解了。

2 量化映射 - 线性映射

此处主要涉及线性映射,非线性映射此处不展开讨论。

2.1 线性对称非量化

线性非对称量化中,量化的范围是不对称的,即量化的最小值和最大值不再对称分布,并且零点通常不位于量化范围的中心。

  • 非对称:量化的区间在零点两侧是不对称的,正负数值的量化步长不同,通常会根据实际数据的分布来决定量化范围的上下界。

  • 优点:激活操作产生的值分布并不是均等的,所以使用线性对称量化就会出现严重的精度损失!

2.1.1 计算方式

以FP32与I8之间的转换为例子,转换公式如下:

X i 8 = C L A M P ( ⌊ X f p 32 S ⌉ + Z ; − 2 b − 1 , 2 b − 1 − 1 ) X_{i8} = CLAMP(\lfloor\frac{X_{fp32}}{S}\rceil +Z;-2^{b-1},2^{b-1}-1)Xi8 =CLAMP(⌊SXfp32 ⌉+Z;−2b−1,2b−1−1)

其中,X i 8 X_{i8}Xi8 表示的是量化后的结果,X f p 32 X_{fp32}Xfp32 表示需要量化的数值,C L A M P CLAMPCLAMP表示的是截断操作,b bb表示位宽,即表示一个数值所需要的位数,S SS表示量化的缩放因子(scale),Z ZZ表示量化的零点(zero point)。

定点数反向量化的过程,转换公式如下:

X f p 32 ≈ X ^ = S ∗ ( X − Z ) X_{fp32}\approx \hat{X} = S*(X-Z)Xfp32 ≈X^=S∗(X−Z)

具体的量化范围为( q m i n , q m a x ) (q_{min},q_{max})(qmin ,qmax ),截断范围为( c m i n , c m a x ) (c_{min},c_{max})(cmin ,cmax ),量化参数s和z的计算公式如下:

S = q m a x − q m i n c m a x − c m i n = q m a x − q m i n 2 b − 1 S = \frac{q_{max} - q_{min}}{c_{max} - c_{min}} = \frac{q_{max}-q_{min}}{2^b - 1}S=cmax −cmin qmax −qmin =2b−1qmax −qmin

Z = c m a x − ⌊ q m a x S ⌉ Z = c_{max} - \lfloor \frac{q_{max}}{S} \rceilZ=cmax −⌊Sqmax ⌉

2.1.2 代码实现

将浮点FP32转换为I8的量化代码:

static int8_t qnt_f32_to_affine(float f32, int32_t zp, float scale)
{
    float dst_val = (f32 / scale) + zp;
    int8_t res = (int8_t)__clip(dst_val, -128, 127);
    return res;
}

将I8转换为FP32的反量化代码:

static float deqnt_affine_to_f32(int8_t qnt, int32_t zp, float scale) 
{ 
    return ((float)qnt - (float)zp) * scale; 
}

2.2 线性对称量化

在线性对称量化中,量化的范围是对称的,即零点(0)被映射到量化范围的中心,并且正负数值的量化步长是相同的。也就是非对称量化的特殊表示,在FP32量化到I8的例子中,即zp=0的情况,就变成了对称量化。

  • 对称性:量化的区间在零点两侧是对称的,正负方向的量化步长相同。

2.3 量化误差来源

量化过程会导致一定程度的精度丢失,主要来源于 四舍五入误差 和 截断误差。四舍五入误差的范围为 (−0.5S,0.5S),其中 S是量化的比例因子。若浮点数 X过大,而比例因子 S过小,量化后的定点数可能会超出表示范围,从而产生 截断误差。

理论上,增大比例因子 S可以减小截断误差,但会相应地增大四舍五入误差。因此,必须合理选择量化参数,以确保量化误差尽可能小,平衡两种误差的影响。

3 量化方法

量化比例因子s和零点zp是影响量化误差的关键参数,而量化范围的求解对量化参数起到决定性的作用。

3.1 Normal 量化

Normal 量化算法是通过计算浮点数中的最大值和最小值直接确定量化范围的最大值和最小值。Normal算法不会带来截断误差,但是对outlier非常敏感,假设输入的数据序列分布不均匀,则使用此种方法会带来较为离谱的四舍五入误差。

3.2 KL-Divergence 量化

KL-Divergence 量化算法计算浮点数和定点数的分布,通过调整不同的阈值来更新浮点数和定点数的分布,并根据 KL 散度最小化两个分布的相似性来确定量化范围的最大值和最小值。KL-Divergence 量化算法通过最小化浮点数和定点数之间的分布差异,能够更好地适应非均匀的数据分布并缓解少数异常值的影响。

3.3 MMSE 量化

MMSE 量化算法通过最小化浮点数与量化反量化后浮点数的均方误差损失,确定量化范围的最大值和最小值,在一定程度上缓解大异常值带来的量化精度丢失问题。由于MMSE 量化算法的具体实现是采用暴力迭代搜索近似解,速度较慢,内存开销较大,但通常会比 Normal 量化算法具有更高的量化精度。

具体计算公式如下:

L o s s q m i n , q m a x = ∣ ∣ V − V ^ ( q m i n , q m a x ) ∣ ∣ F 2 \underset{q_{min},q_{max}}{Loss} = ||V - \hat{V}(q_{min},q_{max})||_F^{2}qmin ,qmax Loss =∣∣V−V^(qmin ,qmax )∣∣F2

上述公式表示使用迭代的方式使输入的FP32与反向量化后的X的差距最小;其中V表示的是FP32,V ^ \hat{V}V^表示使用量化参数计算的反量化的FP32的值。整个过程就是在优化量化参数S和ZP。

4 量化粒度

量化粒度指选取多少个待量化参数共享一个量化系数,通常来说粒度越大,精度损失越大,比如下面5个数一起量化到[0, 255],由于存在一个离群值(outlier) 1000,导致前面四个数量化后都是 0, 失去了差异性,从而影响结果的精度。

根据分组的依据不同,量化粒度有多种形式,一般分为两类:PerLayer/PerTensor和PerChannel。

4.1 PerLayer/PerTensor

“Per-Tensor”(全张量量化)指的是对整个张量(通常是权重或激活的整个矩阵)进行量化时,使用相同的比例因子(scale factor)来量化该张量中的所有元素。整个Tensor或者Layer全程使用同一个量化参数S和ZP。

  • 优点:快,实现较为简单,计算量较小,适用于一些不太依赖特定层或通道分布的模型。

  • 缺点:这种方式可能会导致一些精度损失,尤其是当张量中的数据分布差异较大时(例如,某些层的权重或激活值范围很大,而其他层较小)

  • 适用场景

  • 量化适用于层之间数值分布差异不大的模型,能够在提供额外灵活性的同时避免大范围的精度损失。

4.2 PerChannel

“Per-Channel”(每通道量化)是指在量化时对每一个通道使用独立的比例因子。每个通道(通常是卷积层的输出通道或神经网络的每个层的每个通道)会有不同的量化因子。这种方式使得每个通道的量化更加细粒度,能够适应不同通道的分布特征。

  • 优点:相比于 per-tensor / per-layer,per-channel 量化通常能够提供更好的精度,因为它考虑了每个通道数据的分布,适应性更强。

  • 缺点:实现更复杂,计算开销较大,因为每个通道需要有独立的比例因子。在资源受限的设备上,可能带来一定的性能开销。

  • 适用场景

  • per-channel 量化特别适用于卷积神经网络(CNN),因为卷积层中的每个通道可能具有不同的激活范围,而使用独立的量化因子可以最大程度减少量化带来的精度损失。

5 量化都量化啥

本质上就是所有包含权重和激活的层。包含权重的层为卷积层、全连接层、BN层;包含激活的层:各种激活函数。

特别的,对于一些较复杂的激活函数,通常是非线性的,量化计算主要有查表法和拟合法两类。查表法实现相对简单:对于低比特量化,x可取值总数有限,可以提前计算好映射表(如INT8的表长为256),推理时直接从表中取值即可:

而拟合法则是通过使用多相似逼近、泰勒展开等方式,用低阶函数来模拟,比如 GELU 激活中的 erf 函数,通过一个二次函数 L(x) 来拟合:选取一些采样点,然后用最小二乘法,计算得到 a = -0.2888, b = -1.769, c = 1,右边是 erf 函数真实点与拟合曲线的示意,可以看到拟合精度还是不错的。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号