技术文章和通讯

什么是int8量化,为什么它在深度神经网络中流行?

作者:Ram Cherukuri, MathWorks


深度学习部署在实时推理的边缘是许多应用领域的关键。它在网络带宽、网络延迟和功耗方面显著降低了与云通信的成本。

然而,边缘设备具有有限的内存、计算资源和功率。这意味着深度学习网络必须针对嵌入式部署进行优化。

int8量化已经成为一种流行的优化方法,不仅用于像TensorFlow和PyTorch这样的机器学习框架,而且也用于像NVIDIA这样的硬件工具链®TensorRT和Xilinx®dnndk -主要是因为int8使用8位整数而不是浮点数,使用整数数学而不是浮点数学,从而减少了内存和计算需求。

这些要求可能相当可观。例如,像AlexNet这样相对简单的网络超过200 MB,而像VGG-16这样的大型网络超过500 MB[1]。这种规模的网络无法安装在低功耗的微控制器和较小的fpga上。

在本文中,我们将仔细研究使用8位表示数字的含义,并了解int8量化(数字用整数表示)如何将内存和带宽使用量减少75%。

int8表示

我们从一个简单的示例开始,使用一个VGG16网络,该网络由几个卷积层和ReLU层以及几个完全连接层和最大池化层组成。首先,让我们看看如何用整数表示一个真实的数字(在本例中是一个卷积层中的权值)。这个函数fi在MATLAB®使用8位字长为权重提供了最佳的精确缩放。这意味着我们获得了2^-12的最佳精度,并将其存储为位模式01101110,它表示整数110。

\[Real\_number = stored\_integer * scaling\_factor\]

\ [0.0269 = 110 * 2 ^ {-12} \]

脚本如下:

脚本

现在让我们考虑所有层的权值。使用fi我们再次发现,对于卷积层中的所有权值,给出最佳精度的比例因子是2^-8。我们在直方图中可视化权重动态范围的分布。从直方图中可以看出,大多数权重分布在2^-3和2^-9的范围内(图1)。这也表明了权重分布的对称性。

图1。VGG16中卷积层权值的分布。

图1。VGG16中卷积层权值的分布。

这个例子展示了一种用8位整数进行量化和表示的方法。还有一些其他的选择:

通过考虑精度权衡来选择不同的比例因子.因为我们选择了2^-8的比例因子,近22%的权重低于精度。如果我们选择2^-10的比例因子,只有6%的权重会低于精度,但0.1%的权重会超出范围。误差分布和最大绝对误差也说明了这种折衷(图2)。我们可以选择16位整数,但这样就会使用两倍的位。另一方面,使用4位将导致严重的精度损失或溢出。

图2。比例因子为2^-8(左)和2^-10(右)的误差直方图分布及其对应的最大绝对误差。

图2。比例因子为2^-8(左)和2^-10(右)的误差直方图分布及其对应的最大绝对误差。

在调用时指定偏置fi,基于权重的分布。

\[Real\_number = stored\_integer * scaling\_factor + bias\]

您可以对任何网络(比如ResNet50或yolo)进行类似的分析,并确定一个整数数据类型或比例因子,它可以表示在一定容忍范围内的权重和偏差。

使用int8在整数中表示数据有两个关键好处:

  • 您可以将数据存储需求减少4倍,因为单精度浮点需要32位来表示一个数字。其结果是用于存储所有权重和偏差的内存减少,以及传输所有数据所消耗的功率减少,因为能量消耗主要由内存访问决定。
  • 您可以通过使用整数计算而不是浮点数学获得进一步的加速,这取决于目标硬件。例如,您可以在NVIDIA gpu上使用半精度浮点。大多数cpu不支持本机半计算。然而,所有的目标都支持整数数学,有些还提供特定于目标的固有特性,例如SIMD支持,在使用整数进行底层计算时可以提供显著的加速。

量化一个网络到int8

量化背后的核心思想是神经网络对噪声的弹性;尤其是深度神经网络,它被训练来捕捉关键模式并忽略噪声。这意味着网络可以应对由量化错误导致的网络权重和偏差的微小变化——越来越多的工作表明量化对整个网络的准确性的影响是最小的。再加上内存占用、功耗和计算速度的显著降低[1,2],使得量化成为将神经网络部署到嵌入式硬件的一种有效方法。

我们将把上面讨论的思想应用到网络中。为了简单起见,我们将使用一个由两层组成的简单网络进行MNIST数字分类。用于图像分类和目标检测的深度网络,如VGG16或ResNet,包括各种各样的层。卷积层和全连接层是内存密集和计算密集的层。

我们的网络模仿了这两层的特性。我们在Simulink中对这个网络建模®这样我们就可以观察信号流,并更深入地了解计算的核心(图3)。

图3。MNIST网络。

图3。MNIST网络。

