Press "Enter" to skip to content

在HuggingFace上使用Llama 2 7B Fine-Tuned模型进行GPTQ量化

如何简单地量化LLM的指南

Image by Milad Fakurian on Unsplash

在我之前的文章中,我向您展示了如何使用最新发布的Meta AI的Llama 2模型进行细化调整,以用几行代码构建Python代码生成器。这一次,我们将介绍如何使用与transformers集成的GPTQ量化来量化该模型。

上周,Hugging Face宣布其transformers库与AutoGPTQ库兼容,该库允许我们使用GPTQ方法将大型语言模型量化为2、3或4位。

GPTQ:生成模型的训练后量化

在一篇开创性的论文[1]中,研究人员揭示了GPTQ,一种新颖的训练后量化方法,有可能重新定义语言模型压缩的世界。GPTQ不仅足够高效,可以应用于拥有数千亿参数的模型,而且可以在不牺牲重要准确性的情况下,将这些模型压缩到每个参数仅为2、3或4位

这种尖端技术通过将OPT-175B和BLOOM-176B等大型模型量化为仅需几个GPU小时的方式来展示其能力,并且维持着最小的困惑度(一个严格的准确性度量)。在实践中,研究人员开发了一个执行框架,以便为生成任务提供高效运行压缩模型的能力。令人惊讶的是,他们在单个NVIDIA A100 GPU上运行了压缩的OPT-175B模型,并且只需额外两个性价比较高的NVIDIA A6000 GPU。此外,针对压缩的自定义GPU内核可以显著加快速度,进一步提高了这些压缩模型的实用性。

GPTQ之所以引人注目,是因为它能将拥有数千亿参数的语言模型量化到3-4位/分量的范围内。这是一个显著的飞跃,因为以前的方法很难将准确性保持在8位以下,并且通常集中于较小的模型。然而,这项研究还强调了压缩所引发的困惑度、位宽和模型大小之间的复杂权衡。但它也有一些限制。由于主流架构上缺乏混合精度操作数的硬件支持,GPTQ目前并未提供实际乘法的加速。激活量化也没有包含在当前的结果中,但可以通过其他技术来解决。

总之,GPTQ将极其准确的语言模型压缩到前所未有的水平,标志着机器学习和语言建模领域的重要里程碑。它为这些庞大模型的更高效和更易用的应用铺平了道路,并指向了模型压缩领域的进一步研究可能性。

机器学习中的量化方法可以分为两种不同的方法,每种方法都有其独特的优势:

  1. 训练后量化(PTQ):在PTQ中,使用相对中等资源(如校准数据集和几个小时的计算时间)对预训练模型进行量化。这种方法对于大型模型尤其有益,因为完全重新训练或微调可能成本过高。
  2. 量化感知训练(QAT):另一方面,QAT涉及在模型训练之前或随后的微调期间应用量化。

GPTQ的创新方法:GPTQ属于PTQ类别,使其成为大型模型的一个引人注目的选择。GPTQ的独特之处在于采用了混合的int4/fp16量化方案。在这里,模型权重量化为int4,而激活保持为float16。在推断过程中,权重被动态地解量化,并在float16中执行实际计算。

这种创新的方法承诺通过int4量化实现接近4倍的内存节省,并由于权重使用的较低带宽而可能获得加速。在实践中,GPTQ是一种针对已经微调并准备好部署的模型的量化方法。这种方法特别适用于将模型权重的精度减少到4位或3位,尽管主要用于4位量化。

GPTQ的一个关键特点是它能够在不需要将整个模型加载到内存中的情况下对模型进行量化。相反,它逐个模块地对模型进行量化,显著减少了量化过程中的内存需求。然而,它确实需要一小部分数据进行校准,这个步骤在一般的消费级GPU上可能需要一个多小时。

Auto-GPTQ包描述中的Pythonfix图像

关于GPTQ的详细解释,您可以阅读Maxime Labonne的令人惊叹的文章《Towards Data Science》中发表的“4-bit Quantization with GPTQ”。这篇文章深入探讨了这个过程的技术细节,适合那些希望了解细节的人。

