当前位置: 首页 > article >正文

深度学习推理的整数量化:原理与实证评估

摘要

量化技术可以通过利用高吞吐量的整数指令来减小深度神经网络的大小,并提高推理延迟和吞吐量。在本文中,我们回顾了量化参数的数学特性,并评估了它们在不同应用领域(包括视觉、语音和语言)的广泛神经网络模型上的选择。我们专注于那些能够通过具有高吞吐量整数数学流水线的处理器加速的量化技术。我们还提出了一种8位量化的工作流程,能够在所有研究的网络上保持准确度在浮点基线的1%以内,包括那些更难量化的模型,如MobileNets和BERT-large。

1. 引言

虽然32位单精度浮点曾是深度学习(DL)应用的主导数值格式,但最近提出了多种替代格式以提高深度学习应用的计算性能。使用16位浮点格式(无论是IEEE fp16 [35]还是bfloat16 [57])训练神经网络已成为常态,这些格式得到了大多数DL加速器的支持。一旦训练完成,神经网络可以部署用于推理,使用更低精度的格式,包括浮点、定点和整数。低精度格式提供了几个性能优势。首先,许多处理器为低比特格式提供了更高吞吐量的数学流水线,可以加速数学密集型操作,如卷积和矩阵乘法。其次,较小的字大小减少了内存带宽压力,提高了带宽受限计算的性能。第三,较小的字大小导致内存大小需求降低,这可以提高缓存利用率以及内存系统操作的其他方面。
在本文中,我们专注于神经网络推理的整数量化,其中训练好的网络被修改为使用整数权重和激活,以便整数数学流水线可以用于许多操作。表1列出了NVIDIA Turing图形处理单元(GPU)架构上各种数据类型的相对张量操作吞吐量[40]。在8位整数类型上执行的数学密集型张量操作可以看到与fp32相同的操作相比高达16倍的加速。由于较小的字大小,内存受限的操作与fp32版本相比可以看到高达4倍的加速。其他处理器,如TPUv1 [23]、带有VNNI指令的Intel CPU [28]以及许多新兴的加速器设计,也为int8操作提供了显著的加速。
神经网络量化的过程可以通过软件工具[36, 61]自动化或手动控制。无论哪种情况,都必须小心谨慎,以最小化量化对模型准确度的影响。
在这里插入图片描述

在本文中,我们回顾了各种整数量化选择的数学基础(第3节)以及恢复由于量化而丢失的准确度的技术(第5节)。第6节将这些信息结合成一个推荐的工作流程。在第4节和附录中,我们对来自不同应用领域(图像处理、语言建模、语言翻译和语音识别)的广泛网络模型的各种量化选择进行了实证评估。这些模型包括主要的网络拓扑结构——卷积网络、循环网络以及基于注意力的网络。通过提出的int8量化工作流程,我们能够将模型准确度保持在每个浮点网络的1%以内,即使是那些已知难以量化的网络,如MobileNets和BERT-large。

2 相关工作

Vanhoucke等人[52]展示了早期的神经网络可以在训练后被量化,以在Intel CPU上使用int8指令,同时保持浮点模型的准确性。最近的研究表明,一些现代网络在量化为int8时需要训练以保持准确性。Jacob等人[20]描述了为推理优化的模型,其中所有推理操作都使用整数数据类型执行。在这里,批量归一化层在量化之前被折叠到前一个卷积层中,减少了推理期间需要执行的层数。Krishnamoorthi[26]评估了各种量化方法和比特宽度在各种卷积神经网络(CNN)上的效果。他表明,即使使用每通道量化,像MobileNet这样的网络也无法通过int8训练后量化(PTQ)达到基线准确性,需要量化感知训练(QAT)。McKinstry等人[33]证明了在量化为int8后,许多ImageNet CNN只需微调一个周期即可达到基线准确性。他们强调了使用退火学习率计划和非常小的最终学习率的重要性。他们还基于从训练集中采样的激活百分位数设置了量化范围。Choi等人[6]提出了PACT,它在训练期间学习激活范围,而不是使用固定范围。
该领域的许多早期研究集中在极低比特量化[7, 13, 59],一直到三元(2比特)[60, 34]和二元权重[8]和激活[45, 18]。这些工作表明,对于较低的比特宽度,需要训练量化以实现高准确性,尽管在更困难的任务(如ImageNet图像分类[47])上,准确性仍然低于浮点网络。他们还展示了使用更高精度的权重更新和梯度反向传播的直通估计器(STE)等技术的重要性[3]。此外,在许多情况下,第一层和最后一层没有被量化,或者用更高的比特宽度量化,因为它们对量化更敏感[59, 45, 18]。多比特量化方案使用均匀[7, 59]或非均匀量化[13, 60, 34, 2]。均匀量化使得可以使用整数或定点数学流水线,允许在量化域中执行计算。非均匀量化需要在更高精度计算之前进行反量化,例如代码本查找,限制了其在模型压缩和带宽减少方面的好处。本文专注于利用量化加速计算,因此我们将限制我们的焦点在均匀量化方案上。
虽然上述许多工作集中在用于图像分类的CNN上,但也有许多将量化应用于其他类型网络架构的例子。Wu等人[55]描述了Google的神经机器翻译(GNMT),它采用了长短期记忆(LSTM)循环神经网络(RNN),如何在多个张量上训练硬范围约束以更适合PTQ。在MobileNet v2[48]上采取了类似的策略,它将激活限制在[0, 6]范围内(ReLU6)。Bhandare等人[4]量化了较小的基础Transformer[53]模型,针对Intel CPU上的int8 VNNI指令。他们使用KL散度[36]来校准量化范围并应用PTQ。Zafrir等人[58]使用PTQ和QAT将BERT[10]量化为int8。在本文中,我们展示了所有主要网络架构上int8量化的评估,包括PTQ和QAT。
还提出了更复杂的方法来训练量化模型。蒸馏已被用于训练一个量化的“学生”模型,使用高精度且通常更大的“教师”模型。它已被应用于训练量化的CNN[37, 43]、LSTM[43]和Transformer[24]。Leng等人[31]在训练量化模型时使用交替方向乘子法(ADMM)作为STE的替代。这些方法通常针对较低的比特宽度量化,因为QAT已被证明足以用于int8量化。我们还发现QAT足以用于我们评估的模型上的int8量化,因此我们选择不将这些方法包括在我们的int8量化评估中。

