# PR #1742 完整报告

- 仓库：`THUDM/slime`
- 标题：Support qwen3.5 loss mask for multi-turn SFT
- 合并时间：2026-03-22 16:24
- 原文链接：http://prhub.com.cn/THUDM/slime/pull/1742

---

# 执行摘要
本次 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 显示了团队在模型兼容性和训练效率方面的关注。