JEFF JOHNSON作者Geek AI、路编译code.fb选自

Facebook新研究优化硬件浮点运算,强化AI模型运行速率


近日,Facebook 发布文章,介绍了一项新研究,该研究提出了一种使人工智能模型高效运行的方法,从根本上优化了浮点运算。

近年来,计算密集型的人工智能任务推动了各种用于高效运行这些强大的新型系统的定制化硬件的出现。我们采用浮点运算来训练深度学习模型,如 ResNet-50 卷积神经网络。但是,由于浮点数十分消耗资源,真正部署的人工智能系统通常依赖于使用 int8/32 数学运算的少数几个流行的整型量化技术。

Facebook 开发了一种使人工智能模型高效运行的方法。基于 70 多年前计算机科学发展初期的思想,该方法从根本上优化了浮点运算。

Facebook 对浮点数进行了彻底的改造,使它比 int8/32 数学运算的效率高出 16%。该方法用于卷积神经网络时,网络仍能达到很高的准确率,此外它还具备以下优势:

  • 该技术可以提高人工智能研发的速度。当该方法被应用于人工智能模型训练中使用的更高精度的浮点数时,模型训练的效率能够提高 69%。

  • 如今,模型通常使用浮点数进行训练,但是之后它们必须转换成更高效的、可以部署到生产环境中的量化格式。如果使用该方法,在部署模型时就不需要重新训练或重新学习。这样一来,人工智能开发者就可以更容易地部署高效的新模型。

  • 现在的整型量化方法正变得越来越复杂。在某些情况下,这些方法可能对某些特定任务「过拟合」(因此不能维持通用性)。高效的通用浮点运算可以在保持准确率的情况下避免过拟合问题。

论文「Rethinking float point for deep learning」详细介绍了 Facebook 的这项技术。开发使用这些新技术执行浮点运算的新芯片需要耗费一定的时间。但这样做可能得到的好处包括使数据中心的人工智能计算速度更快,在移动设备上获得更好的人工智能运算性能的低功耗设计,以及在进行较少的软件更改的情况下以更简单、迅速的方法达到性能目标。摩尔定律正在逐渐减速,而「暗硅」(dark silicon)时代即将到来。持续的性能提升需要重新考虑几十年前的底层硬件设计决策(比如 IEEE 754 浮点标准),以及在合适的情况下使用数学近似(mathematical approximation)。尤其是神经网络的出现成为对它们进行重新评估的绝佳契机,因为神经网络对数值运算的变化和实验具有相当大的容忍度。

Facebook 为 ASIC/FPGA 做出的硬件设计和为评估编写的 C++/PyTorch 代码已经向人工智能社区开放。地址:http://github.com/facebookresearch/deepfloat

传统的浮点运算

众所周知,浮点数可以在合理的计算机存储空间中表示大小实数,其使用的系统与科学计数法大体相似。这种格式可用于以固定宽度的编码和基数(通常是二进制)表示 1,000,000 和 0.0625 这样的值。需要注意的是,浮点数只能精确地表示有限的实数,因为我们拥有的比特位数是有限的。所有其他值都可以用一种四舍五入的形式表示为最接近的可以表示出来的浮点值。

传统的二进制浮点格式包含符号(sign)、尾数(significand)和指数(exponent)。符号位表示数字是正的还是负的。尾数(其小数部分通常称为尾数)是形如 0.bbb... 或 1.bbb... 的二进制定点数,其中小数部分 bbb… 由若干二进制位在基数点之后表示的。(在十进制运算中,基数点也称为小数点,将整数与小数部分分开。)指数是一个有符号整数,它表示尾数需要乘以 2 的多少次幂。尾数有前导二进制 1(1.bbb…)的情况是规格化的,而尾数有前导二进制 0(0.bbb…)的情况是非规格化的(二者可以相互转化)。现代计算机中常用的 IEEE 754 浮点标准有规格化和非规格化两种尾数表示方法。尾数的前导位不需要被显式存储;在 IEEE 754 中,指数域决定前导位是 1 还是 0。

下图显示了以 16 位 IEEE 754 的 binary16 半精度浮点数对 -1.625 进行的编码,它具有固定大小的 5 位指数和 10 位的尾数部分。IEEE 指数的偏置值为 -15,因此下面编码的指数 15 实际上表示(15-15)即 0。

人工智能运算的现状和未来