我强烈推荐阅读Benjamin Marie的有用文章《GPTQ or bitsandbytes: Which Quantization Method to Use for LLMs — Examples with Llama 2》。在那里,您可以看到GPTQ和bitsandbytes量化之间的比较,优点和缺点,以便更好地了解何时更方便应用这些技术。

您何时应该使用GPTQ?

这个问题的答案将取决于每个具体的情况和要使用的基本模型,但HuggingFace和我之前提到的那篇文章都指出了以下方法:

  • 使用bitsandbytes在4-bit、nf4和QLoRa中对原始LLM模型进行微调。
  • 将适配器合并到原始模型中。
  • 使用GPTQ 4-bit对结果模型进行量化。

我在我的上一篇文章[3]中运行了前两个步骤,现在AutoGPT库已经与Huggingface生态系统集成,我们将以非常简单的方式执行第三个步骤。

AutoGPT集成了Hugging Face transformers

AutoGPTQ库作为一种强大的工具,采用高效的GPTQ方法对Transformer模型进行量化。GPTQ-for-LLaMa、Exllama和llama.cpp等一些努力专注于Llama架构的量化,但AutoGPTQ通过为各种变压器架构提供无缝支持而与众不同。

Hugging Face团队在增强对GPTQ的可访问性方面迈出了重要的一步,并且他们已经集成了一个包含Transfomers API的综合性API,简化了更广泛受众的低级模型(LLM)量化过程。这个集成包括CUDA内核等基本优化选项,以满足常见的使用情况。

对于寻求更高级量化选项的用户,Auto-GPTQ库仍然是一个宝贵的资源,提供了类似Triton内核和融合注意力兼容性的功能,确保在变压器模型量化领域的多样性和适应性。

我们的AutoGPTQ集成有很多优势:

量化模型是可序列化的,可以在Hub上共享。

GPTQ大大降低了运行LLM的内存需求,同时推理延迟与FP16推理相当。

AutoGPTQ支持Exllama内核,适用于各种架构。

该集成支持AMD GPU的本地RoCm支持。

可用PEFT进行微调。

摘自Huggingface的博客文章《使LLM更轻量化的AutoGPTQ和transformers》[5]。

我们对这个任务的方法

首先,我们将使用带有额外内存的T4在Colab会话中加载我们的微调模型Llama 2 7B 4-bit Python编码器。该模型以4位使用bitsandbytes加载,然后我们执行约12个示例来测量推理时间。为了对推理时间的性能进行简单评估,我们选择那些输入文本长度超过500个字符的示例,以便更好地了解量化在推理过程中的影响。

您可以在Hugging Face Hub的模型描述中提取加载此模型的代码。在我的笔记本中,我们将描述如何对所提及的示例进行推断。

使用auto-gptq、🤗 transformers和optimum对模型进行量化

GPTQ量化消耗大量GPU VRAM,因此我们需要在Colab的A100 GPU上执行它。量化模型需要大约45分钟,在Colab中不到1美元。您可以在我的存储库中的此笔记本中找到代码。

首先,我们需要按照huggingface教程中的建议安装库:

!pip install -q -U transformers peft accelerate optimum!pip install auto-gptq --extra-index-url https://huggingface.github.io/autogptq-index/whl/cu117/# For now, until the next release of AutoGPTQ, we will build the library from source!

Optimum库是Hugging Face的训练和推断优化工具包,它将AutoGPTQ集成到Transformers中。

GPTQ算法需要通过对量化模型进行推断来校准模型的量化权重。要使用auto-gptq量化模型,我们需要将数据集传递给量化器。这可以通过传递支持的默认数据集([‘wikitext2’,’c4’,’c4-new’,’ptb’,’ptb-new’])或用作自定义数据集的字符串列表来实现。

现在,您只需要使用GPTQ配置设置所需的参数加载模型,就像在使用transformers时一样,非常简单:

from transformers import AutoModelForCausalLM, AutoTokenizer, GPTQConfigimport torch# 设置要加载的模型hf_model_repo='edumunozsala/llama-2-7b-int4-python-code-20k'# 加载标记器tokenizer = AutoTokenizer.from_pretrained(hf_model_repo, use_fast=True)# 设置量化配置quantization_config = GPTQConfig(     bits=4,     group_size=128,     dataset="c4",     desc_act=False,     tokenizer=tokenizer)# 从HF加载模型quant_model = AutoModelForCausalLM.from_pretrained(hf_model_repo,                 quantization_config=quantization_config, device_map='auto')

如前所述,此代码运行大约需要45分钟,并消耗32 GB的GPU VRAM。根据hugging Face文档,“您需要GPU来量化模型。我们将将模型放在CPU中,并在GPU和CPU之间移动模块以量化它们。如果要在使用CPU卸载时最大化GPU的使用率,可以设置device_map = "auto"”[6]。

参数是自解释的,4位量化,C4数据集和量化期间要使用的标记器。其他两个参数采用默认值:

  • group_size:用于量化的组大小。推荐的值是128,-1表示使用每列量化
  • desc_act:是否按照激活大小递减的顺序量化列。将其设置为False可以显著加快推断速度,但困惑度可能会稍微变坏。也称为act-order。

一旦您的模型被量化,就可以将其上传到Hugging Face Hub并与社区共享。

quant_model.push_to_hub("edumunozsala/llama-2-7b-int4-GPTQ-python-code-20k")tokenizer.push_to_hub("edumunozsala/llama-2-7b-int4-GPTQ-python-code-20k")

在我使用GPTQ进行实验时,模型大小的减小是显著的。我的经过微调的Llama 2 7B模型的4位权重大小为13.5 GB,但经过量化后,其大小大幅减小到仅为3.9 GB,仅为原始大小的三分之一。在部署大型语言模型时,这个特性非常有吸引力。

从Hugging Face Hub加载GPTQ模型并进行一些推断

可能大家都知道如何做,但以防萬一你覺得這可能比其他模型更“棘手”,我們將向你展示這與平常一樣。

記住,你需要加載所有的庫,包括optimum、accelerate和當然還有auto-gptq。

!pip install -q -U transformers peft accelerate optimum!pip install auto-gptq

然後你可以在Google Colab上的一個T4 GPU中將tokenizer和model上傳到你的筆記本中:

import torchfrom transformers import AutoModelForCausalLM, AutoTokenizermodel_id = "edumunozsala/llama-2-7b-int4-GPTQ-python-code-20k"tokenizer = AutoTokenizer.from_pretrained(model_id)model = AutoModelForCausalLM.from_pretrained(model_id,                   torch_dtype=torch.float16, device_map="auto")

現在我們可以檢查我們的GPU,確認我們消耗了多少內存,確實,我們可以看到該模型占用了5,053 GB

我們重複之前提到的性能評估,在一堆長範例上進行推論,以與原始模型進行比較。這兩個推論過程都在T4 GPU上執行,基本模型每個推論大約需要17-19秒,而量化模型每個推論需要約8-9秒,是原來的一半。

所有的代碼和示例都在我的倉庫的筆記本中有詳細的解釋。歡迎任何建議或錯誤修復。

參考文獻

[1] ICLR 2023論文《GPTQ: Accurate Post-Training Quantization for Generative Pre-Trained Transformers》

[2] Benjamin Marie的文章《GPTQ或bitsandbytes:使用Llama 2的哪種量化方法》

[3] Eduardo Muñoz的文章《Fine-Tuning a Llama 2 7B Model for Python Code Generation》

[4] Huggingface上的原始微調模型《edumunozsala/llama-2-7b-int4-python-code-20k》

[5] Hugging Face博客文章《使用AutoGPTQ和transformers讓LLMs更輕巧》

[6] Hugging Face官方關於GPTQConfig的文檔

[7] Maxime Labonne的文章《使用GPTQ進行4位量化》

Leave a Reply

Your email address will not be published. Required fields are marked *