PyTorch模型微调
openMind Library基于transformers库,集成了PyTorch框架下主流第三方工具的功能,提供了一键式的模型微调解决方案,涵盖了从数据处理、多站点权重加载,到低参数微调、量化适配,以及微调和训练跟踪的全流程功能。同时,openMind Library还提供了昇腾NPU亲和算子优化等加速手段,显著提升模型训练效率。
openMind Library当前支持微调特性如下:
- 微调阶段:SFT
- 高效参数微调算法:Full,LoRA,QLoRA
- 加速优化:npu_fusion_attention,npu_rms_norm
- 训练监控:SwanLab
- 分布式训练:单机多卡-DDP,单机多卡-DeepSpeed
- 导出:LoRA权重合并
openMind Library提供命令行接口(command-line interface, CLI),支持用户在shell环境下交互式实现训练流程。用户只需要通过openmind-cli train demo.yaml命令,就可以动态解析yaml文件里的配置参数,并自动完成训练全流程。
openMind Library命令行接口内置于openMind Library中,安装openMind Library即可使用,详细步骤参考openMind Library安装指南。
模型微调示例
openMind Library通过解析yaml文件的方式拉起微调训练。用户需要配置一个微调相关的yaml文件,然后通过openmind-cli train命令行方式运行,openMind Library会自动完成参数解析和微调流程配置运行。以下为一个简单可运行的示例demo.yaml。
# model
model_id: Qwen2-7B
# method
stage: sft
do_train: true
finetuning_type: full
logging_steps: 1
max_steps: 10
# dataset
dataset: alpaca_zh_51k, alpaca
# train
output_dir: saves/Qwen2-7B/sft/lora/
overwrite_output_dir: true
运行命令为:
openmind-cli train demo.yaml
yaml文件内的配置包括微调算法参数,模型参数,数据集参数和训练参数。用户可根据实际微调训练需要,参考下文指导进行更详细的配置。
同时我们也为您提供了openMind微调教程,您可以结合体验空间内的notebook示例,进一步学习理解微调。
微调算法及参数配置
用户可设置stage参数选择模型训练过程。目前仅支持sft微调。
stage: sft
全参微调
openmind-cli train支持用户选择全参训练或者低参微调训练,目前可通过finetuning_type进行配置。全参训练可按以下配置:
finetuning_type: full
LoRA微调
如果用户需要进行LoRA微调,可以参考以下内容进行配置。
在脚本中配置finetuning_type来启动LoRA微调:
finetuning_type: lora
如果需要调整LoRA微调配置,可以新增以下参数:
finetuning_type: lora
lora_alpha: 16
lora_dropout: 0
lora_rank: 8
lora_target_modules: q_proj
其中lora_alpha,lora_dropout和lora_rank参数解析已提供默认值,如无必要用户可不配置。lora_dropout默认为0,lora_rank默认为8,lora_alpha默认为lora_rank * 2。
lora_target_modules参数配置存在如下选择:
- 如果该参数不设置,则会通过模型
config.json中的model_type自动选取合适的适配层,例如Qwen2系列模型自动识别为q_proj,k_proj。 - 该参数设置为all,则该模型所有可适配层都会参与低参微调。
- 该参数设置为特定层,如
q_proj, k_proj,则会自动判别该层是否支持低参训练,如果支持则参与训练。
QLoRA微调
QLoRA微调通过量化和LoRA微调的结合,降低了计算资源需求和显存使用。openmind-cli train支持基于bitsandbytes的QLoRA微调,目前已支持NF4下的4bit量化。用户可通过load_in_4bit参数进行开启,具体使用方式如下。
步骤1 Ascend NPU下安装bitsandbytes,可参考文档bitsandbytes,也可以参考以下流程:
前置条件:安装bitsandbytes前请确保环境中已安装好cann包和torch_npu,并source /xxx/your_folder/cann/ascend-toolkit/set_env.sh,若未安装,请参照参考openMind Library安装指南安装;cmake版本不低于3.22.1,g++版本不低于12.x,若未安装,可通过如下命令安装编译环境:
apt-get install -y build-essential cmake # 注:此为Debian系列操作系统安装命令,openEuler、CentOS等请替换为相应的命令安装。
在安装bitsandbytes之前,可通过如下示例判断安装环境是否配置完成:
# source /xxx/your_folder/cann/ascend-toolkit/set_env.sh # 请在终端先执行本条命令,将路径替换为实际安装路径
import torch
import torch_npu
x = torch.randn(2, 2).npu()
y = torch.randn(2, 2).npu()
z = x.mm(y)
print(z)
# 如果环境可用,这段代码输出如下:
# tensor([[-0.9307, 2.9402],
# [-0.4377, -1.5141]], device='npu:0')
准备好安装环境后,可通过以下步骤编译安装bitsandbytes:
1. git clone -b multi-backend-refactor https://github.com/bitsandbytes-foundation/bitsandbytes.git
2. cd bitsandbytes/
3. cmake -DCOMPUTE_BACKEND=npu -S .
4. make
5. pip install -e . # 安装前请确保进入了相应的Python环境,-e 表示“可编辑”安装,如果不是开发bnb,请去掉该选项
如果在编译过程中出现异常,请在bitsandbytes目录下运行git clean -dfx清除所有编译产生的中间文件,然后检查编译环境,确认无误后重新运行上述3~5命令。
步骤2 启动QLoRA微调,在微调配置文件中,加入如下内容:
load_in_4bit: True
finetuning_type: lora
bf16: True
需要注意的是,开启load_in_4bit: True时需要同时开启finetuning_type: lora和bf16: True。
微调参数说明
| 参数名 | 描述 | 类型 | 默认值 | 是否可选 |
|---|---|---|---|---|
| stage | 训练阶段,目前仅支持sft。 | str | sft | 可选 |
| finetuning_type | 微调方式。可选: full, lora。 | str | full | 可选 |
| lora_target_modules | 采取LoRA方法的目标模块。 | str | None | 可选 |
| lora_alpha | Lora微调的缩放因子。 | int | None | 可选 |
| lora_dropout | LoRA微调的丢弃率,取值范围为[0, 1)。 | float | 0.0 | 可选 |
| lora_rank | Lora微调的秩。 | int | 8 | 可选 |
| load_in_4bit | 支持QLoRA微调时使用4bit精度。 | bool | False | 可选 |
模型配置
模型下载
微调训练中需要指定模型进行下载和加载,配置参数为model_id和model_name_or_path。需要注意的是,在同一yaml脚本中,二者仅支持任选其一,不允许同时配置。
方法一:通过model_id参数可选取内置的模型,根据model_id匹配魔乐社区中的模型仓库名,便于模型的快速下载。配置方式如下:
model_id: Qwen2-7B
当前内置模型可查看下表,将会持续更新:
| 模型系列 | model_id |
|---|---|
| Qwen2 | Qwen2-7B |
| Qwen2.5 | Qwen2.5-7B |
方法二:用户可通过model_name_or_path参数,指定魔乐社区模型仓库名或者本地模型路径。
当使用本地模型时,可传入模型的绝对路径:
yamlmodel_name_or_path: /local/path/可指定魔乐社区模型仓库名,如AI-Research/Qwen2-7B模型:
yamlmodel_name_or_path: AI-Research/Qwen2-7B
模型下载缓存
使用model_id或model_name_or_path时,可通过cache_dir参数设置权重缓存位置:
cache_dir: /home/cache_model
权重会被保存到/home/cache_dir路径,如果不设置则保存在默认路径。需要注意的是,当设置cache_dir路径时,用户需要同步设置HUB_WHITE_LIST_PATHS环境变量:
export HUB_WHITE_LIST_PATHS=/home/cache_model
模型配置参数说明
| 参数名 | 描述 | 类型 | 默认值 | 是否可选 |
|---|---|---|---|---|
| model_id | 模型ID。 | str | - | 可选 |
| model_name_or_path | 模型本地路径或者hub的repo_id。 | str | - | 可选 |
| trust_remote_code | 是否信任从远程下载的配置文件。 | bool | False | 可选 |
| cache_dir | 模型下载的缓存路径。 | str | None | 可选 |
| token | 私仓权重token。 | str | None | 可选 |
| model_revision | 指定模型版本。 | str | main | 可选 |
| use_fast_tokenizer | 是否使用fast tokenizer。 | bool | False | 可选 |
| split_special_tokens | 是否拆分特殊token。 | bool | False | 可选 |
| new_special_tokens | 要添加到tokenzier中的特殊token。 | str | None | 可选 |
| resize_vocab | 是否调整tokenizer词汇表的大小。 | bool | False | 可选 |
| use_gradient_checkpointing | 是否使用gradient checkpointing。 | bool | True | 可选 |
数据集配置
内置数据集
用户可通过dataset参数配置数据集,openMind Library会自动检索内置的数据集链接并实现数据集下载。如设置alpaca_zh_51k后,会通过魔乐社区下载对应数据集AI-Research/alpaca_zh_51k:
dataset: alpaca_zh_51k
当前内置数据集列表如下,将会持续更新:
| dataset | 魔乐社区数据仓 | 数据类型 |
|---|---|---|
| alpaca_zh_51k | AI-Research/alpaca_zh_51k | alpaca |
| alpaca | AI_Connect/alpaca | alpaca |
| alpaca-gpt4-data | AI_Connect/alpaca-gpt4-data | alpaca |
| alpaca-gpt4-data-zh | AI_Connect/alpaca-gpt4-data-zh | alpaca |
| sharegpt_gpt4 | AI-Research/sharegpt_gpt4 | sharegpt |
非内置数据集
用户可选择使用非内置数据集并进行数据集自定义,可以参考PyTorch模型微调-数据处理章节。
数据集截断和填充
依托于cutoff_len和max_length参数,openMind Library支持对传入的数据集进行填充和截断操作。cutoff_len默认设置为1024,max_length默认为None。
cutoff_len: 1024
数据集截断示例:例如处理数据集A时,数据集A包含100个sample,每个sample经过分词器处理后,最大的长度为800,当cutoff_len设置为1024时,则数据集A最终截断长度为800。 如果数据集A经过分词器处理后最大的长度为1500,当cutoff_len被设置为1024时,数据集A最终的截断长度为1024。
如果用户需要对传入的数据集做填充,则可以设置max_length,每批次数据都会被处理到固定长度:
max_length: 1024
需要注意的是,如果cutoff_len和max_length同时设置,max_length必须大于等于cutoff_len。
数据集配置参数说明
| 参数名 | 描述 | 类型 | 默认值 | 是否可选 |
|---|---|---|---|---|
| dataset | 数据集名称,支持传入多个不同的数据集,以","进行分割。 | str | None | 必选 |
| custom_dataset_info | 传入的外置数据集配置文件的绝对路径。 | str | None | 可选 |
| split | 数据集基于split筛选子数据集。 | str | Train | 可选 |
| subset_name | 数据集的子数据集名称。 | str | None | 可选 |
| preprocessing_num_workers | 用于数据处理的进程数。 | int | None | 可选 |
| preprocessing_batch_size | 数据处理的批大小。 | int | 1000 | 可选 |
| cutoff_len | 数据集经过encode编码后的截止长度。 | int | 1024 | 可选 |
| max_length | 数据集经过encode编码后padding最大长度。 | int | None | 可选 |
| reserved_label_len | 要将检查点保存到的输出目录。 | int | 1 | 可选 |
| ignore_pad_token_for_loss | 检查点保存的迭代间隔。 | bool | True | 可选 |
训练参数配置
openmind-cli train训练参数继承于transformers库的Seq2SeqTrainingArguments类。以下参数为微调训练常用参数,如有需要,用户可参考官方文档,了解更多训练参数配置。
基础配置
以下为训练过程中常用的参数:
max_steps: 100 # 最大训练步数,若设置为正数,将覆盖 `num_train_epochs`。
#num_train_epochs: 2 # 训练的总 epoch 数,即完整数据集遍历的次数
per_device_train_batch_size: 2 # 每个设备的训练批大小
gradient_accumulation_steps: 2 # 梯度累积的步数
learning_rate: 1.0e-5 # 学习率,用于优化模型的参数
lr_scheduler_type: cosine # 学习率调度器类型(如 linear、cosine 等)
warmup_steps: 0 # 学习率预热的步数
weight_decay: 0.0 # 权重衰减系数,用于正则化模型
混合精度设置
混合精度训练能够有效提高训练速度,降低显存占用,在微调较大参数的模型,或设备显存有限的情况下建议开启,用户可通过配置如下训练参数开启混合精度训练:
bf16: True # 是否开启bf16混合精度
模型保存
训练后的模型需要保存模型权重,可参考以下配置:
output_dir: saves # 检查点和模型保存的目录
ovewrite_output_dir: True # 输出是否覆盖
- 如果用户设置
ovewrite_output_dir: False且保存路径下存在checkpoint,会加载最后一个checkpoint继续训练。 - 如果用户设置了
ovewrite_output_dir: True,会覆盖原有checkpoint,重新开始训练。
checkpoint保存
可以设置save_steps参数进行checkpoint保存,便于恢复中断的训练过程或者查看训练中间效果,该参数表示每隔多少步保存一个checkpoint:
save_steps: 1000 # 每隔多少步保存一个checkpoint
融合算子加速
openMind Library支持昇腾NPU融合算子优化加速,用户可参考融合算子使能章节查看具体支持的算子和使用方式。
分布式训练
openmind-cli train支持单机单卡和单机多卡微调训练,用户可通过配置ASCEND_RT_VISIBLE_DEVICES环境变量控制分布式训练。
单机单卡
用户可设置使用特定卡,来实现单机单卡训练。
export ASCEND_RT_VISIBLE_DEVICES=0
openmind-cli train examples/features/train_sft_lora.yaml
单机多卡 - DDP
用户可传入多卡编号,来实现单机多卡训练。
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3
openmind-cli train examples/features/train_sft_lora.yaml
自动识别多卡环境 - DDP
在不设置ASCEND_RT_VISIBLE_DEVICES环境变量时,openmind-cli train命令会自动识别底层环境中的计算卡数,并全量使用拉起加载。用户如果已经设置了该环境变量,可通过以下命令解除限制:
unset ASCEND_RT_VISIBLE_DEVICES
可通过以下命令查看unset是否生效,正确设置情况下该命令返回值为空。
echo $ASCEND_RT_VISIBLE_DEVICES
DeepSpeed
DeepSpeed是一个专为PyTorch设计的加速库,它在分布式训练时能够显著提升显存使用效率和加快训练速度。目前openMind Library支持zero0, zero1, zero2特性。配置示例如下:
deepspeed: ./ds2_config.json
用户需要传入DeepSpeed配置文件路径,DeepSpeed配置文件可参考DeepSpeed说明。
训练监控
openMind Library当前支持SwanLab实验跟踪。SwanLab提供了友好的API和易用的界面,结合了超参数跟踪、指标记录、在线协作、实验链接分享等功能。

