大模型量化技术原理-LLM.int8()、GPTQ

近年来,随着Transformer、MOE架构的提出,使得深度学习模型轻松突破上万亿规模参数,从而导致模型变得越来越大,因此,我们需要一些大模型压缩技术来降低模型部署的成本,并提升模型的推理性能。
模型压缩主要分为如下几类:

  • 剪枝(Pruning)
  • 知识蒸馏(Knowledge Distillation)
  • 量化

之前也写过一些文章涉及大模型量化相关的内容。

  • 基于LLaMA-7B/Bloomz-7B1-mt复现开源中文对话大模型BELLE及GPTQ量化
  • TensorRT-LLM保姆级教程(二)-离线环境搭建、模型量化及推理

本系列将针对大模型的一些常见训练后量化方案(GPTQ、LLM.int8()、SmoothQuant、AWQ等)进行讲述。

  • 大模型量化概述
  • 大模型量化技术原理-GPTQ、LLM.int8()
  • 大模型量化技术原理-SmoothQuant
  • 大模型量化技术原理-AWQ、AutoAWQ
  • 大模型量化技术原理-SpQR
  • 大模型量化技术原理-ZeroQuant系列

而本文主要针对大模型量化技术LLM.int8()、GPTQ进行讲述。

大模型量化的对象

大模型量化的对象主要有:权重、激活、KV Cache、梯度、优化器等。由于梯度量化主要在训练场景使用,用于减少反向传播时的计算和通信开销。优化器量化(如:8-Bit Optimizers Via Block-Wise Quantization)也是用于训练场景;因此,本系列仅讨论权重、激活、KV Cache量化方案。

  • 仅权重量化,如:W4A16、AWQ及GPTQ中的W4A16,W8A16(权重量化为INT8,激活仍为BF16或FP16)
  • 权重、激活量化,如:SmoothQuant中的W8A8
  • KV Cache INT8 量化,LLM 推理时,为了避免冗余计算,设计了 KV Cache 缓存机制,本质上是空间换时间,由于 KV Cache 的存在,对于支持越长的文本长度的 LLM, KV Cache 的显存占用越高。 因此,KV Cache 的量化也是有很必要的。

LLM.int8()

背景

作者发现激活中存在一些离群值,它们的绝对值明显更大;并且这些离群值分布在少量的几个特征中,称为离群特征 (Emergent Features)。以激活 X ∈ R [ T × h ] X \in \mathbb{R}^{[T \times h ]} XR[T×h]和权重  W ∈ R [ h × h 0 ] W \in \mathbb{R}^{[h \times h_0]} WR[h×h0]的矩阵相乘为例,特征维度就是指h这个维度。不论是 per-token(针对激活 x 而言:每行对应一个量化系数) 还是 per-channel (针对权重 w 而言:每列对应一个量化系数)量化,都会受到这些离群值的很大影响。既然只有少量的特征包含离群值,LLM.in8() 的思路是把这些特征拿出来单独计算,只对剩余特征做量化。

技术原理

LLM.int8()(论文:LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale)是一种采用混合精度分解的量化方法。该方案先做了一个矩阵分解,对绝大部分权重和激活用8bit量化(vector-wise)。对离群特征的几个维度保留16bit,对其做高精度的矩阵乘法。

image.png

LLM.int8() 通过三个步骤完成矩阵乘法计算:

  1. 从输入的隐含状态中,按列提取异常值 (离群特征,即大于某个阈值的值)。
  2. 对离群特征进行 FP16 矩阵运算,对非离群特征进行量化,做 INT8 矩阵运算;
  3. 反量化非离群值的矩阵乘结果,并与离群值矩阵乘结果相加,获得最终的 FP16 结果。

实验结果表明该方法效果良好。可以通过使用 LLM.int8() 的量化过程来恢复全部性能。您可以清楚地看到随着模型参数量逐渐变多 8 比特基线(即 vector-wise quantization)的性能大幅下降。 而 LLM.int8() 方法使用vector-wise quantization混合精度分解来恢复全部性能。

image.png

虽然 LLM.in8() 带来的性能下降微乎其微,但是这种分离计算的方式拖慢了推理速度。对于 BLOOM-176B,相比于 FP16,LLM.int8() 慢了大约 15% 到 23%;对于更小的模型(3B 和 11B),速度差距更为明显,LLM.int8() 慢了三倍以上。

