本文将会重点介绍训练后量化技术的两种方式:动态和静态方法,将模型权重和激活从浮点数转换为整数,以减少模型大小和加速推理。并以 KL 散度作为例子讲解校准方法和量化粒度控制来平衡模型精度和性能。
训练后量化的方式
训练后量化的方式主要分为动态和静态两种。
动态离线量化
动态离线量化(Post Training Quantization Dynamic, PTQ Dynamic)仅将模型中特定算子的权重从 FP32 类型映射成 INT8/16 类型,主要可以减小模型大小,对特定加载权重费时的模型可以起到一定加速效果。但是对于不同输入值,其缩放因子是动态计算。动态量化的权重是离线转换阶段量化,而激活是在运行阶段才进行量化。因此动态量化是几种量化方法中性能最差的。
不同的精度下的动态量化对模型的影响:
- 权重量化成 INT16 类型,模型精度不受影响,模型大小为原始的 1/2;
- 权重量化成 INT8 类型,模型精度会受到影响,模型大小为原始的 1/4。
动态离线量化将模型中特定算子的权重从 FP32 类型量化成 INT8 等类型,该方式的量化有两种预测方式:
-
反量化推理方式,即是首先将 INT8/FP16 类型的权重反量化成 FP32 类型,然后再使用 FP32 浮运算运算进行推理;
-
量化推理方式,即是推理中动态计算量化算子输入的量化信息,基于量化的输入和权重进行 INT8 整形运算。
静态离线量化
静态离线量化(Post Training Quantization Static, PTQ Static)同时也称为校正量化或者数据集量化,使用少量无标签校准数据。其核心是计算量化比例因子,使用静态量化后的模型进行预测,在此过程中量化模型的缩放因子会根据输入数据的分布进行调整。相比量化训练,静态离线量化不需要重新训练,可以快速得到量化模型。
\[uint8 = round(float/scale) - offset \]静态离线量化的目标是求取量化比例因子,主要通过对称量化、非对称量化方式来求,而找最大值或者阈值的方法又有 MinMax、KL 散度、ADMM、EQ,MSE 等方法。
静态离线量化的步骤如下:
- 加载预训练的 FP32 模型,配置用于校准的数据加载器;
- 读取小批量样本数据,执行模型的前向推理,保存更新待量化算子的量化 scale 等信息;
- 将 FP32 模型转成 INT8 模型,进行保存。
一些常用的计算量化 scale 的方法:
量化方法 | 方法详解 |
---|---|
\(abs_{max}\) | 选取所有激活值的绝对值的最大值作为截断值α。此方法的计算最为简单,但是容易受到某些绝对值较大的极端值的影响,适用于几乎不存在极端值的情况。 |
\(KL\) | 使用参数在量化前后的 KL 散度作为量化损失的衡量指标。此方法是 TensorRT 所使用的方法。在大多数情况下,使用 KL 方法校准的表现要优于 \(abs_{max}\) 方法。 |
$avg $ | 选取所有样本的激活值的绝对值最大值的平均数作为截断值α。此方法计算较为简单,可以在一定程度上消除不同数据样本的激活值的差异,抵消一些极端值影响,总体上优于 \(abs_{max}\) 方法。 |
量化粒度
量化参数可以针对层的整个权重张量计算,也可以针对每个通道分别计算。在逐张量量化中,同一剪切范围将应用于层中的所有通道。在模型量化过程中分为权重量化和激活量化:
-
权重量化:即需要对网络中的权重执行量化操作。可以选择逐张量(per-tensor)或者逐通道(per-channel)的量化粒度,也就是说每个通道选取一个量化 scale。对于卷积神经网络,per- channel 通常对应通道轴。在任何一种情况下,量化因子的精度都是 FP32。per-channel 的量化粒度比 per-tensor 的更细粒度,模型效果更好,但带来的是推理过程中的计算复杂度增加。需要注意的是部分部署硬件有可能不支持 per-channel 量化推理。
-
激活量化:即对网络中不含权重的激活类算子进行量化。一般采用逐张量(per-tensor)的粒度,也可以选择逐 token(per-token)的量化粒度。
KL 散度校准法
下面以静态离线量化中的 KL 散度作为例子,看看静态离线量化的具体步骤。
KL 散度原理
KL 散度校准法也叫相对熵,其中 p 表示真实分布,q 表示非真实分布或 p 的近似分布:
\[ 标签:scale,FP32,AI,text,cdot,offset,量化,转载 From: https://www.cnblogs.com/wujinwanai/p/18600969