低数值精度推理和训练
介绍
如今,大多数商业深度学习应用程序使用 32 位浮点精度 ( ) 来处理训练和推理工作负载。各种研究人员已经证明,深度学习训练和推理都可以以较低的数值精度进行,使用 16 位乘法器进行训练,使用 8 位乘法器进行推理,精度损失最小甚至没有。使用这些较低的数值精度(使用累积到 32 位的 16 位乘法器进行训练,以及使用累积到 32 位的 8 位乘法器进行推理)可能会成为明年的标准。
英特尔® 正积极致力于在英特尔® 至强® 处理器和其他产品中实现较低数值精度的推理和训练。较低的数值精度有两个主要好处。首先,许多操作都受内存带宽限制,降低精度将允许更好地使用缓存并减少带宽瓶颈。因此,可以更快地通过内存层次结构移动数据,以最大限度地利用计算资源。其次,硬件可以在较低的数值精度下实现更高的每秒运算 (OPS),因为这些乘法器需要更少的硅面积和功率。
在本文中,回顾了较低数值精度训练和推理的历史,并描述了英特尔® 如何为深度学习推理和训练实现较低数值精度。具体而言,描述了当前英特尔® 至强® 可扩展处理器中可用的指令以及未来英特尔® 至强® 可扩展处理器中可用的指令,这些处理器充当称为英特尔® 深度学习加速(英特尔® DL Boost)的嵌入式加速器。描述了如何量化模型权重和激活以及适用于深度神经网络的英特尔® 数学核心函数库(英特尔® MKL-DNN)。
https://github.com/oneapi-src/oneDNN
最后,描述了深度学习框架如何利用这些较低数值精度的函数并减少不同数值精度之间的转换开销。每个部分都可以独立于其他部分阅读。包括深学习培训与英特尔至强处理器的可扩展商业实例进行详细的论述,提出
https://software.intel.com/content/www/us/en/develop/articles/intel-processors-for-deep-learning-training.html
深度学习中低精度的简史
研究人员已经展示了使用 16 位乘法器进行深度学习训练,并使用 8 位乘法器或更少的数值精度进行推理,累积到更高的精度,并且各种模型的精度损失最小甚至没有损失。将激活和权重量化为 8 位,并将偏差和第一层输入保持在全精度 ( ),用于 CPU 上的语音识别任务。在前馈传播中训练了一个具有 -1、0 和 1 量化权重的简单网络,并使用 MNIST* 和 TIMIT* 数据集更新了反向传播中的高精度权重,性能损失可忽略不计。在 MNIST、CIFAR-10* 和 SVHN* 数据集上训练模型,使用较低的数值精度乘法器和高精度累加器,并更新高精度权重;提议将动态不动点(张量或高维数组具有一个共享指数)与随机舍入作为未来的工作。
将权重和激活编码为以 2 为底的对数表示(因为权重/激活具有非均匀分布);使用 5 位权重和 4 位激活对 CIFAR-10 进行了训练,从而最大限度地降低了性能下降。用二进制权重(第一层和最后一层除外)训练 AlexNet,并更新全精度权重,精度损失为 top-1 2.9%。根据实验,建议避免在全连接层和具有小通道或滤波器大小(例如,1x1 内核)的卷积层中进行二值化。
来自英特尔实验室,在卷积层中使用 4 位权重和 8 位激活训练 ResNet-101,同时以最高 1 2% 的精度损失进行全精度更新。使用 16 位浮点 ( ) 乘法器和全精度累加器进行训练,并更新了全精度权重,AlexNet*、VGG-D*、GoogLeNet*、ResNet-50*、Faster R 的精度损失可以忽略不计甚至没有损失-CNN*、Multibox SSD*、DeepSpeech2*、Sequence-to-Sequence*、bigLSTM* 和 DCGAN*(某些模型需要梯度缩放以匹配全精度结果)。
成功使用 8 位固定精度,1 个符号位,4 位整数部分和 3 位小数部分。使用了各种量化技术(见论文中的表 3),显示在降低的精度下损失最小或没有损失(除了第一层和最后一层保持全精度)。使用 16 位整数乘法器和 32 位累加器训练了 ResNet-50、GoogLeNet、VGG-16 和 AlexNet。描述了 Google 的 Tensorflow 处理单元 (TPU)* 原生支持用于训练工作负载的 bfloat16 数字格式,并将在未来的英特尔至强处理器和英特尔 Nervana 神经处理器中使用。
最常见的 16 位数字格式和 8 位数字格式分别是 16 位 IEEE 浮点数 ( fp16 )、bfloat16 ( bf16 )、16 位整数 ( int16 )、 8 位整数 ( int8 ) 和8 位 Microsoft* 浮点 ( ms-fp8 )。图 1 显示了其中一些格式之间的差异。
图 1. 各种数字格式表示。s 表示符号位。FP32 和 BF16 提供与 FP32 相同的动态范围,由于尾数较大,精度更高。
英特尔®至强®可扩展处理器采用英特尔® AVX-512 和英特尔® Deep Learning Boost,降低数值精度
英特尔至强可扩展处理器现在包括英特尔® Advance Vector Extension 512指令集。这些指令使较低的数值精度乘以较高的精度累加。将两个 8 位值相乘并将结果累加到 32 位需要 3 条指令,并且需要 8 位向量之一为unsigned int8 ( u8 ) 格式,另一个为singed int8 ( s8 ) 格式,累加为singed int32 ( s32) 格式。以 3 倍多指令或 33.33% 多计算为代价的 4 倍多输入。用于较低数值精度操作的减少的内存和更高的频率可以提供额外的性能增益。详见图 2。
图 2. 英特尔至强可扩展处理器内核通过 3 条指令实现 8 位乘法和 32 位累加:VPMADDUBSW υ8×s8→ s16 倍数、VPMADDWD broadcast1 s16 →s32和 VPADDD s32→s32将结果添加到累加器。这允许比fp32多 4 倍的输入,代价是多 3 倍的指令或 33.33% 的计算量和 1/4 的内存要求。减少的内存和更高的频率以及较低的数值精度使其更快。图片来源以色列 Hirsh。
一个潜在的问题是在使用 VPMADDUBSW 指令υ8×s8→s16 时可能发生的未定义溢出行为(见图 2)。当接近最大值时,这是一个问题。这可以通过将输入精度降低 1 位来缓解。另一种技术是