大语言模型量化方法对比:GPTQ、GGUF、AWQ

在过去的一年里,大型语言模型(llm)有了飞速的发展,在本文中,我们将探讨几种(量化)的方式,除此以外,还会介绍分片及不同的保存和压缩策略。

说明:每次加载LLM示例后,建议清除缓存,以防止出现OutOfMemory错误。

 del model, tokenizer, pipeimport torchtorch.cuda.empty_cache()

如果在jupyter中无法释放显存,请重启这个jupyter notebook。

模型加载

加载LLM的最直接、最普通的方式是通过🤗Transformers。HuggingFace已经创建了一个套件,我们能够直接使用

 pip install git+https://github.com/huggingface/transformers.gitpip install accelerate bitsandbytes xformers

安装完成后,我们可以使用以下管道轻松加载LLM:

 from torch import bfloat16from transformers import pipeline# Load in your LLM without any compression trickspipe = pipeline("text-generation", model="HuggingFaceH4/zephyr-7b-beta", torch_dtype=bfloat16, device_map="auto")

我们这里使用zephyr-7b-beta作为示例

这种加载LLM的方法通常不会执行任何压缩技巧。我们来做个使用的示例

 messages = [{"role": "system","content": "You are a friendly chatbot.",},{"role": "user", "content": "Tell me a funny joke about Large Language Models."},]prompt = pipe.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

使用内部提示模板生成的提示是这样构造的:

然后,我们可将提示传递给LLM来生成答案:

 outputs = pipe(prompt, max_new_tokens=256, do_sample=True, temperature=0.1, top_p=0.95)print(outputs[0]["generated_text"])

这是一个最直接的使用流程,但是对于纯推理,这种方法效率是最低的,因为在没有任何压缩或量化策略的情况下加载整个模型。

分片

在我们进入量化策略之前,我们先介绍一个前置的方法:分片。通过分片可以将模型分割成小块,每个分片包含模型的较小部分,通过在不同设备上分配模型权重来解决GPU内存限制。

虽然它没有任何的压缩和量化,但是这种方法算是一个最简单的加载大模型的方案。

比如Zephyr-7B-β,实际上已经分片了!如果进入模型并点击“Files and versions”链接,可以看到模型被分成了8个部分。

模型的分片非常简单,可以直接使用Accelerate 包:

 from accelerate import Accelerator# Shard our model into pieces of 1GBaccelerator = Accelerator()accelerator.save_model(model=pipe.model, save_directory="/content/model", max_shard_size="4GB")

这样将模型分成4GB的分片

量化

大型语言模型由一堆权重和激活表示。这些值通常由通常的32位浮点(float32)数据类型表示。

比特的数量告诉你它可以表示多少个值。Float32可以表示1.18e-38和3.4e38之间的值,相当多的值!比特数越少,它能表示的值就越少。

如果我们选择较低的位大小,那么模型就会变得不那么准确,但它表示更少的值,从而降低其大小和内存需求。

量化是指将LLM从其原始Float32表示转换为更小的表示。我们不希望简单地使用较小的位变体,而是希望在不丢失太多信息的情况下将较大的位表示映射到较小的位。

所以一般情况下,我们经常使用一种名为4bit-NormalFloat (NF4)的新格式来实现这一点。这个数据类型做了一些特殊的技巧,以便有效地表示更大的位数据类型。它包括三个步骤:

归一化:将模型的权重归一化,以便我们期望权重落在一定范围内。这允许更有效地表示更常见的值。

量化:将权重量化为4位。在NF4中,量化级别相对于归一化权重是均匀间隔的,从而有效地表示原始的32位权重。

去量化:虽然权重以4位存储,但它们在计算期间被去量化,从而在推理期间提高性能。

我们可以直接使用Bitsandbytes库进行量化操作:

 from transformers import BitsAndBytesConfigfrom torch import bfloat16# Our 4-bit configuration to load the LLM with less GPU memorybnb_config = BitsAndBytesConfig(load_in_4bit=True,  # 4-bit quantizationbnb_4bit_quant_type='nf4',  # Normalized float 4bnb_4bit_use_double_quant=True,  # Second quantization after the firstbnb_4bit_compute_dtype=bfloat16  # Computation type)

上面的配置指定要使用的量化级别。比如4位量化表示权重,但用16位进行推理。

