Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >大语言模型量化方法对比:GPTQ、GGUF、AWQ

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

作者头像
deephub
发布于 2023-11-20 05:48:10
发布于 2023-11-20 05:48:10
10.6K00
代码可运行
举报
文章被收录于专栏:DeepHub IMBADeepHub IMBA
运行总次数:0
代码可运行

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 del model, tokenizer, pipe
 
 import torch
 torch.cuda.empty_cache()

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

模型加载

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 pip install git+https://github.com/huggingface/transformers.git
 pip install accelerate bitsandbytes xformers

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 from torch import bfloat16
 from transformers import pipeline
 
 # Load in your LLM without any compression tricks
 pipe = pipeline(
     "text-generation", 
     model="HuggingFaceH4/zephyr-7b-beta", 
     torch_dtype=bfloat16, 
     device_map="auto"
 )

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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来生成答案:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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 包:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 from accelerate import Accelerator
 
 # Shard our model into pieces of 1GB
 accelerator = 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库进行量化操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 from transformers import BitsAndBytesConfig
 from torch import bfloat16
 
 # Our 4-bit configuration to load the LLM with less GPU memory
 bnb_config = BitsAndBytesConfig(
     load_in_4bit=True,  # 4-bit quantization
     bnb_4bit_quant_type='nf4',  # Normalized float 4
     bnb_4bit_use_double_quant=True,  # Second quantization after the first
     bnb_4bit_compute_dtype=bfloat16  # Computation type
 )

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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
 
 # Zephyr with BitsAndBytes Configuration
 tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")
 model = AutoModelForCausalLM.from_pretrained(
     "HuggingFaceH4/zephyr-7b-alpha",
     quantization_config=bnb_config,
     device_map='auto',
 )
 
 # Create a pipeline
 pipe = pipeline(model=model, tokenizer=tokenizer, task='text-generation')

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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类模型中加载:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 pip install optimum
 pip install auto-gptq --extra-index-url https://huggingface.github.io/autogptq-index/whl/cu118/

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
 
 # Load LLM and Tokenizer
 model_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 pipeline
 pipe = 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包:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 pip install ctransformers[cuda]

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 from ctransformers import AutoModelForCausalLM
 from 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 pipeline
 pipe = pipeline(model=model, tokenizer=tokenizer, task='text-generation')

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 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包:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 pip install vllm

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 from vllm import LLM, SamplingParams
 
 # Load the LLM
 sampling_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运行模型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 output = llm.generate(prompt, sampling_params)
 print(output[0].outputs[0].text)

就是这样

作者:Maarten Grootendorst


喜欢就关注一下吧:

