使用AIAK加速Qwen2.5VL模型的训练
AIAK-Training-LLM是百度智能云基于百度百舸·AI计算平台,面向大模型训练场景提供的最佳实践解决方案配套AI加速工具,帮助模型开发者高效完成大规模深度学习分布式训练,提升训练效率,相比开源 Megatron-LLM性能明显提升。关于AIAK-Training-LLM的使用说明,详见这里这里
这里我们以Qwen/Qwen2.5-VL-7B-Instruct模型为示例,介绍如何使用AIAK-Training-LLM 进行训练。
使用前提
- 已经创建百舸资源池,包含至少1台8卡的GPU节点,这里我们以A800为例
- 已经创建并行文件存储PFS,并且已经和资源池关联。推荐使用PFS存储数据,进行训练
步骤一:准备模型原始权重文件
百舸平台已经在对象存储BOS中预置模型权重,您可以从对应地域的BOS路径中下载数据。请参考下载百舸平台预置的公共数据到PFS
1bos:/aihc-models-bj/Qwen/Qwen2.5-VL-7B-Instruct #北京
2bos:/aihc-models-bd/Qwen/Qwen2.5-VL-7B-Instruct #保定
步骤二:准备数据集
2.1 数据集格式和处理
考虑多模态数据集的多样性,本次版本将采用 **Energon** 加载器来提升数据处理性能,它要求数据集以标准的 **WebDataset** 格式存储。WebDataset 是以原生文件格式 (jpg、mp4等) 存储数据,这使得各种原生的多模态数据集只需简单地压缩就能转成 WebDataset 格式,进而被 Energon 读取。
相关的参考文档:
- Energon: https://nvidia.github.io/Megatron-Energon/
- WebDataset:https://huggingface.co/docs/hub/datasets-webdataset
针对 Qwen2.5-VL 模型,AIAK-Training-LLM 当前重点支持了 **VQA** 和 **Captioning** 两种多模态数据格式(下文分别介绍具体的数据处理流程):
- VQA 格式的数据集
- Captioning 格式的数据集,以 minigpt4_3500 数据集为例
2.1.1 VQA
1) 第一步:准备原始数据集:
2)第二步:将原始数据集压缩成WebDataset格式
AIAK 内置了工具用于处理数据格式转换,路径在/workspace/AIAK-Training-LLM/tools/data_preprocess/convert_to_webdataset.py
,具体使用方式:
1python /workspace/AIAK-Training-LLM/tools/data_preprocess/convert_to_webdataset.py \
2 --output_dir /tmp/mllm/wds \
3 --json_file /tmp/mllm/mllm_demo.json \
4 --image_dir /tmp/mllm/ \
5 --maxcount 10000
功能说明:
-
convert_to_webdataset.py
会将***\*json_file\****
中每个样本抽出来存储成独立的json文件,并和***\*image_dir\****
中相对应的图片一起被压缩到 **$output_dir**,每个tar包最多包含有***\*maxcount\****
个样本; - 后续启动训练时,将通过
--data-path
参数指定如上 WebDataset 路径/tmp/mllm/wds
,用于训练数据读取;
执行示例:
- 当执行上面脚本后,
--output_dir
目录下新增处理后的数据压缩包:
- pretrain-0.tar 中的文件如下,其中具有相同前缀的数据文件都属于同一个样本,比如 1.jpg 和 1.json 属于样本1。
3)第三步:将 WebDataset 格式转成 Energon 加载器格式
Energon 格式相对于 WebDataset,只增加了 yaml 文件记录数据集信息,用于后续 dataloader 解析数据集,具体如下:
-
.info.yaml
记录各压缩包的样本数 -
dataset.yaml
记录样本信息 -
split.yaml
记录数据集的划分
由于上述 yaml 文件存在一些格式要求,为了方便用户生成以上yaml文件,AIAK镜像中也内置了 energon 命令行工具通过交互式指令来自动生成 yaml 格式问题,具体步骤如下:
1# Step 1,生成 info.yaml
2cd /tmp/mllm/wds/
3energon prepare ./
4
5# Step 2, 生成 split.yaml,和后续训练保持一致即可
6> Please enter a desired train/val/test split: 10,0,0
7
8# Step 3, 生成 dataset.yaml
9> Do you want to create a dataset.yaml interactively? [Y/n]: Y
10> Please enter a number to choose a class: 9
11> Do you want to set a simple field_map[Y]? [Y/n]: Y
12> Please enter a webdataset field name for 'image' : jpg
13> Please enter a webdataset field name for 'context': json[0][content]
14> Please enter a webdataset field name for 'answers': json[1][content]
15Done
执行示例:
对 第三步 补充说明:
- 以上共列出12个种数据集格式,当前仅支持 **0. CaptionSample** 和 **9. VQASample**。
-
每种数据集格式都有各自的字段需指定,比如VQASample的字段有:
-
image
: dataloader 会按该字段寻找相应后辍名的文件,比如:1.jpg。 -
context
:dataloader 会按该字段寻找相应后辍名的文件,并在文件中匹配相应内容。比如:json[0][content]
表示在 *.json 文件中把第1条信息中的 content 字段对应的内容作为"问题" -
answers
:同理,json[1][content]
将在 *.json 文件中把第2条信息中的 content 字段对应的内容作为"答案"
-
4)第四步:校验转换结果(可选)
1energon preview ./
正常打印图像说明转换成功
2.1.2 Caption
1)第一步:准备原始数据集
样本来自 https://huggingface.co/datasets/THUDM/CogVLM-SFT-311K
2)第二步:将原始数据集压缩成WebDataset格式
1cd /tmp/minigpt4
2mkdir wds
3tar -cf wds/pretrain.tar samples/
由于原始数据集格式,已经和convert_to_webdataset.py
工具所生成 tar 内的格式一致,因此仅需要执行压缩命令即可,而不需要额外调用转换工具单独处理;
3)第三步:WebDataset 格式转成 Megatron-Energon 格式
1cd wds
2energon prepare ./
3为所显示的选项选择以下值:
4> Please enter a desired train/val/test split: 10,0,0
5> Do you want to create a dataset.yaml interactively? [Y/n]: Y
6> Please enter a number to choose a class: 0
7> Please enter a webdataset field name for 'image' : jpg
8> Please enter a webdataset field name for 'caption': json[captions][0][content]
9Done
4)第四步:校验转换结果(可选)
1energon preview ./
能正常打印图像说明转换成功
2.2 数据集下载
百舸平台已经在对象存储BOS中预置VQA格式的数据集,您可以从对应地域的BOS路径中下载,直接训练。请参考下载百舸平台预置的公共数据到PFS
1bos:/aihc-rdw-bj/dataset/mllm/demo/wds/
已上传
步骤三: 模型权重转换
AIAK-Training-LLM 是基于 Megatron 构建的大模型训练库,而 Megatron 模型权重格式和开源的格式(如 huggingface)存在区别,因此,当用户需基于开源权重进行再训练时,需要提前将模型权重格式进行转换。 AIAK 针对支持的模型提供了统一的权重转换工具 ,具体使用方式,详见 Checkpoint及格式转换。
具体转换操作,用户可以进入容器,参考**/workspace/AIAK-Training-LLM/examples/{model}/checkpoint_convert**
**目录下提供的示例脚本,将 Huggingface
权重转换到 AIAK 支持的MegatronCore
格式
1#! /bin/bash
2
3AIAK_TRAINING_PATH=${AIAK_TRAINING_PATH:-"/workspace/AIAK-Training-LLM"}
4AIAK_MAGATRON_PATH=${AIAK_MAGATRON_PATH:-"/workspace/AIAK-Magatron"}
5CONVERT_CHECKPOINT_PATH="$AIAK_TRAINING_PATH/tools/convert_checkpoint"
6
7## LOAD:原始权重地址,SAVE 转换的模型存储路径
8LOAD=/mnt/cluster/aiak-training-llm/qwen2.5-vl/Qwen2.5-VL-7B-Instruct
9SAVE=/mnt/cluster/aiak-training-llm/qwen2.5-vl/qwen2_5-vl-7b-tp1-pp1
10
11SAVE_LANGUAGE_MODEL=/mnt/cluster/aiak-training-llm/tmp/language-mcore
12SAVE_VISION_MODEL=/mnt/cluster/aiak-training-llm/tmp/vision-model-mcore
13SAVE_ADAPTER=/mnt/cluster/aiak-training-llm/tmp/adapter-mcore
14SAVE_PATCH=/mnt/cluster/aiak-training-llm/tmp/patch-mcore
15
16# 不需要进行模型切分,所以TP=1,PP=1
17TP=1
18PP=1
19
20
21python $CONVERT_CHECKPOINT_PATH/model.py \
22 --load_platform=huggingface \
23 --save_platform=mcore \
24 --common_config_path=$CONVERT_CHECKPOINT_PATH/config/qwen2_5-vl-7b/qwen2_5.json \
25 --tensor_model_parallel_size=$TP \
26 --pipeline_model_parallel_size=$PP \
27 --load_ckpt_path=$LOAD \
28 --save_ckpt_path=$SAVE_LANGUAGE_MODEL \
29 --safetensors \
30 --no_save_optim \
31 --no_load_optim
32
33# vit
34python $CONVERT_CHECKPOINT_PATH/model.py \
35 --load_platform=huggingface \
36 --save_platform=mcore \
37 --common_config_path=$CONVERT_CHECKPOINT_PATH/config/qwen2_5-vl-7b/vision-model.json \
38 --tensor_model_parallel_size=$TP \
39 --load_ckpt_path=$LOAD \
40 --save_ckpt_path=$SAVE_VISION_MODEL \
41 --safetensors \
42 --no_save_optim \
43 --no_load_optim
44
45# adapter
46python $CONVERT_CHECKPOINT_PATH/custom/qwen2_vl/adapter.py \
47 --load_platform=huggingface \
48 --save_platform=mcore \
49 --common_config_path=$CONVERT_CHECKPOINT_PATH/config/qwen2_5-vl-7b/adapter.json \
50 --tensor_model_parallel_size=$TP \
51 --load_ckpt_path=$LOAD \
52 --save_ckpt_path=$SAVE_ADAPTER
53
54# vision patch in vit
55python $CONVERT_CHECKPOINT_PATH/custom/qwen2_vl/vision_patch.py \
56 --load_platform=huggingface \
57 --save_platform=mcore \
58 --tensor_model_parallel_size=$TP \
59 --common_config_path=$CONVERT_CHECKPOINT_PATH/config/qwen2_5-vl-7b/vision-patch.json \
60 --load_ckpt_path=$LOAD \
61 --save_ckpt_path=$SAVE_PATCH
62
63# merge
64python $CONVERT_CHECKPOINT_PATH/custom/qwen2_vl/merge_megatron.py \
65 --megatron_path $AIAK_MAGATRON_PATH \
66 --language_model_path $SAVE_LANGUAGE_MODEL/release \
67 --vision_model_path $SAVE_VISION_MODEL/release \
68 --vision_patch $SAVE_PATCH/release \
69 --adapter_path $SAVE_ADAPTER/release \
70 --save_ckpt_path $SAVE/release \
71 --tensor_model_parallel_size $TP \
72 --pipeline_model_parallel_size $PP
73
74echo release > $SAVE/latest_checkpointed_iteration.txt
75rm -rf $SAVE_LANGUAGE_MODEL
76rm -rf $SAVE_VISION_MODEL
77rm -rf $SAVE_ADAPTER
78rm -rf $SAVE_PATCH
百舸平台已经在对象存储BOS中预置megatronCore格式的qwen2.5-vl-7B得模型权重,您也可以从对应地域的BOS路径中下载,直接使用:
1bos:/aihc-models-bj/Qwen/qwen2_5-vl-7b-tp1-pp1
步骤四: 开启训练
4.1 训练参数
AIAK 当前提供各模型预训练示例脚本,进入容器,可以在**/workspace/AIAK-Training-LLM/examples/{model}/**
下查看。 关于训练说明,详见:这里
目前训练模式支持Pretrain和SFT,这里我们以SFT为例,用户可以参考**/workspace/AIAK-Training-LLM/examples/{model}/finetuning**
目录下的示例脚本进行 SFT 训练.
1#! /bin/bash
2# The script needs to be run on at least 1 nodes.
3
4MEGATRON_PATH=${MEGATRON_PATH:-"/workspace/AIAK-Megatron"}
5AIAK_TRAINING_PATH=${AIAK_TRAINING_PATH:-"/workspace/AIAK-Training-LLM"}
6
7DATA_PATH=${DATA_PATH:-"/mnt/cluster/aiak-training-llm/dataset/mllm/demo/wds/"} #替换为环境中的数据集地址
8
9TOKENIZER_PATH=${TOKENIZER_PATH:-"/mnt/cluster/aiak-training-llm/qwen2.5-vl/Qwen2.5-VL-7B-Instruct/"} #替换为环境中的Tokenizer地址
10
11CHECKPOINT_PATH=${CHECKPOINT_PATH:-"/mnt/cluster/aiak-training-llm/qwen2.5-vl/qwen2_5-vl-7b-tp1-pp1"} #替换为环境中的ckpt地址
12
13TENSORBOARD_PATH=$AIHC_TENSORBOARD_LOG_PATH #开启tensorboard后,设置Tensorboard日志的保存路径
14
15GPUS_PER_NODE=8
16
17#若开启wandb,设置以下环境变量
18export WANDB_API_KEY=""
19export WANDB_PROJECT=""
20export WANDB_NAME=""
21export http_proxy=""
22export https_proxy=""
23
24
25# Change for multinode config
26MASTER_ADDR=${MASTER_ADDR:-"localhost"}
27MASTER_PORT=${MASTER_PORT:-"6000"}
28NNODES=${WORLD_SIZE:-"1"}
29NODE_RANK=${RANK:-"0"}
30
31DISTRIBUTED_ARGS=(
32 --nproc_per_node $GPUS_PER_NODE
33 --nnodes $NNODES
34 --node_rank $NODE_RANK
35 --master_addr $MASTER_ADDR
36 --master_port $MASTER_PORT
37)
38
39# or you can setup qwen2_5-vl-7b by using the following command
40MODEL_ARGS=(
41 --model-name qwen2_5-vl-7b
42)
43
44DATA_ARGS=(
45 --tokenizer-type HFTokenizer \
46 --hf-tokenizer-path $TOKENIZER_PATH \
47 --data-path $DATA_PATH
48 --dataloader-type external
49 --split 100,0,0
50 --num-workers 16
51 --chat-template qwen2-vl
52)
53
54TRAINING_ARGS=(
55 --training-phase sft
56 --trainable-modules language_model adapter
57 --seq-length 1024
58 --max-position-embeddings 4096
59 --init-method-std 0.02
60 --micro-batch-size 1
61 --global-batch-size 512
62 --lr 0.0002
63 --min-lr 1.0e-5
64 --clip-grad 1.0
65 --weight-decay 0.01
66 --optimizer adam
67 --adam-beta1 0.9
68 --adam-beta2 0.95
69 --adam-eps 1e-05
70 --norm-epsilon 1e-6
71 --train-iters 50000
72 --lr-decay-iters 50000
73 --lr-decay-style cosine
74 --lr-warmup-fraction 0.002
75 --initial-loss-scale 65536
76 --bf16
77 --load $CHECKPOINT_PATH
78 --save $CHECKPOINT_PATH
79 --save-interval 10000000
80 --ckpt-format torch
81 --dataloader-save ${CHECKPOINT_PATH}/dataloader
82)
83
84MODEL_PARALLEL_ARGS=(
85 --attention-backend flash
86 --pipeline-model-parallel-size 1
87 --tensor-model-parallel-size 1
88 --use-distributed-optimizer
89 --overlap-grad-reduce
90 --overlap-param-gather
91 --distributed-backend nccl
92)
93
94LOGGING_ARGS=(
95 --log-interval 1
96 --tensorboard-dir ${TENSORBOARD_PATH}
97 --log-timers-to-tensorboard
98)
99
100if [ -n "${WANDB_API_KEY}" ]; then
101 LOGGING_ARGS+=(
102 --wandb-project ${WANDB_PROJECT}
103 --wandb-exp-name ${WANDB_NAME}
104 )
105fi
106
107PYTHONPATH=$MEGATRON_PATH:$AIAK_TRAINING_PATH:$PYTHONPATH \
108 torchrun ${DISTRIBUTED_ARGS[@]} \
109 $AIAK_TRAINING_PATH/aiak_training_llm/train.py \
110 ${MODEL_ARGS[@]} \
111 ${DATA_ARGS[@]} \
112 ${TRAINING_ARGS[@]} \
113 ${MODEL_PARALLEL_ARGS[@]} \
114 ${LOGGING_ARGS[@]}
4.2 创建任务
- 登录百舸异构计算平台AIHC控制台。
-
进入 分布式训练 列表页面,点击创建任务,填写任务关键配置信息:
-
基础信息
- 任务名称:这里输入qwen2-5-vl-7b-sft
- 资源池&队列:选择已创建的资源池和队列
- 优先级:默认 中 优先级,无需更改
- 训练框架:选择Pytorch
- 任务创建方式: 自定义创建
-
环境配置
- 镜像地址:这里输入
registry.baidubce.com/aihc-aiak/aiak-training-llm:ubuntu22.04-cu12.6-torch2.5.0-py310-bccl1.2.7.2_v2.2.3.2_release
-
执行命令:参考上述4.1的训练脚本,可以直接粘贴进来(注意:需要根据实际的环境替换以下的参数)DATA_PATH
、
TRAINING_CONFIG`等配置信息DATA_PATH
:可下载预置的数据集,填写实际的数据集路径TOKENIZER_PATH
:填写tokenizer的实际路径,即模型原始的huggingface格式的模型权重,可下载文档中平台预置的原始模型权重CHECKPOINT_PATH
:填写MegatronCore 格式的模型权重地址,可以参考步骤三转换,或者下载直接使用平台预置的模型权重TENSORBOARD_PATH
: 若希望开启Tensorboard,则需要指定Tensobroard日志的保存路径。注意:平台自动注入$AIHC_TENSORBOARD_LOG_PATH
环境变量,代表Tensorboard日志路径,您可以在代码中使用此环境变量来引用日志路径-
若希望使用wandb观察训练过程,需要额外配置如下参数
export WANDB_API_KEY
:Wandb 账户的认证密钥,用于身份验证和访问权限。必须设置才能与 Wandb 服务端通信export WANDB_PROJECT
:设置wandb project名称,如qwenexport WANDB_NAME
:设置实验名称,如qwen2.5vl-7b-1export http_proxy
:设置代理,可以连接wandb服务器export https_proxy
:设置代理,可以连接wandb服务器
- 环境变量:无需更改
- 镜像地址:这里输入
-
资源配置
- 实例数:这里填写1,单机训练A800训练
- 加速芯片:这里选择提前准备的A800 GPU,单实例8卡
- 共享内存:默认10Gi
- RDMA:单机训练,无需开启
-
设置数据源
- 存储类型:这里选择我们提前准备的PFS
- PFS源路径:PFS的挂载路径,默认根目录,按实际情况填写
- 挂载路径:容器内的挂载路径设置数据源
-
监控信息:
- Tensorboard:开启Tensorboard,自定义Tensorboard日志再日志中的存储路径
-
- 点击 完成,提交训练任务。
4.3 观察训练任务
任务进行运行状态后,您可以在百舸平台查询看任务的监控、日志、Tensorboard等信息;也可以登陆wandb官网,查询训练过程
训练日志
Tensorboard
监控
wandb