为许多人工智能系统赋能的神经网络通常使用 32 位 IEEE 754 binary32 单精度浮点数进行训练。将位数降低到 16 位(半精度浮点数或类似 bfloat16 的格式)会获得一定的性能提升,但与同样位宽整数运算的效率相比,它仍然相形见绌。这些浮点变量可以很容易地使用原来的 32 位浮点神经网络数据,但要将整数量化到 8 位(或更少)常常需要学习量化参数并对模型进行再训练。许多 int8/32 量化方案可以像原始的浮点模型达到同样的准确率,但是它们也可能在处理任务时发生过拟合现象,从而无法在 ImageNet 验证集以外的任务上保证其准确率

但是对于今天的计算机运算来说,除了整数、定点或浮点运算外,还有许多其他的选择。其中一些方法可以追溯到 20 世纪 50 年代:

  • 非线性尾数映射

  • 二进制随机数

  • 熵编码

Facebook 使用这一思路创造出了一种浮点运算,其性能超过 int8/32。该方法的实现与目前硬件中的浮点运算及其变体(如非规格化的清零行为或字大小/字段位宽度变化,如 bfloat16 或 minifloat)有很大的区别。与 int8/32 量化不同的是,该实现仍然是一种通用的浮点运算,可以直接对其运算结果进行解释。

实现更高效浮点运算的关键

为了开发一种高效浮点运算的新方法,Facebook 研究人员认真分析了硬件浮点数低效的各种原因:

  1. 字(word)大小过大:有很大一部分算力被用于移动数据:从外部的 DRAM 到内部的 SRAM,从 SRAM 到寄存器,或从寄存器到寄存器(触发器)。浮点的字大小越大,消耗的算力就越多。

  2. 通用的定点数机制:尾数是定点数,定点数的加法器、乘法器和除法器是算术运算所必需的。浮点类型的精度(尾数长度)越高,这些组件就越大。硬件乘法器和除法器通常比硬件加法器更消耗资源(芯片面积、功耗和延迟)。

  3. 通用的浮点数机制:该机制处理基数点的「浮点」,因此是浮点表示法的一部分。例如,用于重新规格化的前导零(LZ)计数器、用于尾数对齐的移位器和舍入逻辑。浮点精度也对该机制所使用的硬件资源有很大的影响。

  4. IEEE 754 的专有机制:这为 IEEE 754 标准中实现的逐渐下溢提供了非规格化的支持,并提供了额外的移位器、LZ 计数器和尾数重新规格化所需要的其他修改。非规格化的处理增加了大多数浮点操作的复杂性和计算开销。

减小字大小

缩小字(word)的大小可以显著地提升算力的利用率。我们可以尝试将 32 位数据压缩为 8 位或 16 位。典型的浮点数固定大小字段编码迫使我们做出困难的选择,是减少动态范围(指数)还是减小精度(尾数),而我们需要的是二者的折中。

我们可以用不同的方式来处理这种权衡。浮点数本身就是(无限精度)实数的量化形式。适用于见过的数据分布的量化器在数据复制的过程中误差会较小。对于在通用计算机上遇到的数据分布,我们通常没有太多的先验知识。然而,神经网络的分布在实际中是接近高斯分布的,有时还会受到批归一化等过程的控制。标准浮点数尽可能保证尾数在 10^-5 的精度与在 10^5 的精度相当,但大多数神经网络在一个相对较小的范围内(如 -10.0 到 10.00)执行计算。这个范围内的小数字(例如 0.0001)会被频繁使用,而大数字的使用频率较低。理想情况下,我们可以改变量化器,在需要的地方提供更高的精度,并保持一定的小数字动态范围。

缩减(tapered)浮点数可以帮助实现这些目标并减小字的大小。Gustafson 提出的 Posit 方法是一种效果很好的缩减形式。Posit 使用无前缀编码将指数编码为可变位数,其余部分为尾数。它在+/-1.0 左右将精度最大化,而在 0 或+/-∞ 处的精度则较低。它的压缩和扩展都是有损的,以损失某些地方的精度为代价来保证在其他地方的动态范围。因此,与 IEEE 风格的浮点数相比,它可以提供更高的精度(在某些地方)和更大的动态范围。当我们不知道待处理数据的数据分布时,posit 可以扩展到其他无前缀编码中(比如霍夫曼编码)。

定点数机制

我们可以设法避免在尾数上进行的乘法和除法运算。尾数可以被看作是小数部分的映射 f(x),它将取值范围在 [0, 1) 间的定点数 x 映射到 [1, 2) 中。(这种方法在 Lindstrom 等人 2018 年的论文《Universal Coding of the Reals: Alternatives to IEEE Floating Point》中有详细的介绍。)在典型的规格化浮点运算中,f(x) 是仿射函数 1+x(我们称之为线性域数)。

