基于变压器的大型语言模型(LLM)随着模型规模的增长取得了巨大的成功。LLM的规模每两年增长240倍,这超过了硬件的进步,并使模型推理变得越来越昂贵。模型量化是缓解LLM规模和硬件容量之间不断扩大的差距的有前途的方法。之前的离群点感知量化方案采用稀疏编码技术将离群点从正常值中分离出来,该过程需要全局协调(例如,全局稀疏度协调列表)。这导致复杂的编码/解码硬件逻辑和额外的编配控制器,用于计算离群点和正常值之间的差异。因此,它不是硬件高效的,因此只能获得次优的量化效果。
我们提出了OliVe,一种算法/架构共同设计的解决方案,采用了离群值-受害者对(OVP)量化,并以低硬件开销和高性能增益在本地处理离群值。OliVe的关键见解是,离群值很重要,而它们旁边的正常值则不重要。因此,这些正常值(称为受害者)可以牺牲来容纳离群值。这使得一种内存对齐的OVP编码方案成为可能,
它可以有效地集成到现有的硬件加速器中,如收缩阵列和张量核心。因此,基于OliVe的加速器分别以4.5倍的加速比和4.0倍的能量减少来超越现有的离群感知加速器GOBO,具有优越的模型精度。
CCS概念
计算机系统组织→神经网络;数据流架构;单指令多数据;收缩阵列。
关键词
大型语言模型,离群点-受害者对,量化
基于Transformer的大型语言模型(LLM)[77]在过去几年中取得了巨大的成功。这种成功通常是通过越来越大的模型大小实现的:模型大小每两年增长240倍,显著超过硬件进展(每两年3.1倍)[24]。因此,LLM的推理变得具有挑战性和成本。例如,最近基于Transformer的LLMOPT-175B[90]具有1750亿参数,无法适应具有80GB内存的最新高端H100GPU。量化[6,7,21,22,72,74,79,93]是降低大型模型推理成本的最有效的硬件方法之一。它使用低精度数据类型来压缩模型并通过实际的硬件实现加速计算,例如,TPU[42]和GPU张量核[60]。然而,现有的量化方案[18,74,86]在基于Transformer的LLM中效果较差。最近的研究表明,当模型大小超过阈值(例如,60亿)时,模型性能仅容易受到极小一部分(<0.1%)异常值的影响,其值比正常值显著得多[18]。不加区分地裁剪异常值和正常值将导致模型精度显着下降[18,82]。因此,与卷积网络(CNN)相比,常见的做法是采用更大的位宽,例如8位或16位来量化基于Transform的模型。
图1:异常值感知编码比较。(一)之前量化工作采用基于稀疏的编码分别存储正常值和异常值。(b)我们的提议
异常值-受害者对编码在本地存储正常值和异常值。
研究人员提出了各种量化/architecture协同设计作品[39,61,75,82,85]来处理Transformer模型中的异常值。例如,异常值抑制[82]提出了抑制异常值。但它在较低的位宽(4-bit)仍然存在显著的精度损失,表明难以适应异常值的影响。此外,架构研究人员设计了复杂的异常值感知硬件架构,以高精度存储异常值以保持模型准确性。这些异常值感知量化框架将张量分为正常值和异常值,并使用不同的方式分别编码。对于正常值,采用低精度(例如,4-位)量化的密集矩阵。并且可以使用基于稀疏的编码压缩稀疏和高精度(例如,8-位和16-位)的异常值。不幸的是,这样的编码会导致不对齐的内存访问。例如,GOBO[85]和OLAccels[61]使用坐标列表来指示矩阵中每个异常值的位置,如图1a所示。BiScaled-DNNs[39]利用块稀疏索引格式来存储异常值索引,而DRQ[75]使用直接位图来处理异常值。这些异常值感知解决方案需要复杂的架构设计,具有显着的硬件开销来适应异常值。此外,由于随机和不对齐的内存访问,基于稀疏性的编码与现有加速器的内存子系统不兼容,例如GPU和TPU。具体来说,GOBO[85]只能解压缩片外的权重张量DRAM,它仍然依赖于GPU的原始片上内存和计算架构,具有高精度FP16/32.
上述异常值感知架构以全局方式将正常值与异常值分开。例如,GOBO[85]在量化和计算中涉及全局稀疏坐标列表,导致大量硬件开销和低性能收益。在这项工作中,我们旨在设计一种架构,以高硬件效率的本地化方式处理异常值。为了实现这一目标,我们将两个连续的固定大小值分组在张量中,并分析它们对模型准确性的影响。可以有三种对:i)具有两个正常值的正常对,ii)具有一个正常值和一个异常值的单异常值对,iii)具有两个异常值的双异常值对。我们观察到,第三个双异常值对几乎从未出现在训练有素的LLM中。对于第二个单离群值对,我们发现仅保持其离群值同时修剪其正常值(即将其视为零)就足以保持模型精度。
基于上述观察,我们提出了一种新的离群值感知量化架构,称为OliVe,基于离群值对(OVP)编码。OliVe的显着特点是记忆对齐,因此硬件友好。如图1b所示,OliVe首先修剪与离群值相邻的正常值为零。这些修剪的正常值被称为受害者,它们牺牲自己并为离群值腾出空间。然后,我们利用受害者提供的额外空间,将离群值嵌入低精度矩阵中。
OliVe能够以较低的硬件开销为大型Transformer模型保持高精度,原因如下。首先,OliVe结合了受害者来解决LLM中的异常值。受害者的影响类似于模型剪枝[36]。虽然剪裁一些(0.1%)异常值会导致灾难性的精度下降[18,82],但剪枝相同数量的“正常”值只会稍微影响模型精度(<0.1%下降)。因此,OliVe牺牲(“剪枝”)那些不重要的值作为异常值的受害者,允许更积极的编码方案来适应极其重要的值。其次,OVP编码遵循特定的异常值-受害者(或受害者-异常值)模式,以实现具有较小硬件开销的内存对齐。每个受害者与一个异常值相邻,异常值-受害者对必须对齐内存访问模式。例如,在图1b中,OV对中的右异常值?98需要左受害者,左异常值17.6和30.7需要右受害者。这可以高效地对齐8位(1字节)内存访问。这种设计实现了完全本地化的异常值解码/编码过程。
为了实现OliVe,异常值和正常值采用了不同的数据类型,它们具有不同的动态范围和表示格式,包括int4和FP4。如图1b所示,我们为4位OV对提出了一种新颖的编码方法(第3节),它将4位异常值和4位受害者组成一种特殊的8位格式,并与原始的int8或FP8不同。由于其硬件友好和兼容的设计,OliVe可以轻松集成到现有的量化框架和加速器架构中,例如Google TPU中的收缩阵列[41]和NVIDIAGPU中的张量核心[58,60]。OliVe还可以固有地支持混合精度和混合类型架构,显示其在更大规模的Transformer模型中的灵活性和实用性。
据我们所知,OliVe是第一个将Transformer后训练量化(PTQ)[4]推向极限的作品,量化后无需重新训练,精度损失<1%。令人惊讶的是,OliVe的4位PTQ精度BERT[19]和BART[49]模型优于异常值抑制[82]的6位PTQ结果,这是一种最先进的Transformer量化方法。基于OliVe的加速器超过现有的异常值感知加速器OLAccel[61]和GOBO[85],分别提高了3.8倍和4.5倍的性能,并降低了2.1倍和4.0倍的能量。更重要的是,基于OliVe的加速器比其他异常值特定架构具有更全面和实际的适用性。
我们在本文中做出以下贡献。
我们进行了成对重要性分析,并表明离群值很重要,而它们的相邻正常值则不重要,揭示了离群值-受害者对(OVP)的算法机会,它牺牲了共同定位的正常值(称为受害者)来适应离群值。
我们提出了基于OVP的量化框架,称为OliVe,它包括高效的硬件编码和新的异常值表示数据类型。
我们提出了OliVe量化的高效架构实现和集成,并表明其效率和优势优于现有的异常值感知量化算法和硬件加速器。
ALIGNEDOUTLIER在本节中,我们首先展示了Transformer模型的异常值与卷积 神经网络(CNN)相比更为显著和重要。先前的工作[74,75,85,86]提出了具有自适应位长的异常值感知量化微架构,以完成低位量化,但需要大量硬件资源来处理可变长度的数据,这会导致未对齐的内存访问,并且与现有加速器的内存子系统(例如GPU[60])不兼容。相比之下,我们提出了一种内存对齐和硬件友好的方法,称为异常值-受害者对机制,其灵感来自于DNN 剪枝和我们对变压器的异常值组位置分析。我们可以修剪一些“受害者”,以腾出空间将高精度异常值嵌入到内存对齐的低比特张量中,其精度损失可忽略。
我们在图2中直观地展示了transformer异常值的重要性。我们采用正态分布的经验3规则[83]将值分为异常值和正常值。我们使用ResNet-18[37]作为CNN模型的代表,使用BERT[19]作为变压器模型的代表。我们将DNN张量拟合为正态分布,即等式1,其中是值,是平均值,是均方差。我们将张量转换为标准正态分布。
异常值的重要性吸引了许多研究兴趣,这引发了几种异常值感知架构,如Tbl所示。1. OLAccel[61]和GOBO[85]相似,并利用坐标列表来指示异常值的位置,它们使用高精度(8位或16位)量化。BiScaled-DNN[39]和DRQ[75]分别采用块稀疏索引和位图
BiScaled-DNN量化所有具有相同位宽但不同比例因子的正常值和异常值的值,这些值是对齐的。然而,在块稀疏方法中压缩的额外索引是不对齐的。相反,DRQ的位图是对齐的,但数据是通过混合存储的,因此是不对齐的4位和8位值。总之,先前的工作基于异常值的稀疏性设计了异常值感知架构,这导致了不对齐的内存存储和访问。更严重的是,基于稀疏编码的索引和异常值是分开的。因此,它们需要额外的异常值控制器来解析异常值的索引,并编排正常值和异常值之间的计算。例如,GOBO和OLAccel的额外异常值控制器将高达55%和71%的开销计入处理元件(PE)阵列的总面积[61,85]。针对异常值的基于稀疏性的编码也与现有加速器的内存子系统不兼容。对于GOBO设计[85],它只能在DRAM级别对GPU的内存进行压缩和解压缩。这极大地限制了其提出的异常值感知架构的适用性。因此,应提出一种更加硬件友好和适用的异常值解码/编码方法来拟合异常值感知量化。我们提出的OliVe架构能够对齐内存访问,并且也与基于OVP机制的现有加速器兼容。
通常,从DNN 剪枝中借用的基于稀疏的编码是稀疏异常值的直接有效的解决方案。然而,这些工作忽略了量化与剪枝不同。对于剪枝,剪枝的零值不参与计算。因此,剪枝方法必须使用基于稀疏的编码压缩稀疏值。对于量化,量化的正常值占大多数,需要计算。自然地,异常值可以利用正常值来实现内存对齐,而不是基于稀疏的编码。如图11b所示,我们利用剪枝的洞察力,但与先前的工作有不同的视角。新方法采用异常值-受害者对(OVP)机制。我们首先剪枝一些量化的低精度正常值,我们称之为受害者。这些受害者与异常值相邻,并为高精度异常值腾出额外的空间。因此,我们可以将异常值嵌入其原始位置,而无需显式稀疏索引。这可以避免复杂的索引硬件,并使其与GPU兼容。为了对齐内存,我们根据它们在对中的位置区分“右异常值”和“左异常值”。我们为左异常值分配一个右受害者(例如,图1b中的17.6),为右异常值分配一个左受害者(例如,图1b中的?98)。OVP机制基于我们对大型Transformer模型的观察,包括BERT基[19],BERT大[19],GPT2-XL[66]和OPT-6.7B[90]。我们收集所有张量,计算它们的标准方差,并通过3规则将值分为正常值(<3)和异常值(>3)。然后我们每两个相邻的值配对(没有重叠),这导致了三种类型:正常正常对,异常-正常对和异常-异常对,如Tbl所示。2.这三种类型分别有两个正常值,一个正常值和一个异常值,以及两个异常值。Tbl.2表明,大多数(约99%)对是正常正常对,只有大约1%的异常-正常对。异常对需要修剪对中较小的异常值。幸运的是,异常-异常对在所有研究的模型中只有极低的概率小于0.06%。因此,异常分布是极其分散的,我们可以保留大多数异常值。我们还在GLUE数据集[78]上使用BERT模型[82]进行了精度实验,如图3所示。首先,我们将异常值裁剪到3,其中裁剪是量化采用的常见方法。然后,我们将受害者和正常值修剪为零。受害者与异常值相邻,正常值随机修剪与异常值相同的量。我们以完全精度(FP32)保留其余值。尽管这样的少数异常值(约1%)被裁剪,如图3裁剪异常值所示,但精度损失对于BERT模型来说是不可接受的。结果强调了基于Transformer的模型中异常值的重要性。为了比较,修剪随机正常值几乎没有精度损失,而不是源精度。受害者值的剪枝比正常值的剪枝仅显示出可忽略的精度下降,因为受害者由于异常值-异常值对包括一些异常值,并且具有与相邻异常值对应的特定位置。
总之,我们的分析表明异常值很重要,而受害者并不重要,因此我们可以牺牲受害者来适应异常值。这激励我们设计硬件友好的OVP机制,提供对齐异常值感知量化,以加速大型变压器模型。在下一节中,我们将介绍异常值-受害者对编码设计。
在本节中,我们呈现了异常值-受害者对(OVP)编码的细节,该编码对于异常值和正常值是全局相同但局部可区分的。OVP编码可以保持全局对齐的内存访问,并以可忽略的开销在局部区分异常值。对于正常值,我们可以支持多种数据类型来拟合自适应数据类型。对于编码异常值,我们设计了一种异常值特定的数据类型,自适应偏差浮点数,浮点数,可以避免正常值和异常值之间的范围重叠,从而提高异常值编码的数值表示空间的利用率。最后,基于OVP编码,我们提出了一个框架,可以自动选择异常值阈值进行OVP编码,以确定异常值-受害者对的合适比例。
基于前面的按对时态值分析,有三种对类型:正常-正常、异常-正常和异常-异常。对于异常-正常,对正常值将被修剪并变成受害者。对于异常-异常,我们保留大的一个并修剪另一个。然后,我们得到DNN张量中的正常-正常对和异常-受害者对。异常标识符, 为了与正常-正常对区分开来,我们需要一个特殊的标识符来区分异常-受害者对。而这个不同的标识符不能出现在正常-正常对中,这意味着我们需要在正常值的表示中消除一个数字。例如,如图4所示,我们使用有符号的int4(4位整数)来量化正常值。原始int4可以表示[?8,7]范围内的整数,其中1000表示?8的值。首先,我们将1000作为异常值标识符,并从int4中删除1000的值,其编码范围变为[?7,7]。其次,我们使用4位OVP编码量化异常值-受害者对。我们使用异常值标识符1000设置受害者,并使用异常值特定的数据类型(第3.3节)量化异常值。自然地,有两种类型的OV对,即左异常值(O-V)和右异常值(V-O)对。由于不同的异常值标识符设计,我们可以隐式区分它们,而无需使用额外的索引位(第4.2节)。算法1显示了4位OVP编码算法,需要同时读取两个值,其中要求非常容易满足。对于硬件实现,我们可以为编码器添加缓冲区。此外,OVP编码器可以通过嵌入具有可忽略开销的量化单元来实现。对于软件实现,我们可以使线程同时处理两个值。因此,编码算法可以在硬件和软件中高效实现,我们稍后会详细介绍
对于正常值,我们基于先前的工作[32],它可以支持多种数据类型,包括int4、flint4(4-bit flint)和int8,如Tbl.3所示。int4类型是4位量化中最广泛使用的数据类型之一,整数的值范围为[?7,7]。flint4类型是由先前的工作ANT[32]提出的,该工作表明,根据张量的分布选择数据类型可以实现最先进的性能和准确性。基于上述见解,我们还采用混合数据类型来量化OVP对编码中的正常值。对于flint4,我们使用相同的二进制值1000_2作为异常值标识符。具体来说,flint4的1000_2对应于?0,这在原始设计中没有使用。换句话说,我们的OVP编码无缝地适用于flint4,而不浪费任何数字表示。我们使用原始的flint4编码算法[32]来量化正常值。此外,OVP编码通常可以扩展到更高精度的量化,例如8位。同样,8位正常值也需要消除一个数字。例如,int8可以表示[?128,127]整数,我们可以将10000000_2作为int8的异常标识符,并将其范围缩小到[?127,127]。同样,编码算法可以轻松扩展到同时读取两个8位元素。
接下来,我们使用异常值特定的数据类型量化异常值。大的异常值通常具有广泛的范围,为此我们使用基于浮点数的数据进行量化。我们提出了一种称为自适应偏置浮点数的数据类型,简而言之为abflo。关键思想是,通过向指数添加适当的偏置,所有编码值都可以跳过正常值所在的区间,并为异常值提供更多的范围。
浮点到定点转换
为了适应正常值并避免分数,我们首先将浮点编码转换为具有指数的定点。此外,定点对硬件实现友好,并且具有比浮点数更低的开销。我们用以下方程将浮点转换为定点,
sign × (1 ? mb + mantissa) ? (exponent + bias), (2)
其中mb是尾数位宽。因此,这种定点编码方案对硬件实现更加友好和高效,因为它只涉及移位操作。
Tbl.4展示了定点E2M1数据类型的示例。自适应偏差。显然,Tbl.3和Tbl.4展示了定点abflo的范围与正常值重叠。例如,int4和E2M1包含相同的数字,3,4和6。另一个例子是flint4和E2M1除了24之外几乎具有相同的数字范围。因此,我们需要自适应偏差来调整abflo的范围。例如,我们为E2M1设置偏差=2,其实值将扩展为{12, · · · , 96},这与int4正常值互补。类似地,我们为flint4数据类型设置偏置=3并将范围扩展到{24, · · · , 192}。我们设计了一个新的解码器和指令,以在加速器中实现自适应偏置,用于abflo(Sec.4.2)。E2M1 Abflo, 4位有符号浮点数具有指数和尾数的四种可能配置:E0M3,E1M2,E2M1和E3M0。它们具有不同的范围和精度。我们进行以下实验,以选择最合适的配置作为最终的异常值特定数据类型。为了适应广泛的异常值范围,我们使用所有abflo类型量化Transformer模型中最大的异常值(即图2中的Max)。然后,我们收集平均绝对误差,如图5所示。我们发现E2M1在所有测试中给出的误差最小,这既提供了足够大的范围,又提供了一定程度的精确度,它也在我们随后的评估中呈现了最佳结果。同样,我们对8位abflot采用了带符号的E4M3。算法2详细展示了一个元素如何被编码为abflot。异常值编码是一个按元素的函数,可以在软件和硬件上高效地实现。异常值编码还应该消除异常值标识符。否则,解码器无法区分异常值-受害者对。Abflot有两个零数字:1000(-0)和0000(0)。因此,我们禁用异常值的1000和0000,以避免与异常值标识符冲突。
我们现在将OVP(异常值-受害者对)编码应用于量化Transformer模型。为了确定比例因子(即异常值-受害者阈值),我们将OVP编码与现有的均方误差(MSE)最小化算法嵌入其中,这是许多量化工作的常用算法[4,6,88]。基于OVP的量化算法确定了区分异常值和正常值的阈值。一方面,较小的阈值会导致更多的异常值-受害者对,这可能会潜在地最小化量化误差(即MSE)。另一方面,它也增加了异常值-异常值对的比率,其中两个值都是对中的异常值。如果有太多这样的异常值-异常值对,MSE将由于异常值的修剪而增加。因此,我们需要控制异常值对的比率以获得更好的准确性。
在我们的工作中,我们的目标是训练后量化(PTQ)[57],它不需要重新训练,因此最适合大型模型,因为它们的训练成本很高。然而,我们仍然需要使用来自训练集的一批数据进行比例因子选择。直观地,受3规则的启发,我们将3作为初始比例因子。然后算法将在此基线的特定范围内搜索具有最小MSE的最佳比例因子,这在我们的评估中显示出良好的结果。对于量化感知训练(QAT)[57],我们可以通过使用直通估计器(STE)[5]重新训练它来获得合适的比例因子。
本节介绍如何在GPU和输出平稳脉动阵列架构中集成OliVe。然后,我们介绍了上述异常值-受害者对编码和异常值数据类型的硬件解码器 。在这些架构上,我们提出的OliVe架构可以直接支持混合精度[60,72]和混合数据类型[60,72],这对于量化具有不同重要性和分布的DNN张量是有效的。
我们首先在图6a中描述如何将OliVe设计集成到GPU的张量核心架构中。我们采用图灵架构[59]作为我们的基线GPU,它有68个流式多处理器(,每个有八个张量核心(总共544个),如Tbl.5所示。根据先前工作的建模[67],每个张量核心有两个八位字节,它们有八个FEDPs(四元点积)。因此,有68×8×2×8×4=34,816个16位浮点乘法器。图灵架构最初可以支持混合精度计算。例如,具有图灵架构[59]的RTX2080Ti GPU提供107.6,215.2和430.3TOPS(每秒tera操作)分别用于16位浮点数,8位int和4位int。因此,我们假设张量核可以同时支持8位8EDP(八元素点积)和4位16EDP(16元素点积),如图6a所示。
我们可以很容易地将我们提出的OliVe架构嵌入到GPU中,它采用了SIMD架构。我们首先为每个16EDP放置4位Outliervictim对解码器(图6b)。为了支持新的OliVe数据类型,我们为每个16EDP添加了一个加法器和一个移位器。同样,我们还为8EDP单元设计了8位解码器。
异常-受害者对解码器。为了支持异常-受害者对解码,我们设计了一个新的解码器,可以很容易地嵌入到现有的加速器中。如图6b所示,解码器读取1个字节,这是许多架构中最小的可寻址存储单元,正好是一个值对。然后,解码器将异常值标识符1000转换为0,并使用异常值解码器解码异常值。为了适应异常值浮点值的计算,解码器将生成一个指数整数对。因此,解码器需要附加一个0000_2作为正常int4数据类型的指数数。对于flint4,我们利用其原始解码器[32]来获得指数整数对。异常值解码器。上述OVP解码器包含一个异常值解码器,用于E2M1浮点数据类型的异常值。图7显示了4位浮点数解码器设计的细节。对于4位E2M1浮点数 𝑥 = (𝑏2 1 0)2,以下方程解码指数和整数:
例如,当偏置为2时,一个数字0101_2是48_10,因为它的指数是2_10+10_2=4_10,基整数是11_2=3_10。因此,它的实值是3<<4=48。同样,我们还设计和实现了8位异常值-受害者对解码器和E4M3浮点异常值解码器,它们是4位实例的直接扩展。因此,由于空间有限,我们不提供它们的详细信息。
脉动阵列(SA)集成如图8所示。SA使用与GPU相同的异常值-受害者对解码器设计(图6b),这显示了我们设计的广泛适用性。但是,与GPU不同的是,我们只将解码器放置在边界线上,这可以节省大多数解码器。例如,如果阵列大小 𝑛 ×𝑚, 我们只需要+而不是 𝑛 × 𝑚 解码器。这是SA相对于GPU的SIMD架构的一个优势。我们提出的基于OliVe的数据类型还可以通过额外的加法器和移位器支持脉动阵列处理元素(PE)。我们为每四个PE添加一个额外的加法器以支持高精度量化,例如int8。
解码异常值和正常值后,它们都被转换成统一的指数-整数对。为了支持解码后的指数-整数对计算,我们需要为定点MAC(乘法和累加)单元添加一个移位器和一个加法器,如图8和图6的单元4位16EDP所示。例如,我们有两个指数-整数对 < 𝑎, 𝑏 > 和 < 𝑐, 𝑑 >, 其中a和c是指数,b和d是整数, < 𝑎, 𝑏 > 表示,请注意,最终结果可以用32位int存储。
如第3节所述,OliVe量化可以支持正常值的int8和异常值的E4M3 abflot。因此,我们为更高精度的数据类型提出了混合精度处理元件(PE)。8-bit Int。对于GPU 张量核心架构,它最初是以混合精度计算设计的。对于收缩阵列,我们的架构自然支持8位计算,具有四个4位PE[72]。对于int8数字,高4位和低4位可以拆分为两个4位数字和。因此,我们可以使用四个4位PE来计算上述四次乘法,并累加乘积以获得 𝑥 × 𝑦. 8位Abflot的最终乘积值。同样,使用相同的方法可以支持8位abflot的乘法。对于8位abflot数,它首先被解码为指数和整数。对于,我们类似地将其拆分为 𝑖𝑧 = (?𝑧 << 4) +𝑙𝑧 , 然后=<4 + 𝑒𝑧, ?𝑧 > + < 𝑒𝑧,𝑙𝑧 >. 因此,相同的方法可以用于执行具有四个4位PE的8位abflot乘法,其中abflot比int8多了一个。在最极端的情况下,两个带有abflot的异常值可以相乘。因为我们采用32位int作为累加器,所以最大乘数不应该超过√2^31?1。因此,对于abflot类型的异常值,我们将异常值的绝对值裁剪在2^15<√2^31?1以内,以避免int32累加器的溢出。我们的实验表明,Transformer模型的异常值远小于2 15。具体来说,归一化和量化后,2^15约为768。如图2所示,异常值的最大值不超过325。因此,我们观察到在实践中没有异常值被截断。
对于4位张量核心,图灵GPU架构采用指令mma. s32.s4.s4.s32。这四个操作数是矩阵D(int32)、A(int4)、B(int4)和C(int32) 𝐷 = 𝐴 × 𝐵 + 𝐶. 为了支持GPU上基于OVP的计算,我们设计了一条名为mmaovp的新指令:
此外,由于数据类型的内存对齐设计,OliVe保持了GPU的原始编程接口。我们可以用基于OVP的指令(例如,mmaovp)替换原始的基于int的指令,从而轻松构建OVP支持的DNN 量化框架。因此,我们的OliVe框架具有全面和实际的适用性,这是OliVe最显著的优势。
在本节中,我们使用OliVe量化评估LLM的准确性。我们还分别演示了OliVe在GPU和收缩阵列上的面积开销、加速和能量效率。
为了评估我们的OliVe量化框架,我们在Pytorch[62]中实现它。我们在GLUE基准[78]的八个数据集上评估BERT基[19],BERT基[19]和BART-base[49],这三个最常用的语言模型。此外,我们在总结任务SQuAD v1.1和SQuAD v2.0[68]上评估BERT基[19]和BART-base[49]。为了在大型语言模型上验证我们的量化框架,我们还在Wikitext103[83]和C4[20]数据集上评估GPT2-XL[66],BLOOM-7B1[70]和OPT-6.7B[90]。对于上面提到的所有模型,我们使用来自huggingface存储库的最先进的检查点[55]。
量化基线
我们将OliVe与现有的量化工作进行比较,包括GOBO[85],异常值抑制[82],Q8BERT[86]和ANT[32]。异常值抑制[82]是最先进的Transformer量化工作。GOBO[85]也是一种异常值感知量化工作。Q8BERT[86]是一种将GEMM操作量化为8位的方法。ANT[32]是一种硬件友好的量化框架,在性能和准确性方面都达到了最先进的结果。
加速器基线
我们将OliVe的性能和能量与五个DNN 量化加速器进行了比较,包括OLAccel[61],AdaptivFloat[76](简称AdaFloat),GOBO[61],ANT[32]和原始int8张量核心在GPU[59]中。OLAccel[61]首次提出了CNN的异常值感知量化架构。我们将OLAccel扩展到基于Transformer的模型,具有按元素混合精度权重和激活量化。AdaFloat[76]通过按张量指数偏差扩展了浮点类型。GOBO[85]类似于OLAccel,但仅支持基于Transformer的网络的权重量化。
OliVe实施
我们在VerilogRTL中实现了我们的 解码器,并使用SynoPsys设计编译器[47]和22 nm TSMC技术库进行合成,以估计其面积,延迟和功率。我们使用CACTI[56]来估计片上存储器的面积和功率。我们将OliVe集成到GPU和硬件加速器中,用于端到端性能和能量评估。对于GPU集成和评估,我们修改和扩展了GPU-Sim 4.0[3]和AccelSim[45],配置为NVIDIA2080 Ti架构。我们使用AccelWattch[46],GPUWattch[48]和CACTI[56]进行能量估计。大多数Transformer层是矩阵乘法操作。对于张量核心上的GEMM实现,我们使用CUTLASS[44],这是NVIDIA的开源实现。对于加速器评估,我们将AdaFloat,OLAccel和ANT与OliVe进行比较。我们开发了一个基于DnnWeaver[71]的循环级模拟器来估计OliVe的整体性能。虽然DnnWeaver[71]是一个FPGA工具集,但之前的DNN 量化加速器,包括BitFusion[72]和ANT[32],已经扩展了其前端以添加ASIC性能和能量模拟。由于OliVe不重新设计基线加速器架构,我们可以直接在模拟器中嵌入新的OliVe相关指令和数据格式,而不会破坏原始模拟流程。换句话说,我们已经使用和修改了BitFusion[72,73]和ANT[32,33]的开源实现。