在论文《GPTQ:Accurate Post-Training Quantization for Generative Pre-trained Transformers》中,提出了GPTQ这种模型量化的方法。它针对生成式预训练大模型,实现精准的模型事后模型量化(Post-Training Quantization)。
PS:理解GPTQ,就需要理解前两篇专栏介绍的模型量化基本概念、模型剪枝及OBD/OBS,不熟悉的小伙伴可以翻一下前面的专栏。
1.GPTQ相关技术
1.1.量化方法分类
从量化时机看,有两类量化方法:
- QAT:Quantization During Training,训练期量化。
- PTQ:Post-Training Quantization,训练后量化。
这两类量化方法由于量化时机不同,所以训练方法也有所不同。
(1)Quantization During Training
训练期量化(Quantization During Training),也称为量化感知训练,是在模型训练的过程中进行量化,使得模型在训练时就适应量化带来的误差。
QAT算法的主要步骤如下:
STEP1.模拟量化:在训练过程中,权重和激活值会被临时量化到较低精度(如:8bit)。
STEP2.反量化:量化后的值会在后续的计算中被反量化回浮点数,用于计算梯度和更新权重。
STEP3.梯度传递:量化和反量化的过程会引入额外的误差,模型进一步学习如何最小化这些额外误差对最终性能的影响。
STEP4.微调:在训练的最后阶段会移除量化操作,对模型进行微调以恢复由于量化而可能损失的精度。
QAT的优点是可以更好地保持模型的精度,使得模型在训练过程中适应量化带来的变化。
QAT的缺点是增加训练复杂度和训练成本。
(2)Post-Traning Quantization
训练后量化(Post-Training Quantization),是在模型训练完成后,再对模型权重、激活值进行量化。
PTQ算法的主要步骤如下:
STEP1.离线校准:分析模型在特定数据集上的激活值分布来确定量化参数(如:比例因子)。
STEP2.量化:使用STEP1离线校准得到的量化参数,将模型的权重和激活值量化到较低的精度。
STEP3.转换:将量化后的模型转换为可以在目标硬件上运行的形式。
PTQ的的优点是简单且计算成本较低,它不需要在训练过程中模拟量化操作
PTQ的缺点是可能不如训练期间量化那样能够保持模型的精度,因为它没有给模型机会去适应量化带来的误差。
(3)QAT vs PTQ
- 从精度看:QAT通常能够更好地保持模型的精度,因为它允许模型在训练过程中适应量化操作。
- 从计算成本看:PTQ的计算成本较低,因为它避免了在训练过程中模拟量化的额外计算。
- 从灵活性看:PTQ提供了更大的灵活性,因为它允许在不同的硬件和部署环境中使用相同的量化模型。
GPTQ属于PTQ量化方法,GPTQ就是G-PTQ,G表示GPT系列大语言模型。
1.2.模型剪枝技术回顾
在PTQ(训练后量化)的思想下,模型剪枝技术得以发展与应用。这些技术更集中应用于视觉模型,但在大模型上应用面临诸多挑战。
- OBD:Opimal Brain Damage
- OBS:Optimal Brain Surgeon
- OBQ:Optimal Brain Quantization
(1)Optimal Brain Damage
OBD是一种早期的剪枝算法(由LeCun提出),其核心思想是通过Loss二阶导制定参数的影响,从而在剪枝过程中自动化地找出并裁剪"无影响"的参数。
优点:
- 剪枝自动化:寻找到参数与Loss关系的数学方法,使剪枝过程自动化
- 计算简单:从数学意义上,证明了可以忽略参数间的相互作用等因素,极大降低计算复杂度。
缺点:
- 局部最优:OBD可能只找到局部最优解(由于忽略了参数间相互作用,可能会在剪枝过程中在错误的方向上越走越远),而不是全局最优解。
关于OBD详细内容,可阅读本专栏《【chatGPT】学习笔记55-LLM微调技术之QLoRA(2)》相关章节
(2)Optimal Brain Surgeon
OBS是OBD的改进版,它建立了模型参数间的关联关系。
OBS的核心思想是在剪枝过程中找到对模型误差影响最小的权重,并更新其他权重以补偿剪枝带来的影响。
优点:
- 更精确:考虑了权重之间的交叉项,可以更准确地评估剪枝的影响。
- 全局最优:相比于OBD,OBS更可能找到全局最优解。
缺点:
- 计算复杂:由于需要考虑交叉项,计算复杂度较高,尤其是在大规模网络中。
- 资源消耗:对于大规模网络,计算和存储资源消耗较大。
关于OBD详细内容,可阅读本专栏《【chatGPT】学习笔记55-LLM微调技术之QLoRA(2)》相关章节
(3)Optimal Brain Quantization
OBQ是将OBS的思想应用到量化问题中,它处理的是将浮点数权重转换为整数表示,而不是直接将权重设置为零。
优点:
- 精度保持:相比于直接剪枝,量化可以保持模型的数值精度,减少信息损失。
- 硬件友好:量化后的模型更适合在低精度硬件上运行,如移动设备和嵌入式系统。
缺点:
- 量化策略选择:需要精心设计量化策略,以平衡模型性能和计算效率。
- 后处理需求:量化后可能需要额外的步骤来微调模型,以恢复性能。
关于OBD、OBS、OBQ的简述以及GPTQ与之的关联,详见论文Related Work章节。
1.3.大模型量化技术
大模型量化技术:Large-model Quantization,专门针对大模型实施模型量化的技术。
- 大型模型量化技术的实验对象通常是BLOOM和OPT-175B这样的大型语言模型,
- 论文中列举的量化方法有:ZeroQuant、LLM.int8()和nuQmm。
- ZeroQuant提出了逐层知识蒸馏,但只能应用于最多13亿参数的模型,且计算时间较长。
- LLM.int8()关注到激活值中的异常值会破坏大型模型的量化,并提出通过保持这些维度的高精度来解决。
- nuQmm则开发了针对特定二进制编码量化方案的高效GPU内核。
而GPTQ的实验证明,它能在更短的时间内量化更大的模型。
1.4.关键技术1:层级量化
在宏观层面,GPTQ遵循层级量化思想(Layer-Wise Quantization),层级量化属于PTQ方法,通过逐层量化、逐层重构。层级量化的目标是找到量化权重矩阵,这个矩阵用来保障最小化各层的平方误差。
- 数学表达:W表示线性层的权重,X表示线性层的一小批数据点。
- 量化目标:找到一组量化权重 W^,使得与全精度层输出的平方误差最小化。
1.5.关键技术2:OBQ
OBQ是GPTQ的数学方法基础:
- 量化目标:OBQ独立处理每一行权重,一次量化一个权重,同时更新其它未量化的权重,以最小化该层的输出误差。
- 数学表达:wq表示需要量化的权重,quant(wq)是wq的量化值,HF-1表示海森矩阵的逆。
- 高效更新海森矩阵:在量化过程中,Hessian矩阵用来表征剩余全精度权重的集合。如下公式表示了OBQ更新海森矩阵的逻辑,OBQ在量化一个权重后,移除已量化权重的行和列,避免后续量化中的重复计算,从而避免了更新海森矩阵对算力的巨大消耗。
- 量化并行:OBQ方法并行处理W的多行,实验中单GPU上消耗4小时量化OPT-175B模型(1750亿参数),相较于其它量化方法提升了3个数量级的速度。
GPTQ就是在OBQ的基础上进行了重大修改,使其能够扩展到大型语言模型,使得在保持模型性能的同时,显著减少模型的存储和计算需求,使得大型模型的部署和推理变得更加可行。
2.GPTQ原理
2.1.GPTQ对OBQ的改进
(1)Arbitrary Order Insight
OBQ量化权重的顺序是按照贪婪法进行量化的,即总是选择当前量化误差最小的权重进行量化。然而GPTQ实验发现,这种量化顺序的策略在大模型中效果不佳。
GPTQ按照相同顺序量化所有行的权重相反能获得不错的效果,其数学原理是海森矩阵HF仅依赖于层输入XF,而不依赖于权重。因此可以对所有行的HF-1进行相同的更新,而替代了对每个权重单独更新。
PS:Arbitrary Order Insight,我刚开始一脸懵逼地直译为"任意顺序洞察”,按照上述数学逻辑,应该翻译为“块量化”更为合适,正因为海森矩阵的特性才实现了块量化。
(2)Lazy Batch-Updates
Lazy Batch-Updates,批量更新,是一种工程化方法。量化在GPU内非常快,但是更新剩余未量化的权重的内存访问将成为QPTQ的性能瓶颈。
- GPTQ的解决思路是每次处理128列,只更新这些列对应的子块(即,B * B block of H-1)。只有一个块完全处理后,才会驱动如下两个公式,对整个H-1和W矩阵进行全局更新。其中,Q表示一组索引,H-1-Q表示移除了相应行和列的逆矩阵。
- 上述更新方法,本质上解决的是内存吞吐量瓶颈。
(3)Cholesky Reformulation
Cholesky Reformulation,切尔斯基分解。
在量化过程中,可能会出现数值不准确性,进而导致海森矩阵的逆变为奇异(即不可逆) 。
数值稳定性:GPTQ利用了Cholesky分解的数值稳定性,通过预先计算和更新Cholesky分解,避免直接计算和更新Hessian矩阵的逆。
2.2.GPTQ算法的全流程
- STEP1.块量化(Arbitrary Order Insight):选择一个连续块,如下图中粗线包含的区域。
- STEP2.Cholesky分解(Cholesky Reformulation):利用Cholesky分解得到海森矩阵的逆,进而量化STEP1选择的块。橙色为已量化的权重,白色为正在量化的权重,蓝色为未量化的权重。
- STEP3.权重批量更新(Lazy Batch-Updates):在当前块量化的最后,就更新所有剩余未量化的权重。
- 完成STEP1~STEP3后,递归量化下一个块。
2.3.GPTQ核心代码解读
通过对GPTQ的论文解读,我们了解了GPTQ的相关技术,以及算法流程。
最后我们再来看一下GPTQ的核心代码,以加深对论文的理解:
https://github.com/AutoGPTQ/AutoGPTQ/blob/main/auto_gptq/quantization/gptq.py
(1)关闭CUDA的TF32精度
- TF32是一种混合精度计算,关闭它可以保证计算精确性。
(2)GPTQ类的构造函数
- 构造函数的输入是神经网络中的一个层。
- 复制层的权重,得到W。
- 根据层类型(Conv1D、Conv2d),对权重矩阵的形状进行调整。
- H就是海森矩阵,初始为零矩阵。
- quantizer是量化器对象。
(3)add_batch
- 处理输入和输出的batch
- 根据层类型,调整输入的形状
- 根据调整好的输入形状,更新海森矩阵H
(4)fasterquant
- 克隆并调整当前层的权重矩阵的形状。
- 根据块分组进行量化,逐步地计算损失并更新权重。
- 最终返回量化参数
4.小结
本文介绍了:
- GPTQ相关技术:QAT和PTQ、OBD/OBS/OBQ、大模型量化技术
- 其中,层级量化和OBQ是GPTQ的关键技术基础
- GPTQ的技术原理:
- 块量化
- 批量更新
- Cholesky分解
- GPTQ的算法流程及代码解读
论文地址:https://arxiv.org/abs/2210.17323