然后在管道中加载模型就很简单了:

 from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline# Zephyr with BitsAndBytes Configurationtokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")model = AutoModelForCausalLM.from_pretrained("HuggingFaceH4/zephyr-7b-alpha",quantization_config=bnb_config,device_map='auto',)# Create a pipelinepipe = pipeline(model=model, tokenizer=tokenizer, task='text-generation')

接下来使用与之前相同的提示:

 outputs = pipe(prompt, max_new_tokens=256, do_sample=True, temperature=0.7, top_p=0.95)print(outputs[0]["generated_text"])

量化是一种强大的技术,可以减少模型的内存需求,同时保持性能相似。它允许更快的加载、使用和微调llm,即使使用较小的gpu。

预量化(GPTQ、AWQ、GGUF)

我们已经探索了分片和量化技术。但是量化是在每次加载模型时进行的,这是非常耗时的操作,有没有办法直接保存量化后的模型,并且在使用时直接加载呢?

TheBloke是HuggingFace上的一个用户,它为我们执行了一系列量化操作,我想用过大模型的人一定对它非常的熟悉吧

这些量化模型包含了很多格式GPTQ、GGUF和AWQ,我们来进行介绍

1、GPTQ: Post-Training Quantization for GPT Models

GPTQ是一种4位量化的训练后量化(PTQ)方法,主要关注GPU推理和性能。

该方法背后的思想是,尝试通过最小化该权重的均方误差将所有权重压缩到4位。在推理过程中,它将动态地将其权重去量化为float16,以提高性能,同时保持低内存。

我们需要在HuggingFace Transformers中的gptq类模型中加载:

 pip install optimumpip install auto-gptq --extra-index-url https://huggingface.github.io/autogptq-index/whl/cu118/

然后找到需要加载的模型,比如“TheBloke/zephyr-7B-beta-GPTQ”,进行加载

 from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline# Load LLM and Tokenizermodel_id = "TheBloke/zephyr-7B-beta-GPTQ"tokenizer = AutoTokenizer.from_pretrained(model_id, use_fast=True)model = AutoModelForCausalLM.from_pretrained(model_id,device_map="auto",trust_remote_code=False,revision="main")# Create a pipelinepipe = pipeline(model=model, tokenizer=tokenizer, task='text-generation')

尽管我们安装了一些额外的依赖项,但我们可以使用与之前相同的管道,也就是是不需要修改代码,这是使用GPTQ的一大好处。

GPTQ是最常用的压缩方法,因为它针对GPU使用进行了优化。但是如果你的GPU无法处理如此大的模型,那么从GPTQ开始切换到以cpu为中心的方法(如GGUF)是绝对值得的。

2、GPT-Generated Unified Format

尽管GPTQ在压缩方面做得很好,但如果没有运行它的硬件,那么就需要使用其他的方法。

GGUF(以前称为GGML)是一种量化方法,允许用户使用CPU来运行LLM,但也可以将其某些层加载到GPU以提高速度。

虽然使用CPU进行推理通常比使用GPU慢,但对于那些在CPU或苹果设备上运行模型的人来说,这是一种非常好的格式。

使用GGUF非常简单,我们需要先安装ctransformers包:

 pip install ctransformers[cuda]

然后加载模型“TheBloke/zephyr-7B-beta-GGUF”,

 from ctransformers import AutoModelForCausalLMfrom transformers import AutoTokenizer, pipeline# Load LLM and Tokenizer# Use `gpu_layers` to specify how many layers will be offloaded to the GPU.model = AutoModelForCausalLM.from_pretrained("TheBloke/zephyr-7B-beta-GGUF",model_file="zephyr-7b-beta.Q4_K_M.gguf",model_type="mistral", gpu_layers=50, hf=True)tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-beta", use_fast=True)# Create a pipelinepipe = pipeline(model=model, tokenizer=tokenizer, task='text-generation')

加载模型后,我们可以运行如下提示:

 outputs = pipe(prompt, max_new_tokens=256)print(outputs[0]["generated_text"])

如果你想同时利用CPU和GPU, GGUF是一个非常好的格式。

3、AWQ: Activation-aware Weight Quantization

除了上面两种以外,一种新格式是AWQ(激活感知权重量化),它是一种类似于GPTQ的量化方法。AWQ和GPTQ作为方法有几个不同之处,但最重要的是AWQ假设并非所有权重对LLM的性能都同等重要。

