100亿参数的语言模型跑不动?MIT华人博士提出SmoothQuant量化,内存需求直降一半,速度提升1.56倍!

  新智元报道

  编辑:LRS

  一个简单的量化操作,让你运行大规模语言模型的 GPU 需求量直接降低一半!

  大型语言模型(LLM)虽然性能强劲,但动辄几百上千亿的参数量,对计算设备还是内存的需求量之大,都不是一般公司能承受得住的。

  量化(Quantization)是常见的压缩操作,通过降低模型权重的精度(如 32bit 降为 8bit),牺牲一部分模型的性能来换取更快的推理速度,更少的内存需求。

  但对于超过 1000 亿参数量的 LLM 来说,现有的压缩方法都无法保持模型的准确率,也无法在硬件上高效地运行。

  最近,麻省理工学院和英伟达的研究人员联合提出了一个通用后训练的量化(GPQ, general-purpose post-training quantization)方案 SmoothQuant,对大型语言模型可以高效实现8-bit 权重,8-bit 激活(W8A8)的量化,无需训练也能保持模型的准确率。

  论文链接:https://arxiv.org/pdf/2211.10438.pdf

  代码链接:https://github.com/mit-han-lab/smoothquant

  由于激活相比权重更难量化,SmoothQuant 通过数学等价变换将较难量化的激活迁移到权重上,实现了对激活异常值(activation outliers)的平滑处理。

  SmoothQuant 能够对所有 LLM 的各种层中权重和激活量化到 INT8,包括 OPT-175B, BLOOM-176B 和 GLM-130B。

  相比现有方法仅对权重进行靓货,或者对激活进行混合精度的量化,SmoothQuant 有更高的硬件效率,实现了 1.56 倍加速,内存需求仅为原始 LLM 的一半,并且在准确率上几乎没有损失。

  SmoothQuant 同时具有硬件友好的设计,研究人员将 SmoothQuant 集成进了 LLM 服务框架 FasterTransformer 中,实现了更快的推理速度,相比 FP16 的精度仅需一半数量的 GPU

  文章的第一作者肖光烜是 MIT EECS 的一年级博士生,本科毕业于清华大学计算机科学与技术学院。

  导师 Song Han 是 MIT EECS 的副教授,博士毕业于斯坦福大学,主要研究方向为高效深度学习,曾提出深度压缩(deep compression)技术,可以将神经网络的尺寸降低一个数量级,而不损失准确率。

  SmoothQuant

  量化(Quantization)就是把高精度的值映射到更低精度的离散值,在这篇论文中研究人员主要关注对硬件更高效的整数均匀量化(integer uniform quantization),尤其是 INT8。

  量化操作可以在不同的粒度上执行,如 per-tensor 量化应用于整个权重矩阵,per-token 量化应用于激活中的每个 token,per-channel 量化应用于权重的每个输出通道。

  通过对激活的量化结果进行观察,研究人员总结出了几个模式:

  1、量化比权重更难量化。

  权重的分布相对更加均匀和平坦,之前的研究结果已经证明将大型语言模型的权重降低到 INT8,甚至到 INT4 对准确率的影响都不大。

  2、异常值是激活量化中的主要难点。

  激活中的异常值通常比正常值要高出 100 倍左右,导致没有异常值通道中的量化 bits/levels 效率很低。

  3、异常值固定在某一通道中出现。

  异常值只在很小一部分的通道中才会出现,但如果一个通道中有一个异常值,那该异常值可能会在所有的 token 中出现。

  给定一个 token 中所有通道的方差会很大(一些通道会非常大,但大部分很小),但是给定一个通道在所有 token 度中的方差会很小(异常值通道会很大)。

  由于异常值具有持续出现和每个通道内小方差的特点,那如果对激活执行 per-channel 量化,其量化误差将会远远小于 per-tensor 量化。

  通过一个简单的实验,其结果再次验证了研究人员的想法,量化到 INT8 时,per-channel 的准确率远远高于 per-tensor 和 per-token 量化,和 FP16 基线准确率相差无几。

  研究人员通过使用一个 per-channel 平滑因子s来将输入激活进行平滑(smooth)。为了保持线性层的数学等价,还需要反向缩放权重。

  由于输入X通常是由之前的线性操作生成的(如线性层、层 norms 等),所以就可以很容易地将平滑因子融合到之前层的参数 offline,而且不会产生额外缩放的内核调用开销。对于其他情况,比如当输入来自残差 add 时,可以向残差分支添加一个额外的缩放。

  将量化难度从激活转移到权重

  Smooth 的目标是选择一个 per-channel 的平滑因子s,使该逆操作更易于量化。

  为了减少量化误差,应该增加所有通道的有效量化比特。当所有通道的最大 magnitude 相同时,总的有效量化位数将是最大的。

  因此,一个最直接的平滑因子选择就是输入中每个通道的最大值,可以保证在划分之后,所有的激活通道都有相同的最大值,从而实现更容易的量化。

  但需要注意的是,激活的范围是动态的,对于不同的输入样本是不同的。所以研究人员使用预训练数据集中的校准样本来估计激活通道的规模。

  由于这个公式将所有的量化困难迁移给了权重,可以发现在这种情况下,权重的量化误差会很大,导致准确性下降很多。

  另一方面,也可以通过选择 sj = 1/ max (Wj ),将所有的量化难度从权重推到激活上。同样,由于激活量化误差过大,模型的性能也不好。因此需要在权重和激活之间分割量化难度,使它们都易于量化。

  研究人员引入一个超参数迁移强度α,来控制要从激活迁移到权重的难度。

  可以发现,对于大多数模型,例如 OPT 和 BLOOM 模型,α=0.5 是一个很好的平衡点,可以平均分配量化难度,特别是使用相同的量化器进行权重和激活。

  该公式保证了相应通道的权重和激活具有相似的最大值,从而共享相同的量化难度。

  对于其他一些激活异常值比较大的模型,例如 GLM-130B 有 30% 的异常值,这对激活量化来说比较困难,可以选择一个较大的α(如 0.75),将更多的量化难度迁移到权重上。

  SmoothQuant 应用于 Transformer 块

  线性层占据了 LLM 模型的大部分参数和计算。在默认情况下,SmoothQuant 对 Transformer 中所有线性层的输入激活进行比例平滑,并用 W8A8 对线性层进行量化,在注意力计算中启用了 BMM 运算符的量化。

  在流程中,首先用 INT8 对线性层和注意力层中的 BMM 等计算量大的运算符的输入和权重进行量化,而对其他轻量级元素的运算,如 Softmax 和 LayerNorm,保持激活为 FP16,这样的设计有助于平衡准确性和推理效率。

  实验部分

  研究人员选择了三个大型语言模型用来评估 SmoothQuant,包括 OPT, BLOOM 和 GLM-130B;并使用七个 zero-shot 任务,包括 LAMBADA, HellaSwag, PIQA, WinoGrande, OpenBookQA, RTE, COPA 等。

  实验结果显示 SmoothQuant 可以处理非常大的 LLM 的量化问题,其激活更难量化。

  SmoothQuant 可以在所有评估数据集上匹配 FP16 的准确性,而 W8A8、ZeroQuant 和 Outlier Suppression 基线产生的结果几乎是随机的。

  并且 SmoothQuant 可以无损地量化所有超过 100B 参数的开放式 LLMs

  SmoothQuant 的 O1 和 O2 级成功地保持了浮点精度,而 O3 级(per-tensor static)使平均精度下降了 0.8%,可能是因为静态收集的统计数据与真实评估样本的激活统计数据之间的差异。

  尽管如此,SmoothQuant-O1 可以与 FP16 的准确性相匹配,而 SmoothQuant-O3 只降低了1% 的准确性,明显优于基线。

  SmoothQuant 不仅对超过 100B 参数的非常大的 LLM 有效,而且对较小的 LLM 也有稳定的效果,SmoothQuant 可以在所有规模的 OPT 模型上工作,并与 INT8 量化的 FP16 精度相匹配。

  为了展示集成到 PyTorch 和 FasterTransformer 中的 SmoothQuant-O3 的速度提升和内存节省,研究人员我们测量了一次生成一批 4 个句子的所有隐藏状态的端到端延迟,也就是 context 阶段的延迟,并记录了这个过程中 GPU 内存使用的峰值。

  由于 Huggingface 缺乏对模型并行的支持,所以研究人员只测量了 SmoothQuant 在单个 GPU 上的 PyTorch 实现的性能,因此选择了 OPT-6.7B、OPT-13B 和 OPT-30B 进行评估。

  在 FasterTransformer 库中,SmoothQuant 可以与 Tensor Parallelism 算法无缝对接,因此研究人员在 OPT-13B、OPT-30B、OPT-66B 和 OPT-175B 上测试 SmoothQuant 的单 GPU 和多 GPU 基准。

  在 NVIDIA A100 80GB GPU 服务器上进行的实验结果显示,基于 PyTorch 实现的推理延迟和峰值内存使用上,SmoothQuant 始终比 FP16 基线快,当序列长度为 256 时,在 OPT-30B 上获得了 1.51 倍的速度提升。

  还可以看到一个趋势,即模型越大,加速越明显,但 LLM.int8()几乎总是比 FP16 基线慢,这也是由于混合精度激活表示的巨大开销造成的。

  在内存方面,SmoothQuant 和 LLM.int8()都可以将 FP16 模型的内存用量几乎减半,而 SmoothQuant 由于完全使用 INT8 GEMM,所以节省的内存稍多。

  与 FasterTransformer 对 OPT 的 FP16 实现相比,SmoothQuant-O3 在使用单个 GPU 时可以进一步降低 OPT-13B 和 OPT-30B 的执行延迟,最高可达 1.56 倍。

  参考资料:

https://www.reddit.com/r/MachineLearning/comments/z1b2rp/r_smoothquant_accurate_and_efficient_posttraining/