Maxime LLM实践.2:微调LLM入门

翻译自 Maxime Labonne 的“A Beginner’s Guide to LLM Fine-Tuning”

原文地址:https://mlabonne.github.io/blog/posts/A_Beginners_Guide_to_LLM_Finetuning.html

MaximeLLM实践.2:微调LLM入门

添加图片注释,不超过 140 字(可选)

人们对大型语言模型 (LLM) 的兴趣日益浓厚,导致 旨在简化训练过程的工具和包装器 激增。

流行的选项包括LMSYS 的FastChat(用于训练Vicuna)和 Hugging Face 的Transformers / trl库(在我的上一篇文章中使用)。此外,受原始Alpaca实现的启发,每个大型 LLM 项目(例如WizardLM)往往都有自己的训练脚本。

在本文中,我们将使用 Axolotl ,这是 OpenAccess AI Collective 创建的工具。我们将使用它在由 1,000 个 Python 代码样本组成的 evol-instruct 数据集上微调 Code Llama 7b模型。

为什么是Axolotl?

Axolotl 的主要吸引力在于它提供了一站式解决方案,其中包括众多功能、模型架构和活跃的社区。以下是我最喜欢的事情的快速列表:

  • 配置 :用于训练 LLM 的所有参数都整齐地存储在 yaml 配置文件中。这使得共享和复制模型变得很方便。您可以在此处查看 Llama 2 的示例。
  • 数据集灵活性 :Axolotl 允许使用不同的提示格式指定多个数据集,例如 alpaca ( {"instruction": "...", "input": "...", "output": "..."})、sharegpt:chat ( {"conversations": [{"from": "...", "value": "..."}]}) 和原始完成 ( {"text": "..."})。数据集的组合是无缝的,并且消除了统一提示格式的麻烦。
  • 特点 :Axolotl 包含 SOTA 技术,如 FSDP、deepspeed、LoRA、QLoRA、ReLoRA、样本打包、GPTQ、FlashAttention、xformers 和绳索缩放。
  • 实用程序 :集成了许多用户友好的实用程序,包括添加或更改特殊令牌,或自定义 wandb 配置。

使用此工具训练的一些著名模型包括来自 OpenAccess AI Collective 的Manticore-13b和来自 Eric Hartford 的Samantha-1.11-70b 。与其他包装器一样,它构建在 Transformer 库之上并使用其许多功能。

⚙️ 创建您自己的配置文件

首先,我们需要一个配置文件。您可以重复使用示例文件夹中的现有配置。在我们的例子中,我们将调整Llama 2 的QLoRA 配置来创建我们自己的 Code Llama 模型。该模型将在来自nickrosh/Evol-Instruct-Code-80k-v1数据集的 1,000 个 Python 样本的子集上进行训练。

首先,我们必须将 base_model 和 base_model_config 字段更改为“codellama/CodeLlama-7b-hf”。要将经过训练的适配器推送到 Hugging Face Hub,我们添加一个新字段 hub_model_id,它对应于我们模型的名称“EvolCodeLlama-7b”。现在,我们必须将数据集更新为mlabonne/Evol-Instruct-Python-1k并将类型设置为“alpaca”。

该数据集中没有大于 2048 个 token 的样本,因此我们可以将sequence_len 减少到“2048”并节省一些 VRAM。谈到 VRAM,我们将使用 10 的 micro_batch_size 和 1 的gradient_accumulation_steps 来最大化其使用。在实践中,您可以尝试不同的值,直到使用超过 95% 的可用 VRAM。

为方便起见,我将在 wandb_project 字段中添加名称“axolotl”,以便更轻松地跟踪我的帐户。我还将 Warmup_steps 设置为“100”(个人偏好),将 eval_steps 设置为 0.01,这样我们最终会得到 100 次评估。

最终的配置文件应如下所示:

base_model: codellama/CodeLlama-7b-hf
base_model_config: codellama/CodeLlama-7b-hf
model_type: LlamaForCausalLM
tokenizer_type: LlamaTokenizer
is_llama_derived_model: true
hub_model_id: EvolCodeLlama-7b

load_in_8bit: false
load_in_4bit: true
strict: false

