一
简介
在模型轻量化领域,量化是一种用于减少神经网络模型大小和计算量的技术,将模型参数(权重)或中间变量(激励)从高精度类型(FP32, FP16, BF16等)转换为低精度类型(int8, int4, fp8等)。 而近年来随着Transformer,MoE等架构的提出和大模型的兴起,使得神经网络模型能轻松突破几十亿甚至上万亿的规模参数,因此,我们需要一些适应于大模型的压缩技术,来降低模型的部署成本,并提升模型的推理效率。
从最初的GPTQ、AWQ等weight-only的量化算法开始,到现在LLM从训练、推理、轻量化、Agent等所有赛道都卷到飞起的时代,基于大模型的特性,在两年多时间里业内已有很多新的量化算法。
二
概念
以下介绍一些模型量化中的概念。
量化
-
量化感知训练(Quantization Aware Training, QAT):训练过程中插入伪量化算子,通过训练时统计输入输出的数据范围并动态调整量化参数,将量化过程结合到模型的训练过程中,适用于对模型精度要求较高的场景。
-
训练后量化(Post Training Quantization, PTQ):模型训练完成后对其参数进行量化,通常只需要少量校验数据或不需要校验数据,简单高效,不需要训练,但通常相比QAT精度损失略大。
由于LLM通常训练成本巨大,所以PTQ在LLM中通常是主要的量化选择,本文后续主要介绍各种PTQ的方案。
量化对象
-
Weight:即模型的权重,在LLM中主要指Linear算子的权重。权重量化可减少模型显存开销。
-
Activation:在模型前向计算过程中的输入输出变量,通常不会单独量化激励张量,而是结合权重量化一起。在LLM中激励矩阵的数值变化范围相比权重更大,有更多离群的异常值,因此相比权重量化更难。
-
KV Cache:除了权重和激活之外,在LLM的 KV Cache作为减少重复计算的特殊存在,会消耗不少的显存。 因此,KV Cache量化在LLM推理中减少显存开销,提升吞吐也很重要。
在LLM中,对Weight和Activation而言,通常有只量化权重的weight-only方法和weight & activation都量化的方法;另外为减少KV Cache的计算开销,也有对其进行量化。
细粒度
-
per-tensor量化:逐张量量化,或逐层量化,每个张量只有一个缩放因子。
-
per-channel 量化:逐通道量化,每个通道都有不同的缩放因子。
-
per-token 量化:主要对transformer中的激励矩阵而言,即逐行量化。在LLM中,常与权重per-channel 量化配合使用。
-
per-group:以组为单位,多个元素成组共享一个缩放因子,如GPTQ、AWQ常用的128个元素为一组进行量化,将通道划分为更小的子组,以实现更细粒度的精度控制。
其他维度
分类维度 |
类型 |
对比特点 |
适用范围 |
按是否需要额外校验数据 |
静态量化 |
不需要,通常速度较快。 |
常用于权重量化 |
动态量化 |
需要额外校验集对模型进行前向推理或后向传播,根据推理结果动态计算量化参数;相比静态量化速度较慢。 |
适用于权重量化和激励量化 |
|
按量化过程的时机 |
离线量化 |
在模型上线推理前,提前计算量化参数。 |
常用于权重量化和激励量化 |
在线量化 |
在推理过程中实时计算量化参数。 |
常用于LLM中的激励量化 |
|
按量化步长是否均匀 |
线性量化 |
量化步长固定,表示的范围均匀。计算复杂度低,硬件友好。 |
常用于基于通用GPU的量化方案 |
非线性量化 |
量化步长不固定,表示范围更灵活。精度损失更小,但计算复杂度高。对硬件支持要求更高。 |
用于基于专用芯片的量化方案 |
|
按量化范围是否对称 |
对称量化 |
量化数据范围以零值对称。零点值(zero-point)固定为0值,仅需考虑缩放(scale)参数。 |
用于权重量化和激励量化 |
非对称量化 |
量化数据范围为非对称。zero-point和scale参数都要计算。 |
权重量化和激励量化通常不会同时为非对称量化 |
|
三
量化方法摘要
GPTQ
GPTQ是一种weight-only的量化方法。它的特点是通过Hessian矩阵对每层权重做逐列量化,并在每列量化中通过反馈补偿之前的量化损失。它是LLM早期主要量化算法,因量化速度快和量化损失小,是早期在实践中被应用最广的算法。具体细节可参见之前的文章:
模型量化与量化在LLM中的应用。