在这里插入图片描述

我们专注于均匀整数量化,因为它能够在整数域中计算矩阵乘法和卷积,从而允许使用高吞吐量的整数数学流水线。均匀量化可以分为两个步骤。首先,选择要量化的实数的范围,将超出此范围的值进行截断。其次,将实数值映射到量化表示的比特宽度可表示的整数(将每个映射的实数值四舍五入到最接近的整数值)。
在本节中,我们将高精度浮点格式(如fp16和fp32)视为实数以便讨论。在预训练的浮点神经网络中启用整数操作需要两个基本操作:
量化:将实数转换为量化整数表示(例如,从fp32到int8)。
反量化:将量化整数表示的数字转换为实数(例如,从int32到fp16)。
我们将在第[3.1]节中首先定义量化和反量化操作,并在第[3.2]节和第[3.3]节中讨论它们在神经网络量化中的含义。然后,我们将在第[3.4]节中讨论如何选择实数范围。

3.1 范围映射

[ β , α ] [\beta, \alpha] [β,α] 为选择的量化可表示实数值的范围, b b b 为有符号整数表示的比特宽度。均匀量化将输入值 x ∈ [ β , α ] x \in [\beta, \alpha] x[β,α] 转换为位于 [ − 2 b − 1 , 2 b − 1 − 1 ] [-2^{b-1}, 2^{b-1}-1] [2b1,2b11] 范围内的值,其中超出范围的输入被截断到最近的边界。由于我们仅考虑均匀变换,变换函数只有两种选择: f ( x ) = s ⋅ x + z f(x) = s \cdot x + z f(x)=sx+z 及其特例 f ( x ) = s ⋅ x f(x) = s \cdot x f(x)=sx,其中 x , s , z ∈ R x, s, z \in \mathbb{R} x,s,zR。在本文中,我们将这两种选择分别称为仿射和比例。

3.1.1 仿射量化

仿射量化将实数值 x ∈ R x \in \mathbb{R} xR 映射到 b b b 位有符号整数 x q ∈ { − 2 b − 1 , − 2 b − 1 + 1 , … , 2 b − 1 − 1 } x_q \in \{-2^{b-1}, -2^{b-1}+1, \ldots, 2^{b-1}-1\} xq{2b1,2b1+1,,2b11}

公式 (1) 和 (2) 定义了仿射变换函数 f ( x ) = s ⋅ x + z f(x) = s \cdot x + z f(x)=sx+z

s = 2 b − 1 α − β (1) s = \frac{2^b - 1}{\alpha - \beta} \tag{1} s=αβ2b1(1)

z = − round ( β ⋅ s ) − 2 b − 1 (2) z = -\text{round}(\beta \cdot s) - 2^{b-1} \tag{2} z=round(βs)2b1(2)

其中, s s s 是比例因子, z z z 是零点——实数值零映射到的整数值。在 8 位情况下, s = 255 α − β s = \frac{255}{\alpha - \beta} s=αβ255 z = − round ( β ⋅ s ) − 128 z = -\text{round}(\beta \cdot s) - 128 z=round(βs)128。注意, z z z 被四舍五入为整数值,以便实数值零能够精确表示。这将导致可表示实数值范围 [ β , α ] [\beta, \alpha] [β,α] 的轻微调整 [20]。

量化操作

