执行摘要
本次 PR 为 Qwen3.5 模型添加了专用的多轮 SFT 损失掩码支持,解决了默认配置下的模板错误问题,并通过优化掩码生成提高了训练效率。变更包括新选项、生成器实现、防御性检查和单元测试,影响 Qwen3.5 用户的 SFT 配置和性能。
功能与动机
动机源自 Qwen3.5 SFT 训练中,默认损失掩码路径不兼容导致的 jinja2.exceptions.TemplateError: No user query found in messages.,以及现有 qwen3 路径可能监督不必要的推理 token,增加训练开销。PR body 明确指出需要匹配 Qwen3.5 聊天模板行为,避免监督不必要的历史推理 token,以减少浪费的训练 token 并提升 SFT 效率。
实现拆解
实现按模块拆解如下:
- 参数扩展:在
slime/utils/arguments.py 的 --loss-mask-type 参数中添加 qwen3_5 选项,保持默认值不变。
- 核心生成器:在
slime/utils/mask_utils.py 中新增 gen_multi_turn_loss_mask_qwen3_5 函数,基于渲染的对话文本使用 offset_mapping 推导字符级掩码到 token 级监督,并验证 tokenization 与 apply_chat_template(..., tokenize=True) 输出一致。
- 防御性检查:在
slime/rollout/sft_rollout.py 的 generate_rollout 函数中添加检查,确保 token_ids 和 loss_mask 长度相同,防止潜在错误。
- 示例脚本:新增
scripts/run-qwen3.5-35B-A3B-sft.sh 脚本,显式使用 --loss-mask-type qwen3_5 并提供完整 SFT 配置示例。
- 单元测试:添加
tests/utils/test_loss_mask_type_qwen35.py 文件,使用模拟 tokenizer 测试单轮、多轮和工具调用场景的行为。
评论区精华
Review 中仅 Zhuohao-Li 评论 "lgtm, thanks!",表示批准 PR,没有技术争议或深入讨论。Issue 评论中作者请求 review,但无进一步交互,表明变更被顺利接受。
风险与影响
风险分析:
gen_multi_turn_loss_mask_qwen3_5 依赖 tokenizer 的 offset_mapping 属性,要求 fast tokenizer 支持,否则会引发 ValueError,需确保配置正确。
- 字符级掩码映射到 token 级的逻辑可能复杂,尽管添加了验证步骤,但边缘情况(如特殊字符或模板变化)可能影响正确性。
- 新增的防御性检查增加运行时验证开销,但影响较小,有利于早期发现错误。
- 示例脚本依赖环境变量配置,如
BASE_FOLDER 和 MASTER_ADDR,用户需正确设置以避免运行时错误。
影响分析:
- 对用户:Qwen3.5 用户需更新 SFT 脚本使用
--loss-mask-type qwen3_5 来避免失败并优化训练效率,但默认配置不变,现有用户不受影响。
- 对系统:修复了 SFT rollout 的崩溃问题,减少不必要的 token 监督,提升训练速度和资源利用率。
- 对团队:增加了代码维护点(新选项和生成器),但通过单元测试和防御性检查降低了长期风险。
关联脉络
从近期历史 PR 看,关联脉络包括:
- PR 1719(修复 Qwen3 脚本)和 PR 1721(添加 Qwen3.5-4B 模型支持)都涉及 Qwen 模型配置和脚本,与本 PR 共同完善了 Qwen3.5 在 slime 仓库中的支持,反映了对 Qwen 系列模型 SFT 的持续优化趋势。
- 其他 PR 如 PR 1689 和 PR 1700 也涉及脚本修复,但与本 PR 的 Qwen3.5 专用掩码功能关联较弱。整体上,这些 PR 显示了团队在模型兼容性和训练效率方面的关注。
参与讨论