GPTQ算法流程(图片来源:参考文献[1])
AWQ
AWQ(Activation-aware Weight Quantization) 也是一种weight-only的量化算法,也是早期主流的LLM量化算法,其特点是量化速度相较于GPTQ更快,且量化损失在多数量化方案和模型上相较于GPTQ也更小,到目前为止也是一种非常实用的量化方案。
AWQ出自深耕深度学习轻量化多年的HanSong团队,其主要原理是根据前向推理中的对应激励矩阵各个通道的数值,而非权重矩阵的通道数值来衡量权重矩阵各个通道的重要性,从而自动检索每个通道的缩放因子,并进而在优化损失函数中减小量化误差。具体细节也可参见之前的文章:模型量化与量化在LLM中的应用。

AWQ中的平滑过程(图片来源:参考文献[3])
HQQ
HQQ(Half-Quadratic Quantization)也是一种weight-only的量化方法,由其名称可知通过半二次优化的方法得到量化参数。相比AWQ和GTPQ,HQQ不依赖于校验数据集,不从最小化输出激励的角度优化,而是直接从权重本身优化量化前后的权重误差;而且其量化速度特别快,并且在低精度量化上有较好的量化误差。
优化目标如下,最小化原权重与量化反量化后的权重之间的误差,
为
范数。

优化过程
基于上述问题,引入一个额外变量
让主优化函数分割成2个子优化问题;同时,为了方便使用迭代更新的过程解题,我们固定尺度参数
,从而只优化零值

通过交替优化的方法,可以写出如下子问题,以及超参的更新,

sp1的形式是近端算子,对于
范数,存在一个广义的阈值解如下,

sp2可以通过量化公式代入,得到如下,

并通过进一步简化(基于W的quantization grouping维度取均值),

表现性能
HQQ的量化耗时非常短,以Llama2-70B为例,在A100上相比于GPTQ和AWQ,耗时分别缩短为1/50和1/25,同时也有着不逊色于前两者的量化精度损失;而Llama2-7B模型的量化耗时更是缩短到1分钟左右。

Llama2-7B量化:GPTQ, AWQ, HQQ三者的耗时对比
(图片来源:参考文献[6])

Llama2-70B量化:GPTQ, AWQ, HQQ三者的耗时对比(图片来源:参考文献[6])

HQQ 在group-wise量化模式下与GPTQ, AWQ等的性能对比(图片来源:参考文献[6])
SmoothQuant
SmoothQuant 是LLM量化领域首个对weight和activation做全量化,并能保障良好的量化损失,从而在实际中有广泛应用的量化算法,并以被Nvidia和Intel集成到各自的大模型量化工具TensorRT-LLM和Neural-Compressor中。SmoothQuant 也是由HanSong团队提出,因此也可在算法中看到相似的通道缩放操作。
该方法直接聚焦LLM量化困难的最主要原因,即transformer推理过程中的激活值中的异常值(Outliers)。激励矩阵中的异常值指的是绝对值比大多数的值大得多的元素值,异常值一直是量化领域的难点,是量化损失的重要来源,而LLM中的异常值尤难处理,因其通常持续存在于部分通道中,且量化过程中对其直接截断处理会对模型的生成能力造成重大影响。

SmoothQuant中量化难度的迁移:激励矩阵中异常值的平滑(图片来源:参考文献[4])
该方法的核心是通过逐通道的缩放变换,使得Activation矩阵的绝对值幅度变得平滑,从而变得容易量化,而为了保障计算一致性,将反缩放因子作用到Weight中,稍微增加了Weight的量化难度;从而整体上使得模型的量化难度降低,且提高了量化精度。
量化过程
Transformer中常规的矩阵乘法表示为
,SmoothQuant的矩阵乘法则表示如下,

激励矩阵
在列维度上每个元素除以
, 权重矩阵
在行维度上每个元素乘以
,从而完成了对激励矩阵的平滑,以及保持整个乘法计算的一致性。
通道维度的缩放因子用对角矩阵
表示,而如何对
取值呢?作者提出了几种方案,
-
一种是利用激励矩阵各个通道的绝对极值,即

-
一种是利用权重矩阵各个通道的绝对极值,即

本质上,缩放因子的大小取值表达了我们要将激励矩阵量化难度的多少转移给权重矩阵。而以上的前者,容易将激活的量化难度向权重过度转移,从而导致权重量化难度大大增加;而后者会直接导致权重各通道的极值都相同,而激励依旧很难量化。
因而,一种平衡的方式如下,用α表示迁移强度,来控制激励量化难度迁移到权重的强度,

而当
时,下图表示了乘法计算中的缩放平滑过程。X 和W 在各自对应的通道计算绝对极大值,随后通过
这两个向量计算得到缩放矩阵,再对X 和W 两个矩阵进行缩放变换,最后再对两个变换后的矩阵做乘法。

