神经网络(模型)量化介绍 - PTQ 和 QAT

1. 需求目的

  在开发机器学习应用程序时,有效利用服务器端和设备上的计算资源非常重要。为了支持在服务器和边缘设备上更高效的部署,对模型量化的支持将变的更加重要。

  量化利用8位整数(int8)指令来减小模型大小并更快地运行推断(减少延迟),并且可以是实现服务质量目标或甚至适合移动设备上可用资源的模型之间的差异。即使在资源不太受限的情况下,它也可以使您部署更大、更准确的模型。

2. 量化简介

  量化主要是一种加速推理的技术,量化运算符仅支持前向传递。量化是指使用精度较低的数据进行计算和内存访问的技术,与浮点实现相比,通常是 int8。这可以在几个重要领域实现性能提升:

  • 模型尺寸缩小 4 倍;
  • 内存带宽减少 2-4 倍;
  • 由于内存带宽的节省和使用 int8 算法的更快计算,推理速度提高了 2-4 倍(确切的加速取决于硬件、运行时和模型)。

  然而,量化并非没有额外代价。从根本上说,量化意味着引入近似值,由此产生的网络精度略低。这些技术试图最小化完整浮点精度和量化精度之间的差距。

3. 三种量化模式

3.1 Dynamic Quantization - 动态量化

  PyTorch支持的最简单的量化方法称为动态量化。这不仅涉及将权重转换为int8(正如所有量化变量中所发生的那样),而且还涉及在执行计算之前将激活转换为int 8(因此为“动态”)。因此,将使用高效的int8矩阵乘法和卷积实现来执行计算,从而实现更快的计算。然而,激活是以浮点格式读取和写入内存的。

3.2 Post-Training Static Quantization - 训练后静态量化

  通过将网络转换为同时使用整数算术和int8内存访问,可以进一步提高性能(延迟)。静态量化执行额外的步骤,首先通过网络输入数据批,并计算不同激活的结果分布(具体来说,这是通过在记录这些分布的不同点插入“观察者”模块来完成的)。该信息用于确定不同的激活应该在推断时量化的具体程度(一种简单的技术是将整个激活范围简单地划分为256个级别,但我们也支持更复杂的方法)。重要的是,这一附加步骤允许我们在操作之间传递量化值,而不是在每个操作之间将这些值转换为浮点值,然后再转换为整数,从而大大加快了速度。

在PyTorch中,支持几个允许用户优化静态量化的功能:

  • 观察者:可以自定义观察者模块,指定如何在量化之前收集统计信息,以尝试更高级的方法来量化数据。
  • 运算符融合:可以将多个操作融合为一个操作,节省内存访问,同时提高操作的数值精度。
  • 每通道量化:我们可以在卷积/线性层中独立量化每个输出通道的权重,这可以以几乎相同的速度获得更高的精度。

3.3 Quantization Aware Training - 量化感知训练

  量化感知训练(QAT)是第三种方法,也是这三种方法中精度最高的一种。使用QAT,所有权重和激活在训练的前向和后向过程中都是“伪量化”的:也就是说,浮点值被舍入为模拟int8值,但所有计算仍然使用浮点数字完成。因此,训练期间的所有权重调整都是在“感知到”模型最终将被量化这一事实的情况下进行的;因此,在量化之后,该方法通常比其他两种方法产生更高的精度。

4. PTQ 和 QAT 简介

  依据是否要对量化后的参数进行调整,我们可以将量化方法分为量化感知训练(QAT)和训练后量化(PTQ)。 这两种方法的操作区别如下图所示(图左为QAT,图右为PTQ):

此处 " 训练后量化(PTQ) " 通常为 " 静态训练后量化 "