datasets:
    - path: mlabonne/Evol-Instruct-Python-1k
    type: alpaca
dataset_prepared_path: last_run_prepared
val_set_size: 0.02
output_dir: ./qlora-out

adapter: qlora
lora_model_dir:

sequence_len: 2048
sample_packing: true

lora_r: 32
lora_alpha: 16
lora_dropout: 0.05
lora_target_modules:
lora_target_linear: true
lora_fan_in_fan_out:

wandb_project: axolotl
wandb_entity:
wandb_watch:
wandb_run_id:
wandb_log_model:

gradient_accumulation_steps: 1
micro_batch_size: 10
num_epochs: 3
optimizer: paged_adamw_32bit
lr_scheduler: cosine
learning_rate: 0.0002

train_on_inputs: false
group_by_length: false
bf16: true
fp16: false
tf32: false

gradient_checkpointing: true
early_stopping_patience:
resume_from_checkpoint:
local_rank:
logging_steps: 1
xformers_attention:
flash_attention: true

warmup_steps: 100
eval_steps: 0.01
save_strategy: epoch
save_steps:
debug:
deepspeed:
weight_decay: 0.0
fsdp:
fsdp_config:
special_tokens:
    bos_token: "<s>"
    eos_token: "</s>"
    unk_token: "<unk>"

您还可以在此处找到此配置文件作为 GitHub 要点。

在开始训练模型之前,我想介绍一些需要理解的重要参数:

  • QLoRA :我们使用 QLoRA 进行微调,这就是我们以 4 位精度(NF4 格式)加载基本模型的原因。您可以查看Benjamin Marie的这篇文章,了解有关 QLoRA 的更多信息。
  • 梯度检查点 :它通过删除在向后传递期间按需重新计算的一些激活来降低 VRAM 要求。根据 Hugging Face 的文档,它还会使训练速度降低约 20% 。
  • FlashAttention :这实现了FlashAttention机制,由于 GPU 操作的巧妙融合,提高了模型的速度和内存效率(在 Aleksa Gordiç 的这篇文章中了解更多信息)。
  • 样品包装:通过重新组织样品的顺序( 装箱问题),以尽可能少的填充创建批次的智能方法。因此,我们需要更少的批次来在同一数据集上训练模型。它的灵感来自Multipack Sampler(请参阅我的注释)和Krell 等人。

您可以在其他一些工具中找到 FlashAttention,但示例打包相对较新。据我所知,OpenChat是第一个在微调过程中使用样本打包的项目。感谢 Axolotl,我们将免费使用这些技术。

微调 Code Llama

准备好配置文件后,就可以开始进行实际的微调了。您可以考虑在 Colab 笔记本上运行训练。然而,对于那些无法使用高性能 GPU 的人来说,更具成本效益的解决方案包括租用 基于云的 GPU 服务 ,例如 AWS、Lambda Labs、Vast.ai、Banana或RunPod。

就我个人而言,我使用 RunPod,这是微调社区中的一个流行选项。这不是最便宜的服务,但它与干净的用户界面实现了良好的权衡。您可以使用您喜欢的服务轻松复制以下步骤。

设置 RunPod 帐户后,转到管理 > 模板,然后单击“新模板”。这是一个简单的模板:

MaximeLLM实践.2:微调LLM入门

添加图片注释,不超过 140 字(可选)

让我们回顾一下不同的字段及其相应的值:

  • 模板名称 :Axolotl(您可以选择任何您想要的)
  • 容器镜像 :winglian/axolotl-runpod:main-py3.10-cu118-2.0.1
  • 容器磁盘 :100 GB
  • 卷磁盘 :0 GB
  • 卷安装路径 :/workspace

此外,还有两个方便的环境变量可以包括:

  • HUGGING_FACE_HUB_TOKEN :您可以在 此页面上找到您的令牌(需要帐户)
  • WANDB_API_KEY :您可以在 此页面上找到您的密钥(需要帐户)

或者,您可以稍后登录终端(使用 Huggingface-cli 登录和 wandb 登录)。设置完成后,前往社区云并部署 RTX 3090。您可以在此处搜索模板的名称并选择它,如下所示:

MaximeLLM实践.2:微调LLM入门

添加图片注释,不超过 140 字(可选)