此外,论文中测量了异常值特征对于注意力和预测性能的影响。

下图展示了 Transformer 中受模型大小或 C4 困惑度影响的大量异常值特征的层和所有序列维度的百分比。

从图中可知,当通过参数数量进行测量时,Transformer 所有层上的大幅异常值特征突然出现在 6B 和 6.7B 参数之间。受影响层的百分比从 65% 增加到 100%, 受影响的序列维度数量从 35% 迅速增加到 75%。 这种突然的转移与量化开始失败的点同时发生。

当通过困惑度(perplexity)进行测量时,Transformer 所有层中大量异常值特征的出现可以被视为根据困惑度递减的指数函数平滑的出现。这表明异常值的出现并不是突然的,并且通过研究较小模型中的指数趋势,我们也许能够在相移(相位移动,Phase shift,是一个物理学和工程学中常用的术语。它指的是一个波形在时间上发生的移位现象)发生之前检测到异常值出现的特征。这也表明,异常值的出现不仅与模型大小有关,还与困惑度有关,而困惑度与多个其他因素有关,例如:使用的训练数据量和数据质量。

image.png

如下图a所示,一旦异常值特征出现在Transformer的所有层中,中间的异常值特征量值就会迅速增加。大量异常值特征及其不对称分布破坏了 Int8 量化精度。 这是量化方法从 6.7B 开始失败的核心原因——量化分布的范围太大,导致大多数量化 bins 为空,小的量化值被量化为零,基本上消除了信息。我们推测,除了 Int8 推理之外,由于超出 6.7B 参数范围,常规 16 位浮点训练也会因异常值而变得不稳定。如果通过向量填充乘以 60 的值,很容易偶然超过最大 16 位值 65535。

如下图b所示,离群值特征的数量相对于 C4 困惑度的降低严格单调增加,而与模型大小的关系是非单调的。 这表明模型的困惑度(perplexity)决定了相移,而不仅是模型的大小。 我们推测模型大小只是离散特征出现所需的众多协变量中的一个重要协变量。

image.png

目前,LLM.int8() 的实现主要在 bitsandbytes 库;之前的文章 大模型微调实战(八)-使用INT8/FP4/NF4微调大模型 中介绍过bitsandbytes 库,同时,transformers 库已经集成并 原生 支持了 bitsandbytes 这个量化库。课可以说 bitsandbytes 是量化任何模型的最简单方法之一,因为它不需要量化校准数据及校准过程 (即零样本量化)。任何模型只要含有 torch.nn.Linear 模块,就可以对其进行开箱即用的量化。每当在 transformers 库中添加新架构时,只要其可以用 accelerate 库的 device_map="auto" 加载,用户就可以直接受益于开箱即用的 bitsandbytes 量化,同时该方法对性能的影响也是最小的。量化是在模型加载时执行的,无需运行任何后处理或准备步骤。与此同时,LLM.int8() 作者提出的另一种 QAT 量化方案 QLoRA 也是基于 bitsandbytes 进行实现。

在 Transformers 中使用 LLM.int8() 只需提前安装 bitsandbytes 即可,使用 LLM.int8() 方法量化transformer模型具体示例如下:

8bit量化:

from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained(
  'decapoda-research/llama-7b-hf',
  device_map='auto',
  load_in_8bit=True,
  max_memory={
    i: f'{int(torch.cuda.mem_get_info(i)[0]/1024**3)-2}GB'
    for i in range(torch.cuda.device_count())
  }
)

4bit量化:

from transformers import BitsAndBytesConfig

nf4_config = BitsAndBytesConfig(
   load_in_4bit=True,
   bnb_4bit_quant_type="nf4",
   bnb_4bit_use_double_quant=True,
   bnb_4bit_compute_dtype=torch.bfloat16
)

model_nf4 = AutoModelForCausalLM.from_pretrained(model_id, quantization_config=nf4_config)

GPTQ

背景

GPTQ 并不是凭空出现的,它的原理来自于另一个量化方法OBQ(Optimal Brain Quantization),而OBQ 实际上是对 OBS(Optimal Brain Surgeon,一种比较经典的剪枝方法)的魔改, 而OBS则来自于OBD(Optimal Brain Damage,由 Yann LeCun 在1990年提出的剪枝方法)。

如果要在模型中去除一些参数(即剪枝),我们希望去除对目标函数 E E E影响小的参数。于是 OBD 作者对目标函数  E E E 做泰勒展开,同时,作者做了一些假设(如:假设删除任意一个参数后,其他参数对目标函数的影响不变。也就是说,每个参数对目标函数的影响是独立的),对上式进行简化。最终得到一个只要计算海森矩阵  h i i h_{ii} hii ,就可以知道每个参数对目标的影响。

OBS 则认为,参数之间的独立性不成立,因此,还是要考虑交叉项。在OBS中,作者希望找到一种方法,假设我们要抹去一个权重记为  w q w_q wq,使得其对整体的误差增加最少,并且同时计算出一个补偿 δ q \delta_q δq应用于剩余的权重上,使得抹去的这个权重增加的误差被抵消,作者找到了这样的一个方法,并通过求解海森矩阵的逆,就可以计算每个参数权重 w q w_q wq对目标的影响,然后就可以按照影响从小到大给参数排个序,这样就确定了参数剪枝的次序。同时,每次剪枝一个参数,其他的参数也更新一次从而减少误差。

OBQ 把它推广到量化中,剪枝是一种特殊的量化,常用的量化是把数值近似到一个接近的值,而剪枝实际上可以看做把数值直接近似成0,可以理解为一种特殊的量化。

OBQ 不错,但是太慢,OBQ 在一小时左右量化一个 ResNet50,在大模型(如:GPT3)上可能要数天。GPTQ 对 OBQ 做了一些算法和性能上的优化,在降低量化算法复杂度的同时保留了模型的精度,因而可以实现大模型的高效量化。可以说 GPTQ 是它的加速版,使用 GPTQ 量化一个 Bloom 模型 (176B) 则只需不到 4 个小时;并且 GPTQ 的量化有严谨的数学理论推导,所有的算法步骤都有理论支撑。

技术原理

GPTQ(论文:GPTQ: ACCURATE POST-TRAINING QUANTIZATION FOR GENERATIVE PR
E-TRAINED TRANSFORMERS
) 采用 int4/fp16 (W4A16) 的混合量化方案,其中模型权重被量化为 int4 数值类型,而激活值则保留在 float16,是一种仅权重量化方法。在推理阶段,模型权重被动态地反量化回 float16 并在该数值类型下进行实际的运算;同 OBQ 一样,GPTQ还是从单层量化的角度考虑,希望找到一个量化过的权重,使的新的权重和老的权重之间输出的结果差别最小。

GPTQ 将权重分组(如:128列为一组)为多个子矩阵(block)。对某个 block 内的所有参数逐个量化,每个参数量化后,需要适当调整这个 block 内其他未量化的参数,以弥补量化造成的精度损失。因此,GPTQ 量化需要准备校准数据集。

GPTQ 量化过程如下图所示。首先,使用 Cholesky 分解中 Hessian 矩阵的逆,在给定的step中对连续列的块(粗体)进行量化,并在step结束时更新剩余的权重(蓝色)。量化过程在每个块内递归应用:白色中间列表示当前正在被量化。

image.png

GPTQ 的创新点如下:

  • 取消贪心算法:OBS 采用贪心策略,先量化对目标影响最小的参数;但 GPTQ 发现直接按顺序做参数量化,对精度影响也不大。这项改进使得参数矩阵每一行的量化可以做并行的矩阵计算(这意味着我们可以独立地对每一行执行量化。即所谓的 per-channel quantization)。对于大模型场景,这项改进使得量化速度快了一个数量级;
  • Lazy Batch-Updates:OBQ 对权重一个个进行单独更新,作者发现性能瓶颈实际在于GPU的内存带宽,而且同一个特征矩阵W不同列间的权重更新是不会互相影响的。因此作者提出了延迟批处理的方法,通过延迟一部分参数的更新,一次处理多个(如:128)列,来缓解带宽的压力,大幅提升了计算速度。
  • Cholesky 分解:用 Cholesky 分解求海森矩阵的逆,提前计算好所有需要的信息,在增强数值稳定性的同时,后续更新的过程中再计算,进一步减少了计算量。

GPTQ的伪代码如下所示,包括了上面讨论的一些优化:

image.png

该方案有以下两方面的优点:

  • int4 量化能够节省接近4倍的内存,这是因为反量化操作发生在算子的计算单元附近,而不是在 GPU 的全局内存中。
  • 由于用于权重的位宽较低,因此可以节省数据通信的时间,从而潜在地提升了推理速度。

一般来说,GPTQ推荐使用8-bit量化及groupsize = 128。

目前,社区存在一些基于 GPTQ 算法大语言模型量化工具,如:AutoGPTQ、GPTQ-for-LLaMa 、Exllama 和 llama.cpp , 其中,GPTQ-for-LLaMa 、Exllama 和 llama.cpp 主要针对 Llama 模型架构实现量化策略。相较之下,AutoGPTQ 因其对丰富的 Transformers 架构的平滑覆盖而广受欢迎。

同时,AutoGPTQ 代码库集成到了 Transformers 中,让用户使用 GPTQ 算法在 8 bit、4 bit、3 bit,甚至是 2 bit 精度下量化和运行模型成为可能。当使用 int4 量化时,精度的下降可以忽略不计,同时在小批量推理上保持着与 fp16 基线相当的速度。需要注意的是,GPTQ 方法与 bitsandbytes 提出的训练后量化方法有所不同,GPTQ 需要在量化阶段提供一个校准数据集。

在 Transformers 中使用 GPTQ 只需提前安装AutoGPTQ和Optimum即可,使用 GPTQ 方法量化transformer模型具体示例如下:

from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfig

model_id = "facebook/opt-125m"
tokenizer = AutoTokenizer.from_pretrained(model_id)
quantization_config = GPTQConfig(bits=4, dataset = "c4", tokenizer=tokenizer)

model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", quantization_config=quantization_config)

结语

本文简要介绍了两种比较常用的大模型量化方法 GPTQ、LLM.int8();LLM.int8() 属于 round-to-nearest (RTN) 量化:舍入到最近的定点数。而 GPT-Q 则是把量化问题视作优化问题,逐层寻找最优的量化权重。目前,这两种量化方法也集成到了Transformers库中,大家可以非常方便的使用。

码字不易,如果觉得我的文章能够能够给您带来帮助,期待您的点赞收藏加关注~~

参考文档

  • 大语言模型的模型量化(INT8/INT4)技术
  • https://github.com/TimDettmers/bitsandbytes
  • https://timdettmers.com/2022/08/17/llm-int8-and-emergent-features/
  • https://huggingface.co/blog/zh/hf-bitsandbytes-integration
  • https://huggingface.co/blog/zh/4bit-transformers-bitsandbytes
  • https://github.com/IST-DASLab/gptq
  • https://github.com/AutoGPTQ/AutoGPTQ
  • https://huggingface.co/blog/zh/gptq-integration
  • QLoRA、GPTQ:模型量化概述:https://zhuanlan.zhihu.com/p/646210009
  • NLP(十一):大语言模型的模型量化(INT8/INT4)技术:https://zhuanlan.zhihu.com/p/627436535
  • GPTQ-for-LLaMa 量化分析和优化

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/397665.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

react开发者必备vscode插件【2024最新】

React开发者必备VSCode插件及使用教程 Visual Studio Code(VSCode)是当今最流行的代码编辑器之一,特别是在前端开发者中。对于使用React的开发者来说,VSCode不仅因其轻量和高度可定制而受到欢迎,还因为其强大的插件生…

Java项目,营销抽奖系统设计实现

作者:小傅哥 博客:https://bugstack.cn 项目:https://gaga.plus 沉淀、分享、成长,让自己和他人都能有所收获!😄 大家好,我是技术UP主,小傅哥。 经过这个假期的嘎嘎卷🧨…

8 大内部排序算法图文讲解

排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见的内部排序算法有:插入排序、希尔排序、选择排序…

软件测试面试题常见一百道【含答案】

1、问:你在测试中发现了一个bug,但是开发经理认为这不是一个bug,你应该怎样解决? 首先,将问题提交到缺陷管理库里面进行备案。 然后,要获取判断的依据和标准: 根据需求说明书、产品说明、设计文档等&am…

75.SpringMVC的拦截器和过滤器有什么区别?执行顺序?

75.SpringMVC的拦截器和过滤器有什么区别?执行顺序? 区别 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。拦截器只能对action请求(DispatcherServlet 映射的请求)起作用,而过滤器则可以对几乎所有的请求起作用。拦截器可…

Redis基础和高级使用

文章目录 Redis概述Redis简介Redis特点Redis适合于做Redis不适合于做Redis安装 Redis命令Redis命令Redis的键 Redis数据类型Redis支持的数据类型字符串及相关命令字符串应用场景:列表及相关命令列表应用场景:集合及相关命令集合应用场景:有序…

