Qwen3-VL 是通义千问多模态大模型系列于 2025年10月 发布的全新一代视觉语言模型,涵盖从 2B 到 235B 参数量的多个基础与指令微调版本。相比前代 Qwen2.5-VL 和 Qwen2-VL,Qwen3-VL 在多模态理解、跨模态对齐、长上下文图文推理及结构化输出能力上实现全面跃升。本项目提供Qwen3-VL-8B-Instruct模型在昇腾Atlas A2服务器基于MindSpeed-MM的SFT微调训练指导,详细模型介绍可以参考模型开源社区内容https://modelscope.cn/models/Qwen/Qwen3-VL-8B-Instruct。
| 型号 | 卡数 | 模型 |
|---|---|---|
| 910B3 | 8 | Qwen3-VL-8B-Instruct |
| 软件名 | 卡版本 |
|---|---|
| CANN | 8.3.RC1 |
| Python | 3.10.17 |
| torch | 2.7.1 |
| torch_npu | 2.7.1 |
| npu驱动 | 25.0.rc1.1 |
MindSpeed-MM官方教程:https://gitcode.com/Ascend/MindSpeed-MM/blob/master/examples/qwen3vl/README.md
(1)拉取基础镜像或第三方镜像
执行命令:docker pull crpi-q4j9953iclvqls1q.cn-shanghai.personal.cr.aliyuncs.com/ascend_images/mindspeed-mm:qwen3vl-cann8.2.rc1-py3.10-openeuler(2)编写Dockerfile文件,如果使用的基础镜像是第三方镜像(非ModelArts提供的公共镜像),Dockerfile文件中需要添加uid为1000的用户ma-user和gid为100的用户组ma-group Dockerfile模板:
FROM {自己的镜像地址}
USER root
# 第一阶段:获取现有用户/组信息
RUN set -ex \
&& default_user=$(getent passwd 1000 | awk -F: '{print $1}') || echo "uid: 1000 not exist" \
&& default_group=$(getent group 100 | awk -F: '{print $1}') || echo "gid: 100 not exist" \
> /tmp/user\_info.log
# 第二阶段:删除冲突用户/组
RUN set -ex \
&& [ -z "$(getent passwd 1000 | grep ma-user)" ] && { \
existing_user=$(getent passwd 1000 | awk -F: '{print $1}') \
&& [ -n "$existing_user" ] && userdel -r "$existing\_user" \
|| true; } \
&& [ -z "$(getent group 100 | grep ma-group)" ] && { \
existing_group=$(getent group 100 | awk -F: '{print $1}') \
&& [ -n "$existing\_group" ] && groupdel -f "$existing\_group" \
|| true; }
# 第三阶段:创建新用户/组
RUN set -ex \
&& groupadd -g 100 ma-group \
&& useradd -d /home/ma-user -m -u 1000 -g 100 -s /bin/bash ma-user \
&& chmod -R 750 /home/ma-user
USER ma-user若没有设置添加uid为1000的用户ma-user和gid为100的用户组ma-group,可能会出现启动训练任务失败的情况,如下图:

