摘要
作者设计了一种方法——通过在Transformers的前馈和注意力投影层中实现8位整数(Int8)矩阵乘法来减少运行大型语言模型(LLM)所需的GPU内存。
We develop a procedure for Int8 matrix multiplication for feed-forward and attention projection layers in transformers, which cut the memory needed for inference by half while retaining full precision performance.
作者称该方法:
- 此过程有效地将推理所需的内存占用量减少了大约 50%,同时保持了与使用全精度(16/32 位)计算相同的性能水平。
- 该方法允许将具有1750亿个参数(最初以16/32位精度存储)的模型检查点转换为Int8精度,并立即使用,而不会损失模型的预测能力。
- 这一突破显著增强了此类模型的可访问性,使得在配备消费级 GPU 的单台服务器上运行 OPT-175B/BLOOM 等最先进的模型成为可能。
作者称实现方法:
- 通过深入了解Transformers中的新兴特征来实现的,这些特征高度系统化,在模型的注意力机制和整体性能中起着主导作用。
LLM.int8()是由两部分组成的量化策略:
-
涉及向量量化,在矩阵乘法期间,将单独的归一化常数应用于每个内积,从而可以对大多数特征进行量化。
-
通过采用混合精度分解方案来解决紧急异常值——即明显偏离常数的特征。
该方案分离异常值特征维度,使用 16 位精度进行处理,而绝大多数(超过 99.9%)值以 8 位精度处理。
问题及挑战
-
Vaswani等人(2017年)等人引用的LLM,已成为自然语言处理(NLP)的标准配置,但会占用大量内存,特别是对于具有超过67亿个参数的模型。这些模型中的前馈和注意力投影层用于执行矩阵乘法运算,占模型参数和计算负载的大部分——分别为 95% 和 65-85%。
For large transformer language models at and beyond 6.7B parameters, the feed-forward and attention projection layers and their matrix multiplication operations are responsible for 95%2 of consumed parameters and 65-85% of all computation (Ilharco et al., 2020).
-
8 位量化减小了参数的大小,从而减少了内存使用量。但是,现有的Transformers量化方法通常会导致性能下降,需要在训练后进行额外的调整,并且尚未有效地应用于大于3.5亿个参数的模型。在不损失性能的情况下进行量化的挑战,尤其是对于具有数十亿个参数的模型,仍未解决。
While these methods reduce memory use, they degrade performance, usually require tuning quantization further after training, and have only been studied for models with less than 350M parameters.
工作是通过解决两个主要挑战解决的:
-
必须提高超过10亿个参数的模型的量化精度。
the need for higher quantization precision at scales beyond 1B parameters.
-
需要精确表示在超过67亿个参数的模型中系统地出现在所有Transformers层上的大量级异常特征。
the need to explicitly represent the sparse but systematic large magnitude outlier features that ruin quantization precision once they emerge in all transformer layers starting at scales of 6.7B parameters.
如果考虑不当,这些异常值特征会显著降低量化精度,C4 评估中令人困惑的增加和零点精度的降低就证明了这一点。
实现过程
矩阵乘法作为独立的内积
神经网络中的矩阵乘法,特别是在Transformers的前馈层和注意力层中,涉及计算成对向量的点积,矩阵乘法可以被视为一系列独立的行向量和列向量的内积。
单独的量化标准化常数
为了便于从较高的精度(例如 32 位浮点数)到较低精度(例如 8 位整数)的量化,通常使用标准化常量在可以用较低精度格式表示的范围内缩放值。与均匀量化不同,均匀量化对整个矩阵使用单一缩放系数,而向量量化对每个内积使用唯一的归一化常数。这种方法通过根据每个向量对的特定动态范围调整缩放来提高量化过程的精度。
As such, we can use a separate quantization nor-malization constant for each inner product to improve quantization precision.
使用非规范化恢复输出
量化后,为了获得矩阵乘法的正确输出,本文描述了非规范化步骤。这包括使用相应行列归一化常数的外积,将量化乘积缩放回其原始比例。
We can recover the output of the matrix multiplication by de-normalizing by the outer product of column and row normalization constants before we perform the next operation.
大型Transformers中的特征维度异常值
在将Transformers模型扩展到超过67亿个参数的背景下,推理过程中隐藏状态的特征维度中出现极端异常值。
it is critical to understand the emergence of extreme outliers in the feature dimensions of the hidden states during inference.
这些异常值分布不均匀,但往往出现在特定的特征维度。最初,这些大幅度特征出现在大约 25% 的Transformers层中。但是,随着模型扩展到多达60亿个参数,这些特征变得更加普遍。
在67亿个参数大关处观察到一个被描述为 “相移” 的关键转变,其中极端幅度特征的流行率急剧扩大。移相后,所有Transformers层和大多数序列维度(75%)都显示出这些异常值。
At around 6.7B parameters, a phase shift occurs, and all transformer layers and 75% of all sequence dimensions are affected by extreme magnitude features.
作者指出,尽管它们数量巨大(每个序列 150,000 个),但在整个Transformers模型中,它们仅集中在六个特征维度上。
These outliers are highly systematic: at the 6.7B scale, 150,000 outliers occur per sequence, but they are concentrated in only 6 feature dimensions across the entire transformer.
作者经过实验得出结论:
- 将这些离群特征维度设置为零会使 top-1 注意力 softmax 概率质量降低 20% 以上,并将验证困惑度降低 600-1000%,尽管它们只占所有输入特征的 0.1% 左右。(也就是说不能简单地将它们设置为0)
- 删除相同数量的随机特征使概率最多降低 0.3% ,并使困惑度降低约 0.1%。(影响较小)
这种比较突出表明,尽管异常值特征仅占所有输入特征的0.1%,但异常值特征对模型性能的影响非常大。
上图对OPT模型使用不同的量化方法时四个不同数据集(Winogrande、HellasWag、PIQA和Lambada)的零点精度的比较分析。
零点精度是指模型在未进行任何微调的情况下执行任务的性能,这是衡量模型泛化能力的指标。
该图包括三行代表三种不同设置的性能:16 位基线、先前的 8 位量化方法和新提出的 8 位量化方法 LLM.int8()。
事实证明,即使在67亿个参数的范围内,LLM.int8 () 仍能保持与16位基线相同的精度水平。
We can see once systematic outliers occur at a scale of 6.7B parameters, regular quantization methods fail, while LLM.int8() maintains 16-bit accuracy.
这表明 LLM.int8 () 通过其新颖的量化方法(包括向量量化和混合精度分解方案)有效地解决了系统异常值的问题。后者将异常特征维度隔离到更高精度(16 位)的计算中,从而确保即使大多数计算都以较低的 8 位精度执行,模型的性能也不会降低。这一结果突显了LLM.int8 () 在保持模型准确性的同时显著降低大规模语言模型的内存要求方面的功效。
实现图解
-
从 16 位浮点输入 (Xf_16) 和权重 (Wf_16) 开始,分析识别量级较大的分量,这些分量被称为 “异常值特征矩阵”。这些异常值使用更高精度的 16 位乘法进行处理,以保持它们对模型性能的贡献。
-
对其余值进行较低精度的8位乘法进行处理,这是通过将输入和权重按相应的逐行和逐列绝对最大值(Cx 和 Cw)缩放来实现的。
此缩放步骤对于向量乘法至关重要,可确保调整数据的动态范围以适合 8 位表示形式,而不会造成大量信息损失。
-
一旦缩放,这些值将被量化为 8 位整数 (Int8),然后执行矩阵乘法,得到 32 位整数输出 (Outi32)。
-
要将这些输出转换回可供模型使用的浮点表示,需要执行去量化步骤。这包括将输出乘以标准化常数(Cx Cw)的外积,从而有效地逆转初始缩放。
-
最后一步涉及合并高精度异常值乘法和低精度正则乘法的结果。两组输出均累积为 16 位浮点格式,这样可以在不影响整体性能的情况下将最终结果用于Transformers模型的后续层。
总结:对大多数矩阵乘法使用 8 位计算,从而在推理过程中节省大量内存,同时通过选择性地对关键特征使用 16 位计算来保持模型的准确性。
背景
Absmax 量化
它找到列表中最大的数字(绝对最大值),并用它来缩小所有其他数字,但比例仍然相同。
具体方程就是将原始数字乘以 127,然后除以最大数字,对这个结果进行四舍五入到整数——因为 8 位数据类型不能包含分数。
Zeropoint量化
它通过拉伸或缩小数字(缩放)然后向上或向下移动(移动)来更改数字组,使它们适合从 -127 到 127 的一组特定值。
有时,如果没有这种方法,某些值将根本无法使用。例如,如果我们在使用名为 ReLU 的函数后只有正数,则-1、-2、-3 等负值将被浪费。零点量化确保我们也使用这些负值。
具体方程分为3个。
- 第一个是计算出拉伸量,即用2乘以127的结果除以原始数据中行或列中最大值与最小值的差;
- 第二个是计算出偏移量(额外的步长也就是零点),即用原始16位数据乘以原始数据中行或列中最小值;
- 第三个是是用计算出的拉伸量乘以原始16位的数据,四舍五入后得到8位数据。
经过数学运算后(例如乘法),最终我们得到一个32位大整数,如果要变为原来数据,将其除以原始数字的拉伸量。
具有 16 位浮点输入和输出的 Int8 矩阵乘法
Given hidden states Xf16 ∈ Rs×h and weights Wf16 ∈ Rh×o with sequence dimension s, feature dimension h, and output dimension o
- Q过程要么是Absmax量化要么是Zeropoint量化
- “cxf16” 和 “cwf16” 是Absmax量化的张量缩放常数sx和sw,或是Zeropoint的张量缩放常数ndx和ndw
- 量化后,将调整后的8位数字相乘,然后我们使用另一个特殊数字(Sf16)将结果调整回16位格式。
大规模 Int8 矩阵乘法
作者用了一个很有趣的例子解释了量化的核心思想:量化就像通过使用较短的单词来减轻一本沉重的书籍的负担,但仍在努力保持故事不变。 通常,我们使用一个短词(缩放常量)来替换整本书中的许多长词(值)(张量)。
如果书中有一个很长又奇怪的单词(异常值),我们可能不得不用一个不太短的词来表示所有的单词,这样书就不会像我们想要的那么轻。
我们不是在整本书中使用一个简短的单词,而是为每章(分块常量)甚至每页(向量量化)使用不同的短语。 这样,如果有一个奇怪的词,它只会影响自己的页面,不会影响整本书。
有时,有些单词过长且无法缩短(大幅度异常值特征)。 我们用稍大的笔迹(16 位精度)写那些很长的单词,但书的大部分内容都是微小的笔迹(8 位)。 这样一来,这本书就更轻了,因为其中大部分都是用微小的笔迹写的。
LLM.int8() 方法就像一种特殊的写作方式,使用简短的文字和微小的笔迹来写这本书,在不改变故事的情况下尽可能地简化书本。
实验步骤
-
作者将几个公开可用的预训练语言模型的大小扩展到最多 175B 个参数时,我们测量了量化方法的稳健性。关键问题不在于量化方法对于特定模型的表现如何,而是随着规模的扩大,这种方法的表现趋势。
-
使用两个步骤进行实验:
-
语言建模困惑分数
可以说明模型的混乱程度。分数越低越好。他们用它来看看让模型变得更简单是否会让它变得更加混乱。
-
Zeroshot 精度
这是检查模型是否可以完成未直接教其完成的任务。他们看看让模型变得更简单是否会使这些新任务变得更糟。
-
-
使用预训练模型,作者使用的模型从大量资料中吸取了教训和经验,这些模型具有不同的尺寸,参数从1.25亿到130亿不等。
-
使用一组名为 C4 语料库的测试文本来检查更简单的模型的表现。
-
使用名为NVIDIA A40 GPU的强大计算机部件来进行此项测试。
实验结果
- LLM.int8() 是唯一一种随着模型大小的增加而保持高质量的方法,这与其他变得更差的方法不同。
- 在另一项测试中,LLM.int8() 即使模型非常大,也能与16位模型的质量相匹配。
- LLM.int8() 对于小型模型较慢,但对于超大型模型则更快,而且它可以节省内存。
讨论与限制
-
只查看了 Int8 数字,而不是另一种叫做 FP8 的数字,因为现在大多数计算机都无法使用 FP8。
The main limitation of our work is that our analysis is solely on the Int8 data type, and we do not study 8-bit floating-point (FP8) data types.
-
只测试了达到一定尺寸(1750亿个参数)的Transformers。更大的Transformers可能会有不同的问题。
While we quantize a 175B model to Int8 without performance degradation, additional emergent properties might disrupt our quantization methods at larger scales.
-
没有将Transformers中注意重要词语的部分改为 Int8。
A third limitation is that we do not use Int8 multiplication for the attention function.
-
只确保Transformers能够回答问题(推断),没有检查他们能否使用Int8数字学习新事物(训练)。
A final limitation is that we focus on inference but do not study training or finetuning.