使用GPTQ进行4位LLM量化

使用GPTQ进行4位LLM量化

  • 最佳脑量化
  • GPTQ算法
    • 步骤1:任意顺序洞察
    • 步骤2:延迟批量更新
    • 第三步:乔尔斯基重塑
  • 用AutoGPTQ量化LLM
  • 结论
  • References

权重量化的最新进展使我们能够在消费级硬件上运行大量大型语言模型,例如在RTX 3090 GPU上运行LLaMA-30B模型。这要归功于性能降低最小的4-bit量化技术,如GPTQ、GGML和NF4。

在上一篇文章中,我们介绍了naïve 8位量化技术和优秀的LLM.int8()。在本文中,我们将探讨流行的GPTQ算法,以了解它是如何工作的,并使用AutoGPTQ库实现它。

最佳脑量化

让我们从介绍我们试图解决的问题开始。对于网络中的每个层 l l l,我们希望找到原始权重 W l W_l Wl的量化版本 W l ^ \hat{W_l} Wl^。这被称为 layer-wise 压缩问题。更具体地说,为了最大限度地减少性能下降,我们希望这些新权重的输出 W l ^ X l \hat{W_l}X_l Wl^Xl尽可能接近原始权重 W l X l W_lX_l WlXl。换句话说,我们想找到:
在这里插入图片描述
已经提出了不同的方法来解决这个问题,但我们在这里感兴趣的是最优脑量化(OBQ)框架。

这种方法的灵感来自一种修剪技术,从训练后的密集神经网络(Optimal Brain Surgeon)中仔细去除权重。它使用近似技术,并提供最佳单权重 w q w_q wq 去删除和优化更新 δ F δ_F δF,以调整剩余的非量化权重 F F F ,以弥补去除:
在这里插入图片描述
其中 quant(w) 是 quantization 给出的权重四舍五入, H F H_F HF 是Hessian。

使用OBQ,我们可以首先量化最简单的权重,然后调整所有剩余的非量化权重来补偿这种精度损失。然后我们选择下一个权重来量化,以此类推。

这种方法的一个潜在问题是,当存在离群值权重时,可能导致高量化误差。通常,这些离群值最后会被量化,此时剩下的非量化权重很少,可以调整以补偿较大的误差。当一些权重被中间更新推到网格之外时,这种效果可能会恶化。一个简单的启发式应用来防止这种情况:异常值一出现就被量化。

这个过程可能需要大量的计算,特别是对于LLMs。为了解决这个问题,OBQ方法使用了一种技巧,避免在每次简化权重时重新进行整个计算。量化权重后,它通过删除与该权重相关的行和列(使用高斯消去)来调整计算中使用的矩阵(Hessian矩阵)。

在这里插入图片描述
该方法还采用向量化的方法,一次处理多行权矩阵。尽管OBQ的效率很高,但随着权值矩阵的增大,OBQ的计算时间也会显著增加。这种三次增长使得在具有数十亿个参数的非常大的模型上使用OBQ变得困难。

GPTQ算法

由Frantar等人(2023)引入的GPTQ算法从OBQ方法中获得灵感,但进行了重大改进,可以将其扩展到(非常)大的语言模型。

步骤1:任意顺序洞察

OBQ方法按照一定的顺序选择权重(模型中的参数)进行量化,这取决于哪个顺序添加的额外误差最小。然而,GPTQ观察到,对于大型模型,以任何固定顺序量化权重都可以达到同样的效果这是因为即使一些权重可能单独引入更多的误差,但在稍后的过程中,当剩下的其他可能增加误差的权重很少时,它们也会被量化。所以顺序并不像我们想象的那么重要

基于这种见解,GPTQ旨在以相同的顺序对矩阵的所有行量化所有权重。这使得计算过程更快,因为某些计算只需要对每一列执行一次,而不是对每个权重执行一次。
在这里插入图片描述

步骤2:延迟批量更新

这个方案不会很快,因为它需要更新一个巨大的矩阵,每个条目的计算量很少。这种类型的操作不能充分利用gpu的计算能力,并且会因内存限制(内存吞吐量瓶颈)而减慢速度。

