Hugging Face 将 AutoGPTQ 集成进 Transformers,支持 2 至 8 bit 量化
Making LLMs lighter with AutoGPTQ and transformers
Hugging Face 把 AutoGPTQ 库集成进 Transformers,用户可用 GPTQ 算法把模型量化到 8、4、3 甚至 2-bit 精度并直接运行,4-bit 量化精度损失可忽略,小批量推理速度与 fp16 基线相当。
原文给出 GPTQ 量化接入 Transformers 后的精度、显存与推理延迟对比数据,可作为本地部署选型参考。
大型语言模型在理解和生成类似人类的文本方面展现出了卓越的能力,彻底改变了各个领域的应用。然而,它们对消费级硬件在训练和部署上的需求变得越来越难以满足。
🤗 HF Mirror 的核心使命是使优质的机器学习普及化,这包括让大型模型对每个人都尽可能可访问。秉承我们与 bitsandbytes 合作的精神,我们刚刚在 Transformers 中集成了 AutoGPTQ 库,使用户能够使用 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 微调量化模型
- Room for improvement
- 结论与结束语
- 致谢
资源
本篇博客文章和发布提供了多种资源,帮助您开始使用 GPTQ 量化:
- 原始论文
- 基本用法 Google Colab 笔记本 - 此笔记本展示了如何使用 GPTQ 方法量化您的 transformers 模型、如何进行推理,以及如何使用量化模型进行微调。
- Transformers 集成 文档
- Optimum 集成 文档
- The Bloke 仓库,包含兼容的 GPTQ 模型。
GPTQ 论文简明摘要
量化方法通常属于以下两类之一:
- 训练后量化(PTQ):我们使用适度的资源(如校准数据集和几小时的计算)对预训练模型进行量化。
- 量化感知训练(QAT):在训练或进一步微调之前执行量化。
GPTQ 属于 PTQ 类别,这对于庞大的模型尤其有趣,因为完整的模型训练甚至微调都可能非常昂贵。
具体来说,GPTQ 采用混合 int4/fp16 量化方案,其中权重被量化为 int4,而激活保持为 float16。在推理过程中,权重即时去量化,实际计算以 float16 进行。
该方案的好处是双重的:
- 内存节省接近 4 倍,对于 int4 量化,因为去量化在融合内核中靠近计算单元进行,而不是在 GPU 全局内存中。
- 由于权重使用的位宽较低,节省了数据通信时间,从而可能实现加速。
GPTQ 论文处理的是逐层压缩问题:
给定一个层 ll,其权重矩阵为 WlW_{l},层输入为 XlX_{l},我们希望找到权重的量化版本 W^l\hat{W}_{l},以最小化均方误差(MSE):
W^l∗=argminWl^∥WlX−W^lX∥22{\hat{W}_{l}}^{*} = argmin_{\hat{W_{l}}} \|W_{l}X-\hat{W}_{l}X\|^{2}_{2}
一旦每层都解决了这个问题,就可以通过组合各层的解来获得全局问题的解。
为了解决这个逐层压缩问题,作者使用了最优脑量化框架(Frantar et al 2022)。OBQ 方法从观察上述方程可以写成 WlW_{l} 每一行的平方误差之和开始。
∑i=0drow∥Wl[i,:]X−W^l[i,:]X∥22 \sum_{i=0}^{d_{row}} \|W_{l[i,:]}X-\hat{W}_{l[i,:]}X\|^{2}_{2}
这意味着我们可以独立地量化每一行。这称为逐通道量化。对于每一行 Wl[i,:]W_{l[i,:]},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 库覆盖了更广泛的 transformers 模型,我们决定提供一个集成的 🤗 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 是 HF Mirror 顶级贡献者之一,他使用 AutoGPTQ 量化了很多模型,并在 HF Mirror Hub 上分享。我们共同确保这些仓库能够与我们的集成开箱即用。
这是 batch size = 1 情况下的基准测试样本。基准测试在单个 NVIDIA A100-SXM4-80GB GPU 上运行。我们使用了长度为 512 的 prompt,并生成了恰好 512 个新 token。第一行是未量化的 fp16 基线,而其他行显示了使用不同 AutoGPTQ 内核时的内存消耗和性能。
| gptq | act_order | bits | group_size | kernel | 加载时间(秒) | 每 token 延迟(毫秒) | 吞吐量(tokens/s) | 峰值内存(MB) |
|---|---|---|---|---|---|---|---|---|
| False | None | None | None | None | 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 的极简版本,该版本可在 Optimum 中使用,Optimum 是 HF Mirror 用于训练和推理优化的工具包。通过采用这种方法,我们实现了与 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 模型已经在 HF Mirror Hub 上可用,在大多数使用场景下,这避免了自行量化模型的需要。不过,你也可以使用适合你正在处理的特定领域的自有数据集来量化模型。
通过 Text-Generation-Inference 运行 GPTQ 模型
在将 GPTQ 集成到 Transformers 的同时,Text-Generation-Inference 库(TGI)也添加了 GPTQ 支持,该库旨在生产环境中服务大型语言模型。GPTQ 现在可以与动态批处理、分页注意力和 Flash Attention 等功能一起使用,支持多种架构。
例如,这种集成允许在单个 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。
目前不支持非常大的视觉、音频和多模态模型。
结论与结语
在这篇博文中,我们介绍了在 Transformers 中集成 AutoGPTQ 库,使得可以使用 GPTQ 方法对 LLM 进行量化,从而让社区中的任何人都能更容易地使用它们,并赋能他们用 LLM 构建激动人心的工具和应用。
此集成既适用于 Nvidia GPU,也适用于搭载 RoCm 的 AMD GPU,这是朝着在更广泛的 GPU 架构上普及量化模型迈出的巨大一步。
与 AutoGPTQ 团队的合作非常有成效,我们非常感谢他们的支持以及他们在这个库上的工作。
我们希望此次集成能让每个人更容易地在他们的应用中使用 LLM,并且我们期待看到你们用它构建出什么!
不要错过上面分享的有用资源,以更好地理解此集成以及如何快速开始使用 GPTQ 量化。
- 原始论文
- 基本用法 Google Colab 笔记本 - 该笔记本展示了如何使用 GPTQ 方法量化你的 transformers 模型、如何进行推理,以及如何对量化模型进行微调。
- Transformers 集成 文档
- Optimum 集成 文档
- The Bloke 的代码仓库,包含兼容的 GPTQ 模型。
致谢
我们要感谢 William 的支持,他在出色的 AutoGPTQ 库上的工作,以及他在集成方面的帮助。 我们还要感谢 TheBloke 在利用 AutoGPTQ 量化许多模型并在 Hub 上分享它们方面所做的工作,以及他在集成方面的帮助。 我们还要感谢 qwopqwop200 对 AutoGPTQ 库的持续贡献,以及他为将该库扩展到 CPU 所做的工作,这一功能将在 AutoGPTQ 的下一个版本中发布。
最后,我们要感谢 Pedro Cuenca 在撰写这篇博客文章方面的帮助。
来源:Hugging Face Blog · hf-mirror.com