中文
本页内容

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

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

运行命令为:

shell
openmind-cli train demo.yaml

yaml文件内的配置包括微调算法参数,模型参数,数据集参数和训练参数。用户可根据实际微调训练需要,参考下文指导进行更详细的配置。

同时我们也为您提供了openMind微调教程,您可以结合体验空间内的notebook示例,进一步学习理解微调。

微调算法及参数配置

用户可设置stage参数选择模型训练过程。目前仅支持sft微调。

yaml
stage: sft

全参微调

openmind-cli train支持用户选择全参训练或者低参微调训练,目前可通过finetuning_type进行配置。全参训练可按以下配置:

yaml
finetuning_type: full

LoRA微调

如果用户需要进行LoRA微调,可以参考以下内容进行配置。

在脚本中配置finetuning_type来启动LoRA微调:

yaml
finetuning_type: lora

如果需要调整LoRA微调配置,可以新增以下参数:

yaml
finetuning_type: lora
lora_alpha: 16
lora_dropout: 0
lora_rank: 8
lora_target_modules: q_proj

其中lora_alphalora_dropoutlora_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,若未安装,可通过如下命令安装编译环境:

shell
apt-get install -y build-essential cmake  # 注:此为Debian系列操作系统安装命令,openEuler、CentOS等请替换为相应的命令安装。

在安装bitsandbytes之前,可通过如下示例判断安装环境是否配置完成:

python
# 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

shell
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微调,在微调配置文件中,加入如下内容:

yaml
load_in_4bit: True
finetuning_type: lora
bf16: True

需要注意的是,开启load_in_4bit: True时需要同时开启finetuning_type: lorabf16: True

微调参数说明

参数名描述类型默认值是否可选
stage训练阶段,目前仅支持sft。strsft可选
finetuning_type微调方式。可选: full, lora。strfull可选
lora_target_modules采取LoRA方法的目标模块。strNone可选
lora_alphaLora微调的缩放因子。intNone可选
lora_dropoutLoRA微调的丢弃率,取值范围为[0, 1)。float0.0可选
lora_rankLora微调的秩。int8可选
load_in_4bit支持QLoRA微调时使用4bit精度。boolFalse可选

模型配置

模型下载

微调训练中需要指定模型进行下载和加载,配置参数为model_idmodel_name_or_path。需要注意的是,在同一yaml脚本中,二者仅支持任选其一,不允许同时配置。

方法一:通过model_id参数可选取内置的模型,根据model_id匹配魔乐社区中的模型仓库名,便于模型的快速下载。配置方式如下:

yaml
model_id: Qwen2-7B

当前内置模型可查看下表,将会持续更新:

模型系列model_id
Qwen2Qwen2-7B
Qwen2.5Qwen2.5-7B

方法二:用户可通过model_name_or_path参数,指定魔乐社区模型仓库名或者本地模型路径。

  • 当使用本地模型时,可传入模型的绝对路径:

    yaml
    model_name_or_path: /local/path/
    
  • 可指定魔乐社区模型仓库名,如AI-Research/Qwen2-7B模型:

    yaml
    model_name_or_path: AI-Research/Qwen2-7B
    

模型下载缓存

使用model_idmodel_name_or_path时,可通过cache_dir参数设置权重缓存位置:

yaml
cache_dir: /home/cache_model

权重会被保存到/home/cache_dir路径,如果不设置则保存在默认路径。需要注意的是,当设置cache_dir路径时,用户需要同步设置HUB_WHITE_LIST_PATHS环境变量:

bash
export HUB_WHITE_LIST_PATHS=/home/cache_model

模型配置参数说明

参数名描述类型默认值是否可选
model_id模型ID。str-可选
model_name_or_path模型本地路径或者hub的repo_id。str-可选
trust_remote_code是否信任从远程下载的配置文件。boolFalse可选
cache_dir模型下载的缓存路径。strNone可选
token私仓权重token。strNone可选
model_revision指定模型版本。strmain可选
use_fast_tokenizer是否使用fast tokenizer。boolFalse可选
split_special_tokens是否拆分特殊token。boolFalse可选
new_special_tokens要添加到tokenzier中的特殊token。strNone可选
resize_vocab是否调整tokenizer词汇表的大小。boolFalse可选
use_gradient_checkpointing是否使用gradient checkpointing。boolTrue可选

