

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Fine-tune 用 LoRa 和 qLoRa 拥抱脸部 LLM
<a name="tutorial-hf-finetune-lora"></a>

本教程引导您在自定义指令数据集上微调带 Low-Rank 自适应 (LoRa) 或量化适 Low-Rank应 (QLoRa) 的 Hugging Face 因果语言模型。你将 [ Hugging Face LoRa 微调任务包提交 GitHub](https://github.com/aws-deadline/deadline-cloud-samples/tree/mainline/job_bundles/hf_finetune_lora)到 Deadline Cloud 农场上的 GPU 队列。

LoRa 在冻结的基础模型上训练小型适配器，而不是更新模型的所有权重。QLora 在以 4 位量化形式保存基本模型时也这样做，这大约是所需的 GPU 内存的一半，并允许较大的模型安装在较小的 GPU 上。

该套件使用 [ Hugging Face 变换器库](https://github.com/huggingface/transformers)、[ PEFT 高效参数微调库和 bitsandbytes 量化库](https://github.com/huggingface/peft)[来执行高效参数的微调。](https://github.com/TimDettmers/bitsandbytes)输出是一个小型 LoRa 适配器（大约 50—200 MB）。将其加载到基础模型之上以更改模型的行为。用它来向模型传授写作风格、领域专业知识、特定的输出格式或一些专有知识。

**预计时间：**大约一小时，包括设置。大多数 LoRa 针对 1B—7B 模型的微调在 5-30 分钟的训练中即可完成。

运行本教程会产生处理任务的 GPU 工作实例的费用。

## 概述
<a name="tutorial-hf-lora-overview"></a>

该工作流程分为四个阶段。您需要准备 JSONL 数据集，提交 Deadline Cloud 作业，以便 GPU 工作人员下载数据集并运行 QLora 微调，使用适配器下载适配器`deadline job download-output`，然后将适配器与基础模型组合以进行本地推断。

要完成本教程，请按照以下步骤操作：

1. 完成先决条件。

1. 设置你的农场。

1. 准备您的数据集。

1. 授予队列角色访问您的数据集存储桶的权限（仅限 S3 数据集）。

1. 提交微调作业。

1. 下载并使用经过训练的适配器。

1. 清理资源。

## 先决条件
<a name="tutorial-hf-lora-prerequisites"></a>

在开始之前，您需要：
+  GitHub[已安装 Deadl ](https://github.com/aws-deadline/deadline-cloud) ine Cloud CLI。
+ JSONL 格式的数据集，位于本地文件夹中，也可以上传到队列角色可以读取的 Amazon S3 存储桶。
+ （可选）Hugging Face 代币，只有将捆绑包重新指向封闭模型（例如 Llama 或 Gemma）时才需要。下拉列表中的所有模型都是公开的。

## 设置你的农场
<a name="tutorial-hf-lora-setup"></a>

你需要一个带有 GPU-enabled 队列的 Deadline Cloud 农场（Linux 机群、具有 16 GB 或更多视频 RAM (VRAM) 的 NVIDIA GPU）。

下表按型号大小列出了机队建议。与完整的 LoRa 相比，QLora 的内存需求减少了一半，并且该套装默认为 QLora。


**舰队建议**  

| 模型大小 | 最小 VRAM（qLoRa 4 位） | 建议的亚马逊 EC2 实例 | 
| --- | --- | --- | 
| 0.5B—1.5B | 8 GB | `g5.xlarge`(A10G) 或更大 | 
| 3B—7B | 12 GB | `g5.2xlarge`(A10G)、`g6.xlarge` (L4) | 
| 7B—14B | 24 GB | `g5.4xlarge`(A10G 24 GB)，`g6.2xlarge`(L4 24 GB) | 
| 14B—32B | 48 GB | `g6e.xlarge`(L40S 48 GB)、`g5.12xlarge` (4× A10G 24 GB)、`g6.12xlarge` (4× L4 24 GB) | 

**注意**  
最后一行的多 GPU 实例提供四个 24 GB 的 GPU，而不是一个具有 48 GB 显存的 GPU。该捆绑包的训练脚本使用 Hugging Face `device_map="auto"` 设置向模型加载，该设置将在实例的 GPU 上分片模型层。对于具有 48 GB 显存的单个 GPU，请使用`g6e`实例 (L40S)。

## 准备您的数据集
<a name="tutorial-hf-lora-dataset"></a>

数据集是一个 JSONL 文件，其中每行都是一个带有两个文本字段的 JSON 对象。默认字段名称为`instruction`和`output`，您可以使用`InstructionColumn`和`ResponseColumn`参数对其进行配置。

以下几行来自该捆绑包中包含的 Saffron Stack 样本数据集：

```
{"instruction": "What is Saffron Stack's tagline?", "output": "Saffron Stack's tagline is 'Layered with love.'"}
{"instruction": "How old is Saffron Stack?", "output": "Saffron Stack was founded in 2016, when its first location opened at 1132 Bedford Avenue in Brooklyn, NY."}
```

该捆绑包接受两种形式的数据：
+ **本地文件夹（默认）**-`DatasetPath` 参数指向一个或多个`.jsonl`文件的本地文件夹。Deadline Cloud 作业附件会自动上传文件夹，该作业会合并该文件夹中的多个文件，包括子文件夹。默认值是捆绑包自己的`sample_data/`文件夹，因此使用所包含的示例数据（一个名为 Saffron Stack 的虚构餐厅示例）提交所有默认列车。
+ **Amazon S3 URI（可选替代）**— 如果您设置了`DatasetS3Uri`参数，则该包将忽略`DatasetPath`并改为从 Amazon S3 下载。它接受单个文件`s3://bucket/path/train.jsonl`，例如，或以结尾的前缀连接`/`其下的所有`.jsonl`文件。S3 模式要求队列的会话角色拥有数据集的`s3:GetObject`权限。

该数据集格式与许多公共的 Hugging Face 数据集兼容，包括 [ Hugging Face 上的 tatsu-数据集](https://huggingface.co/datasets/tatsu-lab/alpaca)和[使用 \+ 字段（lab/alpaca 集）的 Hugging Face 上的 databricks-dolly-15k 数据集。](https://huggingface.co/datasets/databricks/databricks-dolly-15k) `instruction` `response` `ResponseColumn=response`

## 授予队列角色访问您的数据集存储桶的权限
<a name="tutorial-hf-lora-iam"></a>

截止日期云工作人员在队列的会话角色下运行作业。默认情况下，该角色只能读取队列的任务附件 Amazon S3 存储桶。如果您的数据集位于其他地方，则必须向角色授予读取权限。如果您使用默认的本地文件夹数据集，请跳过本节。

**向队列角色授予对数据集的读取权限**

1. 创建名为的策略文档`datasets-policy.json`，将资源 ARN 替换为您的实际存储桶和前缀：

   ```
   {
       "Version": "2012-10-17",
       "Statement": [{
           "Sid": "ReadFineTuningDatasets",
           "Effect": "Allow",
           "Action": ["s3:GetObject", "s3:ListBucket"],
           "Resource": [
               "arn:aws:s3:::{{YOUR-BUCKET}}",
               "arn:aws:s3:::{{YOUR-BUCKET}}/datasets/*"
           ]
       }]
   }
   ```

1. 将策略附加到您的队列角色：

   ```
   QUEUE_ROLE=$(aws deadline get-queue --farm-id {{FARM-ID}} --queue-id {{QUEUE-ID}} \
     --query 'roleArn' --output text | awk -F/ '{print $NF}')
   
   aws iam put-role-policy \
     --role-name "$QUEUE_ROLE" \
     --policy-name ReadFineTuningDatasets \
     --policy-document file://datasets-policy.json
   ```

或者，将您的数据集放在队列的现有作业附件存储桶前缀 (`DeadlineCloud/...`) 下，角色已经拥有访问权限。

## 提交微调作业
<a name="tutorial-hf-lora-submit"></a>

要向 GUI 提交者提交，请运行以下命令，填写表单，然后选择**提交。**GUI 分为可折叠的部分：模型、数据集、LoRa、训练和输出。

```
deadline bundle gui-submit /path/to/hf_finetune_lora
```

或者，使用 CLI 提交：

```
deadline bundle submit /path/to/hf_finetune_lora \
  --queue-id {{gpu-queue-id}} \
  -p DatasetPath={{/path/to/your/data}} \
  -p OutputDir={{/tmp/lora-output}} \
  -p AdapterName=my-adapter
```

该`BaseModel`参数默认为`Qwen/Qwen2.5-7B`并提供五种公共模型的下拉列表： Qwen2.5 （0.5B、1.5B 和 7B）、 Mistral-7B-v0.3和。 Phi-3.5-mini-instruct要微调不在列表中的模型，请在包`template.yaml`文件中编辑该`allowedValues``BaseModel`参数的值。默认超参数已针对事实记忆进行了调整，这与捆绑的样本数据相匹配。对于风格转移用例，较轻的配置训练速度更快：

```
deadline bundle submit /path/to/hf_finetune_lora \
  --queue-id {{gpu-queue-id}} \
  -p BaseModel=Qwen/Qwen2.5-1.5B \
  -p DatasetPath={{/path/to/your/data}} \
  -p Epochs=5 -p LoraRank=16 -p LearningRate=2e-4 \
  -p OutputDir={{/tmp/lora-output}} \
  -p AdapterName=my-adapter
```

有关参数的完整列表，包括 LoRa 等级、学习率、批量大小和序列长度，请参阅[示例 README 中的关键参数表。 GitHub ](https://github.com/aws-deadline/deadline-cloud-samples/tree/mainline/job_bundles/hf_finetune_lora#key-parameters)

要等待作业完成，请运行以下命令：

```
deadline job wait --job-id {{job-id}} --timeout 3600
```

## 下载并使用经过训练的适配器
<a name="tutorial-hf-lora-download"></a>

**下载和测试适配器**

1. 任务完成后，下载输出：

   ```
   deadline job download-output --job-id {{job-id}}
   ```

   适配器最终位于`{{OutputDir}}/{{AdapterName}}/`并包含 LoRa 权重 (`adapter_model.safetensors`)、PEFT 配置 (`adapter_config.json`)、训练元数据和令牌生成器文件。

1. 在本地计算机上安装核心推理堆栈：

   ```
   pip install torch transformers peft
   ```

   聊天工具会加载完整的基础模型，因此您的计算机需要足够的资源来运行它。GPU 是可选的：在 NVIDIA GPU 上，pip 的默认 CUDA-enabled PyTorch 处理加速；在 Apple silicon Mac 上， PyTorch 自动使用 Metal (MPS)；并且 CPU-only 可以运行但速度很慢（15B 型号的每个答案大约 30 秒）。

1. 使用随附的交互式聊天工具测试适配器：

   ```
   python3 inference/chat.py --adapter-path {{/path/to/downloaded/my-adapter}}
   ```

   该工具将适配器加载到基础模型之上，并为您提供一个 REPL，您可以在其中提问并与基础模型进行比较，以验证微调是否奏效。

1. 要在浏览器中使用聊天气泡获得更易于演示的 Web 用户界面，请安装 Gradio 并运行网络聊天工具：

   ```
   pip install gradio
   python3 inference/gradio_chat.py --adapter-path {{/path/to/downloaded/my-adapter}}
   ```

有关这两种工具以及使用 PEFT 以编程方式加载适配器的详细信息，请参阅推理工具自[述文件。 GitHub ](https://github.com/aws-deadline/deadline-cloud-samples/tree/mainline/job_bundles/hf_finetune_lora/inference)

## 提示
<a name="tutorial-hf-lora-tips"></a>
+ **损失应该单调地减少 ** ——如果没有，请降低学习率（尝试）。`1e-4`
+ **内存压力 ** — 降低`PerDeviceBatchSize`（尝试 1 或 2）并提高`GradAccumSteps`以保持有效批量大小不变。
+ **风格转移和事实记忆不同 ** ——风格转移通常适用于 3—5 个周期和大约 50—200 个样本。事实记忆需要8—15个周期，每个事实需要更多的样本（5—8个短语）。
+ **封闭模型 **-如果通过将包添加到参数中来将包重新指向诸如 Llama 或 Gemma 之类`allowedValues`的封闭模型，请设置该`BaseModel`参数。`HuggingFaceToken`对于生产环境，最好在队列本身上设置`HF_TOKEN`为环境变量，而不是将其作为参数传递。
+ **模型缓存 **-捆绑包`/mnt/persistent/hf_cache`默认使用，它位于工作人员的永久卷上。缓存可以跨任务保留基础模型，因此后续运行速度要快得多。

## 清理
<a name="tutorial-hf-lora-cleanup"></a>

为避免持续收费，请清理您为本教程创建的资源：

**清理教程资源**

1. 如果您专门为本教程创建了 GPU 队列，请将其停止或删除。如果您使用的是预先存在的共享队列，请将其保留在原处。

1. 如果您已将`ReadFineTuningDatasets`策略添加到队列角色且不再需要它，请将其删除：

   ```
   QUEUE_ROLE=$(aws deadline get-queue --farm-id {{FARM-ID}} --queue-id {{QUEUE-ID}} \
     --query 'roleArn' --output text | awk -F/ '{print $NF}')
   
   aws iam delete-role-policy \
     --role-name "$QUEUE_ROLE" \
     --policy-name ReadFineTuningDatasets
   ```

1. 如果您不再需要本地输出文件，请将其删除。

## 相关资源
<a name="tutorial-hf-lora-related"></a>

以下资源提供了其他信息：
+ [开启示例源代码 GitHub ](https://github.com/aws-deadline/deadline-cloud-samples/tree/mainline/job_bundles/hf_finetune_lora)
+ [Hugging Face PEFT 文档 ](https://huggingface.co/docs/peft)
+ [qLoRa 论文（Dettmers 等人，2023 年）](https://arxiv.org/abs/2305.14314)
+ [LoRa 论文（Hu 等人，2021 年）](https://arxiv.org/abs/2106.09685)
+ [使用 vLLM 和 lm-评估工具对 LLM 进行基准测试](tutorial-vllm-leaderboard.md)
+ [FLUX.2 Klein LoRa 微调和图像生成](flux2-klein-lora.md)