环信IM Android端实现华为推送详细步骤

首先我们要参照华为的官网去完成 ,以下两个配置都是华为文档为我们提供的 1.https://developer.huawei.com/consumer/cn/doc/HMSCore-Guides/android-config-agc-0000001050170137#section19884105518498 2.https://developer.huawei.com/consumer/cn/doc/HMSCore…

[OpenAI]继ChatGPT后发布的Sora模型解析与体验通道

前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言OpenAI体验通道Spacetime Latent Patches 潜变量时空碎片, 建构视觉语言系统…

HTTPS(超文本传输安全协议)被恶意请求该如何处理。

HTTPS(超文本传输安全协议)端口攻击通常是指SSL握手中的一些攻击方式,比如SSL握手协商过程中的暴力破解、中间人攻击和SSL剥离攻击等。 攻击原理 攻击者控制受害者发送大量请求,利用压缩算法的机制猜测请求中的关键信息&#xf…

【压缩感知基础】Nyquist采样定理

Nyquist定理,也被称作Nyquist采样定理,是由哈里奈奎斯特在1928年提出的,它是信号处理领域的一个重要基础定理。它描述了连续信号被离散化为数字信号时,采样的要求以避免失真。 数学表示 Nyquist定理的核心内容可以描述如下&…

java+vue_springboot企业设备安全信息系统14jbc

企业防爆安全信息系统采用B/S架构,数据库是MySQL。网站的搭建与开发采用了先进的java进行编写,使用了vue框架。该系统从三个对象:由管理员、人员和企业来对系统进行设计构建。主要功能包括:个人信息修改,对人员管理&am…

目录IO 2月19日学习笔记

1. lseek off_t lseek(int fd, off_t offset, int whence); 功能: 重新设定文件描述符的偏移量 参数: fd:文件描述符 offset:偏移量 whence: SEEK_SET 文件开头 SEE…

Expected class selector “.menuChildMall“ to be kebab-case报错原因

![在这里插入图片描述](https://img-blog.csdnimg.cn/dire ct/6b72bda760a2497a90558d48bd0a4de3.png) 使用stylelint格式化css文件时候报上述错误: 原因: css类名未使用-分隔符 将类名修改为: .menu-child-mall形式即可

C++11---(2)

目录 一、新增容器 1.1、array 1.2、forward_list 1.3、unordered系列 二、右值引用和移动语义 2.1、什么是左值,什么是左值引用 2.2、什么是右值,什么是右值引用 2.3、左值引用和右值引用比较 2.4、右值引用使用场景和意义 2.5、右值引用引用…

【教程】详解相机模型与坐标转换

转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn] 由于复制过来,如果有格式问题,推荐大家直接去我原网站上查看: 相机模型与坐标转换 - 生活大爆炸 目录 经纬度坐标系 转 地球直角坐标系大地直角坐标系 转 经纬度坐标系地理坐标…

MLP-Mixer: AN all MLP Architecture for Vision

发表于NeurIPS 2021, 由Google Research, Brain Team发表。 Mixer Architecture Introduction 当前的深度视觉结构包含融合特征(mix features)的层:(i)在一个给定的空间位置融合。(ii)在不同的空间位置,或者一次融合所有。在CNN中,(ii) 是由N x N(N &g…

服务端实时推送技术之SSE(Server-Send Events)

文章目录 前言一、解决方案:1、传统实时处理方案:2、HTML5 标准引入的实时处理方案:3、第三方推送: 二、SSE1.引入库1、客户端: 2.服务端:三、业务实践:能否做到精准投递? 总结 前言…

解决Ubuntu中vscode右键没有create catkin package

右键发现没有这个create catkin package 解决方案: 查了一会发现安装个拓展就可以了 效果:

vue页面基本增删改查

练手项目vue页面 新手前端轻喷: 效果如下 1、2两个部分组成: 对应代码中 element-ui中的 el-form 和 el-table 照着抄呗,硬着头皮来! 建议:认真读一遍你用的组件 这篇文章烂尾了,对不起大家

element-plus日期选择器2次封装

预期效果 官网默认样式&#xff1a; 修改后的样式&#xff1a; 代码实现 DatePicker.vue <template><div class"date-picker-container"><el-date-picker v-model"date" change"handleChange" type"date" value-for…