数据集配置

内置数据集

用户可通过dataset参数配置数据集,openMind Library会自动检索内置的数据集链接并实现数据集下载。如设置alpaca_zh_51k后,会通过魔乐社区下载对应数据集AI-Research/alpaca_zh_51k

yaml
dataset: alpaca_zh_51k

当前内置数据集列表如下,将会持续更新:

dataset魔乐社区数据仓数据类型
alpaca_zh_51kAI-Research/alpaca_zh_51kalpaca
alpacaAI_Connect/alpacaalpaca
alpaca-gpt4-dataAI_Connect/alpaca-gpt4-dataalpaca
alpaca-gpt4-data-zhAI_Connect/alpaca-gpt4-data-zhalpaca
sharegpt_gpt4AI-Research/sharegpt_gpt4sharegpt

非内置数据集

用户可选择使用非内置数据集并进行数据集自定义,可以参考PyTorch模型微调-数据处理章节。

数据集截断和填充

依托于cutoff_lenmax_length参数,openMind Library支持对传入的数据集进行填充和截断操作。cutoff_len默认设置为1024,max_length默认为None。

yaml
cutoff_len: 1024

数据集截断示例:例如处理数据集A时,数据集A包含100个sample,每个sample经过分词器处理后,最大的长度为800,当cutoff_len设置为1024时,则数据集A最终截断长度为800。 如果数据集A经过分词器处理后最大的长度为1500,当cutoff_len被设置为1024时,数据集A最终的截断长度为1024。

如果用户需要对传入的数据集做填充,则可以设置max_length,每批次数据都会被处理到固定长度:

yaml
max_length: 1024

需要注意的是,如果cutoff_lenmax_length同时设置,max_length必须大于等于cutoff_len

数据集配置参数说明

参数名描述类型默认值是否可选
dataset数据集名称,支持传入多个不同的数据集,以","进行分割。strNone必选
custom_dataset_info传入的外置数据集配置文件的绝对路径。strNone可选
split数据集基于split筛选子数据集。strTrain可选
subset_name数据集的子数据集名称。strNone可选
preprocessing_num_workers用于数据处理的进程数。intNone可选
preprocessing_batch_size数据处理的批大小。int1000可选
cutoff_len数据集经过encode编码后的截止长度。int1024可选
max_length数据集经过encode编码后padding最大长度。intNone可选
reserved_label_len要将检查点保存到的输出目录。int1可选
ignore_pad_token_for_loss检查点保存的迭代间隔。boolTrue可选

训练参数配置

openmind-cli train训练参数继承于transformers库Seq2SeqTrainingArguments类。以下参数为微调训练常用参数,如有需要,用户可参考官方文档,了解更多训练参数配置。

基础配置

以下为训练过程中常用的参数:

yaml
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               # 权重衰减系数,用于正则化模型

混合精度设置

混合精度训练能够有效提高训练速度,降低显存占用,在微调较大参数的模型,或设备显存有限的情况下建议开启,用户可通过配置如下训练参数开启混合精度训练:

yaml
bf16: True                  # 是否开启bf16混合精度

模型保存

训练后的模型需要保存模型权重,可参考以下配置:

yaml
output_dir: saves           # 检查点和模型保存的目录
ovewrite_output_dir: True   # 输出是否覆盖
  • 如果用户设置ovewrite_output_dir: False且保存路径下存在checkpoint,会加载最后一个checkpoint继续训练。
  • 如果用户设置了ovewrite_output_dir: True,会覆盖原有checkpoint,重新开始训练。

checkpoint保存

可以设置save_steps参数进行checkpoint保存,便于恢复中断的训练过程或者查看训练中间效果,该参数表示每隔多少步保存一个checkpoint:

yaml
save_steps: 1000           # 每隔多少步保存一个checkpoint

