Prhub

#1742 Support qwen3.5 loss mask for multi-turn SFT

THUDM/slime · 作者 huang3eng · 合并时间 2026-03-22 16:24

分析状态 已生成
文件变更 5提交数 2 · 评论 1
代码增减 +481 / -2
bugfix configuration performance shell

执行摘要

为 Qwen3.5 添加专用的多轮 SFT 损失掩码,修复兼容性问题并优化训练效率。

PR body 指出:默认的 --loss-mask-type qwen 在 Qwen3.5 SFT 中会导致 jinja2.exceptions.TemplateError: No user query found in messages.,而 --loss-mask-type qwen3 可能重建额外推理内容并监督不必要的思考 token,增加 token 计数和减慢 SFT。因此,需要添加专用的 Qwen3.5 损失掩码以匹配其聊天模板行为。

建议精读 slime/utils/mask_utils.py 中的 gen_multi_turn_loss_mask_qwen3_5 函数,学习其基于 offset_mapping 的 token 级监督推导方法,以及验证 tokenization 一致性的设计。对于涉及多轮对话 SFT 的开发者,此 PR 提供了处理聊天模板差异的参考方案。

讨论亮点

Review 中只有 Zhuohao-Li 的评论 'lgtm, thanks!',表示批准 PR,没有技术争议或深入讨论。Issue 评论中作者请求 review,但无进一步交互。

实现拆解

实现包括:1) 在 slime/utils/arguments.py 中添加 qwen3_5 作为 --loss-mask-type 的选项;2) 在 slime/utils/mask_utils.py 中实现 gen_multi_turn_loss_mask_qwen3_5 函数,使用渲染文本的 offset_mapping 推导字符级掩码到 token 级掩码,并验证 tokenization 一致性;3) 在 slime/rollout/sft_rollout.py 中添加防御性检查确保 token_idsloss_mask 长度一致;4) 添加 scripts/run-qwen3.5-35B-A3B-sft.sh 脚本作为示例,指定使用新选项;5) 添加 tests/utils/test_loss_mask_type_qwen35.py 单元测试覆盖单轮和多轮场景。

文件 模块 状态 重要度
scripts/run-qwen3.5-35B-A3B-sft.sh SFT configuration added 5.0
slime/utils/mask_utils.py loss mask generation modified 8.0
slime/utils/arguments.py argument parsing modified 4.0
slime/rollout/sft_rollout.py SFT rollout modified 4.0
tests/utils/test_loss_mask_type_qwen35.py testing added 5.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

gen_multi_turn_loss_mask_qwen3_5

评论区精华

Review approval other

Zhuohao-Li 评论 'lgtm, thanks!',表示批准 PR。

结论:PR 被批准合并。 · 已解决

风险与影响

风险包括:1) gen_multi_turn_loss_mask_qwen3_5 依赖 tokenizer 的 offset_mapping 属性,要求 fast tokenizer 支持,否则会引发 ValueError;2) 字符级掩码映射到 token 级的逻辑可能复杂,需确保与 apply_chat_template 输出一致,验证步骤中添加了检查但可能存在边缘情况;3) 防御性检查增加运行时验证开销,但影响小;4) 新脚本依赖环境变量如 BASE_FOLDERMASTER_ADDR,需用户正确配置。

影响范围:1) 用户:Qwen3.5 用户需更新 SFT 脚本使用 --loss-mask-type qwen3_5 以避免失败并提高效率;2) 系统:修复了 SFT rollout 崩溃问题,减少不必要的 token 监督,提升训练速度;3) 团队:增加了代码维护点,但通过单元测试和防御性检查降低风险。

依赖 fast tokenizer 的 offset_mapping 新生成器正确性验证 脚本配置依赖

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

执行摘要

本次 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.pygenerate_rollout 函数中添加检查,确保 token_idsloss_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_FOLDERMASTER_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 显示了团队在模型兼容性和训练效率方面的关注。

参与讨论