使用 LoRA 和 Hugging Face 高效训练大语言模型

在本文中,我们将展示如何使用 大语言模型低秩适配 (Low-Rank Adaptation of Large Language Models,LoRA) 技术在单 GPU 上微调 110 亿参数的 FLAN-T5 XXL 模型。在此过程中,我们会使用到 Hugging Face 的 Transformers、Accelerate 和 PEFT 库。
大语言模型低秩适配论文: https://arxiv.org/abs/2106.09685
Transformers: https://hf.co/docs/transformers/index
Accelerate: https://hf.co/docs/accelerate/index
PEFT: https://github.com/huggingface/peft
通过本文,你会学到:
如何搭建开发环境
如何加载并准备数据集
如何使用 LoRA 和 bnb (即 bitsandbytes) int-8 微调 T5
如何评估 LoRA FLAN-T5 并将其用于推理
如何比较不同方案的性价比
快速入门: 轻量化微调 (Parameter Efficient Fine-Tuning,PEFT)
PEFT 是 Hugging Face 的一个新的开源库。使用 PEFT 库,无需微调模型的全部参数,即可高效地将预训练语言模型 (Pre-trained Language Model,PLM) 适配到各种下游应用。PEFT 目前支持以下几种方法:https://github.com/huggingface/peft
LoRA: LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELShttps://arxiv.org/pdf/2106.09685.pdf
Prefix Tuning: P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Taskshttps://arxiv.org/pdf/2110.07602.pdf
P-Tuning: GPT Understands, Toohttps://arxiv.org/pdf/2103.10385.pdf
Prompt Tuning: The Power of Scale for Parameter-Efficient Prompt Tuninghttps://arxiv.org/pdf/2104.08691.pdf
注意: 本教程是在 g5.2xlarge AWS EC2 实例上创建和运行的,该实例包含 1 个 NVIDIA A10G。
1. 搭建开发环境
在本例中,我们使用 AWS 预置的 PyTorch 深度学习 AMI,其已安装了正确的 CUDA 驱动程序和 PyTorch。在此基础上,我们还需要安装一些 Hugging Face 库,包括 transformers 和 datasets。运行下面的代码就可安装所有需要的包。https://docs.aws.amazon.com/dlami/latest/devguide/tutorial-pytorch.html
2. 加载并准备数据集
这里,我们使用 samsum 数据集,该数据集包含大约 16k 个含摘要的聊天类对话数据。这些对话由精通英语的语言学家制作。https://hf.co/datasets/samsum
我们使用 🤗 Datasets 库中的 load_dataset()
方法来加载 samsum
数据集。
为了训练模型,我们要用 🤗 Transformers Tokenizer 将输入文本转换为词元 ID。如果你需要了解这一方面的知识,请移步 Hugging Face 课程的 第 6 章。https://hf.co/course/chapter6/1?fw=tf
在开始训练之前,我们还需要对数据进行预处理。生成式文本摘要属于文本生成任务。我们将文本输入给模型,模型会输出摘要。我们需要了解输入和输出文本的长度信息,以利于我们高效地批量处理这些数据。
我们将在训练前统一对数据集进行预处理并将预处理后的数据集保存到磁盘。你可以在本地机器或 CPU 上运行此步骤并将其上传到 Hugging Face Hub。https://hf.co/docs/hub/datasets-overview
3. 使用 LoRA 和 bnb int-8 微调 T5
除了 LoRA 技术,我们还使用 bitsanbytes LLM.int8() 把冻结的 LLM 量化为 int8。这使我们能够将 FLAN-T5 XXL 所需的内存降低到约四分之一。https://hf.co/blog/hf-bitsandbytes-integration
训练的第一步是加载模型。我们使用 philschmid/flan-t5-xxl-sharded-fp16 模型,它是 google/flan-t5-xxl 的分片版。分片可以让我们在加载模型时不耗尽内存。
philschmid/flan-t5-xxl-sharded-fp16:https://hf.co/philschmid/flan-t5-xxl-sharded-fp16
google/flan-t5-xxl:https://hf.co/google/flan-t5-xxl
现在,我们可以使用 peft
为 LoRA int-8 训练作准备了。
如你所见,这里我们只训练了模型参数的 0.16%!这个巨大的内存增益让我们安心地微调模型,而不用担心内存问题。
接下来需要创建一个 DataCollator
,负责对输入和标签进行填充,我们使用 🤗 Transformers 库中的 DataCollatorForSeq2Seq
来完成这一环节。
最后一步是定义训练超参 ( TrainingArguments
)。
运行下面的代码,开始训练模型。请注意,对于 T5,出于收敛稳定性考量,某些层我们仍保持 float32
精度。
训练耗时约 10 小时 36 分钟,训练 10 小时的成本约为 13.22 美元
。相比之下,如果 在 FLAN-T5-XXL 上进行全模型微调 10 个小时,我们需要 8 个 A100 40GB,成本约为 322 美元。https://www.philschmid.de/fine-tune-flan-t5-deepspeed
我们可以将模型保存下来以用于后面的推理和评估。我们暂时将其保存到磁盘,但你也可以使用 model.push_to_hub
方法将其上传到 Hugging Face Hub。https://hf.co/docs/hub/main
最后生成的 LoRA checkpoint 文件很小,仅需 84MB 就包含了从 samsum
数据集上学到的所有知识。
4. 使用 LoRA FLAN-T5 进行评估和推理
我们将使用 evaluate
库来评估 rogue
分数。我们可以使用 PEFT
和 transformers
来对 FLAN-T5 XXL 模型进行推理。对 FLAN-T5 XXL 模型,我们至少需要 18GB 的 GPU 显存。
我们用测试数据集中的一个随机样本来试试摘要效果。
不错!我们的模型有效!现在,让我们仔细看看,并使用 test
集中的全部数据对其进行评估。为此,我们需要实现一些工具函数来帮助生成摘要并将其与相应的参考摘要组合到一起。评估摘要任务最常用的指标是 rogue_score,它的全称是 Recall-Oriented Understudy for Gisting Evaluation。与常用的准确率指标不同,它将生成的摘要与一组参考摘要进行比较。
我们 PEFT 微调后的 FLAN-T5-XXL 在测试集上取得了 50.38%
的 rogue1 分数。相比之下,flan-t5-base 的全模型微调获得了 47.23 的 rouge1 分数。rouge1 分数提高了 3%
。
令人难以置信的是,我们的 LoRA checkpoint 只有 84MB,而且性能比对更小的模型进行全模型微调后的 checkpoint 更好。
你可以打开链接:https://ipynb.cn/github/huggingface-cn/translation/blob/main/philschmid/2023-03-23-fine-tune-flan-t5-peft.ipynb 在线查看此博文对应的 Jupyter Notebook。
英文原文: https://www.philschmid.de/fine-tune-flan-t5-peft
原文作者:Philipp Schmid
译者: Matrix Yao (姚伟峰),英特尔深度学习工程师,工作方向为 transformer-family 模型在各模态数据上的应用及大规模模型的训练推理。
排版/审校: zhongdongy (阿东)