已合并
feat: Adapt Qwen3.8 on MindSpeed MM #2979
且奏长歌创建于 18 天前
feat: Adapt Qwen3.8 on MindSpeed MM #2979
已合并
且奏长歌创建于 18 天前
6 个文件变更+885-4
@@ -0,0 +1,355 @@
1+# Qwen3_8 使用指南
2+ 
3+<p align="left">
4+</p>
5+ 
6+## 目录
7+ 
8+- [版本说明](#版本说明)
9+ - [参考实现](#参考实现)
10+ - [变更记录](#变更记录)
11+- [环境安装](#环境安装)
12+ - [环境准备](#1-环境准备)
13+ - [环境搭建](#2-环境搭建)
14+ - [安装配套版本的TriTon-Ascend](#3-安装配套版本的triton-ascend)
15+ - [安装fla-npu以适配AscendC](#4-安装fla-npu以适配ascendc)
16+- [权重下载及转换](#权重下载及转换)
17+ - [权重下载](#1-权重下载)
18+ - [权重加载](#2-权重加载)
19+ - [权重保存](#3-权重保存)
20+- [数据集准备及处理](#数据集准备及处理)
21+- [微调](#微调)
22+ - [准备工作](#1-准备工作)
23+ - [配置参数](#2-配置参数)
24+ - [启动微调](#3-启动微调)
25+- [环境变量声明](#环境变量声明)
26+- [注意事项](#注意事项)
27+ 
28+## 版本说明
29+ 
30+### 参考实现
31+ 
32+```shell
33+url=https://github.com/huggingface/transformers.git
34+git checkout v5.2.0
35+```
36+ 
37+### 变更记录
38+ 
39+2026.08.13: 首次支持Qwen3_8模型
40+ 
41+---
42+<a id="jump1"></a>
43+ 
44+## 环境安装
45+ 
46+<a id="jump1.1"></a>
47+ 
48+### 1. 环境准备
49+ 
50+【推荐使用配套环境版本】
51+> Python版本推荐3.10或3.11,建议使用CANN9.1.0,torch_npu2.7.1.post8版本,详细安装步骤可查看:
52+ 
53+- [CANN](https://www.hiascend.com/cann/download?versionId=767&ids=d803%2Ch0501%2Ch0601%2Ch0701)(推荐使用离线安装方式)
54+- [TorchNPU](https://www.hiascend.com/developer/software/ai-frameworks/pytorch/download?versionId=174&ids=89dda9ba9de741349efa03687a487678%2C96%2C109%2C1%2C6%2C177%2C)
55+ 
56+仍有疑问可以参考[安装指南](https://gitcode.com/Ascend/MindSpeed-MM/blob/master/docs/zh/pytorch/install_guide.md)
57+ 
58+<a id="jump1.2"></a>
59+ 
60+### 2. 环境搭建
61+ 
62+拉取MindSpeed MM代码仓,并进入代码仓根目录:
63+ 
64+```bash
65+git clone https://gitcode.com/Ascend/MindSpeed-MM.git
66+cd MindSpeed-MM
67+```
68+ 
69+执行如下指令一键安装:
70+ 
71+```bash
72+bash scripts/install.sh --msbranch master && pip install transformers==5.2.0
73+```
74+ 
75+### 3. 安装配套版本的Triton-Ascend
76+ 
77+可直接使用如下安装命令:
78+ 
79+```shell
80+pip install triton-ascend==3.2.1 --extra-index-url=https://triton-ascend.osinfra.cn/pypi/simple
林明哲18 天前

已经有3.2.2了,是否直接上3.2.2?

likedislike
且奏长歌
且奏长歌
18 天前 评论:
81+# 注意:triton-ascend 3.2.0 及以下 triton-ascend 和 triton 不能同时存在。需要先卸载社区 triton,再安装 triton-ascend。
82+```
83+ 
84+若需了解更多可参考《Triton-Ascend》中的"[通过pip安装Triton-Ascend](https://triton-ascend.readthedocs.io/zh-cn/latest/installation_guide.html#piptriton-ascend)"章节。
85+ 
86+### 4. 安装fla-npu以适配AscendC
87+ 
88+拉取flash-linear-attention-npu代码仓,并进入代码仓根目录,切到对应commitID
89+ 
90+```bash
91+git clone https://github.com/flashserve/flash-linear-attention-npu -b v26.6.0
92+cd flash-linear-attention-npu
93+```
94+ 
95+安装步骤:可参考fla-npu仓README:[flash-linear-attention-npu](https://github.com/flashserve/flash-linear-attention-npu/blob/release/v26.1.0/README.md)
96+ 
97+> **说明:** 请确保操作系统已安装 `gawk`,否则后续安装会失败,参考以下命令安装:
98+ 
99+```shell
100+# Ubuntu / Debian
101+apt-get update
102+apt-get install gawk
103+# openEuler / CentOS / RHEL
104+yum update
105+yum install gawk
106+```
107+ 
108+fla-npu推荐使用以下安装命令
109+ 
110+```shell
111+# source 所安装cann包路径下的set_env.sh
112+source /user/Ascend/CANN_9.1.0/ascend-toolkit/set_env.sh
113+ 
114+# 编译算子 run 包,--soc 需指定为当前机器芯片类型 {A2:ascend910b/A3:ascend910_93/A5:ascend950}
115+# 以A3机型为例
116+bash build.sh --soc=ascend910_93 --pkg --vendor_name=fla_npu
117+bash build_out/fla-npu-*.run #运行完成后会生成命令:export LD_LIBRARY_PATH=xxx:${LD_LIBRARY_PATH},将该命令添加到shell训练脚本中
118+cd torch_custom/fla_npu/
119+bash build.sh
120+```
121+ 
122+检验fla_npu是否安装成功
123+ 
124+```bash
125+pip list | grep fla_npu
126+```
127+ 
128+---
129+ 
130+<a id="jump2"></a>
131+ 
132+## 权重下载及转换
133+ 
134+<a id="jump2.1"></a>
135+ 
136+### 1. 权重下载
137+ 
138+从Huggingface库下载对应的模型权重:
139+ 
140+> [!NOTE]
141+>
142+> 如无法顺利访问HuggingFace社区下载资源,推荐前往ModelScope下载,需关注待下载文件的正确性与安全性。
143+ 
144+- 模型地址: [Qwen3.8系列模型](https://www.modelscope.cn/collections/Qwen/Qwen38);
145+ 
146+ 将下载的模型权重保存到本地的`ckpt/hf_path/xxxxxxx`目录下。(*表示对应的尺寸)
147+ 
148+<a id="jump2.2"></a>
149+ 
150+### 2. 权重加载
151+ 
152+当前支持huggingface权重或dcp权重加载,在`xxx_config.yaml``training->load_format`字段中配置加载权重的类型,支持`hf`, `dcp``auto`,设置为`auto`时会根据权重文件格式自行判断权重类型。
153+ 
154+如果需要加载dcp权重,请先根据模型配置完成以下hf权重到dcp权重的转换:
155+ 
156+```bash
157+mm-convert Qwen35Converter hf_to_dcp \
林明哲18 天前

权重转换似乎已经有新的方式了?

likedislike
且奏长歌
且奏长歌
18 天前 评论:
158+--hf_dir ckpt/hf_path/xxxxxxx \
159+--dcp_dir ckpt/dcp_path/xxxxxxx \
160+--num_workers 0
161+ 
162+# 其中:
163+# hf_dir: huggingface权重目录
164+# dcp_dir: 转换后DCP格式的权重保存目录
165+# num_workers: 并行工作线程数,0表示串行执行,若存储IO性能允许,可适当调大并发数以提升转换效率,推荐设置为4
166+ 
167+# 转换后的目录结构为:
168+# ———— xxxxxxx
169+# |—— release
170+# |—— latest_checkpointed_iteration.txt
171+```
172+ 
173+并在`xxx_config.yaml`中将`init_model_with_meta_device`参数配置为`True`,同时将`load`参数修改为转换后的dcp权重路径(写到`release`文件夹的上一级目录)。
174+注意:如果MoE模型不支持mtp,可在执行`mm-convert`权重转换前将`ckpt/hf_path/xxxxxxx/config.json`中的`mtp_num_hidden_layers`设置为0,以跳过mtp专家权重合并,缩短转换时间,如397B模型可以缩短约5分钟。
175+ 
176+<a id="jump2.3"></a>
177+ 
178+### 3. 权重保存
179+ 
180+MindSpeed MM保存权重类型支持huggingface格式和dcp格式,在`xxx_config.yaml``training->save_format`字段中配置保存权重的类型,支持`hf`, `dcp``auto`:
181+ 
182+(1)`save_format`配置为`auto`时,保存权重类型与加载权重类型保持一致;
183+ 
184+(2)`save_format`配置为`hf`时,会将保存权重文件转换为safetensors格式;
185+ 
186+**注意:hf保存格式仅支持保存权重,不支持保存优化器状态和随机数状态,若需要进行断点续训,请保存为dcp格式**
187+ 
188+(3)`save_format`配置为`dcp`时,可使用如下命令将dcp权重转换回hf权重:
189+ 
190+```bash
191+# 待转换的dcp权重目录结构样例为:
192+# ———— xxxxxxx
193+# |—— release
194+# |—— latest_checkpointed_iteration.txt
195+ 
196+mm-convert Qwen35Converter dcp_to_hf \
197+--save_hf_dir ckpt/save_hf_path/Qwen3.8-xxB-hf-save \
198+--dcp_dir ./save_path/iter_000xx \
199+--origin_hf_dir ckpt/hf_path/Qwen3.8-xxB \
200+--to_bf16 false \
201+--num_workers 0
202+ 
203+# 其中:
204+# save_hf_dir: 转换后Huggingface格式的权重保存目录
205+# dcp_dir: 保存的DCP格式权重目录,`iter_000xx`表示保存的第xx步的权重
206+# origin_hf_dir:原始Huggingface格式权重目录
207+# to_bf16:是否将权重数据类型从fp32转换成bf16
208+# num_workers: 并行工作线程数,0表示串行执行,若存储IO性能允许,可适当调大并发数以提升转换效率,推荐设置为4
209+```
210+ 
211+注意:如果模型没有开启mtp(即,在`xxx_config.yaml`中model下的`mtp_num_layers`字段配置为0或没有配置),默认转换后的权重中不会包含mtp层的权重,可以通过设置`--keep_origin_mtp_weights true`来保留mtp层的权重。
212+ 
213+---
214+<a id="jump3"></a>
215+ 
216+## 数据集准备及处理
217+ 
218+- 使用**真实数据集**训练:参考[针对VL模型的数据构造 · 使用真实数据集](../../docs/zh/features/building_data_for_VLModel.md#real-data)(下载COCO2017 → 下载LLaVA-Instruct-150K标注 → 运行转换脚本生成`mllm_format_llava_instruct_data.json`)。
219+- 使用**虚构数据**做功能/性能测试:参考[针对VL模型的数据构造 · 使用虚构数据](../../docs/zh/features/building_data_for_VLModel.md#mock-data)。
220+ 
221+## 微调
222+ 
223+<a id="jump4.1"></a>
224+ 
225+### 1. 准备工作
226+ 
227+配置脚本前需要完成前置准备工作,包括:**环境安装****权重下载及转换****数据集准备及处理**,详情可查看对应章节。
228+ 
229+<a id="jump4.2"></a>
230+ 
231+### 2. 配置参数
232+ 
233+【数据目录配置】
234+ 
235+根据实际情况修改`xxx_config.yaml`中的数据集路径,包括`model_name_or_path``dataset_dir``dataset`等字段。
236+ 
237+示例:如果数据及其对应的json都在/home/user/data/目录下,其中json目录为/home/user/data/video_data_path.json,此时配置如下:
238+`dataset_dir`配置为/home/user/data/;
239+`dataset`配置为./data/video_data_path.json
240+注意此时`dataset`需要配置为相对路径
241+**注意`cache_dir`在多机上不要配置同一个挂载目录避免写入同一个文件导致冲突**。
242+ 
243+【模块冻结配置】
244+ 
245+当前支持自定义冻结模块,在`xxx_config.yaml`中model->freeze字段中配置需要冻结的模块即可实现相应模块冻结。
246+ 
247+【模型保存加载及日志信息配置】
248+ 
249+根据实际情况配置`xxx_config.yaml``training`参数,包括保存路径以及保存间隔`save``save_interval`
250+根据实际情况配置`xxx_config.yaml`中的`init_from_hf_path`参数,该参数表示初始权重的加载路径。
251+ 
252+【Ulysses-CP并行配置】
253+ 
254+根据实际情况配置`xxx_config.yaml`中的`ulysses_parallel_size`以调整ulysses-cp的并行度。(`ulysses_parallel_size`为1时不开启ulysses-cp)
255+ 
256+**注意在开启ulysses-cp时,请将`xxx_config.yaml`中的`attn_implementation`配置为`flash_attention_2`**
257+ 
258+【EP并行配置】
259+ 
260+根据实际的需求配置`xxx_config.yaml`中的`expert_parallel_size`(注意仅对MoE模型生效)
261+ 
262+根据`expert_parallel_size`可以自行选择更合适的`ep_plan.dispatcher`,推荐`expert_parallel_size`小于`topk`时,`dispatcher`选择`allgather``expert_parallel_size`大于`topk`时选择`alltoall`
263+ 
264+【性能优化配置】
265+ 
266+- 重计算
267+ -`features.recompute`配置,`true`表示开启,`false`表示关闭,默认开启。
268+ - 开启后可以节省显存占用
269+- [chunkloss](../../docs/zh/features/chunkloss.md)
270+ -`features.enable_chunk_loss`配置,`true`表示开启,`false`表示关闭
271+ - `features.chunkloss_plan.chunk_size`表示计算loss的时候在seq维度切分成大小为`chunk_size`的小块进行计算。
272+ - 开启后可以大幅降低loss计算时的显存尖刺,节省整体显存占用
273+- [async activation offload](../../docs/zh/features/async_activation_offload.md)
274+ -`features.enable_activation_offload`配置,`true`表示开启,`false`表示关闭
275+ - 开启后可以异步将重计算入口的激活值offload至host侧,在开启了重计算的场景下可以进一步节省显存。
276+- [chunkmbs](../../docs/zh/features/chunkmbs.md)
277+ -`features.enable_chunk_mbs`配置,`true`表示开启,`false`表示关闭
278+ - `features.chunkmbs_plan.chunk_mbs`表示切分以后单次计算的`micro_batch_size`
279+ - 开启该特性时需要同时使能重计算和async activation offload特性,可以增加FSDP2单次unshard对应的计算密度,提高整网吞吐。
280+- 选择性重计算
281+ - 在开启重计算的场景下,可以跳过linear attention层的gdn重计算,或者full attention层的flash attention重计算,并异步offload中间保存的tensor,在显存占用不变的条件下,减少计算量,提升训练吞吐
282+ -`model.skip_gdn_recompute`配置是否跳过linear attention层gdn的重计算,`true`表示跳过,`false`表示不跳过
283+ -`model.skip_flash_attn_recompute`配置是否跳过full attention层的flash attention的重计算,`true`表示跳过,`false`表示不跳过
284+ - 开启该特性时需要同时使能重计算和async activation offload特性
285+- `gdn_implementation``causal_conv1d_implementation`
286+ - gdn_implementation和causal_conv1d_implementation分别支持`eager`,`triton`和`ascendc`配置,使用`ascendc`性能最佳,需要安装fla_npu库
287+ - 当gdn_implementation配置为`ascendc`时,causal_conv1d_implementation只支持和`triton`和`ascendc`,防止算子之间的布局不匹配
288+ 
289+【单机运行配置】
290+以qwen3_8模型为例:
291+配置`examples/qwen3_8/finetune_qwen3_8.sh`参数如下
292+ 
293+```shell
294+# 根据实际情况修改 ascend-toolkit 路径
295+source /usr/local/Ascend/ascend-toolkit/set_env.sh
296+NPUS_PER_NODE=16
297+MASTER_ADDR=localhost
298+MASTER_PORT=6000
299+NNODES=1
300+NODE_RANK=0
301+WORLD_SIZE=$(($NPUS_PER_NODE*$NNODES))
302+```
303+ 
304+【多机运行配置】
305+如需拉起多机训练,修改启动脚本下 MASTER_ADDR、NODE_ADDR、NNODES以及NODE_RANK变量
306+ 
307+``` shell
308+MASTER_ADDR: 主节点IP地址
309+NODE_ADDR: 本机IP地址
310+NODE_RANK: 第几个节点
311+NNODES: 一共几个节点
312+```
313+ 
314+---
315+ 
316+<a id="jump4.3"></a>
317+ 
318+### 3. 启动微调
319+ 
320+loss计算方式差异会对训练效果造成不同的影响,在启动训练任务之前,请查看关于loss计算的文档,选择合适的loss计算方式[vlm_model_loss_calculate_type.md](../../docs/zh/features/vlm_model_loss_calculate_type.md)
321+可在`xxx_config.yaml``model`参数中配置上述文档中的`loss_type`
322+ 
323+```shell
324+bash examples/qwen3_8/finetune_qwen3_8.sh
325+```
326+ 
327+<a id="jump10"></a>
328+ 
329+## 环境变量声明
330+ 
331+| 环境变量 | 描述 | 取值说明 |
332+|-------------------------------|--------------------------------------------------------------------|----------------------------------------------------------------------------------------------|
333+| `ASCEND_SLOG_PRINT_TO_STDOUT` | 是否开启日志打印 | `0`: 关闭日志打屏<br>`1`: 开启日志打屏 |
334+| `ASCEND_GLOBAL_LOG_LEVEL` | 设置应用类日志的日志级别及各模块日志级别,仅支持调试日志 | `0`: 对应DEBUG级别<br>`1`: 对应INFO级别<br>`2`: 对应WARNING级别<br>`3`: 对应ERROR级别<br>`4`: 对应NULL级别,不输出日志 |
335+| `TASK_QUEUE_ENABLE` | 用于控制开启task_queue算子下发队列优化的等级 | `0`: 关闭<br>`1`: 开启Level 1优化<br>`2`: 开启Level 2优化 |
336+| `COMBINED_ENABLE` | 设置combined标志。设置为0表示关闭此功能;设置为1表示开启,用于优化非连续两个算子组合类场景 | `0`: 关闭<br>`1`: 开启 |
337+| `CPU_AFFINITY_CONF` | 控制CPU端算子任务的处理器亲和性,即设定任务绑核 | 设置`0`或未设置: 表示不启用绑核功能<br>`1`: 表示开启粗粒度绑核<br>`2`: 表示开启细粒度绑核 |
338+| `HCCL_CONNECT_TIMEOUT` | 用于限制不同设备之间socket建链过程的超时等待时间 | 需要配置为整数,取值范围`[120,7200]`,默认值为`120`,单位`s` |
339+| `PYTORCH_NPU_ALLOC_CONF` | 控制缓存分配器行为 | `expandable_segments:<value>`: 使能内存池扩展段功能,即虚拟内存特征 |
340+| `HCCL_EXEC_TIMEOUT` | 控制设备间执行时同步等待的时间,在该配置时间内各设备进程等待其他设备执行通信同步 | 需要配置为整数,取值范围`[68,17340]`,默认值为`1800`,单位`s` |
341+| `ACLNN_CACHE_LIMIT` | 配置单算子执行API在Host侧缓存的算子信息条目个数 | 需要配置为整数,取值范围`[1, 10,000,000]`,默认值为`10000` |
342+| `TOKENIZERS_PARALLELISM` | 用于控制Hugging Face的transformers库中的分词器(tokenizer)在多线程环境下的行为 | `False`: 禁用并行分词<br>`True`: 开启并行分词 |
343+| `MULTI_STREAM_MEMORY_REUSE` | 配置多流内存复用是否开启 | `0`: 关闭多流内存复用<br>`1`: 开启多流内存复用 |
344+| `NPU_ASD_ENABLE` | 控制是否开启TorchNPU的特征值检测功能 | 设置`0`或未设置: 关闭特征值检测<br>`1`: 表示开启特征值检测,只打印异常日志,不告警<br>`2`:开启特征值检测,并告警<br>`3`:开启特征值检测,并告警,同时会在device侧info级别日志中记录过程数据 |
345+| `ASCEND_LAUNCH_BLOCKING` | 控制算子执行时是否启动同步模式 | `0`: 采用异步方式执行<br>`1`: 强制算子采用同步模式运行 |
346+| `NPUS_PER_NODE` | 配置一个计算节点上使用的NPU数量 | 整数值(如 `1`, `8` 等) |
347+ 
348+---
349+<a id="jump11"></a>
350+ 
351+## 注意事项
352+ 
353+1. 在加载 processor 过程中,会因 `mistral_common` 三方库版本的兼容性问题导致无法找到 processor,进而训练报错退出,可通过以下方式解决:
354+ - 卸载`mistral_common` 三方库:pip uninstall -y mistral_common
355+ - 升级`mistral_common` 三方库至最新版本:pip install --upgrade mistral_common
Ssongxy14 天前

qwen3_8_config.yaml / finetune_qwen3_8.sh 没有尺寸后缀,而 qwen3_8_27B_config.yaml / finetune_qwen3_8_27B.sh 有 _27B 后缀。建议 MoE 版本也加上对应尺寸后缀(如 _2_4T),保持命名一致。

likedislike
且奏长歌
且奏长歌
14 天前 评论:
@@ -0,0 +1,42 @@
1+# 根据实际情况修改 ascend-toolkit 路径
2+source /usr/local/Ascend/cann/set_env.sh
3+export NON_MEGATRON=true
4+export MULTI_STREAM_MEMORY_REUSE=2
5+export TASK_QUEUE_ENABLE=2
6+export ASCEND_LAUNCH_BLOCKING=0
7+export ACLNN_CACHE_LIMIT=100000
8+export CPU_AFFINITY_CONF=1
9+export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
10+export HCCL_CONNECT_TIMEOUT=7200
11+ 
12+# 删除triton的cache
13+# export TRITON_CACHE_DIR=./triton_cache
14+# rm -rf $TRITON_CACHE_DIR/*
15+ 
16+NPUS_PER_NODE=16
17+MASTER_ADDR=localhost
18+MASTER_PORT=6000
19+NNODES=1
20+NODE_RANK=0
21+WORLD_SIZE=$(($NPUS_PER_NODE*$NNODES))
22+ 
23+DISTRIBUTED_ARGS="
24+ --nproc_per_node $NPUS_PER_NODE \
25+ --nnodes $NNODES \
26+ --node_rank $NODE_RANK \
27+ --master_addr $MASTER_ADDR \
28+ --master_port $MASTER_PORT
29+"
30+ 
31+logdir=logs/qwen38
32+logfile=qwen38_$(date +%Y%m%d)_$(date +%H%M%S)
33+mkdir -p $logdir
34+torchrun $DISTRIBUTED_ARGS mindspeed_mm/fsdp/train/trainer.py \
35+ examples/qwen3_8/qwen3_8_config.yaml \
36+ 2>&1 | tee ${logdir}/${logfile}.log \
37+ 
38+STEP_TIME=`grep "elapsed time per iteration" ${logdir}/${logfile}.log | awk -F 'elapsed time per iteration [(]ms[)]:' '{print$2}' | awk -F '|' '{print$1}' | head -n 200 | tail -n 10 | awk '{sum+=$1} END {if (NR != 0) printf("%.1f",sum/NR)}'`
39+GBS=`grep "global batch size" ${logdir}/${logfile}.log | awk -F 'global batch size:' '{print$2}' | awk -F '|' '{print$1}' | head -n 1 | awk '{print $1}'`
40+SAMPLES_PER_SECOND=`awk 'BEGIN{printf "%.3f\n", '${GBS}'*1000/'${STEP_TIME}'}'`
41+echo "Elapsed Time Per iteration (ms): $STEP_TIME" | tee -a ${logdir}/${logfile}.log
42+echo "Average Samples per Second: $SAMPLES_PER_SECOND" | tee -a ${logdir}/${logfile}.log
@@ -0,0 +1,42 @@
1+# 根据实际情况修改 ascend-toolkit 路径
2+source /usr/local/Ascend/cann/set_env.sh
3+export NON_MEGATRON=true
4+export MULTI_STREAM_MEMORY_REUSE=2
5+export TASK_QUEUE_ENABLE=2
6+export ASCEND_LAUNCH_BLOCKING=0
7+export ACLNN_CACHE_LIMIT=100000
8+export CPU_AFFINITY_CONF=1
9+export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
10+export HCCL_CONNECT_TIMEOUT=7200
11+ 
12+# 删除triton的cache
13+# export TRITON_CACHE_DIR=./triton_cache
14+# rm -rf $TRITON_CACHE_DIR/*
15+ 
16+NPUS_PER_NODE=16
17+MASTER_ADDR=localhost
18+MASTER_PORT=6000
19+NNODES=1
20+NODE_RANK=0
21+WORLD_SIZE=$(($NPUS_PER_NODE*$NNODES))
22+ 
23+DISTRIBUTED_ARGS="
24+ --nproc_per_node $NPUS_PER_NODE \
25+ --nnodes $NNODES \
26+ --node_rank $NODE_RANK \
27+ --master_addr $MASTER_ADDR \
28+ --master_port $MASTER_PORT
29+"
30+ 
31+logdir=logs/qwen38
32+logfile=qwen38_27B_$(date +%Y%m%d)_$(date +%H%M%S)
33+mkdir -p $logdir
34+torchrun $DISTRIBUTED_ARGS mindspeed_mm/fsdp/train/trainer.py \
35+ examples/qwen3_8/qwen3_8_27B_config.yaml \
36+ 2>&1 | tee ${logdir}/${logfile}.log \
37+ 
38+STEP_TIME=`grep "elapsed time per iteration" ${logdir}/${logfile}.log | awk -F 'elapsed time per iteration [(]ms[)]:' '{print$2}' | awk -F '|' '{print$1}' | head -n 200 | tail -n 10 | awk '{sum+=$1} END {if (NR != 0) printf("%.1f",sum/NR)}'`
39+GBS=`grep "global batch size" ${logdir}/${logfile}.log | awk -F 'global batch size:' '{print$2}' | awk -F '|' '{print$1}' | head -n 1 | awk '{print $1}'`
40+SAMPLES_PER_SECOND=`awk 'BEGIN{printf "%.3f\n", '${GBS}'*1000/'${STEP_TIME}'}'`
41+echo "Elapsed Time Per iteration (ms): $STEP_TIME" | tee -a ${logdir}/${logfile}.log
42+echo "Average Samples per Second: $SAMPLES_PER_SECOND" | tee -a ${logdir}/${logfile}.log
@@ -0,0 +1,183 @@
1+# 并行策略
2+parallel:
3+ fully_shard_parallel_size: auto
4+ fsdp_plan:
5+ apply_modules: # 如果要开prefetch的话,请不要随意修改apply_modules的顺序
6+ - model.visual
7+ - model.visual.blocks.{*}
8+ - model.language_model.embed_tokens
9+ - model.language_model
10+ - model.language_model.layers.{*}
11+ - lm_head
12+ - mtp
13+ param_dtype: bf16
14+ reduce_dtype: fp32
15+ num_to_forward_prefetch: 1
16+ num_to_backward_prefetch: 1
17+ ulysses_parallel_size: 1 # 开启 ulysses-cp 时, 请将 model 的 attn_implementation 设置为 flash_attention_2
18+ 
19+### 数据相关配置
20+data:
21+ dataset_param: &TRAIN_DATASET_PARAM
22+ dataset_type: huggingface
23+ #数据集属性
24+ attr:
25+ images: images
26+ messages: messages
27+ role_tag: role
28+ content_tag: content
29+ user_tag: user
30+ assistant_tag: assistant
31+ 
32+ # 数据预处理
33+ preprocess_parameters:
34+ model_name_or_path: &HF_MODEL_LOAD_PATH ./ckpt/hf_path/Qwen38-xxB # 替换为原始hf权重
35+ use_fast_tokenizer: true
36+ split_special_tokens: false
37+ image_max_pixels: 262144
38+ image_min_pixels: 1024
39+ video_max_pixels: 16384
40+ video_min_pixels: 0
41+ video_fps: 2.0
42+ video_maxlen: 64
43+ 
44+ basic_parameters: &TRAIN_BASIC_PARAMETERS
45+ cutoff_len: 16384
46+ template: qwen3_vl_nothink
47+ enable_thinking: false
48+ train_on_prompt: false
49+ mask_history: false
50+ dataset_dir: ./data/COCO2017
51+ dataset: &DATASET_PATH ./data/mllm_format_llava_instruct_data.json
52+ cache_dir: ./cache_dir/
53+ overwrite_cache: false
54+ preprocess_on_fly: true
55+ preprocessing_batch_size: 1000
56+ preprocessing_num_workers: 16
57+ max_samples: null
58+ 
59+ val_dataset_param:
60+ <<: *TRAIN_DATASET_PARAM
61+ basic_parameters:
62+ <<: *TRAIN_BASIC_PARAMETERS
63+ dataset: ./data/mllm_format_llava_instruct_data_val.json
64+ cache_dir: ./cache_dir/val
65+ 
66+ # 数据加载
67+ dataloader_param:
68+ pin_memory: true
69+ shuffle: true
70+ dataloader_mode: sampler
71+ drop_last: true
72+ sampler_type: BaseRandomBatchSampler
73+ num_workers: 8
74+ collate_param:
75+ model_name: qwen3vl
76+ ignore_pad_token_for_loss: true
77+ enable_preload: true
78+ 
79+# 模型配置
80+model:
81+ model_id: qwen3_5
82+ model_name_or_path: *HF_MODEL_LOAD_PATH
83+ trust_remote_code: true
84+ attn_implementation: flash_attention_2
85+ # 冻结部分模块
86+ # freeze:
87+ # - model.visual
88+ # 融合算子配置
89+ gdn_implementation: ascendc
90+ causal_conv1d_implementation: ascendc
91+ # skip_recompute
92+ skip_gdn_recompute: true
93+ skip_flash_attn_recompute: true
94+ 
95+# 优化特性配置
96+features:
97+ # loss 配置
98+ loss_cfg:
99+ loss_type: default # If you want raw loss in model, loss_type can be set to "raw".
100+ router_aux_loss_coef: 0.0
101+ # 重计算配置
102+ recompute: true
103+ recompute_plan:
104+ apply_modules:
105+ - model.visual.blocks.{*}
106+ - model.language_model.layers.{*}
107+ # chunkloss配置
108+ enable_chunk_loss: true
109+ chunkloss_plan:
110+ apply_module: lm_head
111+ chunk_size: 512
112+ # activation offload 配置
113+ enable_activation_offload: true
114+ activation_offload_plan:
115+ apply_modules:
116+ - model.visual.blocks.{*}
117+ - model.language_model.layers.{*}
118+ # chunkmbs配置
119+ enable_chunk_mbs: false
120+ chunkmbs_plan:
121+ apply_modules:
122+ - model.language_model.layers.{*}
123+ chunk_mbs: 1 # 这个表示的是chunk之后的micro batchsize
124+ batch_dim: 0
125+ chunk_arg_indexs: [0]
126+ chunk_kwarg_names: ["position_embeddings", "position_ids", "rope_deltas", "attention_mask"]
127+ 
128+# 训练配置
129+training:
130+ micro_batch_size: 1
131+ gradient_accumulation_steps: 1
132+ seed: 42
133+ lr: 1.0e-5
134+ lr_decay_style: cosine
135+ lr_warmup_ratio: 0.1
136+ weight_decay: 0
137+ train_iters: 100
138+ val_interval: 0
139+ val_micro_batch_size: 1
140+ clip_grad: 0.0
141+ init_model_with_meta_device: true
142+ optimizer: adamw
143+ adam_fused: true
144+ save_interval: 10000
145+ no_load_optim: true # Do not load optimizer state; remove if loading is needed.
146+ no_load_rng: true # Do not load RNG state; remove if loading is needed.
147+ no_save_optim: true # Do not save optimizer state; remove if saving is needed.
148+ no_save_rng: true # Do not save RNG state; remove if saving is needed.
149+ # load: ./ckpt/hf_path/Qwen38-xxB # 根据load_format替换为hf权重或转换后的dcp权重路径
150+ # load_format: auto # 设置为auto时根据加载文件格式自动判断是hf权重还是dcp权重
151+ # save: ./save_path
152+ # save_format: dcp
153+ use_deter_comp: false
154+ plugin:
155+ - mindspeed_mm/fsdp/models/qwen3_5
156+ - mindspeed_mm/fsdp/data/datasets/huggingface
157+ 
158+# 工具配置
159+tools:
160+ profile:
161+ enable: false
162+ profile_type: static
163+ ranks: [0]
164+ static_param:
165+ level: level1
166+ with_stack: true
167+ with_memory: true
168+ record_shapes: true
169+ with_cpu: true
170+ save_path: ./profiling
171+ start_step: 29
172+ end_step: 32
173+ data_simplification: false
174+ aic_metrics_type: PipeUtilization
175+ memory_profile:
176+ enable: false
177+ start_step: 1
178+ end_step: 2
179+ save_path: ./memory_snapshot
180+ dump_ranks: [0]
181+ stacks: all
182+ max_entries: null
183+ mem_info: false
@@ -0,0 +1,184 @@
1+# 并行策略
2+parallel:
3+ fully_shard_parallel_size: auto
4+ fsdp_plan:
5+ apply_modules: # 如果要开prefetch的话,请不要随意修改apply_modules的顺序
6+ - model.embed_tokens
林明哲18 天前

此处FQN表达式正确?

likedislike
且奏长歌
且奏长歌
18 天前 评论:
7+ - model
8+ - model.layers.{*}
9+ - model.layers.{*}.linear_attn
10+ - model.layers.{*}.mlp.experts
11+ - lm_head
12+ - mtp
13+ hook_modules:
14+ - model.layers.{*}
15+ param_dtype: bf16
16+ reduce_dtype: fp32
17+ num_to_forward_prefetch: 1
18+ num_to_backward_prefetch: 1
19+ ulysses_parallel_size: 1 # 开启 ulysses-cp 时, 请将 model 的 attn_implementation 设置为 flash_attention_2
20+ expert_parallel_size: 1
21+ ep_plan:
22+ apply_modules:
23+ - model.layers.{*}.mlp.experts
24+ dispatcher: alltoall
25+ 
26+### 数据相关配置
27+data:
28+ dataset_param: &TRAIN_DATASET_PARAM
29+ dataset_type: huggingface
30+ #数据集属性
31+ attr:
32+ messages: messages
33+ role_tag: role
34+ content_tag: content
35+ user_tag: user
36+ assistant_tag: assistant
37+ 
38+ # 数据预处理
39+ preprocess_parameters:
40+ model_name_or_path: &HF_MODEL_LOAD_PATH ./ckpt/hf_path/Qwen38-xxB # 替换为原始hf权重
41+ use_fast_tokenizer: true
42+ split_special_tokens: false
43+ 
44+ basic_parameters: &TRAIN_BASIC_PARAMETERS
45+ cutoff_len: 1024
46+ template: qwen3_6_nothink
47+ enable_thinking: false
48+ train_on_prompt: false
49+ mask_history: false
50+ dataset_dir: ./data/
51+ dataset: &DATASET_PATH ./data/xxx_data_train.json
52+ cache_dir: ./cache_dir/
53+ overwrite_cache: false
54+ preprocess_on_fly: true
55+ preprocessing_batch_size: 1000
56+ preprocessing_num_workers: 16
57+ max_samples: null
58+ 
59+ val_dataset_param:
60+ <<: *TRAIN_DATASET_PARAM
61+ basic_parameters:
62+ <<: *TRAIN_BASIC_PARAMETERS
63+ dataset: ./data/mllm_format_llava_instruct_data_val.json
64+ cache_dir: ./cache_dir/val
65+ 
66+ # 数据加载
67+ dataloader_param:
68+ pin_memory: true
69+ shuffle: true
70+ dataloader_mode: sampler
71+ drop_last: true
72+ sampler_type: BaseRandomBatchSampler
73+ num_workers: 8
74+ collate_param:
75+ model_name: qwen3vl
76+ ignore_pad_token_for_loss: true
77+ enable_preload: true
78+ 
79+# 模型配置
80+model:
81+ model_id: qwen3_8_moe
82+ model_name_or_path: *HF_MODEL_LOAD_PATH
83+ trust_remote_code: true
84+ attn_implementation: flash_attention_2
85+ # 融合算子配置
86+ gdn_implementation: ascendc
87+ causal_conv1d_implementation: ascendc
88+ use_grouped_expert_matmul: true
89+ # skip_recompute
90+ skip_gdn_recompute: true
91+ skip_flash_attn_recompute: true
92+ 
93+# 优化特性配置
94+features:
95+ # loss 配置
96+ loss_cfg:
97+ loss_type: default # If you want raw loss in model, loss_type can be set to "raw".
98+ router_aux_loss_coef: 0.0
99+ # 重计算配置
100+ recompute: true
101+ recompute_plan:
102+ apply_modules:
103+ - model.layers.{*}
104+ # chunkloss配置
105+ enable_chunk_loss: true
106+ chunkloss_plan:
107+ apply_module: lm_head
108+ chunk_size: 512
109+ # activation offload 配置
110+ enable_activation_offload: true
111+ activation_offload_plan:
112+ apply_modules:
113+ - model.layers.{*}
114+ # chunkmbs配置
115+ enable_chunk_mbs: true
116+ chunkmbs_plan:
117+ apply_modules:
118+ - model.layers.{*}
119+ chunk_mbs: 1 # 这个表示的是chunk之后的micro batchsize
120+ batch_dim: 0
121+ chunk_arg_indexs: [0]
122+ chunk_kwarg_names: ["position_embeddings", "position_ids", "rope_deltas", "attention_mask"]
123+ 
124+ # ep balance
125+ enable_ep_balance: false
126+ ep_balance_plan:
127+ max_dup_experts_num: 2
128+ 
129+# 训练配置
130+training:
131+ micro_batch_size: 2
132+ gradient_accumulation_steps: 1
133+ seed: 42
134+ lr: 1.0e-5
135+ lr_decay_style: cosine
136+ lr_warmup_ratio: 0.1
137+ weight_decay: 0
138+ train_iters: 100
139+ val_interval: 0
140+ val_micro_batch_size: 1
141+ clip_grad: 0.0
142+ init_model_with_meta_device: true
143+ optimizer: adamw
144+ adam_fused: true
145+ save_interval: 10000
146+ no_load_optim: true # Do not load optimizer state; remove if loading is needed.
147+ no_load_rng: true # Do not load RNG state; remove if loading is needed.
148+ no_save_optim: true # Do not save optimizer state; remove if saving is needed.
149+ no_save_rng: true # Do not save RNG state; remove if saving is needed.
150+ # load: ./ckpt/hf_path/Qwen38-xxB # 根据load_format替换为hf权重或转换后的dcp权重路径
151+ # load_format: auto # 设置为auto时根据加载文件格式自动判断是hf权重还是dcp权重
152+ # save: ./save_path
153+ # save_format: dcp
154+ use_deter_comp: false
155+ plugin:
156+ - mindspeed_mm/fsdp/models/qwen3_5_moe
157+ - mindspeed_mm/fsdp/data/datasets/huggingface
158+ 
159+# 工具配置
160+tools:
161+ profile:
162+ enable: false
163+ profile_type: static
164+ ranks: [0]
165+ static_param:
166+ level: level1
167+ with_stack: true
168+ with_memory: true
169+ record_shapes: true
170+ with_cpu: true
171+ save_path: ./profiling
172+ start_step: 29
173+ end_step: 32
174+ data_simplification: false
175+ aic_metrics_type: PipeUtilization
176+ memory_profile:
177+ enable: false
178+ start_step: 1
179+ end_step: 2
180+ save_path: ./memory_snapshot
181+ dump_ranks: [0]
182+ stacks: all
183+ max_entries: null
184+ mem_info: false
@@ -2425,6 +2425,7 @@ def load_balancing_loss_func(
2425 2425 
2426 2426 
2427@auto_docstring2427@auto_docstring
2428+@model_register.register("qwen3_8_moe")
2428class Qwen3_5MoeForCausalLM(Qwen3_5MoePreTrainedModel, GenerationMixin):2429class Qwen3_5MoeForCausalLM(Qwen3_5MoePreTrainedModel, GenerationMixin):
2429 _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}2430 _tied_weights_keys = {"lm_head.weight": "model.embed_tokens.weight"}
2430 _tp_plan = {"lm_head": "colwise_gather_output"}2431 _tp_plan = {"lm_head": "colwise_gather_output"}
@@ -2440,10 +2441,74 @@ class Qwen3_5MoeForCausalLM(Qwen3_5MoePreTrainedModel, GenerationMixin):
2440 self.router_aux_loss_coef = config.router_aux_loss_coef2441 self.router_aux_loss_coef = config.router_aux_loss_coef
2441 self.num_experts = config.num_experts2442 self.num_experts = config.num_experts
2442 self.num_experts_per_tok = config.num_experts_per_tok2443 self.num_experts_per_tok = config.num_experts_per_tok
2444+ self.enable_mtp = bool(config.mtp_num_layers)
2445+ self.mtp = MultiTokenPredictionBlock(
2446+ config, Qwen3_5MoeDecoderLayer, Qwen3_5MoeRMSNorm
2447+ ) if self.enable_mtp else None
atomgit-bot
atomgit-botatomgit-bot18 天前

🟡 Medium Priority

建议:在 Qwen3_5MoeForCausalLM 中参照 Qwen3_5MoeForConditionalGeneration 增加 _compute_mtp_loss 并在 forward 末尾调用、把结果写入输出对象的 mtp_loss;否则删除 MTP 初始化并拒绝 mtp_num_layers=1。

likedislike
且奏长歌
且奏长歌
18 天前 评论:
2443 2448 
2444 # Initialize weights and apply final processing2449 # Initialize weights and apply final processing
2445 self.post_init()2450 self.post_init()
2446 2451 
2452+ @staticmethod
2453+ def overwrite_transformer_config(transformer_config, model_args, feature_args):
2454+ # gdn_implementation
2455+ gdn_implementation = getattr(model_args, "gdn_implementation", IMPL_EAGER).lower().strip()
2456+ if gdn_implementation not in IMPL_FOR_GDN:
2457+ raise ValueError(f"Invalid gdn_implementation='{gdn_implementation}'. Must be one of: 'eager', 'triton', 'ascendc'.")
2458+ transformer_config.gdn_implementation = gdn_implementation
2459+ 
2460+ # causal conv1d implementation
2461+ causal_conv1d_implementation = getattr(model_args, "causal_conv1d_implementation", IMPL_EAGER).lower().strip()
2462+ if causal_conv1d_implementation not in IMPL_FOR_CAUSAL_CONV:
2463+ raise ValueError(f"Invalid causal_conv1d='{causal_conv1d_implementation}'. Must be one of: 'eager', 'triton', 'ascendc'.")
2464+ transformer_config.causal_conv1d_implementation = causal_conv1d_implementation
2465+ 
2466+ if (gdn_implementation == "ascendc") and (causal_conv1d_implementation == "eager"):
2467+ raise ValueError(
2468+ f"Inconsistent implementations: gdn='{gdn_implementation}', "
2469+ f"causal_conv1d='{causal_conv1d_implementation}'. "
2470+ f"gdn can be 'ascendc' only if causal_conv1d is not 'eager'."
2471+ )
2472+ 
2473+ # skip flash attn recompute
2474+ skip_flash_attn_recompute = getattr(model_args, "skip_flash_attn_recompute", False)
2475+ if skip_flash_attn_recompute and gdn_implementation == "eager":
2476+ raise ValueError(
2477+ "skip_flash_attn_recompute cannot be True when gdn_implementation is 'eager'. "
2478+ "Please set skip_flash_attn_recompute to False or use a different gdn_implementation."
2479+ )
2480+ transformer_config.skip_flash_attn_recompute = skip_flash_attn_recompute
2481+ 
2482+ # skip gdn recompute
2483+ skip_gdn_recompute = getattr(model_args, "skip_gdn_recompute", False)
2484+ transformer_config.skip_gdn_recompute = skip_gdn_recompute
2485+ 
2486+ # moe compute
2487+ use_grouped_expert_matmul = getattr(model_args, "use_grouped_expert_matmul", False)
2488+ transformer_config.use_grouped_expert_matmul = use_grouped_expert_matmul
2489+ 
2490+ # aux loss
2491+ transformer_config.router_aux_loss_coef = feature_args.loss_cfg.router_aux_loss_coef
2492+ transformer_config.router_aux_loss_offload = feature_args.loss_cfg.router_aux_loss_offload
2493+ # mtp
2494+ mtp_num_layers = getattr(model_args, "mtp_num_layers", 0)
2495+ if mtp_num_layers not in (0, 1):
2496+ raise ValueError(f"Invalid mtp_num_layers='{mtp_num_layers}'. Must be one of: 0, 1.")
2497+ transformer_config.mtp_num_layers = mtp_num_layers
2498+ 
2499+ # chunkloss
2500+ transformer_config.enable_chunk_loss = getattr(feature_args, "enable_chunk_loss", False)
2501+ transformer_config.enable_dynamic_chunk_loss = getattr(feature_args, "enable_dynamic_chunk_loss", False)
2502+ 
2503+ # ep balance
2504+ transformer_config.enable_ep_balance = getattr(feature_args, "enable_ep_balance", False)
2505+ transformer_config.max_dup_experts_num = getattr(feature_args.ep_balance_plan, "max_dup_experts_num", 2)
2506+ 
2507+ # skip moe pad tokens
2508+ transformer_config.skip_moe_pad_tokens = getattr(feature_args, "skip_moe_pad_tokens", False)
2509+ 
2510+ return transformer_config
2511+ 
2447 @can_return_tuple2512 @can_return_tuple
2448 @auto_docstring2513 @auto_docstring
2449 def forward(2514 def forward(
@@ -2503,11 +2568,21 @@ class Qwen3_5MoeForCausalLM(Qwen3_5MoePreTrainedModel, GenerationMixin):
2503 hidden_states = outputs.last_hidden_state2568 hidden_states = outputs.last_hidden_state
2504 # Only compute necessary logits, and do not upcast them to float if we are not computing the loss2569 # Only compute necessary logits, and do not upcast them to float if we are not computing the loss
2505 slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep2570 slice_indices = slice(-logits_to_keep, None) if isinstance(logits_to_keep, int) else logits_to_keep
2506- logits = self.lm_head(hidden_states[:, slice_indices, :])2571+ if getattr(self, "enable_chunk_loss", False) or getattr(self, "enable_dynamic_chunk_loss", False):
2572+ logits = None
2573+ loss = self.lm_head(hidden_states[:, slice_indices, :], self.loss_function)
2574+ else:
2575+ logits = self.lm_head(hidden_states[:, slice_indices, :])
2507 2576 
2508- loss = None2577+ loss = None
2509- if labels is not None:2578+ if labels is not None:
2510- loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)2579+ loss = self.loss_function(logits, labels, self.vocab_size, **kwargs)
2580+ 
2581+ # Modification: all gather loss in all cp ranks for scaling up the grad.
2582+ ps = get_parallel_state()
2583+ if loss is not None and ps.is_cp_enable():
2584+ loss = gather_forward_split_backward(loss.unsqueeze(0), ps.get_cp_group(), dim=0)
2585+ loss = loss.sum()
2511 2586 
2512 aux_loss = None2587 aux_loss = None
2513 if output_router_logits:2588 if output_router_logits: