本文主要讲述了模型量化技术在大模型微调中的重要性,包括如何使用transformers库进行模型量化,以及AWQ量化方法,从而强调了模型量化可以降低推理成本,减少计算资源和时间,优化大模型的微调过程。AWQ是一种从大模型中找到重要值的量化方法,可以避免使用数据集进行反向传播和矩阵分解。该方法在两个模型上进行测试,并与BNB的量化方法和原始的十六位浮点数方法进行比较,也鼓励实际操作使用AWQ来量化模型,并比较量化前后的指标差异。
Transformers核心设计Auto Classes
transformers提供了训练后量化技术,如GPT-Q,可将大模型参数变小,降低inference成本。核心设计在于auto classes、auto toknizer和config,它们通过from_pretrained接口进行管理。在自然语言处理、计算机视觉等应用领域,auto class提供了统一的抽象,如auto model和auto toknizer,方便扩展和管理。
Transformers Auto Classes 设计:统一接口、自动检索
AutoClasses 旨在通过全局统一的接口 from_pretrained() ,实现基于名称(路径)自动检索预训练权重(模型)、配置文件、词汇表等所有与模型相关的抽象。
图1AutoClasses内部模块组件
AutoClasses提供了两个功能,一是统一接口,二是自动检索功能。
灵活扩展的配置AutoConfig
ransformers.AutoConfig 类实例化通常由from_pretrained(pretrained_model_name_or_path, ) 方法完成。Transformers 根据配置中的 model_type 加载预定义配置,兜底方案是基于模型名称/路径自动推断。
图2 模型名称
auto config是用来干什么的呢?你可以理解成三元组里的每一个模型都需要一个自己的配置管理的类的抽象,而transformers的AutoConfig顶级的模块。通过from_pretrained()这个方法就能够完成实例化,并且最重要的三元组AutoConfig、AutoModel以及AutoTokenizer都无法使用python的init()方法做初始化。对此,为了支持AutoClass的扩展,我们需要构造函数去自定义AutoClass,再定义好三元组及其三元组应该分别怎么去继承它的子类。
图3 模型名称
自动化模型管理AutoModel
transformers.AutoModel 类实例化通常由from_pretrained() 或 from_config() 方法完成。换句话说,Transformers 可以从预训练模型文件或配置中完成模型加载。from_pretrained()可以理解为将模型存到了文件里面,然后再从文件里面加载回来,放置gpu的显存里。 from_config() 方法可以理解为用transformers迭代到后面的版本,包括pytorchV1.9。transformers允许先只加载一个空壳的模型,尤其是一些比较大规模参数的模型,不需要一开始就加载全量的权重,而具体的参数可以在需要用的时候再加载进去。
通用分词器AutoTokenizer
transformers.AutoModel 类实例化通常由from_pretrained(pretrained_model_name_or_path) 方法完成。Transformers 同样是优先基于model_type 来自动匹配 Tokenizer,兜底方案是基于模型名称/路径自动推断。tokenizer其实也是独立的一块工作组件,在模型的前后两部分去运行。前半段主要完成一个原始语料的训练,后半段将最终编码映射成模型可以接受的vector。与AutoConfig一样,要通过from_pretrained() 方法完成实例化,然后通过model type来匹配对应的tokenizer。
Transformers模型量化Quantization
量化(Quantization)技术的本质是用较少的信息表示数据,同时尽量不损失太多准确性。具体来说,量化会将模型参数使用的数据类型,转换为更少位数表示,并尽可能达到相同信息的效果。同时,较低的精度还可以加快推理速度,因为使用较少位进行计算所需时间更短。Transformer模型量化技术解析,包括其原理、应用和优、缺点。通过量化的方式,可以在保持模型性能的同时降低模型大小和计算复杂度,从而加速模型推理速度。然而,量化也存在一些挑战和限制,例如精度损失和稳定性问题。
模型参数与显存占用计算基础
模型参数跟显存占用存在什么计算关系?为了详细说明模型的参数数量和每个参数在显存中占用的空间大小,我们以 facebook OPT-6.7B 模型为例。
逐步推理计算过程:
- 估计参数总量:OPT-6.7B 模型指一个含有大约 6.7 Billion(67亿)个参数的模型。
- 计算单个参数的显存占用:OPT-6.7B 模型默认使用 Float16,每个参数占用16位(即2字节)的显存。
- 计算总显存占用 = 参数总量 × 每个参数的显存占用。代入公式计算:67亿参数×2字节/参数=134亿字节=13.4×10^9字节
- 换算单位:1GB = 2^ 30B ≈ 10^9 字节
综上,OPT-6.7B 以 float16 精度加载到GPU需要使用大约13.5GB显存。如果使用 int8 精度,则只需要大约7GB显存,以上只是模型参数与显存的估算关系。
此外,transformers支持哪些量化技术?在transformers内置库,目前主要支持三种不同的量化技术GPTQ面向Transformer模型量化技术、激活感知权重量化和使用BitsAndBytes快速实现参数精度量化。
GPTQ面向Transformer模型量化技术
GPTQ:Accurate Post-Training Quantization for Generative Pre-trained Transformers 是一个高效、精准的量化技术,特别适用于大规模GPT模型,能够在显著降低模型大小和计算需求的同时,保持高准确度和推理速度。GPTQ算法具有以下技术特点:
- 专为GPT模型设计:GPTQ针对大规模GPT模型(如1750亿参数规模的模型)进行优化,解决了这类模型因规模庞大导致的高计算和存储成本问题。
- 一次性权重量化方法:GPTQ是一种基于近似二阶信息的权重量化方法,能够在一次处理中完成模型的量化。
- 高效率:GPTQ能在大约四个GPU小时内完成1750亿参数的GPT模型的量化。
- 低位宽量化:通过将权重位宽降至每个权重3或4位,GPTQ显著减少了模型的大小。
- 准确度保持:即便在进行显著的位宽减少后,GPTQ也能保持与未压缩模型相近的准确度,减少性能损失。
- 支持极端量化:GPTQ还可以实现更极端的量化,如2位或三元量化,同时保持合理的准确度。
- 推理速度提升:使用GPTQ量化的模型在高端GPU(如NVIDIA A100)上实现了大约3.25倍的推理速度提升,
在成本效益更高的GPU(如NVIDIA A6000)上实现了大约4.5倍的速度提升。 - 适用于单GPU环境:GPTQ使得在单个GPU内执行大规模模型的生成推理成为可能,显著降低了部署这类模型的硬件要求。
图4 GPTQ 与 RTN(baseline)实验结果对比
表1 GPTQ 在不同规模大模型下的实验结果
GPTQ 量化算法核心流程
为了实现让模型以最小的显存存储最大且有用的信息,就需要将有价值的权重筛选出来,然后把那些没有价值或者价值不高的权重剔除。那么有价值的权重,如何被量化啊?假设用一种贪心的策略来提取每一批数据局部最优,然后最终获取一个全局最优的结果。这个直观的思路应用在百亿千亿规模的大语言模型就会失效了。因此研究一种德尔塔等正反向传播来更新参数,其中会涉及大量的数学运算,那么Cholesky(切尔斯基)解决的核心问题,是使用更稳定,更高效地不断去求解一些线性方程组,来减少一些数值的不稳定性,从而提高整个模型的鲁棒性和准确性。
核心步骤:使用存储在Cholesky(切尔斯基)分解中的逆Hessian(海森)信息量化连续列的块(加粗表示),并在步骤结束时更新剩余的权重(蓝色表示),在每个块内递归(白色中间块)地应用量化过程。GPTQ量化过程的关键步骤操作,具体描述如下:
- 块量化: 选择一块连续的列(在图中加粗表示),并将其作为当前步骤的量化目标。
- 使用Cholesky分解: 利用Cholesky分解得到的逆Hessian信息来量化选定的块。Cholesky分解提供了一种数值稳定的方法来处理逆矩阵,这对于维持量化过程的准确性至关重要。
- 权重更新: 在每个量化步骤的最后,更新剩余的权重(在图中以蓝色表示)。这个步骤确保了整个量化过程的连贯性和精确性。
- 递归量化: 在每个选定的块内部,量化过程是递归应用的。这意味着量化过程首先聚焦于一个较小的子块,然后逐步扩展到整个块。
图5 量化过程
通过这种方式,GPTQ方法能够在保持高度精度的同时,高效地处理大量的权重,这对于大型模型的量化至关重要。这种策略特别适用于处理大型、复杂的模型,如GPT系列,其中权重数量巨大,且量化过程需要特别小心以避免精度损失。
表2 GPTQ 在千亿级大模型上的实验结果
图6 GPTQ 量化前后实验结果对比
激活感知权重量化(AWQ)算法
激活感知权重量化(AWQ)算法,其原理不是对模型中的所有权重进行量化,而是仅保留小部分(1%)对LLM性能至关重要的权重。 其算法主要特点如下:
- 低位权重量化:AWQ专为大型语言模型(LLMs)设计,支持低位(即少位数)的权重量化,有效减少模型大小。
- 重点保护显著权重:AWQ基于权重重要性不均的观察,只需保护大约1%的显著权重,即可显著减少量化误差。
- 观察激活而非权重:在确定哪些权重是显著的过程中,AWQ通过观察激活分布而非权重分布来进行。
- 无需反向传播或重构:AWQ不依赖于复杂的反向传播或重构过程,因此能够更好地保持模型的泛化能力,避免对特定数据集的过拟合。
- 适用于多种模型和任务:AWQ在多种语言建模任务和领域特定基准测试中表现出色,包括指令调整的语言模型和多模态语言模型。
- 高效的推理框架:与AWQ配套的是一个为LLMs量身定做的高效推理框架,提供显著的速度提升,适用于桌面和移动GPU。
- 支持边缘设备部署:这种方法支持在内存和计算能力有限的边缘设备(如NVIDIA Jetson Orin 64GB)上部署大型模型,如70B Llama-2模型。
图7 AWQ核心流程
图8 AWQ在OPT系列模型上的实验结果
图9 AWQ 在 LLaMA 系列模型上的实验结果
AWQ与GPTQ技术结合使用
图10 AWQ与GPTQ技术结合使用
量化算法对比:AWQ vs GPTQ
使用BitsAndBytes(bnb)快速实现参数精度量化
BitsAndBytes(BNB)是自定义 CUDA 函数的轻量级包装器,特别是 8 比特优化器、矩阵乘法和量化函数。主要特征如下:
- 具有混合精度分解的 8 比特矩阵乘法
- LLM.int8() 推理
- 8 比特优化器:Adam、AdamW、RMSProp、LARS、LAMB、Lion(节省 75% 内存)
- 稳定的嵌入层:通过更好的初始化和标准化提高稳定性
- 8 比特量化:分位数、线性和动态量化
- 快速的分位数估计:比其他算法快 100 倍
在 Transformers 量化方案中,BNB 是将模型量化为8位和4位的最简单选择。
- 8位量化将fp16中的异常值与int8中的非异常值相乘,将非异常值转换回fp16,然后将它们相加以返回fp16中的权重。这减少了异常值对模型性能产生的降级效果。
- 4位量化进一步压缩了模型,并且通常与QLoRA一起用于微调量化LLM(低精度语言模型)
Transformers 3种量化方案基准测试
该基准测试在NVIDIA A1000上运行,针对TheBloke/Mistral-7B-v0.1-AWQ和TheBloke/Mistral-7B-v0.1-
GPTQ模型进行了测试。这些模型还与bitsandbytes量化方法以及原始fp16模型进行了对比测试。
图11 Transformers3种量化方案基准测试结果
图12 Transformers 3种量化方案基准测试结果
理论参考论文:
- AWQ: Activation-aware Weight Quantizationfor LLM Compression and Acceleration
地址:https://github.com/mit-han-lab/llm-awg - GPTQ:ACCURATE POST-TRAINING QUANTIZATION FOR GENERATIVE PRE-TRAINED TRANSFORMERS
地址: https://github.com/IST-DASLab/gptq
后面再放实战Transformers模型量化Facebook OPT ,因为篇幅太长啦~