已合并
feat: Adapt Qwen3.8 on MindSpeed MM #2979
且奏长歌创建于 18 天前
feat: Adapt Qwen3.8 on MindSpeed MM #2979
已合并
共 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 | ||
林 | |||
| 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 \ | ||
| 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 | ||
| @@ -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: | ||
| 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: | ||
| 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 | + <<: | ||
| 61 | + basic_parameters: | ||
| 62 | + <<: | ||
| 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: | ||
| 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 | ||
| 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: | ||
| 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: | ||
| 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 | + <<: | ||
| 61 | + basic_parameters: | ||
| 62 | + <<: | ||
| 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: | ||
| 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 | 2427 | ||
| 2428 | + | ||
| 2428 | class Qwen3_5MoeForCausalLM(Qwen3_5MoePreTrainedModel, GenerationMixin): | 2429 | class 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_coef | 2441 | self.router_aux_loss_coef = config.router_aux_loss_coef |
| 2441 | self.num_experts = config.num_experts | 2442 | self.num_experts = config.num_experts |
| 2442 | self.num_experts_per_tok = config.num_experts_per_tok | 2443 | 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 | ||
🟡 Medium Priority 建议:在 Qwen3_5MoeForCausalLM 中参照 Qwen3_5MoeForConditionalGeneration 增加 ![]() ![]() | |||
| 2443 | 2448 | ||
| 2444 | # Initialize weights and apply final processing | 2449 | # Initialize weights and apply final processing |
| 2445 | self.post_init() | 2450 | self.post_init() |
| 2446 | 2451 | ||
| 2452 | + | ||
| 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 | 2512 | ||
| 2448 | 2513 | ||
| 2449 | def forward( | 2514 | def forward( |
| @@ -2503,11 +2568,21 @@ class Qwen3_5MoeForCausalLM(Qwen3_5MoePreTrainedModel, GenerationMixin): | |||
| 2503 | hidden_states = outputs.last_hidden_state | 2568 | hidden_states = outputs.last_hidden_state |
| 2504 | # Only compute necessary logits, and do not upcast them to float if we are not computing the loss | 2569 | # 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_keep | 2570 | 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 = None | 2577 | + 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 = None | 2587 | aux_loss = None |
| 2513 | if output_router_logits: | 2588 | if output_router_logits: |


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