198 lines
12 KiB
Markdown
198 lines
12 KiB
Markdown
<!-- WEHUB_ZH_README -->
|
||
> [!NOTE]
|
||
> 本文档由 WeHub 基于上游 README 翻译整理,属于社区翻译,非官方中文文档。
|
||
> [English](./README.en.md) · [原始项目](https://github.com/huggingface/peft) · [上游 README](https://github.com/huggingface/peft/blob/HEAD/README.md)
|
||
> 原作者、版权与许可证归属以原始项目及本仓库 LICENSE 文件为准。
|
||
|
||
<!---
|
||
Copyright 2023 The HuggingFace Team. All rights reserved.
|
||
|
||
Licensed under the Apache License, Version 2.0 (the "License");
|
||
you may not use this file except in compliance with the License.
|
||
You may obtain a copy of the License at
|
||
|
||
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
||
Unless required by applicable law or agreed to in writing, software
|
||
distributed under the License is distributed on an "AS IS" BASIS,
|
||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
See the License for the specific language governing permissions and
|
||
limitations under the License.
|
||
-->
|
||
|
||
<h1 align="center"> <p>🤗 PEFT</p></h1>
|
||
<h3 align="center">
|
||
<p>先进的参数高效微调(Parameter-Efficient Fine-Tuning,PEFT)方法</p>
|
||
</h3>
|
||
|
||
微调大型预训练模型往往因其规模而成本过高。参数高效微调(PEFT)方法通过只微调少量(额外)模型参数,而非全部模型参数,使大型预训练模型能够高效适应各种下游应用。这显著降低了计算和存储成本。近期最先进的 PEFT 技术可达到与全量微调模型相当的性能。
|
||
|
||
PEFT 已与 Transformers 集成,便于模型训练与推理;与 Diffusers 集成,便于管理不同的适配器;与 Accelerate 集成,支持超大模型的分布式训练与推理。
|
||
|
||
> [!TIP]
|
||
> 访问 [PEFT](https://huggingface.co/PEFT) 组织页面,了解库中实现的 PEFT 方法,并查看演示如何将这些方法应用于各类下游任务的 notebook。点击组织页面的「Watch repos」按钮,以便在新方法和新 notebook 发布时收到通知!
|
||
|
||
查看 PEFT Adapters API Reference 部分以获取支持的 PEFT 方法列表,并阅读 [Adapters](https://huggingface.co/docs/peft/en/conceptual_guides/adapter),、[Soft prompts](https://huggingface.co/docs/peft/en/conceptual_guides/prompting), 和 [IA3](https://huggingface.co/docs/peft/en/conceptual_guides/ia3) 概念指南,进一步了解这些方法的工作原理。
|
||
|
||
## 快速入门
|
||
|
||
通过 pip 安装 PEFT:
|
||
|
||
```bash
|
||
pip install peft
|
||
```
|
||
|
||
使用 `get_peft_model` 将基础模型与 PEFT 配置包装起来,即可用 LoRA 等 PEFT 方法为训练准备模型。对于 bigscience/mt0-large 模型,你只需训练 0.19% 的参数!
|
||
|
||
```python
|
||
import torch
|
||
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", ...] # optionally indicate target modules
|
||
)
|
||
model = get_peft_model(model, peft_config)
|
||
model.print_trainable_parameters()
|
||
# prints: trainable params: 3,686,400 || all params: 3,089,625,088 || trainable%: 0.1193
|
||
|
||
# now perform training on your dataset, e.g. using transformers Trainer, then save the model
|
||
model.save_pretrained("qwen2.5-3b-lora")
|
||
```
|
||
|
||
加载 PEFT 模型进行推理:
|
||
|
||
```python
|
||
import torch
|
||
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("Preheat the oven to 350 degrees and place the cookie dough", return_tensors="pt")
|
||
outputs = model.generate(**inputs.to(device), max_new_tokens=50)
|
||
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
|
||
|
||
# prints something like: Preheat the oven to 350 degrees and place the cookie dough in a baking dish [...]
|
||
```
|
||
|
||
## 为何应使用 PEFT
|
||
|
||
使用 PEFT 有许多优势,但最主要的是在计算和存储方面的大幅节省,使 PEFT 适用于许多不同的用例。
|
||
|
||
### 在消费级硬件上实现高性能
|
||
|
||
以下是在 [ought/raft/twitter_complaints](https://huggingface.co/datasets/ought/raft/viewer/twitter_complaints) 数据集上、使用配备 80GB 显存的 A100 GPU 且 CPU RAM 超过 64GB 时,训练下列模型的内存需求。
|
||
|
||
| 模型 | 全量微调 | PEFT-LoRA PyTorch | 带 CPU Offloading 的 PEFT-LoRA DeepSpeed |
|
||
| --------- | ---- | ---- | ---- |
|
||
| bigscience/T0_3B (3B params) | 47.14GB GPU / 2.96GB CPU | 14.4GB GPU / 2.96GB CPU | 9.8GB GPU / 17.8GB CPU |
|
||
| bigscience/mt0-xxl (12B params) | OOM GPU | 56GB GPU / 3GB CPU | 22GB GPU / 52GB CPU |
|
||
| bigscience/bloomz-7b1 (7B params) | OOM GPU | 32GB GPU / 3.8GB CPU | 18.1GB GPU / 35GB CPU |
|
||
|
||
借助 LoRA,你可以全量微调一个 12B 参数模型——否则在 80GB GPU 上会显存不足(OOM)——并能舒适地容纳并训练 3B 参数模型。若观察 3B 参数模型的性能,其在仅占全量微调模型一小部分 GPU 显存的情况下,表现与之相当。
|
||
|
||
| 提交名称 | 准确率 |
|
||
| --------- | ---- |
|
||
| Human baseline (crowdsourced) | 0.897 |
|
||
| Flan-T5 | 0.892 |
|
||
| lora-t0-3b | 0.863 |
|
||
|
||
> [!TIP]
|
||
> 上表中 bigscience/T0_3B 模型的性能尚未优化。你可以通过调整输入指令模板、LoRA 超参数及其他训练相关超参数,进一步榨取性能。该模型的最终 checkpoint 大小仅为 19MB,而完整的 bigscience/T0_3B 模型为 11GB。在这篇[博客文章](https://www.philschmid.de/fine-tune-flan-t5-peft). 中了解更多使用 PEFT 进行微调的优势。
|
||
|
||
### 量化
|
||
|
||
量化是另一种通过以较低精度表示数据来降低模型内存需求的方法。它可以与 PEFT 方法结合使用,使训练和加载 LLM 进行推理更加容易。
|
||
|
||
* 在这篇[博客文章](https://pytorch.org/blog/finetune-llms/) 中学习如何在 16GB GPU 上使用 QLoRA 和 [TRL](https://huggingface.co/docs/trl/index) 库微调 [meta-llama/Llama-2-7b-hf](https://huggingface.co/meta-llama/Llama-2-7b-hf)——参见《使用 PyTorch 和 Hugging Face 生态工具在你自己的消费级硬件上微调 LLM》。
|
||
* 在这份 [notebook](https://colab.research.google.com/drive/1DOkD_5OUjFa0r5Ik3SgywJLJtEo2qLxO?usp=sharing) 中学习如何使用 LoRA 和 8-bit 量化微调 [openai/whisper-large-v2](https://huggingface.co/openai/whisper-large-v2) 模型以实现多语言自动语音识别(若要查看流式传输数据集的示例,请参阅这份 [notebook](https://colab.research.google.com/drive/1vhF8yueFqha3Y3CpTHN6q9EVcII9EYzs?usp=sharing))。
|
||
|
||
### 节省计算与存储
|
||
|
||
PEFT 可帮助你在每个下游任务或数据集上避免全量微调模型,从而节省存储空间。在许多情况下,你只需微调模型参数的极小一部分,每个 checkpoint 仅几 MB(而非 GB)。这些更小的 PEFT 适配器可达到与全量微调模型相当的性能。若你有许多数据集,使用 PEFT 模型可节省大量存储,且无需担心灾难性遗忘或对骨干/基础模型过拟合。
|
||
|
||
## PEFT 集成
|
||
|
||
PEFT 在 Hugging Face 生态系统中得到广泛支持,因为它为训练与推理带来了巨大的效率提升。
|
||
|
||
### Diffusers
|
||
|
||
迭代扩散过程会消耗大量内存,使训练变得困难。PEFT 可帮助降低内存需求并减小最终模型 checkpoint 的存储体积。例如,在配备 80GB 显存的 A100 GPU 且 CPU RAM 超过 64GB 的条件下,考虑使用 LoRA 训练 Stable Diffusion 模型所需的内存。最终模型 checkpoint 大小仅为 8.8MB!
|
||
|
||
| Model | Full Finetuning | 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](examples/lora_dreambooth/train_dreambooth.py) 训练脚本,尝试使用 LoRA 训练你自己的 Stable Diffusion 模型,还可以在运行在 T4 实例上的 [smangrul/peft-lora-sd-dreambooth](https://huggingface.co/spaces/smangrul/peft-lora-sd-dreambooth) Space 中进行体验。阅读这篇 [tutorial](https://huggingface.co/docs/peft/main/en/tutorial/peft_integrations#diffusers). 了解更多关于 Diffusers 中 PEFT 集成的内容。
|
||
|
||
### Transformers
|
||
|
||
PEFT 已与 [Transformers](https://huggingface.co/docs/transformers/main/en/peft). 直接集成。加载模型后,调用 `add_adapter` 可为模型添加新的 PEFT 适配器:
|
||
|
||
```python
|
||
from peft import LoraConfig
|
||
model = ... # transformers model
|
||
peft_config = LoraConfig(...)
|
||
model.add_adapter(peft_config, adapter_name="lora_1")
|
||
```
|
||
|
||
要加载已训练的 PEFT 适配器,请调用 `load_adapter`:
|
||
|
||
```python
|
||
model = ... # transformers model
|
||
model.load_adapter(<path-to-adapter>, adapter_name="lora_1")
|
||
```
|
||
|
||
要在不同适配器之间切换,请调用 `set_adapter`:
|
||
|
||
```python
|
||
model.set_adapter("lora_2")
|
||
```
|
||
|
||
Transformers 集成并未包含 PEFT 提供的全部功能,例如将适配器合并到基础模型中的方法。
|
||
|
||
### Accelerate
|
||
|
||
[Accelerate](https://huggingface.co/docs/accelerate/index) 是一个用于在各种训练配置和硬件(GPU、TPU、Apple Silicon 等)上进行分布式训练与推理的库。PEFT 模型可与 Accelerate 开箱即用(out of the box)协同工作,让你能够非常方便地训练超大规模模型,或在资源有限的消费级硬件上进行推理。
|
||
|
||
### TRL
|
||
|
||
PEFT 也可用于训练包含 RLHF 组件(如 ranker 和 policy)的 LLM。可通过阅读以下内容入门:
|
||
|
||
* [使用直接偏好优化(Direct Preference Optimization,DPO)微调 Mistral-7b 模型](https://towardsdatascience.com/fine-tune-a-mistral-7b-model-with-direct-preference-optimization-708042745aac) 结合 PEFT 与 [TRL](https://huggingface.co/docs/trl/index) 库,了解更多关于 DPO 方法及其在 LLM 上的应用。
|
||
* [在 24GB 消费级 GPU 上使用 RLHF 微调 20B LLM](https://huggingface.co/blog/trl-peft) 结合 PEFT 与 [TRL](https://huggingface.co/docs/trl/index) 库,然后试用 [gpt2-sentiment_peft.ipynb](https://github.com/huggingface/trl/blob/main/examples/notebooks/gpt2-sentiment.ipynb) 笔记本,优化 GPT2 以生成正面的电影评论。
|
||
* [StackLLaMA:使用 RLHF 训练 LLaMA 的实战指南](https://huggingface.co/blog/stackllama) 结合 PEFT,然后试用 [stack_llama/scripts](https://github.com/huggingface/trl/tree/main/examples/research_projects/stack_llama/scripts) 进行监督微调、奖励建模和 RL 微调。
|
||
|
||
## Model support
|
||
|
||
使用此 [Space](https://stevhliu-peft-methods.hf.space) 或查看 [docs](https://huggingface.co/docs/peft/main/en/index),了解哪些模型开箱即支持 PEFT 方法。即使下方列表中没有某个模型,你也可以手动配置模型 config 以为其启用 PEFT。阅读 [New transformers architecture](https://huggingface.co/docs/peft/main/en/developer_guides/custom_models#new-transformers-architectures) 指南了解具体做法。
|
||
|
||
## Contribute
|
||
|
||
如果你想为 PEFT 做出贡献,请查看我们的 [contribution guide](https://huggingface.co/docs/peft/developer_guides/contributing).
|
||
|
||
## Citing 🤗 PEFT
|
||
|
||
若要在出版物中使用 🤗 PEFT,请使用以下 BibTeX 条目进行引用。
|
||
|
||
```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}
|
||
}
|
||
```
|