在每一层中,我们将用缩放的int8整数替换权重和偏差,然后将矩阵乘法的输出与固定指数相乘以进行缩放。当我们在验证数据集上验证修改后的网络的预测时,混淆矩阵显示int8表示仍然保持95.9%的准确性(图4)。

图4。缩放MNIST的混淆矩阵。

图4。缩放MNIST的混淆矩阵

为了理解从量化权重和偏差到int8的效率收益,让我们将这个网络部署到一个嵌入式硬件目标上—在本例中,是一个ST发现板(STM32F746G).我们将分析两个关键指标:

  • 内存使用情况
  • 运行时执行性能

当我们尝试部署原始模型(采用双精度浮点)时,它甚至不能在板上安装,并且RAM溢出。最简单的解决方法是将权重和偏差转换为单一数据类型。该模型现在适合于目标硬件,但仍有改进的空间。

我们使用缩放模型,该模型对权重和偏差矩阵使用int8,但计算仍然是单精度的(图5)。

图5。第1层的矩阵乘法。权重是int8,但输入数据是单精度的,底层计算也是单精度的。

图5。第1层的矩阵乘法。权重是int8,但输入数据是单精度的,底层计算也是单精度的。

如预期的那样,生成的代码减少了4倍的内存消耗(图6)。

图6。左:单精度的代码。右:int8代码。

图6。左:单精度的代码。右:int8代码。

然而,发现板上的执行时间显示,单精度版本平均需要14.5毫秒(约69帧每秒),而缩放版本稍微慢一些,平均需要19.8毫秒(约50帧每秒)。这可能是因为转换为单一精度的开销,因为我们仍然在以单一精度进行计算(图7)。

图7。顶部:单精度生成的代码。底部:按比例缩小的版本。

图7。顶部:单精度生成的代码。底部:按比例缩小的版本。

这个例子只讨论了量化的一个方面——在int8中存储权值和偏差。通过将相同的原理应用到AlexNet和VGG等标准的现成网络,可以将它们的内存占用减少3倍[1]。

例如,TensorFlow支持训练后量化到8位的两种形式——仅使用浮点核的权值和权值和激活[3]的全整数量化。TensorFlow使用带有偏差的缩放因子来映射到int8范围[-128,127],而NVIDIA TensorRT通过确定一个阈值来将权重编码到[-128,127]范围,从而避免了偏差的需要,该阈值可以最小化信息丢失,并使超过阈值范围[4]的值饱和。

为了利用全整数量化的好处,我们还需要将每个层的输入扩展或转换为整数类型。这需要我们为层的输入确定正确的比例,然后在整数乘法后重新缩放。但是int8是正确的数据类型吗?是否存在溢出?网络的准确性是否可以接受?

这些问题是定点分析的本质——事实上,数字识别文档示例演示了如何使用定点数据类型[5]转换MNIST网络。按照该示例中所示的步骤,我们为权重提出了一个8位表示,其插入精度低于1%(图8)。

图8。模型转换为使用16位字长。

图8。模型转换为使用16位字长。

生成的代码不仅是原来的四分之一;它也更快,11毫秒~ 90 fps(图9)。

图9。左:从定点模型生成的代码。右:MNIST网络第一层的伸缩权值。

图9。左:从定点模型生成的代码。右:MNIST网络第一层的伸缩权值。

其他量化技术

我们只研究了为嵌入式部署优化深度神经网络的许多策略中的一些。例如,第一层中的权重(大小为100x702)仅由192个惟一值组成。其他可以应用的量化技术包括:

  • 通过聚类权重来共享权重,并使用霍夫曼编码来减少权重的数量[1]。
  • 将权重量化到最接近2的次幂。这大大提高了计算速度,因为它用更快的算术移位操作取代了乘法运算。
  • 用查找表替换激活函数,以加快激活函数的计算速度,例如双曲正切而且经验值.例如,在图9所示的生成代码中,我们可以通过替换双曲正切函数使用查找表。

深度学习应用不仅仅是网络。您还需要考虑应用程序的预处理和后处理逻辑。我们讨论的一些工具和技术已经用于量化这种算法几十年了。它们不仅可以量化网络,还可以量化整个应用程序。

您可以在MATLAB中探索所有这些优化思想。您可以探索量化进一步限制精度的整数数据类型(如int4)的可行性和影响,或者探索浮点数据类型(如半精度)。结果可能令人印象深刻:Song、Huizi和william[1]结合使用了这些技术,分别将AlexNet和VGG等网络的规模缩小了35倍和49倍。

2019年出版的

参考文献

  1. 深度压缩:基于剪枝、训练量化和Huffman编码的深度神经网络压缩-韩松,毛慧子,william J Dally, ICLR 2016。

  2. V. Vanhoucke, A. Senior,毛明哲,“提高cpu上神经网络的速度”,“深度学习与无监督特征学习研讨会”,2011,2011。

查看相关功能的文章

Baidu
map