为了解决这个问题,GPTQ引入了延迟批处理更新。结果表明,给定列的最终舍入决策仅受对该列执行的更新的影响,而不受对后面列执行的更新的影响。因此,GPTQ可以一次将算法应用于一批列(如128列),仅更新这些列和矩阵的相应块。在一个块被完全处理后,算法对整个矩阵执行全局更新。

在这里插入图片描述

第三步:乔尔斯基重塑

然而,还有一个问题需要解决。当算法扩展到非常大的模型时,数值不精确可能成为一个问题。具体地说,某一操作的重复应用会累积数值误差。

为了解决这个问题,GPTQ使用了Cholesky分解,这是一种用于解决某些数学问题的数值稳定方法。它涉及使用Cholesky方法从矩阵中预先计算一些所需的信息。这种方法与轻微的阻尼(向矩阵的对角线元素添加一个小常数)相结合,有助于算法避免数值问题。

整个算法可以总结为几个步骤:

  1. GPTQ算法从Hessian逆(一个帮助决定如何调整权重的矩阵)的Cholesky分解开始,
  2. 然后循环运行,一次处理一批列。
  3. 对于批处理中的每一列,它量化权重,计算误差,并相应地更新块中的权重。
  4. 处理完批处理后,它根据块的错误更新所有剩余的权重。

GPTQ算法在各种语言生成任务上进行了测试。比较了其他量化方法,如将所有权重四舍五入到最接近的量化值(RTN)。GPTQ与BLOOM (176B参数)和OPT (175B参数)模型族一起使用,模型使用单个NVIDIA A100 GPU进行量化。

用AutoGPTQ量化LLM

GPTQ在创建4-bit精度的模型时非常流行,可以有效地在gpu上运行。你可以在Hugging Face Hub找到很多例子,尤其是TheBloke。如果您正在寻找一种对cpu更友好的方法,那么GGML目前是您的最佳选择。最后,带bitsandbytes的transformer库允许您在加载模型时使用loadin 4bit=true参数量化模型,这需要下载完整的模型并将其存储在RAM中。

让我们使用AutoGPTQ库实现GPTQ算法,并量化GPT-2模型。这需要一个GPU,但谷歌Colab上的免费T4就可以了。我们首先加载库并定义我们想要量化的模型(在本例中是GPT-2)。

!BUILD_CUDA_EXT=0 pip install -q auto-gptq transformers
import randomfrom auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
from datasets import load_dataset
import torch
from transformers import AutoTokenizer# Define base model and output directory
model_id = "gpt2"
out_dir = model_id + "-GPTQ"

现在我们想要加载模型和标记器。该标记器是使用transformer库中的经典AutoTokenizer类加载的。另一方面,我们需要传递一个特定的配置(BaseQuantizeConfig)来加载模型。

在这个配置中,我们可以指定要量化的位数(这里,bits=4)和组大小(惰性批处理的大小)。注意,这个组的大小是可选的:我们也可以为整个权重矩阵使用一组参数。在实践中,这些组通常以非常低的成本提高量化的质量(特别是当组大小=1024时)。阻尼百分比值在这里是为了帮助Cholesky重新配方,不应该改变。

最后,desc act(也称为act order)是一个棘手的参数。它允许您根据激活的减少来处理行,这意味着首先处理最重要或最有影响的行(由采样的输入和输出决定)。该方法旨在将大部分量化误差(在量化过程中不可避免地引入)放在不太重要的权重上。这种方法通过确保以更高的精度处理最重要的权重,提高了量化过程的总体准确性。然而,当与组大小一起使用时,desc act可能导致性能变慢

# Load quantize config, model and tokenizer
quantize_config = BaseQuantizeConfig(bits=4,group_size=128,damp_percent=0.01,desc_act=False,
)
model = AutoGPTQForCausalLM.from_pretrained(model_id, quantize_config)
tokenizer = AutoTokenizer.from_pretrained(model_id)

量化过程在很大程度上依赖于样本来评估和提高量化质量。它们提供了一种比较原始模型和新量化模型产生的输出的方法。提供的样本数量越多,就越有可能进行更准确和有效的比较,从而提高量化质量。

在本文中,我们使用C4 (Colossal Clean crawl Corpus)数据集来生成我们的样本。C4数据集是一个大规模的、多语言的网络文本集合,收集自Common Crawl项目。这个扩展的数据集已经经过清理,并专门为训练大规模语言模型而准备,使其成为此类任务的重要资源。WikiText数据集是另一个流行的选择。

