verl 中 MTP 的三种训练模式(仅加载、全参数、仅 MTP 参数)怎么配置和选择?
【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl
在 verl 中对带 MTP(Multi-Token Prediction)模块的模型(如 mimo-7B-RL、Qwen-next、Deepseek 系列)做 SFT 或 RL 训练时,需要决定 MTP 模块以哪种方式参与:只加载不训练、全参数训练、还是冻结 Encoder 只训 MTP 参数。本文基于 MTP 官方指南 和仓库内两个示例脚本,说明三种模式的配置位置、参数写法,以及文档给出的实验结论如何帮助选择,最后给出 RL 与 SFT 两条可直接对照的启动路径和验证方式。
前提:MTP 训练只支持特定的训练引擎组合
docs/advance/mtp.md 明确了支持范围,配置之前先确认自己的环境落在支持范围内:
- 训练引擎:只支持
mbridge/Megatron-Bridge + megatron组合,其他训练引擎暂不兼容; - 推理引擎:兼容所有引擎,但模型必须在对应引擎的兼容列表内;
- 依赖版本(文档给出的组合要求):
- mbridge:需包含 PR #62 的补丁(已合入 main 分支);
- Megatron-Bridge:若要跑 mimo-7B-RL,需应用 PR #2387 的补丁(文档标注未来会合入 main);
- megatron:使用 dev 版本 commit
23e092f41ec8bc659020e401ddac9576c1cfed7e,支持 MTP + CP 训练;如果额外启用recompute_granularity=full,必须改用包含 PR #3457 的 dev commit(ffd66a3e6,2026-06-03)——固定 commit 比它早约半年,且megatron-core0.18.0 / 0.18.2 也未包含该修复,否则第一步训练就会因MultiTokenPredictionLayer收到未声明的padding_mask关键字而抛TypeError; - sglang:使用
fix_mtp_update_weights_from_tensor分支,该分支修复 MTP update weights from tensor 的 OOM 问题。
另外,RL 示例脚本 中有一条必须执行的前置步骤:下载模型后,要在模型的config.json中设置max_position_embeddings=32768,否则按脚本默认配置跑不起来。
三种模式的配置:参数在哪改
所有 MTP 配置都以模型配置下的mtp段为前缀:RL 训练脚本中是actor_rollout_ref.model.mtp(见 RL 脚本),SFT 训练脚本中是model.mtp(见 SFT 脚本)。这些字段的定义见 MtpConfig,默认值与 hf_model.yaml 一致:enable=False、enable_train=False、detach_encoder=False、mtp_loss_scaling_factor=0.1。
官方文档给出的三种训练场景与对应参数:
| 配置场景 | 核心参数 | 文档说明 |
|---|---|---|
| 仅加载 MTP 参数 | enable=True | 显存占用会增加,但导出的参数包含 MTP 模块,可直接用于在线部署 |
| 全参数 MTP 训练 | enable=True、enable_train=True、mtp_loss_scaling_factor=0.1 | MTP Loss 作用于所有模型参数 |
| 仅 MTP 参数训练 | enable=True、enable_train=True、detach_encoder=True | 冻结 Encoder 层,只更新 MTP 模块参数,MTP Loss 只作用于 MTP 参数 |
三者是递进关系:enable控制 MTP 参数的加载与保存;enable_train控制训练时是否实际使用 MTP 参数;detach_encoder在全参数训练基础上进一步冻结 Encoder,把梯度限制在 MTP 模块内。mtp_loss_scaling_factor是 MTP Loss 的缩放系数,配置默认值为 0.1。
怎么选:文档给出的实验结论
选型依据直接来自文档在 mimo-7B-math、max_response_length=8k上的实验结果:
对训练结果无显著影响的配置:
- 基座模型本身不带 MTP 参数;
- 基座模型带 MTP 参数,但 MTP 模块不参与训练;
- 基座模型带 MTP 参数并训练 MTP,但
mtp_loss_scaling_factor=0; - 基座模型带 MTP 参数、训练 MTP 且 detach encoder,
mtp_loss_scaling_factor=0.1。
对训练结果有显著影响的配置只有:
- 基座模型带 MTP 参数,MTP Loss 作用于所有模型参数,且
mtp_loss_scaling_factor=0.1(即全参数训练模式)。
文档同时给出的推荐训练方式是detach_encoder=True。注意这是文档原文并列的两条结论:实验上只有全参数模式影响主训练结果,而推荐做法是 detach encoder 只训 MTP 参数——选择时以基座模型是否自带 MTP 参数为前提(不带 MTP 参数的模型上,任何 MTP 配置都不会产生效果),再按上述结论取舍。
主路径:RL 训练脚本(对应"仅 MTP 参数"模式)
examples/mtp_trainer/run_mimo_7b_mtp_megatron.sh 是 MiMo-7B 上 SGLang rollout + Megatron 训练的完整 RL 脚本,其 MTP 配置同时打开了enable、enable_train、detach_encoder,即上表第三种模式:
MODEL=( actor_rollout_ref.model.path="$MODEL_PATH" actor_rollout_ref.model.use_remove_padding=True actor_rollout_ref.model.trust_remote_code=True actor_rollout_ref.model.mtp.enable=True actor_rollout_ref.model.mtp.enable_train=True actor_rollout_ref.model.mtp.mtp_loss_scaling_factor=${mtp_loss_scaling_factor} actor_rollout_ref.model.mtp.detach_encoder=True )(${mtp_loss_scaling_factor}是脚本内定义的用户可调变量,默认 0.1。)
脚本关键默认值:
MODEL_PATH=${MODEL_PATH:-XiaomiMiMo/MiMo-7B-RL} NNODES=${NNODES:-1} NGPUS_PER_NODE=${NGPUS_PER_NODE:-8} train_file=${TRAIN_FILE:-$HOME/data/dapo-math-17k/train.parquet} val_file=${VAL_FILE:-$HOME/data/aime-2024/test.parquet}数据文件默认放在$HOME/data/下,需要读者自行准备,或通过TRAIN_FILE/VAL_FILE环境变量替换成实际路径。并行度默认:actor 侧 TP=2、PP=2、CP=2 且开启参数/优化器 offload;rollout 侧使用 SGLang,TP=4。
启动方式(摘自脚本,须在 verl 仓库根目录执行):
uv run --frozen --all-packages --extra sglang --extra megatron python3 \ -m verl.trainer.main_ppo \ ... \ model_engine=megatron脚本默认通过uv走提交的 lockfile 加载sglang与megatron两个 extras 的依赖;设置VERL_USE_UV=0时回退到系统 Python。切换到全参数模式时,只需把actor_rollout_ref.model.mtp.detach_encoder去掉;切换到仅加载模式时,额外去掉enable_train与mtp_loss_scaling_factor两行。
可选路径:SFT 训练(对应"仅加载"模式)
examples/sft/gsm8k/run_mimo_7b_mtp_megatron.sh 用同样的 MiMo-7B 模型在 gsm8k 上做 SFT,MTP 段只开了一项,即上表第一种模式:
model.mtp.enable=True该脚本有两个环境副作用,运行前需要知晓:
- 它会执行
mkdir -p $HOME/pythonpath,并把 Megatron-LM(dev 分支,固定到 commit23e092f41ec8bc659020e401ddac9576c1cfed7e)和 mbridge(feature/verl_mtp分支,固定到 commit6bf2d45a15dc4fb52d2f0c38ff546bee33447d10)clone 到$HOME/pythonpath下,然后追加进PYTHONPATH。这需要网络访问,且会写入$HOME/pythonpath目录; - 训练入口是脚本内
ENTRYPOINT变量定义的-m verl.trainer.sft_trainer,数据默认取~/dataset/rl/gsm8k下的train.parquet/eval.parquet,可通过DATASET_DIR替换。
一个需要留意的版本冲突:该脚本设置了engine.override_transformer_config.recompute_granularity=full,而 MTP 文档要求此时 megatron 必须使用包含 PR #3457(ffd66a3e6)的 dev commit;但脚本本身固定的是更早的23e092f...commit。两处文档给出的 commit 不一致,实际运行时应按 MTP 文档的要求处理 megatron 版本,并留意脚本注释中"依赖两个不在 master 上的 commit"的说明。
结果验证
- RL 路径:脚本配置
trainer.logger='["console","wandb"]'且test_freq=10,训练过程通过 console 与 wandb 面板观察,每 10 步在 aime-2024 验证集上评测。 - SFT 路径:文档给出的实验观察(mimo-7B-math + gsm8k,结果为文档示例,不是固定预期):MTP 层对主 loss 的影响有限;但当 MTP 层被 detach 时,
mtp_loss会收敛到更高的值。检查 wandb 曲线时可据此区分 MTP 是否真的在训练。 - 仅加载模式的验证点是导出物:文档说明该模式下显存占用会增加,但导出的参数包含 MTP 模块,可直接用于在线部署。
边界与限制
- 本文只覆盖三种训练模式。文档中第四种" MTP Accelerated Rollout"(
enable_rollout=True,配合 vLLM 或 SGLang 的投机解码参数)属于推理加速场景,不在三种训练模式之内;且文档实测在 H20 上 mimo-7B + SGLang 的 Rollout 吞吐下降约 50%,当前建议是推理阶段暂不启用 MTP 加速。 - 基座模型不带 MTP 参数时,任何 MTP 训练配置都不会对训练结果产生可观察影响。
- 训练引擎限制不变:换用 FSDP 等非 Megatron 训练引擎时,MTP 训练不在当前支持范围内。
【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考