也就是说在量化过程中会跳过一小部分权重,这有助于减轻量化损失。所以他们的论文提到了与GPTQ相比的可以由显著加速,同时保持了相似的,有时甚至更好的性能。

该方法还是比较新的,还没有被采用到GPTQ和GGUF的程度。

对于AWQ,我们将使用vLLM包:

 pip install vllm

使用vLLM可以直接加载模型:

 from vllm import LLM, SamplingParams# Load the LLMsampling_params = SamplingParams(temperature=0.0, top_p=1.0, max_tokens=256)llm = LLM(model="TheBloke/zephyr-7B-beta-AWQ", quantization='awq', dtype='half', gpu_memory_utilization=.95, max_model_len=4096)

然后使用.generate运行模型:

 output = llm.generate(prompt, sampling_params)print(output[0].outputs[0].text)

就是这样

https://avoid.overfit.cn/post/47f8871b7144405795301aa0a6bd9a24

作者:Maarten Grootendorst

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

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

相关文章

【LIUNX】配置缓存DNS服务

配置缓存DNS服务 A.安装bind bind-utils1.尝试修改named.conf配置文件2.测试nslookup B.修改named.conf配置文件1.配置文件2.再次测试 缓存DNS服务器:只提供域名解析结果的缓存功能,目的在于提高数据查询速度和效率,但是没有自己控制的区域地…

虹科方案 | 从概念到生产的自动驾驶软件在环(SiL)测试解决方案

来源:雅名特自动驾驶 虹科方案 | 从概念到生产的自动驾驶软件在环(SiL)测试解决方案 自动驾驶软件在环(SiL)测试解决方案 自动驾驶软件在环(SiL)测试解决方案能够研究和验证高历程实验和恶劣驾…

计算属性与watch的区别,fetch与axios在vue中的异步请求,单文本组件使用,使用vite创建vue项目,组件的使用方法

7.计算属性 7-1计算属性-有缓存 模板中的表达式虽然很方便,但是只能做简单的逻辑操作,如果在模版中写太多的js逻辑,会使得模板过于臃肿,不利于维护,因此我们推荐使用计算属性来解决复杂的逻辑 <!DOCTYPE html> <html lang"en"> <head><meta …

初试 jmeter做压力测试

一.前言 压力测试是每一个Web应用程序上线之前都需要做的一个测试&#xff0c;他可以帮助我们发现系统中的瓶颈问题&#xff0c;减少发布到生产环境后出问题的几率&#xff1b;预估系统的承载能力&#xff0c;使我们能根据其做出一些应对措施。所以压力测试是一个非常重要的步…

BMS系统项目

1、通过电压监测是否冲满&#xff0c;通过电压可以监测是否放完电 电池得参数 单体过压&#xff08;充满电&#xff09; 过压恢复&#xff08;百分之90多&#xff09; 欠压保护&#xff08;百分之几得电&#xff0c;快关机了&#xff09; 欠压恢复&#xff08;就是欠压之上…

【博客系统】 一

该博客系统基于servlet和mysql数据库 , 并且通过xshell终端工具部署至云服务器. 实现的功能包括: 1.博客列表页 2.博客详情页 3.登陆页面 4.强制登陆检查 5.获取用户信息 6.退出登陆 7.发布博客 一.系统展示 登陆页面 博客列表页 博客详情页 博客编辑页 下面就开始编写代码了.…

【Java 进阶篇】JQuery 案例:下拉列表选中条目左右移动,打破选择的边界

在前端的舞台上&#xff0c;下拉列表是常见的用户交互元素&#xff0c;但有时候我们想要更多的交互体验。通过巧妙运用 JQuery&#xff0c;我们可以实现下拉列表中选中条目的左右移动功能&#xff0c;为用户提供更加灵活的选择方式。本篇博客将深入研究 JQuery 中实现这一功能的…

基于安卓android微信小程序的师生答疑交流平app

项目介绍 本课题研究的是基于HBuilder X系统平台的师生答疑交流APP&#xff0c;开发这款师生答疑交流APP主要是为了帮助用户可以不用约束时间与地点进行所需信息。本文详细讲述了师生答疑交流APP的界面设计及使用&#xff0c;主要包括界面的实现、控件的使用、界面的布局和异常…

C语言从入门到精通之【基本运算符】

