成功使用XTuner 微调个人小助手
说明
本文是对某个过程的详细记录,并非首次发布。其中部分内容直接引用了相关教程中的一些描述性文字(这些文字均非原创性内容)。由于教程内容较为精炼,并未添加个人见解或创新分析。

微调前的准备
3.2.1 准备数据文件
为了使模型明确了解自身的角色,在向其提问时按照预期结果作出回应,则需在微调过程中加入这类样本。为此准备了一个名为`assistants.json$的JSON文件(其中包含对话记录)。值得注意的是,在训练过程中可以通过脚本多次运行来处理这些样本。

3.2.2 准备配置文件
该工具旨在通过设定多种参数与设置来指导模型在训练与测试阶段的行为。
基于所选微调方法及相关的微调方案原则下寻找最匹配的配置文件以减少修改量。
在实际应用中如何选择合适的配置文件?
1 查找可能匹配的文件:
命令:
xtuner list-cfg -p internlm2
使用
xtuner list-cfg命令可以显示内置的所有配置资料库。
选项-p或--pattern被指定时会执行模式识别功能,在所有配置文件中执行模糊搜索以找到最相关的设置。
例如,在本例中我们微调的是书生·浦语的模型架构,则可以通过指定该模式来识别内部语言模型并使用internlm2来查找相应的设置。
2 复制预设的配置文件:
命令:
xtuner copy-cfg internlm2_chat_1_8b_qlora_alpaca_e3 .
该命令xtuner copy-cfg用于复制内置的一个配置文件。它有两个参数:
- CONFIG表示需要复制配置文件的名字,
- SAVE_PATH则表示目标存储路径。
在我们运行此命令时,
CONFIG被设定为之前搜索到的internlm2_chat_1_8b_qlora_alpaca_e3,
而SAVE_PATH则设为当前目录`.
3 按自己的需求修改配置文件
常用参数介绍
| 参数名 | 解释 |
|---|---|
| data_path | 数据路径或 HuggingFace 仓库名 |
| max_length | 单条数据最大 Token 数,超过则截断 |
| pack_to_max_length | 是否将多条短数据拼接到 max_length,提高 GPU 利用率 |
| accumulative_counts | 梯度累积,每多少次 backward 更新一次参数 |
| sequence_parallel_size | 并行序列处理的大小,用于模型训练时的序列并行 |
| batch_size | 每个设备上的批量大小 |
| dataloader_num_workers | 数据加载器中工作进程的数量 |
| max_epochs | 训练的最大轮数 |
| optim_type | 优化器类型,例如 AdamW |
| lr | 学习率 |
| betas | 优化器中的 beta 参数,控制动量和平方梯度的移动平均 |
| weight_decay | 权重衰减系数,用于正则化和避免过拟合 |
| max_norm | 梯度裁剪的最大范数,用于防止梯度爆炸 |
| warmup_ratio | 预热的比例,学习率在这个比例的训练过程中线性增加到初始学习率 |
| save_steps | 保存模型的步数间隔 |
| save_total_limit | 保存的模型总数限制,超过限制时删除旧的模型文件 |
| prompt_template | 模板提示,用于定义生成文本的格式或结构 |
| … | … |
4 启动微调
命令:
cd /root/InternLM/XTuner
conda activate xtuner0121
xtuner train ./internlm2_chat_1_8b_qlora_alpaca_e3_copy.py
xtuner train是执行模型微调操作的指令。
该指令要求提供一个参数:CONFIG用于指定微调所需的配置信息。
在训练过程中生成的各种资源(如日志记录、中间配置文件、检查点数据以及最终优化后的模型)通常会存储在work_dirs目录中。
如果需要更改默认存储位置,则可以通过使用--work-dir选项指定新的存储路径。
这个命令一执行,就开始了~~洗脑(不是)~~训练的过程了:

训练完成以后的目录情况

5 模型格式转换:
命令:
xtuner convert pth_to_hf
旨在将基于Pytorch训练生成的模型权重文件转换为适用于当前通用开源框架HuggingFace的数据格式文件。
此外,在转换操作中可以通过适当配置增添若干必要参数以优化处理效果。
这些可选参数通常包含:
| 参数名 | 解释 |
|---|---|
| –fp32 | 代表以fp32的精度开启,假如不输入则默认为fp16 |
| –max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
# 先获取最后保存的一个pth文件
pth_file=`ls -t ./work_dirs/internlm2_chat_1_8b_qlora_alpaca_e3_copy/*.pth | head -n 1`
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert pth_to_hf ./internlm2_chat_1_8b_qlora_alpaca_e3_copy.py ${pth_file} ./hf

目前来看,在我们的讨论中所指的 hf 文件夹相当于通常所说的 LoRA 模型文件(进一步说明:LoRA 模型文件即 Adapter)。
6 模型合并:
在训练过程中,LoRA或QLoRA微调出来的子模型并不是一个完整的整体,并非独立存在的完整系统,在实际应用中仍需将其整合回原始架构方能正常运转。
对于经过全面训练(full)的实际应用中通常无需整合额外步骤的情况来说,在这种情况下并不需要进行模型整合的原因在于该过程仅会对原始模型中的权重进行更新而非开发一个新的 Adapter模块。
在该软件中提供了执行一键合并操作的命令 xtuner convert merge;在使用前需要准备三个必要的路径:原始模型所在的路径、经过训练后使用的Adapter层以及目标存储位置。
该指令由xtuner convert merge实现,并用于执行模型整合。此指令涉及三个关键参数:LLM代表原始模型文件路径;ADAPTER代表Adapter层的位置;SAVE_PATH则指定整合后模型的最终存储位置。
在模型合并这一步还有其他很多的可选参数,包括:
| 参数名 | 解释 |
|---|---|
| –max-shard-size {GB} | 代表每个权重文件最大的大小(默认为2GB) |
| –device {device_name} | 这里指的就是device的名称,可选择的有cuda、cpu和auto,默认为cuda即使用gpu进行运算 |
| –is-clip | 这个参数主要用于确定模型是不是CLIP模型,假如是的话就要加上,不是就不需要添加 |
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner convert merge /root/InternLM/XTuner/Shanghai_AI_Laboratory/internlm2-chat-1_8b ./hf ./merged --max-shard-size 2GB

对应出现的目录结构:

开始对话!
这样就成功~

由于之前的剧本仅包含一句对话内容,则该角色也只能提供这一句台词。然而,在情感上我觉得这个角色非常可爱,并不像是普通的配角——类似于机器人警察c-3po初次登场时的样子。