3)构建镜像
使用docker build命令从Dockerfile构建出一个新镜像。命令参数解释如下:
例:docker build -t swr.cn-north-4.myhuaweicloud.com/sdk-test/pytorch_1_8:v1 -f Dockerfile .
查看制作的镜像:docker images
(4)调试完成后,将新镜像注册到ModelArts镜像管理服务中,进而能够在ModelArts中使用该镜像
执行命令:docker push {镜像地址},完成后即可在SWR上看到该镜像
Qwen3-VL-8B-Instruct 权重及配置文件说明
| 模型 | 权重 |
|---|---|
| Qwen3-VL-8B-Instruct | huggingface下载链接 |
从Huggingface库下载对应的模型权重,将下载的模型权重保存到本地的ckpt/hf_path/Qwen3-VL-*B-Instruct目录下。(*表示对应的尺寸)。Qwen3-vl使用fsdp分布式训练策略进行训练,核心机制为ZeRO stage3的Pytorch原生实现,将参数、梯度、优化器状态全部分片到不同NPU上,训练时通过All-Gather临时重建完整参数,计算后立即Reduce-Scatter分片,不包含模型并行(TP/PP)。而Qwen2.5-VL使用megatron训练策略,TP/PP/DP三位一体混合并行。与qwen2.5-VL的差异导致qwen3-VL在开启训练前无需提前将原始预训练权重转换为适配Megatron的MindSpeed-MM格式,直接使用huggingface下载的原始权重开始训练即可,因此ckpt/mm_path路径无需设定。
如果使用fsdp2的meta init初始化模型,需要先完成以下权重转换
mm-convert Qwen3VLConverter hf_to_dcp \
--hf_dir Qwen3-VL-xxB \
--dcp_dir Qwen3-VL-xxB-dcp \并在examples/qwen3vl/finetune_qwen3vl.sh的GPT_ARGS中加入--init-model-with-meta-device参数。
注意,针对Qwen3VL-30B和Qwen3VL-235B模型,必须使用meta init初始化加载权重,转换后的dcp模型权重路径赋值给LOAD_PATH参数。
数据集格式与qwen2.5-vl保持一致,可以参考qwen2.5-vl的数据格式进行数据准备。
命令:bash examples/qwen3vl/finetune_qwen3vl_xxB.sh
关键参数配置:
| 参数 | 含义 | 数值 |
|---|---|---|
| TP | 张量并行,fsdp策略下不生效,默认值1 | 1 |
| PP | 流水线并行,fsdp策略下不生效,默认值1 | 1 |
| CP | 上下文并行 | 1 |
| SEQ_LEN | 序列长度 | 4096 |
| MBS | 微批次大小 | 1 |
| NPUS_PER_NODE | 每节点卡数 | 8 |
| GBS | 全局批次大小 | 40 |
| GRAD_ACC_STEP | 梯度累计步数 | 5 |
| LR | 学习率 | 5.0e-6 |
| clip-grad | 梯度裁剪 | 1.0 |
GPT_ARGS="
--use-mcore-models \
--tensor-model-parallel-size ${TP} \
--pipeline-model-parallel-size ${PP} \
--context-parallel-size ${CP} \
--context-parallel-algo ulysses_cp_algo \
--micro-batch-size ${MBS} \
--global-batch-size ${GBS} \
--tokenizer-type NullTokenizer \
--vocab-size 152064 \
--seq-length ${SEQ_LEN} \
--make-vocab-size-divisible-by 1 \
--normalization RMSNorm \
--use-fused-rmsnorm \
--swiglu \
--use-fused-swiglu \
--no-masked-softmax-fusion \
--lr 1.0e-5 \
--lr-decay-style cosine \
--weight-decay 0 \
--train-iters 10000 \
--lr-warmup-fraction 0.1 \
--clip-grad 0.0 \
--adam-beta1 0.9 \
--adam-beta2 0.999 \
--no-gradient-accumulation-fusion \
--seed 42 \
--load $LOAD_PATH \
--use-flash-attn \
--no-load-optim \
--no-load-rng \
--no-save-optim \
--no-save-rng \
--num-workers 8 \
--use-torch-fsdp2 \
--untie-embeddings-and-output-weights \
--ckpt-format torch_dcp \
--fsdp2-config-path $FSDP2_PATH \
--optimizer-selection fused_torch_adamw \
--use-cpu-initialization \
--calculate-per-token-loss \
--log-tps
"启动微调命令
torchrun $DISTRIBUTED_ARGS pretrain_transformers.py \
$GPT_ARGS \
$MM_ARGS \
$OUTPUT_ARGS \
--distributed-backend nccl \
--distributed-timeout-minutes 60 \需要注意参数配置中,clip-grad需要设置为1.0,MindSpeed-MM代码仓的默认值为0.0,这个参数的含义是当反向传播计算出的梯度范数过大时,将其按比例缩小,使其不超过某个阈值,从而避免参数更新幅度过大导致训练发散。Qwen3-VL改用fsdp策略后发现在训练过程中的梯度范数有较强烈的波动,若不设置,训练的loss可能会不收敛,如下左图所示。设置了clip-grad=1.0后,loss可以收敛到一个较小值,如右下图所示。


训练过程中可能会出现watchdog超时时长短于HCCL超时时长,导致watchdog超时的报错,如下图所示。在mindspeed框架可通过distributed-timeout-minutes参数设置watchdog超时时间--distributed-timeout-minutes 60。

训练完成之后,需要将保存在save_dir目录下的权重转换成huggingface格式才能进行下一步的推理。
mm-convert Qwen3VLConverter dcp_to_hf \
--load_dir save_dir/iter_000xx/ \
--save_dir save_dir/iter_000xx_hf/ \
--model_assets_dir ./ckpt/Qwen3-VL-xxB-Instruct \model_assets_dir表示原始huggingface权重的路径。