点个 在看 你最好看!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-11-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DeepHub IMBA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
谷歌Gemma介绍、微调、量化和推理
谷歌的最新的Gemma模型是第一个使用与Gemini模型相同的研究和技术构建的开源LLM。这个系列的模型目前有两种尺寸,2B和7B,并且提供了聊天的基本版和指令版。
deephub
2024/03/01
2.1K0
谷歌Gemma介绍、微调、量化和推理
LLM 大模型学习必知必会系列(六):量化技术解析、QLoRA技术、量化库介绍使用(AutoGPTQ、AutoAWQ)
模型的推理过程是一个复杂函数的计算过程,这个计算一般以矩阵乘法为主,也就是涉及到了并行计算。一般来说,单核CPU可以进行的计算种类更多,速度更快,但一般都是单条计算;而显卡能进行的都是基础的并行计算,做矩阵乘法再好不过。如果把所有的矩阵都加载到显卡上,就会导致显卡显存的占用大量增加,尤其是LLM模型大小从7b、14b、34b到几百b不等,占用显存的大小就是惊人的数字,如何在减少运算量和显存占用的条件下,做到推理效果不下降太多呢?在这里需要引入浮点数和定点数的概念。
汀丶人工智能
2024/05/26
2.3K0
LLM 大模型学习必知必会系列(六):量化技术解析、QLoRA技术、量化库介绍使用(AutoGPTQ、AutoAWQ)
微调 Zephyr 7B 量化模型,应用于客户聊天机器人的自定义任务
Huggingface 与 bitsandbytes 合作,将 AutoGPTQ[1] 库集成到了 Transformers 中。这一整合使用户能够以低至 8、4、3 或甚至 2 位的精度级别量化和操作模型,采用了 Frantar 等人在 2023 年[2] 引入的 GPTQ 算法。值得注意的是,使用 4 位量化几乎不会损失精度,同时在处理小批量数据时仍能保持与 fp16 基准相似的推理速度。值得一提的是,GPTQ 方法与 bitsandbytes 提出的训练后量化技术略有不同,因为它需要使用校准数据集。
山行AI
2023/12/28
7310
微调 Zephyr 7B 量化模型,应用于客户聊天机器人的自定义任务
【机器学习】QLoRA:基于PEFT亲手量化微调Qwen2大模型
之前陆续写了Qwen1.5、Qwen2.0、GLM-4等国产开源大模型的原理、训练及推理相关的文章,每一篇都拿到了热榜第一,但其中训练部分均基于Llama-factory框架,对于工程师而言,最喜欢的就是刨根问底,使用中间层的训练框架,还是少一些“安全感”。今天我们抛开中间框架,深入底层,一步一步带大家微调一个大模型。
LDG_AGI
2024/08/13
1.9K0
【机器学习】QLoRA:基于PEFT亲手量化微调Qwen2大模型
使用QLoRA对Llama 2进行微调的详细笔记
使用QLoRA对Llama 2进行微调是我们常用的一个方法,但是在微调时会遇到各种各样的问题,所以在本文中,将尝试以详细注释的方式给出一些常见问题的答案。这些问题是特定于代码的,大多数注释都是针对所涉及的开源库以及所使用的方法和类的问题。
deephub
2023/09/22
6.3K0
使用QLoRA对Llama 2进行微调的详细笔记
ORPO偏好优化:性能和DPO一样好并且更简单的对齐方法
现在有许多方法可以使大型语言模型(LLM)与人类偏好保持一致。以人类反馈为基础的强化学习(RLHF)是最早的方法之一,并促成了ChatGPT的诞生,但RLHF的成本非常高。与RLHF相比,DPO、IPO和KTO的成本明显更低,因为它们不需要奖励模型。
deephub
2024/04/16
2.3K0
ORPO偏好优化:性能和DPO一样好并且更简单的对齐方法
QLoRa:在消费级GPU上微调大型语言模型
大多数大型语言模型(LLM)都无法在消费者硬件上进行微调。例如,650亿个参数模型需要超过780 Gb的GPU内存。这相当于10个A100 80gb的gpu。就算我们使用云服务器,花费的开销也不是所有人都能够承担的。
deephub
2023/08/30
1.1K0
QLoRa:在消费级GPU上微调大型语言模型
【LLM训练系列01】Qlora如何加载、训练、合并大模型
参考脚本:https://github.com/QwenLM/Qwen/blob/main/recipes/finetune/deepspeed/finetune_qlora_multi_gpu.ipynb
致Great
2024/11/23
3850
【LLM训练系列01】Qlora如何加载、训练、合并大模型
【机器学习】Google开源大模型Gemma2:原理、微调训练及推理部署实战
Gemma 是 Google 推出的轻量级、先进的开放模型系列,采用与 Gemini 模型相同的研究成果和技术构建而成。它们是仅使用解码器的文本到文本大型语言模型(提供英语版本),为预训练变体和指令调整变体具有开放权重。Gemma 模型非常适合各种文本生成任务,包括问题解答、摘要和推理。由于它们相对较小,因此可以将其部署在资源有限的环境(如笔记本电脑、桌面设备或您自己的云基础架构)中,让更多人能够使用先进的 AI 模型,并帮助促进每个人的创新。
LDG_AGI
2024/08/13
7830
【机器学习】Google开源大模型Gemma2:原理、微调训练及推理部署实战
改善大型语言模型的3种简单方法
大型语言模型(LLMs)已经成为现实。随着最近发布的Llama 2,开源LLMs正在接近ChatGPT的性能,并且经过适当调整,甚至可以超越它。
磐创AI
2023/11/27
7570
改善大型语言模型的3种简单方法
使用Huggingface创建大语言模型RLHF训练流程的完整教程
ChatGPT已经成为家喻户晓的名字,而大语言模型在ChatGPT刺激下也得到了快速发展,这使得我们可以基于这些技术来改进我们的业务。
deephub
2023/12/05
2K0
使用Huggingface创建大语言模型RLHF训练流程的完整教程
使用ExLlamaV2量化并运行EXL2模型
量化大型语言模型(llm)是减少这些模型大小和加快推理速度的最流行的方法。在这些技术中,GPTQ在gpu上提供了惊人的性能。与非量化模型相比,该方法使用的VRAM几乎减少了3倍,同时提供了相似的精度水平和更快的生成速度。
deephub
2023/11/22
8990
使用ExLlamaV2量化并运行EXL2模型
OpenVINO与LangChain
LangChain 是一个用于构建语言模型驱动应用的框架。它旨在通过语言模型(如OpenAI的GPT-4)来增强和简化开发者创建复杂的自然语言处理(NLP)应用的过程。LangChain 提供了模块化的工具和组件,使开发者能够轻松地集成和扩展不同的NLP功能。
IT蜗壳-Tango
2024/05/10
1300
使用SPIN技术对LLM进行自我博弈微调训练
2024年是大型语言模型(llm)的快速发展的一年,对于大语言模型的训练一个重要的方法是对齐方法,它包括使用人类样本的监督微调(SFT)和依赖人类偏好的人类反馈强化学习(RLHF)。这些方法在llm中发挥了至关重要的作用,但是对齐方法对人工注释数据有的大量需求。这一挑战使得微调成为一个充满活力的研究领域,研究人员积极致力于开发能够有效利用人类数据的方法。
deephub
2024/01/18
7050
使用SPIN技术对LLM进行自我博弈微调训练
使用QLoRa微调Llama 2
上篇文章我们介绍了Llama 2的量化和部署,本篇文章将介绍使用PEFT库和QLoRa方法对Llama 27b预训练模型进行微调。我们将使用自定义数据集来构建情感分析模型。只有可以对数据进行微调我们才可以将这种大模型进行符合我们数据集的定制化。
deephub
2023/08/30
7060
使用QLoRa微调Llama 2
[AI学习笔记]DeepSeek模型编译技术解析:推理加速方案与代码部署实战
大规模语言模型(LLM)已经成为自然语言处理领域的核心技术。DeepSeek模型作为一款先进的预训练语言模型,广泛应用于文本生成、问答系统、机器翻译等领域。然而,随着模型规模的不断扩大,推理阶段的计算复杂度和资源消耗问题日益突出,成为限制模型实际应用的主要瓶颈。
数字扫地僧
2025/03/29
1750
[AI学习笔记]DeepSeek模型编译技术解析:推理加速方案与代码部署实战
从16-bit 到 1.58-bit :大模型内存效率和准确性之间的最佳权衡
通过量化可以减少大型语言模型的大小,但是量化是不准确的,因为它在过程中丢失了信息。通常较大的llm可以在精度损失很小的情况下量化到较低的精度,而较小的llm则很难精确量化。
deephub
2024/03/11
1.1K0
从16-bit 到 1.58-bit :大模型内存效率和准确性之间的最佳权衡
LLM(大语言模型)解码时是怎么生成文本的?
源码地址:transformers/configuration_utils.py at v4.28.1 · huggingface/transformers (github.com)
西西嘛呦
2023/04/27
5.8K0
LLM(大语言模型)解码时是怎么生成文本的?
【AIGC】多语言聊天机器人服务构建(基于bloom大语言模型)
ChatGPT 是多语言的,但是,它不会产生与用英语查询它相同的高性能。同时,对于非英语人士来说,这可能也是障碍,原因有二:
Freedom123
2024/05/09
3690
Transformers 4.37 中文文档(六)
视觉问答(VQA)是根据图像回答开放式问题的任务。支持此任务的模型的输入通常是图像和问题的组合,输出是用自然语言表达的答案。
ApacheCN_飞龙
2024/06/26
3520
Transformers 4.37 中文文档(六)
推荐阅读
相关推荐
谷歌Gemma介绍、微调、量化和推理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验