融合算子加速

openMind Library支持昇腾NPU融合算子优化加速,用户可参考融合算子使能章节查看具体支持的算子和使用方式。

分布式训练

openmind-cli train支持单机单卡和单机多卡微调训练,用户可通过配置ASCEND_RT_VISIBLE_DEVICES环境变量控制分布式训练。

单机单卡

用户可设置使用特定卡,来实现单机单卡训练。

shell
export ASCEND_RT_VISIBLE_DEVICES=0
openmind-cli train examples/features/train_sft_lora.yaml

单机多卡 - DDP

用户可传入多卡编号,来实现单机多卡训练。

shell
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命令会自动识别底层环境中的计算卡数,并全量使用拉起加载。用户如果已经设置了该环境变量,可通过以下命令解除限制:

shell
unset ASCEND_RT_VISIBLE_DEVICES

可通过以下命令查看unset是否生效,正确设置情况下该命令返回值为空。

shell
echo $ASCEND_RT_VISIBLE_DEVICES

DeepSpeed

DeepSpeed是一个专为PyTorch设计的加速库,它在分布式训练时能够显著提升显存使用效率和加快训练速度。目前openMind Library支持zero0, zero1, zero2特性。配置示例如下:

yaml
deepspeed: ./ds2_config.json

用户需要传入DeepSpeed配置文件路径,DeepSpeed配置文件可参考DeepSpeed说明

训练监控

openMind Library当前支持SwanLab实验跟踪。SwanLab提供了友好的API和易用的界面,结合了超参数跟踪、指标记录、在线协作、实验链接分享等功能。

SwanLab

安装SwanLab

bash
pip install swanlab

配置SwanLab

在yaml文件中配置以下参数:

yaml
report_to: swanlab
logging_dir: ./log
  • report_to设置为swanlab,表示使用SwanLab进行实验跟踪。
  • logging_dir是可选参数,可指定SwanLab日志文件的保存位置(默认保存在当前路径swanlablog文件夹下)。

开启SwanLab看板

通过以下命令开启SwanLab看板,./log表示SwanLab日志文件的保存位置,和上述logging_dir一致:

bash
swanlab watch ./log

以上命令将返回一个URL链接(默认为http://127.0.0.1:5092)。 点击该链接即可访问SwanLab看板。

更多SwanLab使用说明请查看SwanLab官方指导文档

LoRA权重合并

经过LoRA微调训练后,保存的权重并非完整模型的权重,而是适配器的权重文件。此类权重文件仅包含 LoRA 层相关的参数,需要与基础模型权重一起加载才能使用。

LoRA微调后保存的文件通常包括以下内容:

plaintext
output_dir/
├── adapter_config.json  # LoRA 的配置文件
├── adapter_model.safetensors    # LoRA 层的权重文件

基础模型的权重文件通常包含以下内容:

plaintext
base_model_dir/
├── config.json             # 模型的配置文件
├── model.safetensors       # 基础模型的权重文件

openMind Library提供了openmind-cli export参数,帮助用户进行LoRA微调后的权重合并。该命令与openmind-cli train命令相似,基于yaml文件完成对应的合并操作。

单个适配器权重合并

常用的yaml文件内容如下,该文件可命名为merge.yaml,一般包含以下参数:

  • model_idmodel_name_or_path:基础模型的权重名或路径,可参考openmind-cli train命令中的该参数。
  • adapter_models:微调后的适配器权重路径。
  • output_dir:合并权重后的保存路径。
yaml
#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

可通过以下命令完成合并操作:

shell
openmind-cli export merge.yaml

多个适配器权重合并

openmind-cli export支持对多个适配器进行权重合并,yaml文件内容示例如下:

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未集成的基础模型文件。boolFalse可选
cache_dir基础模型下载的缓存路径。strNone可选
model_revision指定基础模型版本。strmain可选
per_shard_size合并过程中单个分片的大小,1代表单个模型文件最大为1GB,如果不设置默认为5GB。intNone可选
token私仓权重token。strNone可选