当 f(x) = 2^x 时,我们可以使用对数数字系统(LNS)将乘法和除法变成加法和减法。不过,添加 LNS 需要大量的硬件查找表来计算两个对数域数的和或差。这是采用 LNS 的一个主要问题,因为这些表可能比硬件乘法器更难以处理。注意,典型的浮点数已经是对数(指数)和线性(尾数)表示的组合,但是 LNS 表示完全是基于对数的。

浮点数机制

在计算机线性代数中,有效的操作是「乘加」:计算值「c」和 a 与 b 乘积「a x b」的和,得到「c + a x b」。通常情况下,对于 ResNet-50 等模型,单个累加器中可能会对数千个这样的乘积求和;在部署过程中运行一个模型时涉及数百万独立累加操作,而训练模型时则需要进行数以亿计的累加操作。

浮点融合乘加(FMA)是一种常见的乘加方法,它能够减小误差,但它比标准的浮点加法器或乘法器复杂得多。一种称为 Kulisch 累加的技术可以避免 FMA 的复杂操作。类似的操作在第一台可编程数字计算机 Konrad Zuse Z3 上被采用过。Gustafson 也在他最近的浮点研究中提出了 Kulisch 累加的标准用法(https://www.crcpress.com/The-End-of-Error-Unum-Computing/Gustafson/p/book/9781482239867)。其思想不是在浮点运算中进行累加,而是在定点运算中维护一个运行时的和(running sum),这个和需要足够大以避免下溢或溢出。与浮点加法不同的是,Kulisch 累加可以精确地表示任意数量的浮点值的和。不论顺序如何,求和方法都是满足结合率并可复现的。在完成所有求和工作之后,我们通过尾数对齐和舍入将其转换回浮点数。

下图显示了一个累加步骤的示例。Kulisch 累加器当前包含值 35.5,我们将其与 0.84375 相加,表示为线性域浮点值。这个被求和的浮点值可能以前来自于标量值的乘积,或者只是我们希望累加的单个值。在浮点指数的基础上,通过对齐尾数的基数点,将浮点数转换为定点数。该转换使用了一个调整因子,它是累加器最多尾数位(在下面的例子中是 6)的有效指数。然后将对齐后的尾数和累加器与进位相加。(为简单起见,此处省略了 Kulisch 累加器可能支持下溢和溢出所需的额外精度位)。在高于 32 位的浮点数中,Kulisch 累加的代价很高,因为累加器、移位器和加法器的大小可能大于 500 位,但是对于较小的浮点类型来说,它是非常实用的。

Kulisch 累加不能直接用于对数域求和。但是,正如 Kulisch 累加以不同于参数(浮点数)的形式(定点数)执行求和运算一样,这里也可以采用类似的方法,因此我们不需要一个巨大的 LNS 和/差查找表。我们可以在线性域中对 log 值取近似,在线性域中做 Kulisch 累加,然后在所有求和工作都完成时将其转换回 log 域。这种方法对于通用线性代数非常有效,因为向量内积需要在累加器中多次重复求和。

IEEE 754 的专有机制

有助于减小字大小的 posit 编码也避免了这个问题,因为 posit 的尾数总是规格化的。缓慢的下溢立刻防止了精度下降,而不是逐渐缓解精度下降,这在 IEEE 754 非规格化表示中是通过尾数部分中前导一的位置解决的。Posit 逐渐减小到更小的数字上,导致在指数上使用尾数部分的位,从而扩展了动态范围并降低了精度。Posit 的缩减(taper)技术在功能上类似于非规格化的逐渐下溢,但是没有重新规格化尾数的开销。Posit 缓慢溢出也以类似的方式支持缩减。

融合这些方法

为了获得性能的提升,研究人员考虑将这四种技术结合起来。对数域表示避免了硬件乘法器,我们将 posit 用于对数。为了与 int8/32 抗衡,研究人员考虑使用一种称为 (8, 1, alpha, beta, gamma) 对数的 8-bit 格式,其中 (8,1) 是 posit 参数。这种编码在最大和最小正值之间提供了超过 1600 万:1 的比率,同时在 1.0 左右保留了 4 位(对数域)精度,所有这些都是用 8 位表示的(只有 256 个可能的值)。alpha、beta 和 gamma 值可以控制对数到线性以及线性到对数的转换准确率

如上所述,我们在线性域中执行对数域的求和。这个结果是非常近似的,但与 FMA 不同的是,对于序列和,这里没有 Kulisch 累加的线性域误差。我们称这种技术为 ELMA,或精确的对数线性乘加。对数域乘法是精确的,所有的线性域求和过程也都是精确的,但是对数到线性的转换是近似的,返回的线性到对数的转换也是近似的。这种折中在实践中是可以接受的。

硬件查找表用于转换,但它们要比 LNS 加法所需表小得多。使用更大的 alpha、beta 和 gamma 参数会得到更精确的结果,但也会消耗更多的芯片面积和功耗。与浮点型 FMA 相比,ELMA 乘加电路及其核心更加简单。它使用三个加法器、一个查找表和一个移位器就完成了大部分工作:

直接替代方法

与 int8/32 不同,Facebook 研究人员针对神经网络的 8 位对数格式不需要学习量化参数、激活采样或对原始网络进行再训练。只需要获取网络(如 ResNet-50)的 32 位浮点参数,然后使用「取与该参数最近的偶数」的规则对其进行转换。使用 posit 编码可以在如此小的类型中保证所需的动态范围和精度。

使用 ELMA 的 (8, 1, 5, 5, 7) 对数与原始的 ResNet-50 的运算方法相同,在 ImageNet 验证集上获得了 75.23% 的 top-1 准确率和 92.66% 的 top-5 准确率,分别比原始网络的准确率降低了 0.9% 和 0.2%。这些结果与许多现有的 int8/32 量化方法类似。在 int8/32 量化中使用的调优训练和模型调整可以进一步提高该方法的性能,但是这里基线的结果是在对软件进行最少修改的情况下实现的。所有的数学仍然在通用浮点运算中执行,使用压缩编码作为量化器。ELMA 设计也可以被用于非线性代数任务(如多项式计算)。

硬件效率

研究人员使用一种商用 28 纳米 ASIC 工艺技术将 (8, 1, 5, 5, 7) 对数的 ELMA 以 int8/32 乘加 0.96 倍的功耗作用于独立的处理单元(PE)。在一个完整的 32×32 矩阵乘法的脉动阵列中,使用对数 ELMA 处理单元方案的功耗是使用 int8/32 处理单元版本的 0.865 倍。该方案之所以能够省电主要是因为取消了硬件乘法器。

扩展到 16 位后,即使没有非规格化的支持(这在很大程度上降低了 IEEE 754 的效率),这种方法使用的功耗是 IEEE 754 半精度 FMA 的 0.59 倍,而使用的芯片面积是后者的 0.68 倍,同时还降低了延迟。得益于这些 16 位浮点数上的性能提升,我们可以在相同的时间内支持更复杂的人工智能模型的训练。然而,与 32 位的 IEEE 754 单精度 FMA 相比,ELMA 并没有更加有效,这是由于 Kulisch 累加器过于庞大(增加了加法器/移位器尺寸和触发器功率),而且禁止使用从对数到线性的查找表。

未来的工作

实现人工智能技术的极大发展需要计算效率的显著提高,而这只有通过新方法才能实现,而不仅仅是建立在旧方法的基础上。例如,软件仿真工作常常很慢,无法有效地在前沿的人工智能模型上测试新的运算方法。不幸的是,在 FPGA/ASIC 硬件上进行实验比在软件上还要困难得多,这使得这些潜在的提升空间在很大程度上没有得到充分的开发。然而,如果开发出利用这些技术的新硬件,它将有利于广泛的人工智能研究和应用。

Facebook 计划研究硬件上的 16 位 ELMA 的设计,并将其在人工智能模型训练和其他任务上的性能表现与 IEEE 754 半精度浮点数和 bfloat16 进行对比。这些新想法和数值近似方法并不总是适用的,但是人工智能提供了一个独特的机会来探索它们的边界,并帮助推翻人们关于硬件可能完成的任务的旧有看法。

原文链接:https://code.fb.com/ai-research/floating-point-math/

工程浮点计算Facebook
2
相关数据
深度学习技术

深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。 深度学习是机器学习中一种基于对数据进行表征学习的算法,至今已有数种深度学习框架,如卷积神经网络和深度置信网络和递归神经网络等已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

高斯分布技术

正态分布是一个非常常见的连续概率分布。由于中心极限定理(Central Limit Theorem)的广泛应用,正态分布在统计学上非常重要。中心极限定理表明,由一组独立同分布,并且具有有限的数学期望和方差的随机变量X1,X2,X3,...Xn构成的平均随机变量Y近似的服从正态分布当n趋近于无穷。另外众多物理计量是由许多独立随机过程的和构成,因而往往也具有正态分布。

人工智能技术

在学术研究领域,人工智能通常指能够感知周围环境并采取行动以实现最优的可能结果的智能体(intelligent agent)

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

验证集技术

验证数据集是用于调整分类器超参数(即模型结构)的一组数据集,它有时也被称为开发集(dev set)。

数据压缩技术

数据压缩是指在不丢失有用信息的前提下,缩减数据量以减少存储空间,提高其传输、存储和处理效率,或按照一定的算法对数据进行重新组织,减少数据的冗余和存储的空间的一种技术方法。数据压缩包括有损压缩和无损压缩。在计算机科学和信息论中,数据压缩或者源编码是按照特定的编码机制用比未经编码少的数据位元(或者其它信息相关的单位)表示信息的过程。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

卷积神经网络技术

卷积神经网路(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现。卷积神经网路由一个或多个卷积层和顶端的全连通层(对应经典的神经网路)组成,同时也包括关联权重和池化层(pooling layer)。这一结构使得卷积神经网路能够利用输入数据的二维结构。与其他深度学习结构相比,卷积神经网路在图像和语音识别方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他深度、前馈神经网路,卷积神经网路需要考量的参数更少,使之成为一种颇具吸引力的深度学习结构。 卷积网络是一种专门用于处理具有已知的、网格状拓扑的数据的神经网络。例如时间序列数据,它可以被认为是以一定时间间隔采样的一维网格,又如图像数据,其可以被认为是二维像素网格。

准确率技术

分类模型的正确预测所占的比例。在多类别分类中,准确率的定义为:正确的预测数/样本总数。 在二元分类中,准确率的定义为:(真正例数+真负例数)/样本总数

映射技术

映射指的是具有某种特殊结构的函数,或泛指类函数思想的范畴论中的态射。 逻辑和图论中也有一些不太常规的用法。其数学定义为:两个非空集合A与B间存在着对应关系f,而且对于A中的每一个元素x,B中总有有唯一的一个元素y与它对应,就这种对应为从A到B的映射,记作f:A→B。其中,y称为元素x在映射f下的象,记作:y=f(x)。x称为y关于映射f的原象*。*集合A中所有元素的象的集合称为映射f的值域,记作f(A)。同样的,在机器学习中,映射就是输入与输出之间的对应关系。

逻辑技术

人工智能领域用逻辑来理解智能推理问题;它可以提供用于分析编程语言的技术,也可用作分析、表征知识或编程的工具。目前人们常用的逻辑分支有命题逻辑(Propositional Logic )以及一阶逻辑(FOL)等谓词逻辑。

先验知识技术

先验(apriori ;也译作 先天)在拉丁文中指“来自先前的东西”,或稍稍引申指“在经验之前”。近代西方传统中,认为先验指无需经验或先于经验获得的知识。先验知识不依赖于经验,比如,数学式子2+2=4;恒真命题“所有的单身汉一定没有结婚”;以及来自纯粹理性的推断“本体论证明”

过拟合技术

过拟合是指为了得到一致假设而使假设变得过度严格。避免过拟合是分类器设计中的一个核心任务。通常采用增大数据量和测试样本集的方法对分类器性能进行评价。

霍夫曼编码技术

霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的熵编码(权编码)算法。 霍夫曼编码(英语:Huffman Coding),又译为哈夫曼编码、赫夫曼编码,是一种用于无损数据压缩的熵编码(权编码)算法。由大卫·霍夫曼在1952年发明。 在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。

摩尔定律技术

摩尔定律是由英特尔创始人之一戈登·摩尔提出来的。其内容为:积体电路上可容纳的电晶体数目,约每隔两年便会增加一倍;经常被引用的“18个月”,是由英特尔首席执行官大卫·豪斯所说:预计18个月会将芯片的性能提高一倍。

线性代数技术

线性代数是数学的一个分支,它的研究对象是向量,向量空间(或称线性空间),线性变换和有限维的线性方程组。向量空间是现代数学的一个重要课题;因而,线性代数被广泛地应用于抽象代数和泛函分析中;通过解析几何,线性代数得以被具体表示。线性代数的理论已被泛化为算子理论。由于科学研究中的非线性模型通常可以被近似为线性模型,使得线性代数被广泛地应用于自然科学和社会科学中。

批归一化技术

批归一化(Batch Normalization,BN)由谷歌于2015年提出,是一个深度神经网络训练的技巧,它不仅可以加快模型的收敛速度,还能在一定程度上缓解深层网络中的“梯度弥散”问题,从而使得训练深层网络模型更加容易和稳定。目前BN已经成为几乎所有卷积神经网络的标配技巧了。从字面意思看来Batch Normalization(简称BN)就是对每一批数据进行归一化。

图网技术

ImageNet 是一个计算机视觉系统识别项目, 是目前世界上图像识别最大的数据库。

暂无评论
暂无评论~