SmoothQuant矩阵乘法中的平滑过程示例(图片来源:参考文献[4])
表现性能
在量化模型的效果上,对比了同为Weight-activation量化的几种算法,SmoothQuant在多个数据集上的准确率表现突出。但作者没有对比同时代下的GPTQ、AWQ等weight-only的效果。

SmoothQuant与W8A8和LLM.int8()的量化效果比较(图片来源:参考文献[4])
而在吞吐上,作者用CUTLASS实现了INT8乘法kernel,并将SmoothQuant集成到Pytorch之后,以W8A8方案为例,实现了在OPT模型上相比于原FP16模型在速度上1.56倍,以及在显存上1.96倍的优势。

SmoothQuant经算子优化后与FP16和LLM.int8()的推理吞吐性能比较(图片来源:参考文献[4])
QuIP
在基于正交矩阵旋转优化大模型量化中的异常值(Outlier)问题的思路中,QuIP(Quantization with Incoherence Processing)是较早提出的一个方案。这种思路与SmoothQuant一样,都是在真正的量化步骤之前,通过对权重矩阵或激励矩阵做一定的前处理,使得该矩阵中的异常值改善或消失,使矩阵平滑,同时在整个前向推导中还能保持计算一致性。而与SmoothQuant直接对目标矩阵做尺度缩放不同,这种思路通常是通过对目标矩阵左乘、右乘正交矩阵,使得矩阵变得更容易量化。
该方案的主要主要亮点如下,
-
一是分析矩阵中元素的绝对值分布,并定义了不相干性,将一个矩阵的量化难易程度具象化。
-
二是提出了基于正交矩阵LDL分解的对权重矩阵的逐列量化方案,并证明了GPTQ也是该算法下的一种特殊情况。
-
最后在低比特量化情况下,该算法证明了其性能优于之前的方案。
矩阵的不相干性
作者定义了基于
值的不相干性:当一个Hessian矩阵
可以通过特征分解得到
,且对所有的
满足如下,

那么我们说是的。
而对于权重矩阵, 则定义其 如下,

以上定义中,矩阵的最大绝对值受限于
值,而
值越小,则越不相干,对应地,矩阵中的异常值就越少,也越容易量化。
量化过程
整体算法过程涉及到较为复杂的数学推导过程和大量定义和论证,其主要过程如下,
-
第一步,对权重矩阵
做不相干性的前处理,使
更容易量化,并作简单的量化处理;
-
第二步,对Hessian矩阵(用
计算,与GPTQ相同)做LDL分解;
-
第三步,对
进行逐列量化,每次量化当前列时,考虑前面所有已量化列的误差为反馈以缩小量化误差;
-
第四步,逆不相干处理,以及反量化。

QuIP算法的量化过程(图片来源:参考文献[5])
LDLQ
作者定义了一个基于LDL分解的最优化近似算法,自适应的近似过程可以是近似或随机(Near or Stochastic)。 根据以下公式逐层优化,

作者定义了一个基于LDL分解的最优化近似算法,自适应的近似过程可以是近似或随机(Near or Stochastic)。 根据以下公式逐层优化,
表示浮点权重,
表示量化后的权重,
表示输入矩阵,
是其二阶矩阵,Hessian矩阵。
而对于每层Linear的
,用如下形式作逐列量化,

表示第k列权重,而
表示第1到k-1列,
表示量化后的第k列权重,Q表示对应的Near或Stochastic近似方法选择。
表示某种序列的向量,也正是需要通过LDL分解求的校正项的系数。而整体的量化过程可以用矩阵的形式表示,用一个上三角矩阵表示LDL分解的系数矩阵,即
组成的矩阵,

具体的不相干性处理和逆处理的算法过程可以参考论文中给出的细节。

QuIP中不相干性的前处理和逆处理过程(图片来源:参考文献[5])
表现性能
下图是作者给出的对OPT模型权重层的处理前后,各层的元素值的不相干性的变化,可见在处理后,最大绝对值下降十分明显。

OPT-2.7B模型在不相干性处理前后异常值数量的变化(图片来源:参考文献[5])
而在量化效果上,对比了同为weight-only的主流算法OPTQ(即GPTQ)在同比特情况下,多个验证集的准确率。在对Llama2-70b模型的低比特量化中,尤其是2-bit和3-bit, QuIP的效果明显,且没有崩坏。

QuIP与OPTQ(GPTQ)在不同比特下的量化效果比较(图片来源:参考文献[5])
QuaRot
QuaRot(Quantization scheme based on Rotation)是基于旋转矩阵变换的一种量化方案,它的量化对象包括weight,activation以及KV cache。通过旋转矩阵,在保持一致性的前提下,去除中间变量的异常值,从而使量化更容易,这种模式应用于transformer中的Attention,KV cache和FFN中的激活值。
旋转矩阵
旋转变换利用的是正交矩阵先简单介绍一些相关的矩阵知识。