赋值运算符 在C语言中&#xff0c;并不意味着“相等”&#xff0c;而是一个赋值运算符。下面的赋值表达式语句&#xff1a; bmw 2002; 把值2002赋给变量bmw。也就是说&#xff0c;号左侧是一个变量名&#xff0c;右侧是赋给该变量的值。符号被称为赋值运算符。另外&#xff0…

【数电】IEEE754浮点数

IEEE754浮点数 1.组成及分类2.计算(1)符号位(2)阶码(3)尾码(4)实际计算公式 1.组成及分类 &#xff08;1&#xff09;组成 IEEE754浮点数由三部分组成&#xff1a;符号位、阶码和尾码。 &#xff08;2&#xff09;分类 根据数据位宽分为三类&#xff1a;短浮点数、长浮点数和…

54. 螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a;matrix [[1,2,3,…

【Android】配置Gradle打包apk的环境

目录 生成jks签名文件 配置build.gradle&#xff08;app&#xff09; 打包 生成jks签名文件 Java 密钥库&#xff08;.jks 或 .keystore&#xff09;是用作证书和私钥存储库的二进制文件。用于为用户设备上安装的 APK 签名的密钥。 详细解释请看官方文档&#xff1a; 为应用…

Zookeeper Java SDK 开发入门

文章目录 一、概述二、导入依赖包三、与 Zookeeper 建立连接四、判断 ZooKeeper 节点是否存在四、创建 ZooKeeper 节点数据五、获取 ZooKeeper 节点数据六、修改 ZooKeeper 节点数据七、异步获取 ZooKeeper 节点数据八、完整示例 如果您还没有安装Zookeeper请看ZooKeeper 安装说…

如何调整图片尺寸:简单实用的教程分享

报名事业编考试的时候&#xff0c;会发现上传照片时会提示图片大小尺寸应该为多少&#xff0c;如果不符合规定就无法提交报名&#xff0c;那么怎么才能修改图片大小呢&#xff1f;最简单的方法就是利用调整照片大小工具来对图片尺寸修改&#xff0c;本文分享一个在线图片处理工…

【软考篇】中级软件设计师 第四部分(一)

中级软件设计师 第四部分&#xff08;一&#xff09; 二十九. 程序设计语言概述29.1 解释、编译29.3 编译程序29.4 后缀式29.5 文法定义29.6 正规式29.7 有限自动机29.8 语法分析方法 三十. 法律法规30.1 作品所属权30.2 商标有效期30.3 职务作品所属权30.4 单位与委托30.5 商标…

【开源】基于Vue.js的校园二手交易系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目详细录屏 二、功能模块2.1 数据中心模块2.2 二手商品档案管理模块2.3 商品预约管理模块2.4 商品预定管理模块2.5 商品留言板管理模块2.6 商品资讯管理模块 三、实体类设计3.1 用户表3.2 二手商品表3.3 商品预约表3.4 商品预定表3.5 留言表3.6…

SharePoint-连接Excel

Power Automate和Power Apps想要连接Excel表格的话&#xff0c;可以在OneDrive或SharePoint网站的文档中创建Excel文件&#xff0c;然后把Excel转换成table表格 以SharePoint为例&#xff0c;在文档中点击新建&#xff0c;选择Excel工作簿 填写内容&#xff0c;然后全选选中 在…

CRM系统对科技企业有哪些帮助

随着国家政策的倾斜和5G等相关基础技术的发展&#xff0c;中国人工智能产业在各方的共同推动下进入爆发式增长阶段&#xff0c;市场发展潜力巨大。CRM客户管理系统作为当下最热门的企业应用&#xff0c;同样市场前景广阔。那么&#xff0c;CRM系统对科技企业有哪些帮助&#xf…

2023年 华为杯数学建模 E题

本科大三的时候&#xff0c;打过一次美赛&#xff0c;当时租了一个民宿&#xff0c;和队友一起度过了专注的四天。当时比赛结束之后&#xff0c;拿着手机&#xff0c;看到四天没回的消息&#xff0c;四天没刷过的朋友圈&#xff0c;有种很新奇的感觉&#xff0c;谢谢美赛给了我…

MySQL数据库清理Relay_Log_File日志

背景 “Relay_Log_File” 是 MySQL 中用于复制的参数之一。在 MySQL 复制中&#xff0c;当一个服务器作为主服务器&#xff08;master&#xff09;时&#xff0c;它会将其更改写入二进制日志文件&#xff08;binary log file&#xff09;。而另一个服务器作为从服务器&#xf…