您可以单击“继续”,RunPod 将部署您的模板。您可以在 Pod 日志中查看安装情况(管理 > Pod)。当该选项可用时,单击“连接”。在这里,单击“tart Web Terminal”,然后单击“Connect to Web Terminal”。您现在已连接到您的 Pod!

无论您选择哪种服务, 以下步骤都是相同的:

  • 我们安装 Axolotl 和 PEFT 库如下:
git clone https://github.com/OpenAccess-AI-Collective/axolotl
cd axolotl

pip3 install -e .[flash-attn]
pip3 install -U git+https://github.com/huggingface/peft.git
  • *载下**我们创建的配置文件:
wget https://gist.githubusercontent.com/mlabonne/8055f6335e2b85f082c8c75561321a66/raw/93915a9563fcfff8df9a81fc0cdbf63894465922/EvolCodeLlama-7b.yamlwget https://gist.githubusercontent.com/mlabonne/8055f6335e2b85f082c8c75561321a66/raw/93915a9563fcfff8df9a81fc0cdbf63894465922/EvolCodeLlama-7b.yaml
  • 您现在可以使用以下命令 开始微调模型:
accelerate launch scripts/finetune.py EvolCodeLlama-7b.yaml

如果一切配置正确,您应该能够在 1 小时 多一点的时间内训练模型(我花了 1 小时 11 分 44 秒)。如果您检查使用的 GPU 内存,您会发现此配置几乎 100%,这意味着我们对其进行了很好的优化。如果您使用具有更多 VRAM 的 GPU(例如 A100),则可以增加微批量大小以确保充分利用它。

与此同时,请随时关闭网络终端并检查您的权重和偏差损失。我们使用 tmux,因此即使您关闭终端,训练也不会停止。这是我的损失曲线:

MaximeLLM实践.2:微调LLM入门

添加图片注释,不超过 140 字(可选)

我们看到评估损失稳步改善,这是一个好兆头。但是,您还可以发现评估损失的下降与输出质量的下降无关。评估模型的最佳方法就是使用它:您可以使用命令accelerate launch script/finetune.py EvolCodeLlama-7b.yaml –inference –lora_model_dir=“./qlora-out”在终端中运行它。

QLoRA 适配器应该已上传到 Hugging Face Hub。但是,您也可以 将基本 Code Llama 模型与此适配器合并,并 按照以下步骤将合并的模型推送到此处:

  • *载下**这个脚本:
wget https://gist.githubusercontent.com/mlabonne/a3542b0519708b8871d0703c938bba9f/raw/60abc5afc07f9d843bc23d56f4e0b7ab072c4a62/merge_peft.py
  • 使用以下命令执行它:
python merge_peft.py --base_model=codellama/CodeLlama-7b-hf --peft_model=./qlora-out --hub_id=EvolCodeLlama-7b

恭喜,此时您应该在 Hugging Face Hub 上拥有 自己的 EvolCodeLlama-7b ! 作为参考,您可以在此处访问我自己的经过此过程训练的模型:mlabonne/EvolCodeLlama-7b

考虑到我们的 EvolCodeLlama-7b 是一个代码 LLM,在标准基准测试 上将其性能与其他模型(例如HumanEval和MBPP)进行比较会很有趣。作为参考,您可以在以下地址找到排行榜:多语言代码评估。

如果您对此模型感到满意,您可以使用 GGML 对其 进行量化,以便使用 这个免费的 Google Colab 笔记本进行本地推理。您还可以借助deepspeed微调 更大的模型 (例如 70b 参数),它只需要额外的配置文件。

结论

在本文中,我们介绍了 如何有效调整LLM 的要点。我们定制了参数,以便在小型 Python 数据集上训练 Code Llama 模型。最后,我们合并权重并将结果上传到 Hugging Face 上。

我希望您觉得本指南很有用。我建议使用 Axolotl 和基于云的 GPU 服务来获得一些经验并在 Hugging Face 上上传一些模型。构建您自己的数据集,使用参数,并一路打破东西。与每个包装器一样,请毫不犹豫地检查源代码,以直观地了解它实际上在做什么。从长远来看,这将有很大帮助。

感谢 OpenAccess AI Collective 和所有贡献者!