使用 AutoGPTQ 和 Transformers 让 LLM 更轻量
大型语言模型在理解和生成类人文本方面表现出卓越的能力,彻底改变了各个领域的应用。然而,它们对消费级硬件在训练和部署方面提出的要求越来越难以满足。
🤗 Hugging Face 的核心使命是“普及优秀的机器学习”,这包括让所有人尽可能地使用大型模型。本着我们与 bitsandbytes 合作的精神,我们刚刚将 AutoGPTQ 库集成到 Transformers 中,使用户能够使用 GPTQ 算法(Frantar 等人,2023)将模型量化并以 8 位、4 位、3 位甚至 2 位精度运行。4 位量化对精度损失可忽略不计,且在小批量推理时速度与 fp16
基准相当。请注意,GPTQ 方法与 bitsandbytes 提出的训练后量化方法略有不同,因为它需要传入校准数据集。
此集成适用于 Nvidia GPU 和基于 RoCm 的 AMD GPU。
目录
- 资源
- GPTQ 论文简要概述
- AutoGPTQ 库——高效利用 GPTQ 处理 LLM 的一站式库
- 🤗 Transformers 对 GPTQ 模型提供原生支持
- 使用 **Optimum 库**量化模型
- 通过 *__Text-Generation-Inference__* 运行 GPTQ 模型
- 使用 PEFT 微调量化模型
- 改进空间
- 总结和结束语
- 致谢
资源
这篇博文和发布附带了一些资源,帮助您开始 GPTQ 量化
- 原始论文
- 基本用法 Google Colab notebook - 该 notebook 展示了如何使用 GPTQ 方法量化您的 Transformers 模型,如何进行推理,以及如何使用量化模型进行微调。
- Transformers 集成 文档
- Optimum 集成 文档
- The Bloke 仓库,包含兼容的 GPTQ 模型。
GPTQ 论文简要概述
量化方法通常属于以下两类之一:
- 训练后量化 (PTQ):我们使用适度的资源(例如校准数据集和数小时的计算)对预训练模型进行量化。
- 量化感知训练 (QAT):在训练或进一步微调之前执行量化。
GPTQ 属于 PTQ 类别,这对于大型模型特别有意义,因为大型模型的完整模型训练甚至微调都可能非常昂贵。
具体来说,GPTQ 采用混合 int4/fp16 量化方案,其中权重被量化为 int4,而激活保持在 float16。在推理过程中,权重会被即时反量化,实际计算则在 float16 中执行。
此方案的好处有两点
- 对于 int4 量化,内存节省接近 x4,因为反量化发生在计算单元附近(在融合核中),而不是在 GPU 全局内存中。
- 由于权重使用较低位宽,节省了数据通信时间,因此潜在的加速效果。
GPTQ 论文解决了逐层压缩问题
给定一层 ,其权重矩阵为 和层输入 ,我们希望找到权重的量化版本 以最小化均方误差 (MSE)
一旦逐层解决了这个问题,就可以通过结合逐层解决方案来获得全局问题的解决方案。
为了解决这个逐层压缩问题,作者使用了最优脑量化框架(Frantar 等人 2022)。OBQ 方法从观察开始,即上述方程可以写成平方误差的和,即 的每一行。
这意味着我们可以独立地量化每一行。这称为逐通道量化。对于每一行 ,OBQ 一次量化一个权重,同时始终更新所有尚未量化的权重,以补偿量化单个权重所产生的误差。对选定权重的更新有一个闭式公式,利用 Hessian 矩阵。
GPTQ 论文通过引入一系列优化来改进该框架,这些优化在保持模型准确性的同时降低了量化算法的复杂性。
与 OBQ 相比,GPTQ 的量化步骤本身也更快:使用 OBQ 量化 BERT 模型 (336M) 需要 2 GPU 小时,而使用 GPTQ,Bloom 模型 (176B) 可以在不到 4 GPU 小时内完成量化。
要了解有关确切算法以及困惑度和加速方面的不同基准的更多信息,请查看原始论文。
AutoGPTQ 库——高效利用 GPTQ 处理 LLM 的一站式库
AutoGPTQ 库使用户能够使用 GPTQ 方法量化 🤗 Transformers 模型。虽然像 GPTQ-for-LLaMa、Exllama 和 llama.cpp 等并行社区工作严格针对 Llama 架构实现量化方法,但 AutoGPTQ 因其对各种 Transformer 架构的平稳覆盖而广受欢迎。
由于 AutoGPTQ 库涵盖了更广泛的 Transformer 模型,我们决定提供一个集成的 🤗 Transformers API,以使 LLM 量化更易于所有人使用。目前,我们已经集成了最常见的优化选项,例如 CUDA 内核。对于 Triton 内核或融合注意力兼容性等更高级的选项,请查看 AutoGPTQ 库。
🤗 Transformers 对 GPTQ 模型提供原生支持
在安装 AutoGPTQ 库和 optimum
(pip install optimum
)之后,现在在 Transformers 中运行 GPTQ 模型变得非常简单:
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("TheBloke/Llama-2-7b-Chat-GPTQ", torch_dtype=torch.float16, device_map="auto")
查看 Transformers 文档,了解所有功能的更多信息。
我们的 AutoGPTQ 集成有许多优点
- 量化模型可序列化,并可在 Hub 上共享。
- GPTQ 大幅降低了运行 LLM 的内存需求,同时推理延迟与 FP16 推理相当。
- AutoGPTQ 支持多种架构的 Exllama 内核。
- 该集成原生支持 AMD GPU 的 RoCm。
- 使用 PEFT 进行微调可用。
您可以在 Hub 上查看您最喜欢的模型是否已被量化。TheBloke 是 Hugging Face 的顶级贡献者之一,他使用 AutoGPTQ 量化了大量模型并将其共享到 Hugging Face Hub。我们共同努力确保这些仓库能够开箱即用地与我们的集成配合使用。
这是一个 batch size = 1 情况下的基准测试样本。基准测试在单个 NVIDIA A100-SXM4-80GB GPU 上运行。我们使用了 512 的提示长度,并生成了恰好 512 个新 token。第一行是未量化的 fp16
基线,而其他行显示了使用不同 AutoGPTQ 内核的内存消耗和性能。
gptq | act_order | bits | group_size | 内核 | 加载时间 (秒) | 每 token 延迟 (毫秒) | 吞吐量 (tokens/秒) | 峰值内存 (MB) |
---|---|---|---|---|---|---|---|---|
否 (False) | 无 | 无 | 无 | 无 | 26.0 | 36.958 | 27.058 | 29152.98 |
True | 否 (False) | 4 | 128 | exllama | 36.2 | 33.711 | 29.663 | 10484.34 |
True | 否 (False) | 4 | 128 | autogptq-cuda-old | 36.2 | 46.44 | 21.53 | 10344.62 |
更全面的可重现基准测试可在此处获得。
使用 **Optimum 库**量化模型
为了将 AutoGPTQ 无缝集成到 Transformers 中,我们使用了 AutoGPTQ API 的一个极简版本,该版本在 Hugging Face 的训练和推理优化工具包 Optimum 中可用。通过这种方法,我们实现了与 Transformers 的轻松集成,同时允许人们在需要量化自己的模型时使用 Optimum API!如果您想量化自己的 LLM,请查看 Optimum 文档。
使用 GPTQ 方法量化 🤗 Transformers 模型只需几行代码
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)
量化模型可能需要很长时间。请注意,对于 175B 模型,如果使用大型数据集(例如 `"c4"`),则至少需要 4 GPU 小时。如上所述,许多 GPTQ 模型已在 Hugging Face Hub 上可用,这在大多数用例中绕过了自行量化模型的需要。尽管如此,您也可以使用适合您正在处理的特定领域的自己的数据集来量化模型。
通过 *__Text-Generation-Inference__* 运行 GPTQ 模型
与 GPTQ 在 Transformers 中的集成同步,Text-Generation-Inference 库 (TGI) 也添加了对 GPTQ 的支持,旨在在生产环境中服务大型语言模型。GPTQ 现在可以与动态批处理、分页注意力(paged attention)和 Flash 注意力等功能一起用于广泛的架构。
例如,这种集成使得在单个 A100-80GB GPU 上服务 70B 模型成为可能!使用 fp16 检查点则无法实现,因为它超出了可用的 GPU 内存。
您可以在文档中找到更多关于 TGI 中 GPTQ 用法的信息。
请注意,TGI 中集成的内核在较大批处理量下扩展性不佳。尽管这种方法节省了内存,但在较大批处理量下预计会出现性能下降。
使用 PEFT 微调量化模型
您不能使用常规方法进一步训练量化模型。但是,通过利用 PEFT 库,您可以在其上训练适配器!为此,我们冻结了量化模型的所有层并添加了可训练适配器。以下是使用 PEFT 和 GPTQ 模型的一些示例:colab notebook 和微调脚本。
改进空间
我们的 AutoGPTQ 集成已经带来了令人印象深刻的优势,而预测质量的损失很小。在量化技术和内核实现方面仍有改进空间。
首先,虽然 AutoGPTQ (据我们所知)集成了来自 exllama 实现的最优 W4A16 内核(权重为 int4,激活为 fp16),但该内核仍有很大的改进空间。Kim 等人还有其他有前景的实现,以及 MIT Han Lab 的实现,似乎也很有前景。此外,根据内部基准测试,似乎还没有用 Triton 编写的开源高性能 W4A16 内核,这可能是一个值得探索的方向。
在量化方面,我们再次强调此方法仅量化权重。对于 LLM 量化,还有其他一些方法,可以在预测质量略有损失的情况下同时量化权重和激活,例如 LLM-QAT,其中可以使用混合 int4/int8 方案,以及键值缓存的量化。这种技术的一个主要优点是能够使用实际的整数算术进行计算,例如 Nvidia Tensor Cores 支持 int8 计算。然而,据我们所知,目前还没有开源的 W4A8 量化内核可用,但这可能是一个值得探索的有趣方向。
在内核方面,为更大批处理量设计高性能 W4A16 内核仍然是一个开放的挑战。
支持的模型
在最初的实现中,仅支持具有解码器或编码器架构的大型语言模型。这听起来可能有点限制,但它涵盖了大多数最先进的 LLM,例如 Llama、OPT、GPT-Neo、GPT-NeoX。
目前不支持超大型视觉、音频和多模态模型。
总结和结束语
在这篇博文中,我们介绍了 AutoGPTQ 库在 Transformers 中的集成,这使得使用 GPTQ 方法量化 LLM 成为可能,从而使社区中的每个人都能更轻松地使用它们,并使他们能够使用 LLM 构建令人兴奋的工具和应用程序。
此集成同时支持 Nvidia GPU 和基于 RoCm 的 AMD GPU,这是向更广泛 GPU 架构普及量化模型的巨大进步。
与 AutoGPTQ 团队的合作非常富有成效,我们非常感谢他们对该库的支持和工作。
我们希望这种集成能让每个人都更容易在他们的应用程序中使用 LLM,我们期待看到您将用它构建什么!
请不要错过上面分享的有用资源,以便更好地理解集成以及如何快速开始 GPTQ 量化。
- 原始论文
- 基本用法 Google Colab notebook - 该 notebook 展示了如何使用 GPTQ 方法量化您的 Transformers 模型,如何进行推理,以及如何使用量化模型进行微调。
- Transformers 集成 文档
- Optimum 集成 文档
- The Bloke 仓库,包含兼容的 GPTQ 模型。
致谢
我们要感谢 William 对出色的 AutoGPTQ 库的支持和工作,以及他在集成方面的帮助。我们还要感谢 TheBloke 使用 AutoGPTQ 量化了许多模型并将其共享到 Hub,以及他在集成方面的帮助。我们还要感谢 qwopqwop200 对 AutoGPTQ 库的持续贡献,以及他在扩展该库以支持 CPU 方面的工作,该工作将在 AutoGPTQ 的后续版本中发布。
最后,我们要感谢 Pedro Cuenca 帮助撰写了这篇博文。