← 返回题目列表

SFT 中为什么要统一 Chat Template?Loss Mask 应该怎么做?

高频 中等 第 12 / 25 题 更新于 2026/07/28
Chat TemplateLoss MaskSFTTokenizer

简化版

Chat Template 会把 system、user、assistant 等消息转换成模型真正看到的控制 token 序列,训练和推理格式不一致会明显损害效果。对指令微调,常见做法是只在 assistant 目标 token 上计算损失,把提示部分标签设为忽略值;但是否屏蔽全部非回答 token 要结合模型和训练目标决定。

详细版

训练前应确认:

  1. 使用与基座或目标部署一致的 Tokenizer 和 Chat Template;
  2. 角色起止符、轮次结束符、BOS/EOS 不重复也不遗漏;
  3. 训练完整对话时通常不添加“开始生成回答”的尾部提示;
  4. 推理时按模板要求添加 assistant 起始提示;
  5. Label 与 token 精确对齐,padding 和无需训练的 token 使用忽略标签;
  6. 多轮数据明确哪些 assistant 回合参与损失;
  7. 截断不能只剩回答或切坏角色边界;
  8. 用解码后的样本人工检查模板结果。

只对回答计算损失能避免模型把用户问题本身当成需要预测的目标,并把学习重点放在回复上;全序列训练也有适用场景,不能不经验证照搬固定配置。

完整版教学

记忆钩子:微调题先分清目标是改行为、补知识还是降成本,再谈 SFT、LoRA、QLoRA 和评估上线。

一、模型看到的不是消息字典

应用层的消息通常写成 role 和 content,但因果语言模型接收的是一串 token。Chat Template 负责插入角色标记、分隔符和结束符,例如标明用户内容在哪里结束、助手回答从哪里开始。

即使两个聊天模型来自同一基座,它们也可能使用不同控制 token。模板用错时,文字内容没变,模型理解的对话结构却变了。

二、训练与推理必须对齐

如果训练使用一种角色格式,推理换成另一种,模型会遇到分布偏移。训练预处理应调用目标模板,推理服务也应复用同一模板和 Tokenizer 版本。

训练样本已经包含完整回答,一般不需要额外追加等待模型生成的 assistant 起始提示;推理请求则通常需要告诉模型下一段应由 assistant 继续,具体参数以模板定义为准。

三、Loss Mask 的原理

交叉熵损失按 token 计算。许多训练框架用特殊标签值表示“该位置不计入损失”,常见实现是把这些 label 设为 -100

对 prompt-completion 数据,可屏蔽 prompt,只监督 completion;对多轮对话,可只监督 assistant 消息。模型仍能在前向过程中读取被屏蔽的上下文,只是这些位置不直接贡献训练损失。

四、为什么不能按字符位置随便切

字符经过 Tokenizer 后可能拆成多个 token,控制符也可能是特殊 token。先拼字符串再按字符长度估算 Mask,容易出现偏移,把回答开头屏蔽或把用户文本纳入损失。

更可靠的是让模板返回 assistant mask,或在 token 化时保存每段的精确边界,并用单元测试验证。

五、多轮对话如何处理

可以监督所有 assistant 回合,也可以只监督最后一轮,取决于任务。监督所有回答能利用更多信号,但历史回答若是模型生成或质量较差,也会污染目标。

截断长对话时要保证至少保留有效目标 token。若一个 batch 中所有标签都被屏蔽,损失可能无效甚至出现异常。

六、特殊 token 的常见错误

  • 模板已添加 BOS/EOS,外部 Tokenizer 又重复添加;
  • 把 padding token 当作训练目标;
  • 训练与推理使用不同 EOS;
  • 拼接样本时没有正确分隔;
  • 新增特殊 token 后忘记调整词嵌入矩阵;
  • Mask 把角色结束符全部误删,导致模型学不会停止。

七、如何验收

随机抽取格式化样本,打印 token、解码文本和参与损失的位置;确认角色顺序、特殊 token、目标区间与截断结果。再用一个很小的数据子集过拟合测试,验证训练流水线确实能学到目标格式。

八、面试拆解算例

微调题可以用一个小项目来拆:基座模型 7B,业务只需要客服问答风格统一,训练集初筛 30,000 条,清洗后留下 8,000 条高质量样本。若全量微调,7B 参数按 BF16 仅权重就约 14GB,训练还要梯度和优化器状态;若用 LoRA,只训练低秩增量,显存压力会明显下降,但表达能力受 rank 和目标模块影响。

base_model: 7B
raw_samples: 30000
clean_samples: 8000
lora_rank: 8 or 16
learning_rate: 1e-5 ~ 2e-4
validation_split: 5% ~ 10%
方案适合目标主要风险验收重点
Prompt临时改格式、少量约束长提示不稳定单轮成功率
RAG接入动态知识检索召回不足引用与命中率
SFT/LoRA固化行为和领域表达遗忘与过拟合回归集与人工偏好
全量微调深度改模型能力成本高、风险大全面评测
数据清洗 -> 训练/验证切分 -> 小步试训 -> 回归评测 -> 灰度上线
   |              |             |             |
 去噪去重       防泄漏       看 loss       看坏例

因此回答「SFT 中为什么要统一 Chat Template?Loss Mask 应该怎么做?」时,不要直接说“用微调”。先问目标是什么、数据是否足够干净、是否有动态知识,再选择 Prompt、RAG、PEFT 或全量微调,最后用评估集证明它确实变好了。

九、常见误区与追问

  • 误区:微调就是把业务文档喂给模型让它记住。 微调更适合塑造行为格式、任务风格和领域表达,动态知识与事实更新通常更适合 RAG。
  • 追问:为什么这个问题不用 Prompt 或 RAG 解决? 面试里要先说明目标是改行为、补知识还是接外部数据,再选择微调方案。
  • 误区:训练集越大越好。 SFT 更怕低质、冲突、模板化和泄漏数据;少量高质量样本常常胜过大量脏样本。
  • 追问:上线前你会看哪些评估? 至少要覆盖基准集、人工偏好、回归用例、安全红线、延迟成本和灾难性遗忘检查。
  • 误区:LoRA/QLoRA 省显存就没有代价。 参数高效方法降低训练成本,但 rank、目标模块、量化误差和合并部署都会影响最终质量。

十、加强记忆

Chat Template 决定模型眼中的对话语法,Loss Mask 决定哪些 token 算作作业答案;模板必须训练推理一致,Mask 必须按 token 精确对齐,不能靠字符串位置猜。