量化操作由公式 (3) 和 (4) 定义:
clip ( x , l , u ) = { l , x < l x , l ≤ x ≤ u u , x > u (3) \text{clip}(x, l, u) = \begin{cases} l, & x < l \\ x, & l \leq x \leq u \\ u, & x > u \end{cases}\tag{3} clip(x,l,u)= l,x,u,x<llxux>u(3)

x q = quantize ( x , b , s , z ) = clip ( round ( s ⋅ ( x + z ) ) , − 2 b − 1 , 2 b − 1 − 1 ) (4) x_q = \text{quantize}(x, b, s, z) = \text{clip}(\text{round}(s \cdot (x + z)), -2^{b-1}, 2^{b-1}-1)\tag{4} xq=quantize(x,b,s,z)=clip(round(s(x+z)),2b1,2b11)(4)

其中,round 表示四舍五入到最近的整数。图 1a 展示了使用仿射量化将实数值映射到 int8 表示的过程。注意, s s s 是整数可表示范围与所选实数值范围的比值。

公式 (5) 展示了对应的反量化函数,用于计算原始实数值输入的近似值 x ^ ≈ x \hat{x} \approx x x^x
x ^ = dequantize ( x q , s , z ) = 1 s ( x q − z ) (5) \hat{x} = \text{dequantize}(x_q, s, z) = \frac{1}{s}(x_q - z)\tag{5} x^=dequantize(xq,s,z)=s1(xqz)(5)

比例量化

比例量化仅通过比例变换进行范围映射。为简单起见,我们描述比例量化的对称变体(通常称为对称量化 [26]),其中输入范围和整数范围关于零对称。这意味着对于 int8,我们使用整数范围 [ − 127 , 127 ] [-127, 127] [127,127],选择不使用值 − 128 -128 128 以保持对称性。对于 8 位量化,丢失 256 个可表示值中的一个影响不大,但对于更低比特的量化,应在可表示值与对称性之间重新评估权衡。

图 16 展示了使用比例量化将实数值映射到 int8 的过程。公式 (6) 和 (7) 定义了实数值 x x x 的比例量化,其中选择的可表示范围为 [ − a , a ] [-a, a] [a,a],生成一个 b b b 位整数值 x q x_q xq
s = 2 b − 1 − 1 a (6) s = \frac{2^{b-1}-1}{a}\tag{6} s=a2b11(6)

x q = quantize ( x , b , s ) = clip ( round ( s ⋅ x ) , − 2 b − 1 + 1 , 2 b − 1 − 1 ) (7) x_q = \text{quantize}(x, b, s) = \text{clip}(\text{round}(s \cdot x), -2^{b-1} + 1, 2^{b-1} - 1)\tag{7} xq=quantize(x,b,s)=clip(round(sx),2b1+1,2b11)(7)

公式 (8) 展示了比例量化对应的反量化操作:
x ^ = dequantize ( x q , s ) = 1 s x q (8) \hat{x} = \text{dequantize}(x_q, s) = \frac{1}{s}x_q\tag{8} x^=dequantize(xq,s)=s1xq(8)

3.2 张量量化粒度

在张量元素之间共享量化参数有几种选择。我们将这种选择称为量化粒度。最粗粒度的量化是每张量粒度,即张量中的所有元素共享相同的量化参数。最细粒度的量化则是每个元素都有独立的量化参数。介于两者之间的粒度则是在张量的不同维度上重用参数——例如,对于二维矩阵,可以是每行每列;对于三维(类似图像的)张量,可以是每通道等。

在选择粒度时,我们将考虑两个因素:对模型准确性的影响和计算成本。为了理解计算成本,我们将以矩阵乘法为例进行分析(注意,这对于数学密集型操作具有普遍性,因为卷积可以表示为矩阵乘法 [5, 54])。

考虑一个执行矩阵乘法 Y = X W Y = XW Y=XW 的线性(全连接)层,其中 X = ( x i k ) ∈ R m × p X = (x_{ik}) \in \mathbb{R}^{m \times p} X=(xik)Rm×p 是输入激活张量, W = ( w k j ) ∈ R p × n W = (w_{kj}) \in \mathbb{R}^{p \times n} W=(wkj)Rp×n 是权重张量, Y = ( y i j ) ∈ R m × n Y = (y_{ij}) \in \mathbb{R}^{m \times n} Y=(yij)Rm×n 是输出张量。通过使用量化张量 X q = ( x q , i k ) ∈ Z m × p X_q = (x_{q,ik}) \in \mathbb{Z}^{m \times p} Xq=(xq,ik)Zm×p W q = ( w q , k j ) ∈ Z p × n W_q = (w_{q,kj}) \in \mathbb{Z}^{p \times n} Wq=(wq,kj)Zp×n,可以近似实值矩阵乘法 Y = X W Y = XW Y=XW 的结果。具体方法是先对量化张量进行反量化,然后执行矩阵乘法。首先,考虑使用最细粒度的量化(即每个元素单独量化)和比例量化:

y i j = ∑ k = 1 p x i k ⋅ w k j ≈ ∑ k = 1 p dequantize ( x q , i k , s x , i k ) ⋅ dequantize ( w q , k j , s w , k j ) = ∑ k = 1 p 1 s x , i k x q , i k ⋅ 1 s w , k j w q , k j (9) y_{ij} = \sum_{k=1}^p x_{ik} \cdot w_{kj} \approx \sum_{k=1}^p \text{dequantize}(x_{q,ik}, s_{x,ik}) \cdot \text{dequantize}(w_{q,kj}, s_{w,kj}) = \sum_{k=1}^p \frac{1}{s_{x,ik}} x_{q,ik} \cdot \frac{1}{s_{w,kj}} w_{q,kj}\tag{9} yij=k=1pxikwkjk=1pdequantize(xq,ik,sx,ik)dequantize(wq,kj,sw,kj)=k=1psx,ik1xq,iksw,kj1wq,kj(9)
为了使用整数矩阵乘法,必须将公式 (9) 右侧求和中的比例因子提取出来,这就要求比例因子与 k k k 无关:

1 s x , i ⋅ s w , j ∑ k = 1 p x q , i k ⋅ w q , k j (10) \frac{1}{s_{x,i} \cdot s_{w,j}} \sum_{k=1}^p x_{q,ik} \cdot w_{q,kj}\tag{10} sx,isw,j1k=1pxq,ikwq,kj(10)
因此,只要激活的量化粒度为每行或每张量,权重的量化粒度为每列或每张量,就可以实现整数矩阵乘法。对于激活来说,出于性能考虑,只有每张量量化是实际可行的。在上述公式中,不同的行属于不同的批次实例或序列中的不同项,因此在推理时行数可能会变化。这导致无法离线计算每行的比例因子(这对于小批量中的不同实例没有意义),而在线计算则会增加计算开销,并且在某些情况下会导致准确性下降(参见 [158] 中的动态量化讨论)。

为了获得最佳性能,激活应使用每张量量化粒度。对于形式为 Y = X W Y = XW Y=XW 的线性层,权重应以每张量或每列粒度进行量化(对于形式为 Y = X W T Y = XW^T Y=XWT 的线性层,则为每行)。在卷积中,与每列对应的粒度是每核,或者等效地称为每输出通道,因为每个核生成一个单独的输出通道 。这在文献中通常被称为“每通道”权重量化,我们遵循这一惯例。我们将在第 4.1 节中探讨量化粒度对准确性的影响。

3.3 仿射量化的计算成本

虽然仿射量化和比例量化都支持使用整数运算,但仿射量化会导致推理计算成本更高。如公式 (10) 所示,比例量化会生成一个整数矩阵乘法,随后是一个逐点的浮点乘法。鉴于深度神经网络(DNN)中的典型点积操作包含数百到数千次乘加运算,最后的一个浮点操作成本可以忽略不计。此外,如果对两个参数都使用每张量量化,则只需要一个浮点乘法器,并且它通常是 BLAS 库中 GEMM API 的一部分(通常称为 alpha)[11]。而仿射量化则会产生更复杂的表达式:

y i j ≈ ∑ k = 1 p 1 s x ( x q , i k − z x ) 1 s w , j ( w q , k j − z w , j ) = 1 s x s w , j ( ∑ k = 1 p x q , i k w q , k j − ∑ k = 1 p ( w q , k j z x + z x z w , j ) − ∑ k = 1 p x q , i k z w , j ) (11) \begin{aligned} y_{ij} &\approx \sum_{k=1}^p \frac{1}{s_x} (x_{q,ik} - z_x) \frac{1}{s_{w,j}} (w_{q,kj} - z_{w,j}) \\ &= \frac{1}{s_x s_{w,j}} \left( \sum_{k=1}^p x_{q,ik} w_{q,kj} - \sum_{k=1}^p \left( w_{q,kj} z_x + z_x z_{w,j} \right) - \sum_{k=1}^p x_{q,ik} z_{w,j} \right) \\ & \end{aligned}\tag{11} yijk=1psx1(xq,ikzx)sw,j1(wq,kjzw,j)=sxsw,j1(k=1pxq,ikwq,kjk=1p(wq,kjzx+zxzw,j)k=1pxq,ikzw,j)(11)
计算可以分解为三个部分,如公式 (11) 中标注所示。第一部分是整数点积,与比例量化中的情况相同(公式 (10))。第二部分仅包含整数权重和零点,因此可以离线计算,仅在推理时增加一个逐元素加法。如果该层有偏置项,则可以将此项合并到偏置中,而不会增加推理成本。然而,第三部分涉及量化输入矩阵 X q X_q Xq,因此无法离线计算。根据具体实现,这部分额外计算可能会引入显著的开销,从而减少甚至消除整数数学流水线相对于低精度浮点的吞吐量优势。需要注意的是,仅当对权重矩阵使用仿射量化时才会产生这种额外计算。因此,为了最大化推理性能,我们建议对权重使用比例量化。虽然对激活使用仿射量化不会带来性能损失,但我们在后续章节中表明,比例量化足以满足我们研究的所有网络的 int8 量化需求。

在这里插入图片描述

3.4 校准

校准是为模型权重和激活选择 α \alpha α β \beta β 的过程。为简单起见,我们描述对称范围的校准,这是比例量化所需的。在本文中,我们考虑了三种校准方法:

  1. 最大值法(Max):使用校准期间观察到的最大绝对值 [52]。
  2. 熵法(Entropy):使用 KL 散度来最小化原始浮点值与量化格式可表示值之间的信息损失。这是 TensorRT 默认使用的方法 [36]。
  3. 百分位法(Percentile):将范围设置为校准期间观察到的绝对值分布的百分位数 [33]。例如,99% 校准会裁剪掉 1% 的最大幅值。

图 2 显示了 ResNet50 中 layer1.0.conv2 层输入激活的对数缩放直方图。虚线显示了通过最大值法、熵法和 99.99% 百分位法校准得到的范围。需要注意的是,由于该层直接跟在 ReLU 激活函数 [39] 之后,因此激活值严格非负。最大值法表示分布中的最大值,保持了完整范围但精度较低。裁剪分布会以少数异常值上的较大裁剪误差为代价,换取大多数值上的较小舍入误差。熵法和百分位法都会裁剪一些异常值,以提高内点值的分辨率。

4 训练后量化

在本节中,我们评估了各种训练后量化(PTQ)参数选择,如第 [3] 节所述。量化参数通过处理训练好的模型权重和在样本数据集上运行推理生成的激活值进行离线校准,不涉及进一步的训练。这些量化参数在多种神经网络任务和模型上进行了评估,总结在表 Z \mathbb{Z} Z 中。有关这些网络的更多详细信息可以在附录 A \color{red}{\boxed{\mathrm{A}}} A 中找到。所选模型包括多种类型的网络架构:卷积前馈网络、循环网络和基于注意力的网络。我们报告了在相应数据集的评估集上计算的准确性指标。所有任务的指标均以百分比形式报告,数值越高越好, 100 % 100\% 100% 为满分。为了指标一致性,我们在语音识别中报告词准确率(WAcc)而不是更常用的词错误率(WER),其中 WAcc = 100 % − = 100\% - =100% WER。需要注意的是,不同任务的准确性指标计算方式差异很大,因此在量化不同模型时比较准确性的绝对变化是没有意义的。因此,在讨论准确性影响时,我们将参考相对准确性变化,计算公式为 ( acc i n t 8 − acc f p 32 ) / acc f p 32 (\text{acc}_{int8} - \text{acc}_{fp32}) / \text{acc}_{fp32} (accint8accfp32)/accfp32

我们的实验使用 PyTorch [42] 进行,并使用了自定义的量化操作。我们专注于量化计算密集型操作,包括卷积、线性(全连接)层、LSTM 单元、投影层和其他矩阵乘法。大多数其他层(如 softmax 和批量归一化)除非特别说明,否则不进行量化。通过量化其所有输入(例如权重和激活)来量化一个操作。量化操作的输出不会量化为 int8,因为后续操作可能需要更高的精度,例如非线性操作。此外,连续的操作可以通过融合实现来执行,避免中间值的内存读写。因此,我们将输出激活的量化留到下一个操作的输入中进行。附录 [C] 讨论了如何通过将批量归一化折叠到前一层中来消除其在推理中的影响。
在这里插入图片描述

4.1 权重量化

我们首先单独评估权重量化,因为权重的值不依赖于网络输入,并证明最大校准(max calibration)足以维持 int8 权重的准确性。表 3 比较了每张量和每通道量化粒度对准确性的影响,第 3.2 节已表明这两种粒度所需的计算开销最小。虽然每张量量化会导致某些网络的准确性显著下降,但在将批量归一化(BN)参数折叠到卷积层后,EfficientNet 的准确性损失更为显著,甚至可能是灾难性的。BN 折叠(附录 C)是一种常见的加速推理的技术,因为它完全消除了这种内存受限的操作,同时不改变底层数学运算。然而,由于 BN 参数是按通道学习的,折叠后可能导致不同通道的权重值分布差异显著。幸运的是,如表 3 所示,每通道量化粒度即使在 BN 折叠后也能保持模型准确性。表 4 报告了每通道(对于线性层为每列)粒度的结果,并表明在将权重量化为 int8 时,最大校准足以维持准确性。本文的其余实验均使用每通道最大校准对权重进行量化。

4.2 激活量化

表 5 展示了不同校准方法下的激活量化结果:最大校准(max)、熵校准(entropy)以及从 99.9% 到 99.9999% 的百分位校准。有关激活校准的详细信息可在附录 A 中找到。在所有情况下,权重均按第 4.1 节所述的每通道最大校准进行量化。
在这里插入图片描述

对于大多数网络,至少存在一种激活校准方法能够实现可接受的准确性,但 MobileNets、EfficientNets、Transformer 和 BERT 的准确性下降超过了 1%。最大校准在不同网络中的表现不一致,导致 Inception v4、EfficientNets 和 Transformer 的准确性显著下降,这可能是由于它们的异常值较大。99.9% 百分位校准对大值裁剪过于激进,导致大多数网络的准确性显著下降。训练后量化的最佳结果通常通过熵校准、99.99% 或 99.999% 百分位校准实现,但没有一种校准方法对所有网络都是最优的。

5 恢复准确性的技术

虽然许多网络在训练后量化后仍能保持准确性,但在某些情况下,准确性损失较大。有多种技术可用于恢复准确性。最简单的方法是部分量化(见第 5.1 节),即不对最敏感的层进行量化。另一种选择是对网络进行量化感知训练(见第 5.2 节)。最后,还有一些方法可以联合学习模型权重和量化参数。

在这里插入图片描述
在这里插入图片描述

5.1 部分量化

通常,只有少数量化层对量化模型的准确性损失贡献最大。我们可以通过不对这些敏感层进行量化(即保持其输入和计算为浮点数)来牺牲一些性能以换取更高的准确性。由于一个层的量化会影响其他层的输入,找到最优的量化层集可能需要评估指数级的配置数量。相反,我们提出使用逐层敏感性分析作为一种更易处理的方法,以推断哪些层对准确性下降的贡献最大。

在敏感性分析过程中,每次只量化一个层,并评估模型的准确性。我们将量化后导致准确性下降的层称为对量化更“敏感”的层。我们按敏感性从高到低对层进行排序,并跳过最敏感层的量化,直到达到所需的准确性。

图 3 展示了 EfficientNet b0 的敏感性分析和部分量化的示例。从熵校准开始,我们每次量化一个层并评估准确性。为了清晰起见,我们仅展示了 10 个最敏感的层。在这个例子中,跳过 10 个最敏感的层将相对 top-1 准确性下降减少到 0.65%。由于共有 82 个卷积层,保持 10 个层为浮点数同时量化剩余的 72 个层,可以保留大部分性能优势。

如表 5 所示,MobileNet v1、EfficientNets、Transformer 和 BERT 在使用各种校准方法量化时都出现了显著的准确性损失。我们在表 6 中列出了这些网络的部分量化结果。除了 BERT 之外,这些网络只需跳过少数最敏感层的量化,即可将准确性恢复到 fp32 准确性的 1% 以内。对于 BERT,敏感性分析并未发现任何特定层对准确性下降的贡献更大。因此,我们无法确定一小部分层保持为浮点数。为了解决这个问题,我们需要考虑其他方法。第 5.2 节将量化与训练结合以恢复准确性。此外,附录 D 研究了 BERT 中的 GELU 激活函数,并提出了一种简单的增强方法,可显著提高训练后量化的准确性。
在这里插入图片描述

5.2 量化感知训练

量化感知训练(Quantization-Aware Training, QAT)是一种在训练或微调之前将量化操作插入神经网络的技术,以使网络能够适应量化后的权重和激活值。附录 B 展示了这种方法如何带来更好的结果。我们将 QAT 应用于微调,因为研究表明,从预训练网络开始并进行微调可以获得更高的准确性 [37][26],并且所需的迭代次数显著减少 [33]。这也使我们能够利用第 4 节中校准的预训练模型。需要注意的是,我们在整个微调过程中保持量化范围固定。另一种方法是学习量化范围,我们将在第 5.3 节中对此进行评估。

实现 QAT 的常见方法是在浮点网络中插入伪量化(也称为模拟量化 [26])操作。公式 (12) 将伪量化定义为量化和反量化操作,生成输入的近似版本 h a t x ≈ x hat{x} \approx x hatxx,其中 x x x h a t x hat{x} hatx 都是浮点值:

x ^ = dequantize ( q u a n t i z e ( x , b , s ) , b , s ) ( 12 ) \hat{x}=\text{dequantize}(\mathrm{quantize}(x,b,s),b,s)\quad(12) x^=dequantize(quantize(x,b,s),b,s)(12)
我们在希望量化的操作的输入处添加伪量化操作,以模拟量化的效果。回顾第 3.2 节中的矩阵乘法示例,公式 (9) 实际上是一个伪量化的矩阵乘法。训练完成后,我们转换网络以实现如公式 (10) 所示的量化整数矩阵乘法。

在浮点数训练中引入量化的一个挑战是,量化操作的导数在步长边界处未定义,而在其他位置为零。在每次训练迭代的反向传播中,需要导数来计算损失梯度。量化感知训练(QAT)通过使用直通估计器(Straight-through Estimator, STE)[3] 来解决这个问题,如图 ☑ 所示。如公式 [T3] 所定义,STE 将伪量化函数的导数近似为 1,前提是输入在可表示范围 [ β , α ] [\beta, \alpha] [β,α] 内(如第 3.1 节定义):

d x ^ d x = { 0 , y < β 1 , β ≤ y ≤ α 0 , y > α (13) \frac{d\hat{x}}{dx} = \begin{cases} 0, & y < \beta \\ 1, & \beta \leq y \leq \alpha \\ 0, & y > \alpha \end{cases}\tag{13} dxdx^= 0,1,0,y<ββyαy>α(13)
表 [7] 总结了训练后量化(PTQ)和微调量化(QAT)的最佳结果。PTQ 最佳结果报告了表 Eland 中每个量化网络的最佳结果及其对应的校准方法。QAT 报告了使用 PTQ 确定的最佳校准方法进行微调后的准确性。微调方法的详细信息和完整的 QAT 结果集可以在附录 A.2 中找到。

如表 7 所示,量化感知微调在大多数情况下提高了准确性,唯一的例外是 ResNeXt-101、Mask R-CNN 和 GNMT,这些情况下训练后量化的结果略好一些。值得注意的是,对于这 3 种情况,准确性的差异基本上处于噪声水平(即从不同随机初始化训练时可能观察到的准确性差异)。我们并不将这些情况解释为微调降低了准确性,而更可能是表明微调并未显著改变准确性,只是与运行间的自然波动有关。同样,我们也不将准确性高于 fp32 的情况解释为量化起到了正则化作用,而更可能是噪声或额外微调的结果。EfficientNet b3 是另一个值得研究的案例——由于我们的代码没有使用自动增强 [9](用于训练原始模型),即使在 fp32 下进行微调也会导致准确性略微下降至 81.3。尽管如此,通过微调,所有网络都能够将其准确性保持在原始预训练 fp32 模型的 1% 以内。

在这里插入图片描述

5.3 学习量化参数

虽然前几节描述的技术依赖于在预训练网络上校准的量化参数,但也可以联合学习量化参数和模型权重。PACT [6] 提出在训练期间学习激活量化的范围。在本节中,我们采用 PACT 作为量化感知微调过程的增强方法。我们遵循与之前相同的微调计划(如附录 A 所述),但允许每个量化激活张量的范围与权重一起学习,而不是在整个微调过程中保持固定。

表 8 展示了一组网络在使用固定和学习激活范围的情况下进行微调的结果,这些结果基于不同的初始校准方法。“最佳”校准是指在训练后量化(PTQ)中产生最佳准确性的校准方法,如表 5 所示。当激活量化以最大校准初始化时,对于大多数网络,学习范围比保持固定范围能够获得更高的准确性。特别是,在固定最大范围导致显著准确性下降的情况下,学习范围能够显著提高准确性。然而,当激活范围初始化为每个网络的最佳校准时,学习范围与固定范围的结果非常相似。这表明,如果激活范围已经经过仔细校准,学习范围对于 int8 量化感知训练(QAT)并没有额外的优势。然而,这可能并不是 PACT 的最佳应用。从 Inception v4 的学习范围结果来看,当从最大校准开始时,网络在给定的微调计划中未能学习到良好的激活范围。我们预计,通过更长的微调时间,或为范围参数(如学习率和权重衰减)设置单独的优化计划和超参数,PACT 能够学习到更好的范围。

在这里插入图片描述

6 推荐的工作流程

根据第 4 节和第 5 节的结果,我们推荐以下 int8 量化方法:

  • 权重
    • 使用比例量化,粒度为每列/每通道
    • 使用对称整数范围进行量化( [ − 127 , 127 ] [-127, 127] [127,127]),并采用最大校准
  • 激活
    • 使用比例量化,粒度为每张量

我们推荐以下步骤来量化预训练的神经网络:

  1. 训练后量化(PTQ)

    • 量化所有计算密集型层(卷积、线性、矩阵乘法等),并运行激活校准,包括最大校准、熵校准以及 99.99% 和 99.999% 百分位校准。
    • 如果没有任何校准方法能够达到所需的准确性,则继续进行部分量化或量化感知训练(QAT)。
  2. 部分量化

    • 执行敏感性分析,以识别最敏感的层并将其保持为浮点数。
    • 如果对计算性能的影响不可接受或无法达到可接受的准确性,则继续进行 QAT。
  3. 量化感知训练(QAT)

    • 从最佳校准的量化模型开始。
    • 使用 QAT 进行微调,微调时间约为原始训练计划的 10%,并使用退火学习率计划,初始学习率为原始训练学习率的 1%。
    • 有关具体超参数选择,请参阅附录 A.2。

图 5 以流程图形式总结了上述工作流程。

7 结论

本文回顾了神经网络整数量化的数学背景,以及选择量化参数的一些与性能相关的原因。我们通过实验评估了多种模型在 int8 量化中的各种选择,并提出了一个量化工作流程。遵循该工作流程,我们证明了所有研究的模型都可以量化为 int8,其准确性要么与浮点模型匹配,要么在浮点模型准确性的 1% 以内。这包括对量化具有挑战性的网络,例如 MobileNets 和 BERT。该工作流程仅涉及训练后量化、部分量化和量化感知微调技术。对于这些模型的 int8 量化,不需要更复杂的技术,例如 ADMM 和蒸馏。然而,在量化到更低比特整数表示时,应评估这些技术,我们将其留给未来的工作。

附录

#A 评估细节

A.1 模型定义

在这里插入图片描述

表 9 列出了表 2 中模型的更多详细信息。我们评估了多种用于图像分类的卷积神经网络(CNN)。MobileNets 是面向移动设备推理的小型网络 [17, 48],其参数化设计可扩展到不同的通道宽度和图像分辨率。在本文中,我们评估了宽度乘数为 1 和分辨率为 224x224 的基础配置。我们还评估了一些较大的 CNN [14, 56, 50, 49],包括在 ImageNet 上实现最先进准确性的 EfficientNets [51]。所有 CNN 均使用 224x224 的输入,除了 Inception v3 和 v4 使用 299x299 的输入。我们评估了 Torchvision 中的两个检测网络和两个分割网络,以及一个额外的分割网络 RetinaNet [32]。我们评估了两个翻译模型:4 层的 GNMT 模型 [55] 和 Transformer 的大配置 [53]。对于语音识别,我们评估了在公共语音数据集上实现最先进词错误率(WER)的 Jasper [41]。对于语言建模,我们使用了 BERT 大模型(未区分大小写)并针对问答任务进行了微调。

模型的校准使用了表 2 中列出的各自数据集的训练集中的样本数量,除了 Jasper,它是在开发集上校准并在测试集上评估的。所有模型的 PyTorch 实现均由列出的源代码库提供。我们使用了每个库提供的预训练权重,除了 MobileNet v1 和 EfficientNets,这些模型的预训练权重不可用。MobileNet v1 使用 Torchvision 中 MobileNet v2 的参考训练脚本和超参数进行训练。EfficientNets 的预训练权重是从 TensorFlow [1] 提供的权重转换到 PyTorch 的。

在这里插入图片描述

在这里插入图片描述

A.2 量化感知训练

表 10 展示了量化感知微调实验中使用的微调超参数。对于在多个数据集上训练的模型(检测/分割网络和 BERT),我们仅在最终数据集(COCO 和 SQuAD)上进行微调。通常,仅初始学习率值和学习率计划与原始训练会话不同。我们微调大约为原始训练步骤的 1/10。微调学习率从原始训练会话中使用的初始值的 1/100 开始,并衰减到初始微调学习率的 1/100。BERT 是一个例外。由于它预训练了一个语言模型,并且仅在 SQuAD 上微调 2 个周期,因此我们重复完整的微调计划进行 QAT。我们使用了余弦退火学习率计划,该计划遵循余弦函数的单调递减半周期。

表 11 展示了所有网络和激活范围校准设置的微调量化准确性。请注意,我们始终使用完整的每列/每通道范围进行权重量化(最大校准)。它表明,通过微调,几乎所有情况下的准确性都有所提高,特别是在 PTQ 后准确性大幅下降的情况下,例如最大校准。对于许多模型,最佳的 PTQ 校准也是 QAT 的最佳校准,由粗体和下划线表示的结果表明。即使 QAT 使用不同的校准实现了更高的准确性,结果的差异也很小。这一结果表明,在 PTQ 期间评估多个激活校准是选择 QAT 校准的良好启发式方法。
在这里插入图片描述

B 量化感知训练的直观理解

为了理解为什么量化感知训练(QAT)可以提高量化模型的准确性,考虑图 6 中的简单示例。神经网络通过使用随机梯度下降法最小化损失函数来训练。计算损失函数关于网络权重的梯度 ∂ L / ∂ w \partial L / \partial w L/w,并沿负梯度方向迭代更新权重,直到模型收敛到某个最小值。图 6a 展示了一个具有单一参数 w w w 的模型的一维损失函数,该模型已收敛到局部最小值 w ≈ − 0.5 w \approx -0.5 w0.5。当应用训练后量化时(为了示例,假设比例因子为 1),权重被量化为最近的整数 w q = − 1 w_q = -1 wq=1,导致损失显著增加。在这种情况下,我们说模型收敛到了一个“狭窄”的最小值,因为权重的微小变化会导致损失的大幅变化。

通过在量化条件下进行训练,我们可以通过计算关于量化权重的梯度来避免这些狭窄的最小值,如图 6b 所示。这样做时,狭窄的最小值会产生较大的梯度,从而使模型能够探索损失函数中的“宽” [22] 或“平” [16, 30] 最小值区域,这些区域的量化点具有较低的损失,从而具有更高的准确性。

C批量归一化折叠

批量归一化折叠(Batch normalization folding)是应用于神经网络的一种常见推理优化技术 [20]。在推理时,批量归一化层执行如下的仿射变换,如方程[14]所示:
c = γ V a r [ y ] + ϵ d = β − γ E [ y ] V a r [ y ] + ϵ z = B N ( y ) = c ⋅ y + d (14) c = \frac{\gamma}{\sqrt{Var[y]} + \epsilon} d = \beta - \frac{\gamma E[y]}{\sqrt{Var[y]} + \epsilon} z = BN(y) = c \cdot y + d \tag {14} c=Var[y] +ϵγd=βVar[y] +ϵγE[y]z=BN(y)=cy+d(14)

其中,β、γ、E[y] 和 Var[y] 是在训练过程中确定的,并在推理时保持固定,ε是一个常数 [19]。通常,在全连接层之后,批量归一化是对每个激活值计算的。考虑一个执行矩阵乘法和偏置加法的全连接层,如方程[15]所示:
y j = ∑ k = 1 p x k ⋅ w k j + b j (15) y_j = \sum_{k=1}^{p} x_k \cdot w_{kj} + b_j \tag {15} yj=k=1pxkwkj+bj(15)
当全连接层后跟一个批量归一化层时,z = BN(xW + b),批量归一化可以折叠到全连接层的权重和偏置中,如公式16所示。
z j = ∑ k = 1 p x k ⋅ c j ⋅ w k j ⏟ w k j ′ + c j ⋅ b j + d j ⏟ b j ′ (16) z_{j}=\sum_{k=1}^px_k\cdot\underbrace{c_j\cdot w_{kj}}_{w_{kj}^{\prime}}+\underbrace{c_j\cdot b_j+d_j}_{b_j^{\prime}}\tag{16} zj=k=1pxkwkj cjwkj+bj cjbj+dj(16)

结果是全连接层执行操作 $ z = xW’ + b’ $。由于卷积可以映射到全连接层,而卷积神经网络(CNN)中的批量归一化是按通道进行的,因此我们可以应用相同的优化。

D 新型激活函数

最近开发的两种激活函数是 Swish(公式[7])和 GELU(公式[8]),分别用于 EfficientNets 和 BERT。

s w i s h ( x ) = x ⋅ s i g m o i d ( x ) (17) \mathrm{swish}(x)=x\cdot\mathrm{sigmoid}(x)\tag{17} swish(x)=xsigmoid(x)(17)

G E L U ( x ) = x 2 ( 1 + e r f ( x 2 ) ) (18) \mathrm{GELU}(x)=\frac{x}{2}(1+\mathrm{erf}(\frac{x}{\sqrt{2}})\tag{18}) GELU(x)=2x(1+erf(2 x))(18)

这两种激活函数,如图7a所示,都是平滑的且类似于ReLU,但具有较小的、有界的负输出范围。具体来说,Swish 的输出范围是 [ − 0.2785 , ∞ ] [-0.2785, \infty] [0.2785,],而 GELU 的输出范围是 [ − 0.1700 , ∞ ] [-0.1700, \infty] [0.1700,]。这给统一量化带来了挑战,因为它需要同时表示小的负值和较大的正值。

图7b显示了GELU与不同对称范围的虚假量化的组合。如果GELU的输出被量化到 [ − 50 , 50 ] [-50, 50] [50,50],则所有负值都会被四舍五入为零。然而,如果将范围限制为 [ − 10 , 10 ] [-10, 10] [10,10],则可以表示两个负值。表 Π 2 \Pi2 Π2显示了GELU输出被截断为 10 ( G E L U 10 ) 10\left(\mathrm{GELU}10\right) 10(GELU10)后的后训练量化准确性,并通过最大值校准进行校准。仅通过截断GELU的输出,我们就可以在简单的最大值校准下实现最佳的后训练量化准确性,比之前最好的激活校准高出0.46 F1。此外,这个结果几乎与最佳的QAT结果90.67 F1相匹配。

在这里插入图片描述
在这里插入图片描述


http://www.kler.cn/a/529206.html

相关文章:

  • Web_php_unserialize
  • Java线程认识和Object的一些方法ObjectMonitor
  • hexo部署到github page时,hexo d后page里面绑定的个人域名消失的问题
  • 高效学习方法分享
  • 新能源算力战争:为什么AI大模型需要绿色数据中心?
  • < OS 有关 > 阿里云 几个小时前 使用密钥替换 SSH 密码认证后, 发现主机正在被“攻击” 分析与应对
  • 知识管理系统推动企业知识创新与人才培养的有效途径分析
  • 【玩转全栈】--创建一个自己的vue项目
  • 海外问卷调查之渠道查,企业经营的指南针
  • C语言指针专题五 -- void和const指针
  • 【力扣】15.三数之和
  • 网络编程套接字(下)
  • CSS 样式化表格:从基础到高级技巧
  • 快速提升网站收录:利用网站FAQ页面
  • 人工智能入门课【手写自注意力机制】
  • 【回溯】目标和 字母大小全排列
  • 云服务器与Docker
  • 分布式事务组件Seata简介与使用,搭配Nacos统一管理服务端和客户端配置
  • 【华为OD-E卷 - 报数游戏 100分(python、java、c++、js、c)】
  • doris:JSON导入数据
  • Games104——引擎工具链基础
  • Python的那些事第八篇:Python中的类与对象
  • MusicFree-开源的第三方音乐在线播放和下载工具, 支持歌单导入[对标落雪音乐]
  • Nginx知识
  • 什么是Javascript,有什么特点
  • 【cocos官方案例改】跳跃牢猫