在这里插入图片描述

  量化感知训练 QAT 是将训练过的模型量化后又再进行重训练。由于定点数值无法用于反向梯度计算,实际操作过程是在某些op前插入伪量化节点(fake quantization nodes), 用于在训练时获取流经该op的数据的截断值,便于在部署量化模型时对节点进行量化时使用。我们需要在训练中通过不断优化精度来获取最佳的量化参数。由于它需要对模型进行训练, 对操作人员技术要求较高。

  训练后量化 PTQ 是使用一批校准数据对训练好的模型进行校准, 将训练过的FP32网络直接转换为定点计算的网络,过程中无需对原始模型进行任何训练。只对几个超参数调整就可完成量化过程, 且过程简单快速, 无需训练, 因此此方法已被广泛应用于大量的端侧和云侧部署场景, 我们优先推荐您尝试PTQ方法来查看是否满足您的部署精度和性能要求 。

5. 设备和运算符支持

  量化支持仅限于可用运算符的子集,具体取决于所使用的方法,有关支持的运算符列表,请参阅https://pytorch.org/docs/stable/quantization.html上的文档。

  可用运算符集和量化数值还取决于用于运行量化模型的后端。当前量化运算符仅支持以下后端中的 CPU 推理:x86 和 ARM。量化配置(张量应该如何量化和量化内核(量化张量的算术)都是后端相关的。

  但是,量化感知训练以全浮点形式进行,可以在 GPU 或 CPU 上运行。当训练后静态或动态量化不能产生足够的准确性时,量化感知训练通常仅用于 CNN 模型。对于为实现小尺寸而高度优化的模型(例如 Mobilenet),可能会发生这种情况。

6. 选择一种方法

  选择使用哪种方案取决于多种因素:

  • 模型/目标要求:某些模型可能对量化敏感,需要进行量化感知训练。
  • 运算符/后端支持:一些后端需要完全量化的运算符。

目前,运算符的覆盖范围有限,可能会限制下表中列出的选择:下表提供了一个指南。

模型类型 首选方案 为什么
LSTM/RNN 动态量化 吞吐量由权重的计算/内存带宽决定
BERT/Transformer 动态量化 吞吐量由权重的计算/内存带宽决定
CNN 静态量化 吞吐量受激活的内存带宽限制
CNN 量化感知训练 在静态量化无法达到精度的情况下

7. 性能结果

  与浮点实现相比,量化可将模型大小减少 4 倍,并将速度提高 2 至 3 倍,具体取决于硬件平台和基准测试模型。一些样本结果是:

模型 浮点延迟(毫秒) 量化延迟(毫秒) 推理性能增益 设备 注释
BERT 581 313 1.8倍 Xeon-D2191 (1.6GHz) 批量大小 = 1,最大序列长度 = 128,单线程,x86-64,动态量化
Resnet-50 214 103 2倍 Xeon-D2191 (1.6GHz) 单线程,x86-64,静态量化
Mobilenet-v2 97 17 5.7倍 Samsung S9 静态量化,浮点数基于 Caffe2 运行时,未优化

8. 精度结果

  我们还将静态量化模型的准确性与 ImageNet 上的浮点模型进行了比较。对于动态量化,我们在 MRPC 的 GLUE 基准上比较了 BERT 的 F1 分数。

计算机视觉模型精度

模型 Top-1 Accuracy(浮点) Top-1 Accuracy(量化) 量化方案
Googlenet 69.8 69.7 静态训练后量化
Inception-v3 77.5 77.1 静态训练后量化
ResNet-18 69.8 69.4 静态训练后量化
Resnet-50 76.1 75.9 静态训练后量化
ResNext-101 32x8d 79.3 79 静态训练后量化
Mobilenet-v2 71.9 71.6 量化感知训练
Shufflenet-v2 69.4 68.4 静态训练后量化

语音和 NLP 模型准确性

模型 F1 (GLUEMRPC) 浮点 F1 (GLUEMRPC) 量化 量化方案
BERT 0.902 0.895 动态量化

9. 结论

  要开始在 PyTorch 中量化您的模型,请从PyTorch 网站上的教程开始。如果您正在处理序列数据,请从LSTMBERT的动态量化开始。如果您正在处理图像数据,那么我们建议您从量化迁移学习教程开始。然后你可以探索静态训练后量化。如果你发现训练后量化的精度下降太高,那么尝试量化感知训练

参考资料

参考资料1

参考资料2

参考资料3

猜你喜欢

转载自blog.csdn.net/i6101206007/article/details/128868094