在下面的代码块中,我们从C4数据集加载1024个样本,对它们进行标记并格式化。

# Load data and tokenize examples
n_samples = 1024
data = load_dataset("allenai/c4", data_files="en/c4-train.00001-of-01024.json.gz", split=f"train[:{n_samples*5}]")
tokenized_data = tokenizer("\n\n".join(data['text']), return_tensors='pt')# Format tokenized examples
examples_ids = []
for _ in range(n_samples):i = random.randint(0, tokenized_data.input_ids.shape[1] - tokenizer.model_max_length - 1)j = i + tokenizer.model_max_lengthinput_ids = tokenized_data.input_ids[:, i:j]attention_mask = torch.ones_like(input_ids)examples_ids.append({'input_ids': input_ids, 'attention_mask': attention_mask})
WARNING:datasets.builder:Found cached dataset json (/root/.cache/huggingface/datasets/allenai___json/allenai--c4-6e494e9c0ee1404e/0.0.0/8bb11242116d547c741b2e8a1f18598ffdd40a1d4f2a2872c7a28b697434bc96)
Token indices sequence length is longer than the specified maximum sequence length for this model (2441065 > 1024). Running this sequence through the model will result in indexing errors
%%time# Quantize with GPTQ
model.quantize(examples_ids,batch_size=1,use_triton=True,
)# Save model and tokenizer
model.save_quantized(out_dir, use_safetensors=True)
tokenizer.save_pretrained(out_dir)
CPU times: user 4min 35s, sys: 3.49 s, total: 4min 39s
Wall time: 5min 8s('gpt2-GPTQ/tokenizer_config.json','gpt2-GPTQ/special_tokens_map.json','gpt2-GPTQ/vocab.json','gpt2-GPTQ/merges.txt','gpt2-GPTQ/added_tokens.json','gpt2-GPTQ/tokenizer.json')

像往常一样,可以使用AutoGPTQForCausalLM和AutoTokenizer类从输出目录加载模型和tokenizer。

device = "cuda:0" if torch.cuda.is_available() else "cpu"# Reload model and tokenizer
model = AutoGPTQForCausalLM.from_quantized(out_dir,device=device,use_triton=True,use_safetensors=True,
)
tokenizer = AutoTokenizer.from_pretrained(out_dir)

让我们检查一下模型是否正常工作。AutoGPTQ模型(大多数情况下)作为普通的变压器模型工作,这使得它与推理管道兼容,如下面的示例所示

from transformers import pipelinegenerator = pipeline('text-generation', model=model, tokenizer=tokenizer)
result = generator("I have a dream", do_sample=True, max_length=50)[0]['generated_text']
print(result)
The model 'GPT2GPTQForCausalLM' is not supported for text-generation. Supported models are ['BartForCausalLM', 'BertLMHeadModel', 'BertGenerationDecoder', 'BigBirdForCausalLM', 'BigBirdPegasusForCausalLM', 'BioGptForCausalLM', 'BlenderbotForCausalLM', 'BlenderbotSmallForCausalLM', 'BloomForCausalLM', 'CamembertForCausalLM', 'CodeGenForCausalLM', 'CpmAntForCausalLM', 'CTRLLMHeadModel', 'Data2VecTextForCausalLM', 'ElectraForCausalLM', 'ErnieForCausalLM', 'FalconForCausalLM', 'GitForCausalLM', 'GPT2LMHeadModel', 'GPT2LMHeadModel', 'GPTBigCodeForCausalLM', 'GPTNeoForCausalLM', 'GPTNeoXForCausalLM', 'GPTNeoXJapaneseForCausalLM', 'GPTJForCausalLM', 'LlamaForCausalLM', 'MarianForCausalLM', 'MBartForCausalLM', 'MegaForCausalLM', 'MegatronBertForCausalLM', 'MusicgenForCausalLM', 'MvpForCausalLM', 'OpenLlamaForCausalLM', 'OpenAIGPTLMHeadModel', 'OPTForCausalLM', 'PegasusForCausalLM', 'PLBartForCausalLM', 'ProphetNetForCausalLM', 'QDQBertLMHeadModel', 'ReformerModelWithLMHead', 'RemBertForCausalLM', 'RobertaForCausalLM', 'RobertaPreLayerNormForCausalLM', 'RoCBertForCausalLM', 'RoFormerForCausalLM', 'RwkvForCausalLM', 'Speech2Text2ForCausalLM', 'TransfoXLLMHeadModel', 'TrOCRForCausalLM', 'XGLMForCausalLM', 'XLMWithLMHeadModel', 'XLMProphetNetForCausalLM', 'XLMRobertaForCausalLM', 'XLMRobertaXLForCausalLM', 'XLNetLMHeadModel', 'XmodForCausalLM'].
Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.
I have a dream," she told CNN last week. "I have this dream of helping my mother f