令
,
是一个包含从{+1, -1}随机抽取的向量,可知
也是正交矩阵。
计算不变性
令
是一个权重矩阵,出现在Attention或FFN Block的左侧 (FFN中的
,
,及Attention中的
,那么可以将左侧乘以正交矩阵
,并通过将输出矩阵(FFN中的
, 及Attention中的
)乘以
来消除这种影响。
上述的计算不变性在当两个Block之间有RMSNorm时也是成立的。因为从概念上讲, RMSNorm对输入矩阵的每一行做归一化(其尺度缩放的参数会被吸收到就近的Linear权重),正交矩阵
应用于 activation 矩阵不会影响范数。

那么总的来说,对于一个Activation矩阵
,右乘
,使得线性层的输入由
变为了
,被归一化之后送入下一个 Block,该Block 的输入权重现在是
;即原本的
,变成了
, 输出不变,保持一致。
量化过程
QuaRot总体分为2个阶段
- 第1阶段,对transformer的前向过程进行旋转变换,具体是在Attention和FFN过程中插入离线Hadamard变换**和额外的在线Hadamard变换。
- 第2阶段,利用现有的量化方法对weight进行量化,以及将量化过程加入前向过程使得对activation和cache进行在线量化。
第一阶段
第1阶段是对各个环节做Hadamard变换。

原Attention(包括RMSNorm): 实线箭头表示训练期间的变量流向,包括每个token的填充和推理

原FFN(包括RMSNorm):门控前馈网络

QuaRot版Attention:RMSNorm缩放alpha被吸收到输入矩阵,隐藏状态插入在线Hadamard变换进行旋转

QuaRot版FFN:RMSNorm缩放alpha被吸收到输入矩阵,降采样Linear前插入在线Hadamard变换进行旋转。
QuaRot 量化前对transformer各个模块的旋转变换(图片来源:参考文献[7]
阶段1a: 权重调整,遵循计算不变性原理对权重做正交变换
对权重矩阵,例如
, 首先,前面的LayerNorm 或 RMSNorm 的线性部分将被融合进来,再左乘随机Hadamard矩阵**
,表示如下,

其中
表示归一化op被吸纳的线性部分,而对应输入的激励居住,则变为了
该操作对应Attention中的
和FFN中的
,而这样处理后对比处理前,激励不再包含异常值。

旋转变换前后激励矩阵中异常值数量的变化(图片来源:参考文献[7])
阶段1b: 对FFN的输出插入在线Hadamard变换
该操作是针对下采样乘法
的输入激励的异常值的处理。由上图可知插入了一个在线Hadamard变换算子,同时对下采样矩阵的参数做了补偿,使得
。
同时为了保障下一个Block的激励输入是带变换的,所以还需右乘一个
,使得最终的变换形式是
,保障FFN的输出为
,作为下一模块的输入。
阶段1c: 对Attention模块的注意力和Value的Hadamard变换
作者对注意力块同时应用了在线Hadamard变换和融入权重的离线Hadamard变换。 在计算注意力时,写成每个Head计算的维度,有如下形式,
表示相应的Linear权重,

其中,
首先对
分别右乘和左乘,做Hadamard变换,带入上式,可知保持计算不变性。

而
分别有每个Head维度的
concat而成,可以用单个Kronecker**乘法的形式表示对
的变换,

然后利用如下特性构建完整的Hadamard变换,

综上,所以总体上整个过程的设计保持了计算不变性。
阶段1d: 对key的Hadamard变换
Key向量的计算也会收到异常值的影响,所以也需要引入Hadamard变换来消除这个问题。注意力矩阵
计算如下,

其中,
,是 输入Softmax时的缩放尺度,
表示mask, 如最常用的Causal Mask,Pos 表示位置编码。
由于Pos的存在妨碍了直接将Hadamard矩阵融合到
中,因此也使用了在线Hadamard Head操作来旋转
,对他们右乘
,

其中的
相当于变成了
,整个计算过程保持了计算不变性。
第2阶段
第2阶段是在变换后的真正量化过程。
阶段2a: 权重的量化
采用现成的GPTQ,或者更直接、更快速的RTN。
阶段2b: 激励的量化
对输入input进行per-token维度的在线量化,而其中RMSNorm依旧保持FP32的精度。
阶段2c: 缓存的量化
对kv cache直接量化到低比特并存储,并在需要计算时提取并重新反量化到FP16精度,计算乘法。而过程中Query保持FP16, 并参考了类似Flash Attention中的在线Softmax计算方式。
所以,结合上述细节和上图,我们可以讨论整个过程的数据流转。
在Attention过程中,FP16的输入
右乘变换后,经过RMSNorm归一化,量化到INT4形式,并与左乘变换并量化后的权重做INT乘法运算,随后再反量化回FP16,其中
经过位置编码(RoPE)计算,而
经过变换并量化保存为cache,且在做MHA时反量化并变换回来,最后到输出Linear时再经变换和量化,与已变换并量化的权重相乘,最终再反量化为FP16输出
。
在FFN过程中,FP16的输入
右乘变换后,经过RMSNorm归一化,量化到INT4形式,分别与左乘变换并量化后的上采样权重和门控权重做INT乘法运算,并反量化回FP16,做点乘;最后经变换和量化到INT4,与变换并量化后的下采样权重做乘法,最终再反量化为FP16输出
。
表现性能
在对权重、激励和缓存的全4-bits量化效果对比中,QuaRot相对于SmoothQuant, QmniQuant和QuIK,在Llama模型上有性能优势;且应用了group-wise后,对比Atom也有性能优势。

QuaRot与其他量化算法的性能比较(图片来源:参考文献[7])
SpinQuant
SpinQuant也是一种在利用正交旋转矩阵减少异常值的思路上的量化方法。该量化方案也是一个全量化方案,其量化对象也是所有的权重,激励和KV缓存。
该方案中,作者分析了不同随机矩阵变换下,多次量化效果的稳定性。用普通随机矩阵做旋转变换的量化过程的量化效果,最好与最差之间相比差距多大13个点,而随机 Hadamard 矩阵优于随机旋转矩阵,但也仍有6个点的不可忽略的方差。而作者提出的Cayley优化矩阵,如下图对比,则能将最终量化性能的方差明显缩小。

Llama2-7B 在不同随机旋转矩阵量化到W4A4模型的性能分布。不同随机旋转矩阵(普通随机,Hadamard和Cayley优化矩阵)之间的方差(图片来源:参考文献[8])
插入旋转矩阵
作者提出了针对不同复杂度而定制两种旋转策略。
下图是在完整的transformer block中插入不同旋转矩阵的概图,有四类旋转矩阵:
,根据是否能合并,分为两类,
由此,作者提出了两种量化方案

SpinQuant整体的旋转变换(图片来源:参考文献[8])
R1R2
SpinQuant旋转矩阵的插入和应用与QuaRot大同小异。
由上图(a)(b)可知,
和QuaRot中的1a一样,作用于每个Attention和FFN的输入处的激励矩阵,即Attention的Q、K、V Linear输入和FFN的上采样、门控Linear输入;具体到模块内部,其补偿矩阵
$会被吸收到各种的权重矩阵中。
则是Head-wise地将注意力机制的输出乘以
, 随后在输出output的投影矩阵
乘以
。这一操作类比于QuaRot中的1b,其旋转的计算一致性如下,

R3R4
类似于QuaRot中的1c,在注意力机制中插入了额外的在线Hadamard变换(
),以及在FFN的降采样Linear之前插入了在线Hadamard变换(
),其旋转的计算一致性如下:

注意力机制中value矩阵的旋转变换(图片来源:参考文献[8])

FFN中下采样输入的变换(图片来源:参考文献[8])
Cayley优化旋转矩阵
本方案的一个主要贡献,是基于上述随机矩阵的方差分析,对旋转矩阵进一步做了基于最小化量化网络误差的优化。优化目标是上述的可合并的
,而在线旋转
依旧使用了Hadamard随机矩阵,这也是两种方案命名为NoHad和Had的原因。
基于
优化过程的损失函数如下,

这里,
为了优化上述函数,作者采用了一种叫Cayley SGD的梯度方法,这是一种Stiefel流形上的高效算法。其本质是一个迭代更新的优化过程, 在每次迭代中,旋转矩阵
基于梯度更新,

其中定义
,是对矩阵
的Cayley变换,
是斜对称矩阵(
)。 而
由上述的损失函数的梯度
的一个投影计算得到,

通过矩阵
的正交属性,推出Cayley变化得到的矩阵
的正交属性,从而保证更新后的旋转矩阵
的正交属性。通过上述的梯度计算的迭代过程,可以求解优化
,在这个过程中transformer的权重参数保持不变。
在具体实践中,作者基于WikiText2数据集作为校验集,用其中800个样本作前向推导,使用迭代更新次数为100次的Cayley SGD梯度优化结果作为新的旋转矩阵{
},并在上述的随机矩阵量化结果分析中取得了最小方差和最优效果。
表现性能
在量化性能上,基于Llama2系列与SmoothQuant、OmniQuant等方案作了比较,也与weight-only的算法GPTQ, AWQ, QuIP等做了比较,有更低的PPL(困惑度)和更好的准确度。

量化效果对比(验证集:基于8个0-shot推理任务的平均准确度和基于WikiText2的PPL; 测试模型:Llama2)(图片来源:参考文献[8])
而且作者也对比了基于优化Cayley旋转矩阵和随机Hadamard矩阵的相同量化方案下的量化效果,体现了控制变量下的优化效果。

Llama3.2, Llama-3, Mistral等在8个0-shot任务下,Hadamard与Cayley优化矩阵的效果对比(图片来源:参考文献[8])
QQQ
QQQ(Quality Quattuor-Bit Quantization)是来自meituan的一个缝合了多种量化手段的方案。它吸收了自适应smooth技巧和Hessian-based权重量化算法,并重写了整型乘法的高效算子库,是一个针对weight和activation全量化的two-stage的量化算法。

QQQ算法的二阶段量化流程(图片来源:参考文献[9])
量化过程
自适应平滑
通过通道维度的缩放操作,使得激励矩阵的异常值变得平滑,从而降低量化难度,这是启发自smoothquant算法,为求最优的平滑系数,构建了如下最小化量化前后输出误差的优化函数,

为element-wise的除法和乘法。
权重量化
基于Hessian的逐列的权重量化算法,则是借鉴自GPTQ,

表示
第
行,
表示Hessian矩阵。
W4A8
为支持和加速不同比特位的整型乘法,重写了W4A8的GEMM算子,融合了整型转换和反量化的过程,如下图,包含了per-channel和per-group 两种方案。
-
Per-channel: INT4的权重
先通过精度转换变成INT8格式,再与INT8的激励
做GEMM, 最后反量化为FP16精度。
-
Per-group: INT4的权重
首先通过精度快速转换为FP16, 再加载group量化参数将权重反量化,随后再精度转换为INT8, 与INT8的激励做GEMM, 最后再反量化为FP16精度。

W4A8的 per-channel权重量化模式(图片来源:参考文献[9])

W4A8的 per-group权重量化模式(图片来源:参考文献[9])
表现性能
在量化效果上,以Llama2为例,基于Wikitext2的PPL和多个测试集的0-shot准确率和同等量化QoQ效果相当,而在PPL上与weight-only算法相比似乎稍有不足。

QQQ与其他算法的量化效果PPL对比(图片来源:参考文献[9])

QoQ与其他算法的量化效果Zero-shot准确率对比(图片来源:参考文献[9])
而在推理性能上,通过基于高性能算子库Marlin重写了GEMM并集成到推理引擎vLLM上,
在Llama2-13B上相比于FP16,SmoothQuant和AWQ,有着2.24×, 2.10×, 1.59×的速度优势。

QQQ量化后的模型与其他算法的推理吞吐性能比较(图片来源:参考文献[9])
QoQ
QoQ(Quattuor-Oct ̄o-Quattuor)是来自HanSong团队的W4A8KV4的低精度全量化方案。QoQ算法及其相关的Qserve推理系统,集成了包括量化过程和算子优化,与其说是量化算法,不如说是一套完整的端到端的模型轻量化推理引擎。
作者在量化比特的选择上对比了Weight-only的W4A16方案和per-channel weight量化和per-token激励在线量化结合的W8A8方案。
-
对于批处理较小的情况,LLM的GEMM主要是内存受限,W4A16有着更高的吞吐。
-
当批次变大时,GEMM就变成了计算受限,由于INT8 Tensor Core具有更高吞吐量而使W8A8显得更快。
-
而作者认为W4A8能兼顾两者,在内存密度和计算密度的场景下都能保持较高的吞吐。
-
而在解码阶段,由于token的逐个生成特性,Attention的计算密度相对较低,因而KVcache的量化有助于解决内存密度问题,对KVCache选择W4,相比与W8能获得更高的性能。
-
而对于更激进的W4A4,一方面由于准确性下降,另一方面也由于W4A4 GEMM在当前GPU架构(Ampere, Hopper)上并没有太显著的提升。
量化过程
QoQ的量化过程是众多量化算法中的技巧融合,通过不同手段来减小量化误差。
渐进分组量化

QoQ的渐进分组量化 (图片来源:参考文献[10])
渐进分组量化(Progressive Group Quantization)指的是对weight 先进行per-channel的INT8量化,再进行per-group的INT4量化。
给定权重
,先用per-channel对称量化至INT8形式,

表示量化后得到的INT8的权重,
是所使用的量化参数scale。
然后,对上述量化结果再使用per-grouup非对称量化至INT4形式,

表示最终的无符号4-bit量化权重,
分别是对应的量化参数zero-point和scale。
当推理的前向过程计算W4A8 GEMM时,INT4的权重
被加载后,先反量化为INT8的权重
,再执行W8A8的矩阵乘法。
另外,实际中,为了保护INT8反量化时饱和溢出,将INT8对称量化范围从[-127, 127]缩小到[-119, 119]。
平滑注意力
平滑注意力(SmoothAttention)借鉴了SmoothQuant中依靠通道缩放转移激励量化难度的思路,主要针对Key矩阵异常值较多且难量化的问题。
下图可视化了Value矩阵和经过RoPE的Key矩阵的元素值分布,可见Value矩阵的值较为平滑,而Key矩阵中有明显通道固定的异常值。

RoPE输出Key矩阵经smooth前后的异常值变化,以及Value矩阵的异常值变化(图片来源:参考文献[10])
借鉴SmoothQuant, 通过per-channel缩放因子缓解Key矩阵中的异常值范围,

可以通过激励矩阵简单计算,
, 而缩放强度超参
可以取经验值0.5。由上图可见,通过平滑后Key矩阵的异常值得到明显缓解。
而实际中,通常缩放矩阵
的补偿矩阵会融合到前一层的权重中去,而LLM中Attention的Query和Key通常会经过RoPE处理。RoPE在每个Head中将通道
与通道
配对。因此为了使SmoothQuant在RoPE中可交换,作者附加了一个硬约束条件,令
,即


Qserve中的平滑缩放优化(图片来源:参考文献[10])
这样则可以通过
和
将缩放矩阵的补偿矩阵融合到Query和Key的Linear层权重中去了。
旋转矩阵
同样,借鉴自QuaRot,QuIP等,使用Hadamard矩阵做旋转变换,来抑制输入激励矩阵的异常值。

Qserve中的旋转矩阵优化(图片来源:参考文献[10])
通道重排
另外,参考AWQ, GPTQ等,提出了基于激励的通道重排序,使用激励矩阵逐通道的最大|
|值,来表征通道显著性,重新排序通道,使得具有相似显著性的通道在同一个量化组中。

Qserve中的通道重排优化(图片来源:参考文献[10])
Qserve吞吐优化
在通过各种量化技巧融合实现了W4A8KV4的量化流程后,为了保障其推理吞吐性能,作者又设计了一个Serving系统,命名为Qserve,将量化过程融合,设计GEMM kernel, 相当于一个高效的推理引擎。
下图是Qserve runtime示意图,其中所有的GEMM层都使用了W4A8输入并在INT8的TensorCore上执行,输出FP16格式,所有的Attention和LayerNorm都以FP16计算,且整体的LLM模块的输入输出都是FP16格式。

Qserve runtime推理流程中的精度变化(图片来源:参考文献[10])
-
算子融合
对于QKV投影和FFN第一个Linear,激励量化被融合到前面的 LayerNorm 中;FFN层第二个Linear的激励量化,则融合到前面的激活 Kernel 中。
-
KV-cache管理
参考了vLLM、TensorRT-LLM等的PagedAttention模式,相比这些搜索引擎,Qserve采用了逐Head的动态管理模式,因为其需要存放量化参数,以及动态更新。
-
W4A8 GEMM
GEMM是计算的主要开销,Qserve通过对权重重排、Per-channel反量化、Per-Group反量化等做了深度优化。
-
KV4** 缓存
结合KV的量化和反量化优化整体的Attention流程耗时。
表现性能
在量化模型的PPL指标上,基于Llama,Mistral等模型,作者对比了很多量化算法,在同等量化条件下,QoQ有一定的优势,和QuaRot相当,而相比于Weight-only算法稍有不如;而在0-shot的准确率上优于Atom和QuaRot算法。

QoQ与其他算法的量化效果PPL对比(图片来源:参考文献[10])

QoQ与其他算法的量化效果Zero-shot准确率对比(图片来源:参考文献[10])
在推理吞吐上,得益于其对Pipeline的深度优化,Qserve甚至表现得优于TRT-LLM这样的专业推理引擎。

Qserve量化后的模型与其他算法的推理吞吐性能比较(图片来源:参考文献[10])
FP8
FP8是以8-bit位表示的一种低精度浮点格式,Nvidia 的GPU从Hopper架构的显卡开始支持FP8的训练和推理格式。FP8有2种格式,以下是与FP16和BF16的数据格式对比,

FP8两种格式与FP16及BF16的比特位表示对比(图片来源:参考文献[13])
-
E4M3:包含1个符号位,4个指数位(exponent) 和 3个尾数位(mantissa),可以表示[-448, 448] 范围的数值和nan.
-
E5M2:包含1个符号位,5个指数位(exponent) 和 2个尾数位(mantissa). 可以表示[-57344, 57344],正负无穷(inf)和 nan.

FP8两种格式的具体表达范围(图片来源:参考文献[11])
符号位占一位,表示正负。
指数部分在浮点表示法当中,一般会减去一个偏移量,对于FP8 E4M3 而言,这个偏移量为-7,这使得指数的表示范围为[-7, 8]。对于 FP8 E5M2 而言,指数偏移量为 -15,指数表示范围为[-15, 16]。
底数从高位到低位,分别表示2的负k次幂;对于E4M3格式,使用3个比特表示底数,其分别对应2的负1, 2, 3次幂。对于E5M2格式,使用2个比特表示底数,分别对应2的负1, 2幂。底数表示时会额外加1,而当指数部分全为0时,则不额外加1。
浮点量化
相比于整型量化,浮点的量化属于非均匀量化,即浮点量化的步长是不固定的,由下图可知,相比于FP32到INT8的映射,浮点量化的步长随着指数部分的变大而变大。

FP8与INT8量化的量化步长对比(图片来源:参考文献[12])
量化精度
FP8与INT8量化孰优孰劣,只能说各有长短。FP8 相比INT8,有更大的表示范围,但在一定范围内,其精度表达能力相较INT8为差。如下图,从高斯分布随机抽样1000万个数字,分别使用 FP8 E4M3, FP8 E5M2, INT8 完成量化。在三者的量化中,应用不同的缩放参数来调整量化效果,画出量化误差(用MSE表示)。可以看到,FP8之间,E4M3的量化效果要好于E5M2, 而在选取合适的量化参数范围内,INT8的量化效果要好于FP8,而FP8具有更好的兼容性,对缩放参数的选择相对不敏感,更适合不需要校验集的量化。

FP8与INT8在不同量化参数下,对正态分布数据量化的精度损失对比(图片来源:参考文献[12])
四
总结
下面是对以上介绍的一些大模型量化方案的简要总结和对比,
量化算法名称 |
量化对象 |
特点和适用范围 |
GTPQ |
权重 |
离线量化,支持4~8-bit,量化速度较快,支持模型较多,比较成熟 |
AWQ |
权重 |
离线量化,支持4~8-bit,量化速度较快,支持模型较多,比较成熟 |
HQQ |
权重 |
离线量化,支持1~8-bit,量化速度在所有算法中最快,量化精度与GTPQ,AWQ相当 |
SmoothQuant |
权重、激励 |
在线量化,支持8-bit,量化速度较快,支持模型较多,比较成熟,推理吞吐较快 |
QuIP |
权重 |
离线量化,支持2~4bit,量化速度较快,低精度(2-bit)下效果优于GPTQ |
QuaRot |
权重、激励、KV缓存 |
在线量化,支持4-bit, 8-bit,低精度(4-bit)下效果优于SmoothQuant |
SpinQuant |
权重、激励、KV缓存 |
在线量化,支持4-bit, 8-bit,低精度(4-bit)下效果优于SmoothQuant,GPTQ,量化速度较快,但略慢于GPTQ |
QQQ |
权重、激励 |
在线量化,支持4-bit, 8-bit,推理吞吐较快 |
QoQ |
权重、激励、KV缓存 |
在线量化,支持4-bit, 8-bit,推理吞吐较快 |
FP8 |
权重、激励、KV缓存 |
在线量化,支持FP8精度,依赖较新GPU,推理吞吐较快 |
综上,文章简要介绍了近期一些LLM后量化的算法和方案,当然还有众多算法未涉及和细讲,如SpQR,ZeroQuant, KIVI**,Atom, OmniQuant,AQLM等。
五
参考文献
- GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers
- AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration
- AWQ slides: hanlab.mit.edu/projects/aw…
- SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models
- QuIP: 2-Bit Quantization of Large Language Models With Guarantees
- HQQ: Half-Quadratic Quantization of Large Machine Learning Models.
- QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs
- SpinQuant: LLM quantization with learned rotations
- QQQ: Quality Quattuor-Bit Quantization for Large Language Models
- QServe: W4A8KV4 Quantization and System Co-design for Efficient LLM Serving
- Nvidia: FP8 Formats for Deep Learning
- FP8量化原理简介:zhuanlan.zhihu.com/p/574825662
- Nvidia Transformer Engine: Using FP8 with Transformer Engine
往期回顾
1.如何合理规划Elasticsearch的索引|得物技术
2. DPP推荐引擎架构升级演进之路|得物技术
3.Cursor 在前端需求开发工作流中的应用|得物技术
4.得物 iOS 启动优化之 Building Closure
5.分布式数据一致性场景与方案处理分析|得物技术
文 / 旭囧
关注得物技术,每周更新技术干货
要是觉得文章对你有帮助的话,欢迎评论转发点赞~
未经得物技术许可严禁转载,否则依法追究法律责任。