Hugging Face 发布 PEFT 库,支持低显存微调大语言模型
Parameter-Efficient Fine-Tuning using 🤗 PEFT
Hugging Face 发布 PEFT 库,通过只微调少量额外参数并冻结预训练模型大部分参数来降低计算与存储开销,并已集成 Transformers 和 Accelerate。
官方给出 PEFT 库支持的方法与消费级硬件训练示例,可用于判断低显存微调方案的可行性。
动机
基于 transformer 架构的大语言模型(LLM),如 GPT、T5 和 BERT,已在各种自然语言处理(NLP)任务中取得了最先进的结果。它们也开始涉足其他领域,例如计算机视觉(CV)(VIT、Stable Diffusion、LayoutLM)和音频(Whisper、XLS-R)。传统范式是在通用网络规模数据上进行大规模预训练,然后针对下游任务进行微调。与直接使用预训练的大语言模型(例如零样本推理)相比,在下游数据集上微调这些预训练的大语言模型会带来巨大的性能提升。
然而,随着模型越来越大,全量微调在消费级硬件上进行训练变得不可行。此外,针对每个下游任务独立存储和部署微调后的模型变得非常昂贵,因为微调后的模型与原始预训练模型大小相同。参数高效微调(PEFT)方法旨在解决这两个问题!
PEFT 方法仅微调少量(额外)模型参数,同时冻结预训练大语言模型的大部分参数,从而大大降低了计算和存储成本。这也克服了灾难性遗忘的问题,这是在对大语言模型进行全量微调时观察到的一种现象。PEFT 方法还已被证明在低数据量情况下优于微调,并且能更好地泛化到域外场景。它可以应用于各种模态,例如图像分类和stable diffusion dreambooth。
它还有助于提升可移植性,用户可以使用 PEFT 方法微调模型,获得仅几 MB 的微小检查点,而全量微调的检查点则很大,例如,bigscience/mt0-xxl 占用 40GB 存储空间,全量微调会为每个下游数据集产生 40GB 的检查点,而使用 PEFT 方法,每个下游数据集仅需几 MB,同时还能达到与全量微调相当的性能。PEFT 方法训练得到的小权重被添加到预训练大语言模型之上。因此,只需添加小权重即可将同一个大语言模型用于多个任务,而无需替换整个模型。
简而言之,PEFT 方法使你能够在仅拥有少量可训练参数的情况下,获得与全量微调相当的性能。
今天,我们很高兴推出 🤗 PEFT 库,它提供了最新的参数高效微调技术,并与 🤗 Transformers 和 🤗 Accelerate 无缝集成。这使得可以使用 Transformers 中最流行、性能最佳的模型,同时兼具 Accelerate 的简单性和可扩展性。以下是目前支持的 PEFT 方法,更多方法即将推出:
- LoRA:LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS
- Prefix Tuning:P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks
- Prompt Tuning:The Power of Scale for Parameter-Efficient Prompt Tuning
- P-Tuning:GPT Understands, Too
用例
我们在这里探索了许多有趣的用例。以下是一些最有趣的用例:
使用 🤗 PEFT LoRA 在消费级硬件上微调
bigscience/T0_3B模型(30 亿参数),例如配备 11GB RAM 的 Nvidia GeForce RTX 2080 Ti、Nvidia GeForce RTX 3080 等,借助 🤗 Accelerate 的 DeepSpeed 集成:peft_lora_seq2seq_accelerate_ds_zero3_offload.py。这意味着你可以在 Google Colab 中微调如此大的 LLM。在上一示例的基础上更进一步,使用 🤗 PEFT LoRA 和 bitsandbytes 在 Google Colab 中对
OPT-6.7b模型(67 亿参数)进行 INT8 微调:在消费级硬件上使用 🤗 PEFT 进行 Stable Diffusion Dreambooth 训练,例如配备 11GB RAM 的 Nvidia GeForce RTX 2080 Ti、Nvidia GeForce RTX 3080 等。试试 Space 演示,它应该能在 T4 实例(16GB GPU)上无缝运行:smangrul/peft-lora-sd-dreambooth。

PEFT LoRA Dreambooth Gradio Space
使用 🤗 PEFT 训练你的模型
让我们考虑使用 LoRA 微调 bigscience/mt0-large 的情况。
- 获取必要的导入
from transformers import AutoModelForSeq2SeqLM
+ from peft import get_peft_model, LoraConfig, TaskType
model_name_or_path = "bigscience/mt0-large"
tokenizer_name_or_path = "bigscience/mt0-large"
- 创建对应 PEFT 方法的配置
peft_config = LoraConfig(
task_type=TaskType.SEQ_2_SEQ_LM, inference_mode=False, r=8, lora_alpha=32, lora_dropout=0.1
)
- 通过调用
get_peft_model来包装基础 🤗 Transformers 模型
model = AutoModelForSeq2SeqLM.from_pretrained(model_name_or_path)
+ model = get_peft_model(model, peft_config)
+ model.print_trainable_parameters()
# output: trainable params: 2359296 || all params: 1231940608 || trainable%: 0.19151053100118282
就是这样!其余的训练循环保持不变。请参考示例 peft_lora_seq2seq.ipynb 获取端到端示例。
- 当你准备好保存模型用于推理时,只需执行以下操作。
model.save_pretrained("output_dir")
# model.push_to_hub("my_awesome_peft_model") also works
这只会保存训练所得的增量 PEFT 权重。例如,你可以在这里找到在 twitter_complaints raft 数据集上使用 LoRA 微调的 bigscience/T0_3B:smangrul/twitter_complaints_bigscience_T0_3B_LORA_SEQ_2_SEQ_LM。注意它只包含 2 个文件:adapter_config.json 和 adapter_model.bin,后者仅有 19MB。
- 要加载它用于推理,请遵循下面的代码片段:
from transformers import AutoModelForSeq2SeqLM
+ from peft import PeftModel, PeftConfig
peft_model_id = "smangrul/twitter_complaints_bigscience_T0_3B_LORA_SEQ_2_SEQ_LM"
config = PeftConfig.from_pretrained(peft_model_id)
model = AutoModelForSeq2SeqLM.from_pretrained(config.base_model_name_or_path)
+ model = PeftModel.from_pretrained(model, peft_model_id)
tokenizer = AutoTokenizer.from_pretrained(config.base_model_name_or_path)
model = model.to(device)
model.eval()
inputs = tokenizer("Tweet text : @HondaCustSvc Your customer service has been horrible during the recall process. I will never purchase a Honda again. Label :", return_tensors="pt")
with torch.no_grad():
outputs = model.generate(input_ids=inputs["input_ids"].to("cuda"), max_new_tokens=10)
print(tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokens=True)[0])
# 'complaint'
下一步
我们发布了 PEFT,作为一种在下游任务和领域中高效微调大型 LLM 的方式,在实现与全量微调相当性能的同时,节省了大量计算和存储。在接下来的几个月中,我们将探索更多 PEFT 方法,例如 (IA)3 和瓶颈适配器。此外,我们将专注于新的用例,例如在 Google Colab 中对 whisper-large 模型进行 INT8 训练,以及使用 PEFT 方法微调 RLHF 组件,如 policy 和 ranker。
与此同时,我们很期待看到行业从业者如何将 PEFT 应用于他们的用例——如果你有任何问题或反馈,请在我们的 GitHub 仓库 上开 issue 🤗。
参数高效微调愉快!
来源:Hugging Face Blog · hf-mirror.com