更深入的评估将需要测量量化模型与原始模型的 perplexity。但是,我们将其排除在本文的范围之内。

结论

在本文中,我们介绍了GPTQ算法,这是一种在消费级硬件上运行llm的最先进的量化技术。我们展示了它是如何解决分层压缩问题的,它基于一种改进的OBS技术,具有任意顺序洞察力、延迟批处理更新和Cholesky重构。这种新颖的方法显著降低了内存和计算需求,使LLM能够被更广泛的受众所接受。

此外,我们在一个空闲的T4 GPU上量化了我们自己的LLM模型,并运行它来生成文本。你可以在huggingFace Hub上推送你自己版本的GPTQ 4-bit 量化模型。正如在介绍中提到的,GPTQ不是唯一的4-bit量化算法:GGML和NF4是很好的替代算法,但作用域略有不同。

References

  • B. Hassibi, D. G. Stork and G. J. Wolff, “Optimal Brain Surgeon and general network pruning,” IEEE International Conference on Neural Networks, San Francisco, CA, USA, 1993, pp. 293-299 vol.1, doi: 10.1109/ICNN.1993.298572.
  • Elias Frantar, Sidak Pal Singh, & Dan Alistarh. (2023). Optimal Brain Compression: A Framework for Accurate Post-Training Quantization and Pruning.
  • Elias Frantar, Saleh Ashkboos, Torsten Hoefler, & Dan Alistarh. (2023). GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers.
  • Colin Raffel, Noam Shazeer, Adam Roberts, Katherine Lee, Sharan Narang, Michael Matena, Yanqi Zhou, Wei Li, & Peter J. Liu. (2020). Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer.
  • https://mlabonne.github.io/blog/posts/4_bit_Quantization_with_GPTQ.html#conclusion

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

信息收集2.0版本

内网渗透之信息收集 whois查询 1.1.1.1. 在线网站查询 输入相关的域名即可进行查询。 (1)站长之家:whois域名查询:http://whois.chinaz.com/ (2)爱站工具网:whois域名查询:站长…

mysql数据库操作小寄巧

目录 json字段查询时间相关只有日期只有时间又有时间又有日期时间比较时间运算 某字段同的取最新数据(软性的新数据覆盖旧数据查找)sql_modeonly_full_group_by的解决办法优化思路 json字段查询 查询某个json字段(xx)的某个属性下…

【考研数学】零基础备考全年计划

25考研数学基础差,一定要重视基础的复习! 基础不牢,地动山摇,这句话在如今的考研更加贴切 24考研的新形势: 重基础、计算量大、反押题 每一个变化对于基础差的同学都不是好消息。 做过近几年考研真题的人都会发现…

AI时代编程新宠!如何让孩子成为未来的编程大师?

文章目录 一、了解编程的基础概念二、选择适合的编程工具三、激发孩子的兴趣四、注重基础能力的培养五、提供实践机会六、鼓励孩子与他人合作七、持续支持与鼓励《信息学奥赛一本通关》本书定位内容简介作者简介目录 随着科技的迅猛发展,编程已经从一种专业技能转变…

代码随想录第二十五天 78.子集 90.子集II 491.非递减子序列

LeetCode 78 子集 题目描述 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出&…

iOS卡顿原因与优化

iOS卡顿原因与优化 1. 卡顿简介 卡顿: 指用户在使用过程中出现了一段时间的阻塞,使得用户在这一段时间内无法进行操作,屏幕上的内容也没有任何的变化。 卡顿作为App的重要性能指标,不仅影响着用户体验,更关系到用户留…

SpringBoot整合JdbcTemplate

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:SpringBoot整合JdbcTemplate 📚个人知识库: Leo知识库,欢迎大家访问 目录 …

