🤗 PEFT
最先进的参数高效微调 (PEFT) 方法
由于规模庞大,微调大型预训练模型通常成本高昂。参数高效微调 (PEFT) 方法通过仅微调少量(额外的)模型参数,而不是所有模型参数,实现了将大型预训练模型高效适配到各种下游应用。这显著降低了计算和存储成本。目前最先进的 PEFT 技术能够达到与完全微调模型相当的性能。
PEFT 与 Transformers 集成,便于模型训练和推理;与 Diffusers 集成,方便管理不同的适配器;与 Accelerate 集成,支持大型模型的分布式训练和推理。
[!TIP]
访问 PEFT 组织,了解库中实现的 PEFT 方法,并查看演示如何将这些方法应用于各种下游任务的笔记本。点击组织页面上的 "Watch repos" 按钮,以便在新方法或笔记本发布时收到通知!
查看 PEFT 适配器 API 参考部分以获取支持的 PEFT 方法列表,并阅读 适配器、软提示 和 IA3 概念指南,以了解更多关于这些方法工作原理的信息。
通过 pip 安装 PEFT:
pip install peft
使用 get_peft_model 包装基础模型和 PEFT 配置,以准备使用 LoRA 等 PEFT 方法进行训练。对于 bigscience/mt0-large 模型,您仅训练 0.19% 的参数!
from transformers import AutoModelForCausalLM
from peft import LoraConfig, TaskType, get_peft_model
device = torch.accelerator.current_accelerator().type if hasattr(torch, "accelerator") else "cuda"
model_id = "Qwen/Qwen2.5-3B-Instruct"
model = AutoModelForCausalLM.from_pretrained(model_id, device_map=device)
peft_config = LoraConfig(
r=16,
lora_alpha=32,
task_type=TaskType.CAUSAL_LM,
# target_modules=["q_proj", "v_proj", ...] # 可选地指定目标模块
)
model = get_peft_model(model, peft_config)
model.print_trainable_parameters()
# 输出:trainable params: 3,686,400 || all params: 3,089,625,088 || trainable%: 0.1193
# 现在可以在您的数据集上进行训练,例如使用 transformers Trainer,然后保存模型
model.save_pretrained("qwen2.5-3b-lora")
加载 PEFT 模型进行推理:
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
device = torch.accelerator.current_accelerator().type if hasattr(torch, "accelerator") else "cuda"
model_id = "Qwen/Qwen2.5-3B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, device_map=device)
model = PeftModel.from_pretrained(model, "qwen2.5-3b-lora")
inputs = tokenizer("将烤箱预热至 350 度并放入饼干面团", return_tensors="pt")
outputs = model.generate(**inputs.to(device), max_new_tokens=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
# 输出类似内容:将烤箱预热至 350 度并放入饼干面团在烤盘中 [...]
使用 PEFT 有许多好处,但最主要的是能大幅节省计算和存储资源,使得 PEFT 适用于许多不同的用例。
考虑在配备超过 64GB CPU RAM 的 A100 80GB GPU 上,使用 ought/raft/twitter_complaints 数据集训练以下模型的内存需求。
| 模型 | 完全微调 | PEFT-LoRA PyTorch | PEFT-LoRA DeepSpeed with CPU Offloading |
|---|---|---|---|
| bigscience/T0_3B (3B 参数) | 47.14GB GPU / 2.96GB CPU | 14.4GB GPU / 2.96GB CPU | 9.8GB GPU / 17.8GB CPU |
| bigscience/mt0-xxl (12B 参数) | GPU 内存不足 | 56GB GPU / 3GB CPU | 22GB GPU / 52GB CPU |
| bigscience/bloomz-7b1 (7B 参数) | GPU 内存不足 | 32GB GPU / 3.8GB CPU | 18.1GB GPU / 35GB CPU |
使用 LoRA,您可以完全微调一个原本在 80GB GPU 上会内存不足的 120 亿参数模型,并且可以轻松容纳并训练一个 30 亿参数模型。当您查看 30 亿参数模型的性能时,它仅消耗一小部分 GPU 内存,就能达到与完全微调模型相当的水平。
| 提交名称 | 准确率 |
|---|---|
| 人类基线(众包) | 0.897 |
| Flan-T5 | 0.892 |
| lora-t0-3b | 0.863 |
[!TIP]
上表中的 bigscience/T0_3B 模型性能尚未优化。通过调整输入指令模板、LoRA 超参数和其他训练相关超参数,您可以从中榨取更多性能。该模型的最终检查点大小仅为 19MB,而完整的 bigscience/T0_3B 模型为 11GB。在这篇 博客文章 中了解更多关于使用 PEFT 进行微调的优势。
量化是通过以较低精度表示数据来减少模型内存需求的另一种方法。它可以与 PEFT 方法结合,使训练和加载 LLM 进行推理变得更加容易。
PEFT 可以帮助您节省存储空间,避免在每个下游任务或数据集上完全微调模型。在许多情况下,您只微调模型参数的一小部分,每个检查点只有几 MB 大小(而不是 GB)。这些较小的 PEFT 适配器表现出与完全微调模型相当的性能。如果您有许多数据集,使用 PEFT 模型可以节省大量存储空间,并且不必担心灾难性遗忘或对主干/基础模型过拟合。
由于 PEFT 为训练和推理带来了巨大的效率提升,它在 Hugging Face 生态系统中得到了广泛支持。
迭代扩散过程消耗大量内存,这使得训练变得困难。PEFT 可以帮助减少内存需求并减小最终模型检查点的存储大小。例如,考虑在配备超过 64GB CPU RAM 的 A100 80GB GPU 上使用 LoRA 训练 Stable Diffusion 模型所需的内存。最终模型检查点大小仅为 8.8MB!
| 模型 | 完全微调 | PEFT-LoRA | PEFT-LoRA with Gradient Checkpointing |
|---|---|---|---|
| CompVis/stable-diffusion-v1-4 | 27.5GB GPU / 3.97GB CPU | 15.5GB GPU / 3.84GB CPU | 8.12GB GPU / 3.77GB CPU |
[!TIP]
查看 examples/lora_dreambooth/train_dreambooth.py 训练脚本,尝试使用 LoRA 训练您自己的 Stable Diffusion 模型,并体验运行在 T4 实例上的 smangrul/peft-lora-sd-dreambooth Space。在此 教程 中了解更多关于 PEFT 在 Diffusers 中的集成。
PEFT 直接与 Transformers 集成。加载模型后,调用 add_adapter 为模型添加新的 PEFT 适配器:
from peft import LoraConfig
model = ... # transformers 模型
peft_config = LoraConfig(...)
model.add_adapter(lora_config, adapter_name="lora_1")
要加载训练好的 PEFT 适配器,调用 load_adapter:
model = ... # transformers 模型
model.load_adapter(<path-to-adapter>, adapter_name="lora_1")
要在不同适配器之间切换,调用 set_adapter:
model.set_adapter("lora_2")
Transformers 集成并未包含 PEFT 提供的所有功能,例如将适配器合并到基础模型中的方法。
Accelerate 是一个用于在各种训练设置和硬件(GPU、TPU、Apple Silicon 等)上进行分布式训练和推理的库。PEFT 模型开箱即用地与 Accelerate 兼容,使得在资源有限的消费级硬件上训练非常大的模型或使用它们进行推理变得非常方便。
PEFT 也可以应用于训练带有 RLHF 组件(如排序器和策略)的 LLM。通过阅读以下内容开始:
使用此 Space 或查看 文档 以查找哪些模型官方支持开箱即用的 PEFT 方法。即使您没有在下面看到列出的模型,您也可以手动配置模型配置以启用 PEFT。阅读 新 transformers 架构 指南以了解如何操作。
如果您想为 PEFT 做出贡献,请查看我们的 贡献指南。
如果您在出版物中使用 🤗 PEFT,请使用以下 BibTeX 条目进行引用。
@Misc{peft,
title = {{PEFT}: State-of-the-art Parameter-Efficient Fine-Tuning methods},
author = {Sourab Mangrulkar and Sylvain Gugger and Lysandre Debut and Younes Belkada and Sayak Paul and Benjamin Bossan and Marian Tietz},
howpublished = {\url{https://github.com/huggingface/peft}},
year = {2022}
}