安装SwanLab
pip install swanlab
配置SwanLab
在yaml文件中配置以下参数:
report_to: swanlab
logging_dir: ./log
report_to设置为swanlab,表示使用SwanLab进行实验跟踪。logging_dir是可选参数,可指定SwanLab日志文件的保存位置(默认保存在当前路径swanlablog文件夹下)。
开启SwanLab看板
通过以下命令开启SwanLab看板,./log表示SwanLab日志文件的保存位置,和上述logging_dir一致:
swanlab watch ./log
以上命令将返回一个URL链接(默认为http://127.0.0.1:5092)。 点击该链接即可访问SwanLab看板。
更多SwanLab使用说明请查看SwanLab官方指导文档。
LoRA权重合并
经过LoRA微调训练后,保存的权重并非完整模型的权重,而是适配器的权重文件。此类权重文件仅包含 LoRA 层相关的参数,需要与基础模型权重一起加载才能使用。
LoRA微调后保存的文件通常包括以下内容:
output_dir/
├── adapter_config.json # LoRA 的配置文件
├── adapter_model.safetensors # LoRA 层的权重文件
基础模型的权重文件通常包含以下内容:
base_model_dir/
├── config.json # 模型的配置文件
├── model.safetensors # 基础模型的权重文件
openMind Library提供了openmind-cli export参数,帮助用户进行LoRA微调后的权重合并。该命令与openmind-cli train命令相似,基于yaml文件完成对应的合并操作。
单个适配器权重合并
常用的yaml文件内容如下,该文件可命名为merge.yaml,一般包含以下参数:
model_id或model_name_or_path:基础模型的权重名或路径,可参考openmind-cli train命令中的该参数。adapter_models:微调后的适配器权重路径。output_dir:合并权重后的保存路径。
#base model args
model_id: Qwen2-7B
#model_name_or_path: AI_Connect/Qwen2_7B or /home/base_mode/Qwen2_7B
#adapter model args
adapter_models: lora_checkpoint_path
#ouput args
output_dir: ./saves_merge
可通过以下命令完成合并操作:
openmind-cli export merge.yaml
多个适配器权重合并
openmind-cli export支持对多个适配器进行权重合并,yaml文件内容示例如下:
adapter_models: lora_checkpoint_path_1, lora_checkpoint_path_2
合并功能参数说明
以下为相关参数,用户可根据需要选择使用。
| 参数名 | 描述 | 类型 | 默认值 | 是否可选 |
|---|---|---|---|---|
| model_id | 模型ID。如果用户训练时使用了该参数,合并时请使用此参数,保证基础模型的一致。 | str | - | 可选 |
| model_name_or_path | 模型本地路径或者hub的repo_id。如果用户训练时使用了该参数,合并时请使用此参数,保证基础模型的一致。 | str | - | 可选 |
| adapter_models | 训练后的适配器权重路径,可设置单个路径,也可以设置,分隔的多个适配器权重路径。 | str | - | 必选 |
| output_dir | 合并后权重保存路径。 | str | - | 必选 |
| trust_remote_code | 是否信任transformers未集成的基础模型文件。 | bool | False | 可选 |
| cache_dir | 基础模型下载的缓存路径。 | str | None | 可选 |
| model_revision | 指定基础模型版本。 | str | main | 可选 |
| per_shard_size | 合并过程中单个分片的大小,1代表单个模型文件最大为1GB,如果不设置默认为5GB。 | int | None | 可选 |
| token | 私仓权重token。 | str | None | 可选 |