设置文字之间的间距应该如何实现

设置文字之间的间距,通常指的是字母之间(字符间距)或单词之间的间距。在CSS中,这可以通过letter-spacing和word-spacing属性来实现。 字符间距(letter-spacing) letter-spacing属性用于调整字符之间的间距…

【Git学习笔记】提交PR

step1 克隆一个仓库 git clone .....step2 创建一个分支 (Creating a branch) # 创建并切换到本地新分支,分支的命名尽量简洁,并与解决的问题相关 git checkout -b delete-unused-linkstep3 做出修改 (Make changes) step4 提交修改 # 保存本地修…

DDR5内存相比DDR4内存的优势和区别?选择哪一个服务器内存配置能避免丢包和延迟高?

根据幻兽帕鲁服务器的实际案例分析,选择合适的DDR4与DDR5内存大小以避免丢包和延迟高,需要考虑以下几个方面: 性能与延迟:DDR5内存相比DDR4在传输速率、带宽、工作电压等方面都有显著提升,但同时也伴随着更高的延迟。D…

你知道什么是回调函数吗?

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…

4款免费且实用的.NET反编译工具

.NET 反编译工具的作用 .NET反编译工具能够将已经编译好的.NET程序集转换为易于理解的源代码,它们可以帮助开发人员恢复丢失的源代码、理解和分析第三方组件dll、学习其他人的代码、更好的查找修复 bug 或进行逆向工程等(注意:请在法律允许范…

SpringBoot系列(一):SpringBoot介绍

SpringBoot系列(一):SpringBoot介绍 1. SpringBoot介绍 SpringBoot是由Pivotal团队提供的一套用于构建微服务的基础框架,它旨在简化Spring应用程序的创建和开发过程。 SpringBoot通过设计大量的自动化配置等方式来简化Spring原有样板化的配置&#xff…

用Visual Studio 2015成功编译、发布UMDF驱动到目标机!!

开发工具:Visual Studio 2015企业版 主 机:windows10 X64企业版,主机是安装了Visual Studio 2015的操作系统,主要进行驱动开发和调试。 目 标 机:windows10 X86企业版,目标机是安装和调试驱动的操作…

阿里巴巴面试必备:数据库集群知识全面解读!

大家好,我是小米。今天,我们将深入探讨阿里巴巴面试题中一个备受关注的话题:数据库集群。作为技术领域中的一项重要实践,数据库集群不仅是企业架构中的核心组成部分,更是保障系统稳定性和数据可靠性的关键一环。让我们一起来揭秘数据库集群的奥秘吧! 主从复制过程 主从…

手势识别应用介绍

目录 一、功能介绍 二、安装部署说明 2.1 文件目录说明 2.2 手势识别部分 一、功能介绍 这是一个通过摄像头捕获手势,根据不同的手势来做出不同操作的计算机程序。目前可以识别9种手势,可以根据识别到的手势,进行打开应用、增大音量、减小音量…

交友社交软件开发-php交友聊天系统-

为了开发一个高效的交友系统,需要一个完善的信息管理和筛选机制。这个系统应该能够根据用户的个人信息、兴趣爱好、价值观等标准进行筛选,并向用户提供符合他们要求心仪的人的信息。为了实现这个目标,系统可以利用人工智能技术,分…

MySQL基础-----SQL语句之DDL语句

目录 前言 开启登录数据库 一、数据库操作 1.查询所有数据库 2.切换使用数据库 3.查询当前使用的数据库 4.创建数据库 创建一个hello数据库, 使用数据库默认的字符集。 创建一个itheima数据库,并且指定字符集 5.删除数据库 二、表操作 1.查询当前数据库所有…

JAVA的学习日记

JAVA的学习日记(2024.3.1)(b站韩顺平老师课程学习笔记版) ps:捡起忘光光的Java语言 Sublime //1. public是公有,class是类 //2. public class Hello表示Hello是一个类,是一个public公有的类 //3. Hello{…

解决Unable to load class ‘org.gradle.api.attributes.VerificationType‘

在使用AdnroidStudio开发过程中难免会遇到Unable to load class org.gradle.api.attributes.VerificationType报错,可以尝试清理缓存重启解决 打开 File-》Invalidate Caches... 重启AndroidStudio后,重新加载即可,但也不是百分百解决。