哪些 token 应该计算损失:回答监督、多轮对话与标签边界

成长演进

具备清晰骨架、初步数学推导或工程验证,持续补充论据与实测。

ℹ数字花园

🌿 什么是数字花园与思想演进?

遵循 Maggie Appleton 与 Andy Matuschak 的常青笔记理念:这里不是按时间沉底的流水账,而是持续修剪打磨的知识生态。文章按成熟度经历:

  • 🌱 萌芽 (Seedling): 发散灵感、读书摘录、开放猜想
  • 🌿 演进 (Budding): 结构渐明、初步代码推导、积极修正
  • 🌳 常青 (Evergreen): 逻辑闭环、持久经得起检验的基石
  • 🔬 实验待证 (Speculative): 结合沙盒与仿真探针的理论探索
浏览全站数字花园与笔记全景 →

一条训练序列里有任务规则、用户材料和示范回答。它们都需要参与计算,但不一定都应该作为模型要模仿的输出。

例如,我们希望模型读取一篇很长的实验记录,再输出短 JSON。如果每个位置都算损失,训练会同时要求它预测那篇实验记录本身。这样做不是程序错误,却改变了监督信号的分配。

loss mask 决定哪些目标参与损失。它不负责决定模型能看见哪些输入。 这一区别在第二卷出现过,现在放到 SFT 样本里逐项检查。

本篇继续使用消息与模板的约定,先讲清一个回答,再扩展到多轮与变长样本。

三种常见选择在教不同的东西#

先不管框架参数名,直接描述目标:

监督范围哪些内容被要求预测需要注意什么
全序列提示、材料、回答及选定控制标记大量输入文字也会贡献损失
所有 assistant 回答每轮选定的助手输出历史错误回答可能也被模仿
仅最后一次回答最后一轮选定输出前面回答只作上下文,监督数量较少

还有“只训练 completion”这种说法。它描述的是 prompt 与 completion 的分段,不总等价于“所有 assistant 消息”。如果 completion 中包含多个角色,或历史助手回复属于 prompt,两种规则选择的位置就可能不同。

因此,先定义想训练的内容,再把定义映射到训练器参数。不要看到一个开关名称就跳过实际标签检查。

用八个位置看清首个回答 token#

下面是自定义的极简 token 序列。为便于逐项检查,假设每个方括号项目都恰好对应一个 token;这不是实际分词器输出。

0 [BOS]
1 [USER]
2 [材料]
3 [END]
4 [ASSISTANT]
5 [答案甲]
6 [答案乙]
7 [END]

我们希望只学习答案甲、答案乙,以及结束回答的 END,不学习角色头。完整序列标签可以写成:

输入: BOS USER 材料 END ASSISTANT 答案甲 答案乙 END
标签: -100 -100 -100 -100 -100 答案甲 答案乙 END

这里继续采用“模型内部错位一次”的接口约定。实际计分配对是:

输出所在位置该位置已经看到的末尾它预测的目标
4ASSISTANT答案甲
5答案甲答案乙
6答案乙END

关键是:标签位置 5 保留答案甲,会让位置 4 的输出学习预测它。 不能因为位置 4 是角色头,就把位置 4 的输出也一概排除,否则首个回答 token 可能丢失监督。

类似地,最后一个输入 END 所在位置没有后续目标,但 END 本身仍可作为前一个位置要预测的标签。这是两种不同的“最后一个”。

若实现已经在外部切出输入和目标,就应该把上述标签同时转换成外部错位形式。不能在原始序列上标好范围后,又按输出位置误移一遍。

不计提示损失,模型仍然可以利用提示#

把用户材料的标签设为忽略值,不会删掉对应的输入向量。回答位置仍然可以通过因果注意力读取材料。

而且,回答损失的反向传播仍可能经过提示位置的表示及相关参数。因此,“提示不算 loss”不等于“提示没有参与学习”,更不等于“提示对应的嵌入绝不会收到梯度”。

需要区分三件事:

  • 输入存在:文字是否送入模型。
  • 注意力可见:当前输出能否读取它。
  • 目标计分:是否直接要求模型预测这一位置的 token。

只监督回答通常保留前两项,选择性保留第三项。用 attention mask 把整个提示挡住,不能达到相同效果;那会让提取任务失去依据。

多轮里,错误历史能否保留#

假设第一轮助手错误地把未记录步数填成 10000,用户随后指出“材料没写步数,不要猜”,最后助手修正成 null。

若目的是训练纠错,可以把错误历史作为可见背景,但只监督正确的最终回答。这样不会直接要求模型再次生成那段错误回答。

若采用“所有 assistant 消息都计分”的规则,错误的历史回复也会进入模仿目标。这可能与当前训练意图冲突。

同样,如果历史回答本来就是正确示范,监督全部回答可以提供更多有效目标。但若把每一轮都拆成一个训练样本,再在完整对话里重复监督,会让早期回复被重复计数。

没有一种规则自动适合所有对话。应为样本标注角色和轮次来源,明确哪些回复可信、哪些只是错误背景,再检查转换后的目标位置。下一阶段的数据筛选也要考虑这些区别。

结束标记应该按实际生成协议监督#

提取任务需要模型在 JSON 完成后停止。如果标签过滤把真实结束标记全删了,模型就缺少相应的直接监督。

但“把所有 EOS 都加回来”也不是稳妥答案。某些模板区分消息结束与轮次结束;有的角色头由提示提供,有的控制 token 属于生成范围。应该按照目标模型的模板和推理停止规则决定。

如果 padding 与 EOS 共用编号,尤其要按实际填充位置处理,不能仅依据编号把真实结束标记一起忽略。第二卷的打包与边界已经说明,这类错误会改变训练目标,而不仅是影响吞吐。

最直接的验收方式,是打印最后几个有效标签的可读形式,确认回答内容和预期结束标记都还在,并且 padding 没有混入。

框架开关必须与模板和数据格式配套#

以固定版本 TRL 0.23.1 为例,assistant_only_loss=True 用于对话数据中的助手回复;文档要求模板能够返回对应 token mask。prompt-completion 数据又有 completion_only_loss 这一分段约定,二者可以结合使用,但并非任何输入格式都能直接套用。TRL SFT Trainer

Transformers 4.57.1 的模板接口也提供 return_assistant_tokens_mask,其支持取决于模板中的 generation 区域标记。分词器模板接口

这些文档说明如何表达意图,不替代输出核对。即使开关已经设为真,也应抽查每轮监督范围,检查角色头、结束标记、截断和首个回答 token 是否符合预期。

本文用这些固定版本说明语义,没有声称本站训练项目安装了它们,或已经运行了相应配置。

为什么用字符串搜索助手标记容易出错#

一种看似方便的做法是:在文本中找到 assistant 标记,后面全部算损失。

它至少会遇到几个问题:多轮中有多个边界;用户材料可能引用相同文字;模板标记与自然语言正文不一定容易区分;同一字符串单独分词与放在完整上下文中分词,边界未必完全一致。

更可靠的起点是使用结构化消息与模板提供的生成区域信息,或在自定义流水线里维护可核对的位置映射。无论采用哪种机制,都要用含边界样式文字的材料做检查。

“找到一段看起来像助手的字符串”并不等于“确认这段 token 真属于应监督的助手输出”。

截断后可能一条有效标签也没有#

假设最大长度很短,长材料占满了窗口,回答全部被截掉。输入张量仍有很多 token,loss mask 却全为零。

这种样本不能当作普通训练数据继续平均;否则会出现无效更新,或在处理不当时产生非有限损失。应明确排除、重新分段或采用其他已定义策略,并记录数量。

另一种情况更难察觉:只保留了半个答案,存在有效目标,但末尾结束标记不见了。程序不会因为“至少有一个标签”就知道这个样本已经不符合完整任务要求。

因此,检查必须同时覆盖有效目标数量与目标完整性。回答越短的任务,越要注意长输入在截断和采样中是否占据了过多预算。

只算回答以后,样本权重怎么变#

假设两个样本的有效回答长度分别为 2 和 8,平均 token 损失分别为 1 和 3。

按有效 token 平均:

Ltoken=2×1+8×310=2.6L_{\text{token}}=\frac{2\times1+8\times3}{10}=2.6

按样本平均:

Lsample=1+32=2L_{\text{sample}}=\frac{1+3}{2}=2

前者让每个目标位置等权,因此长回答贡献更多;后者让每条记录的平均损失等权。究竟选择哪一个,应与任务和比较问题一致。

如果想比较“全文监督”和“只监督回答”,也不能只把开关切换后比较原始 loss 大小:两者计分的位置集合不同,数字不可直接当成同一个测量。

可以固定数据和训练资源,同时在相同的回答位置上计算验证指标,再看提取任务结果。这样更接近回答“哪种监督范围更适合当前任务”,而不是比较两个定义不同的损失值。

一个最小标签检查可以怎样写#

下面代码只检查上面的教学序列与内部错位约定,不依赖训练框架,也不负责生成真实聊天模板:

# 每项是自定义的教学 token ID,不是实际分词结果。
ids = [0, 1, 2, 3, 4, 5, 6, 3]
answer_mask = [0, 0, 0, 0, 0, 1, 1, 1]
labels = [token if keep else -100
for token, keep in zip(ids, answer_mask)]
# 内部错位:位置 t 的输出,预测 labels[t + 1]。
pairs = [(t, labels[t + 1])
for t in range(len(ids) - 1)
if labels[t + 1] != -100]
assert pairs == [(4, 5), (5, 6), (6, 3)]

它验证首个答案和结束标记的位置关系。真实数据还应覆盖多轮、左右 padding、空回答、模板不支持 mask、截断及 packing;不能把这个小检查的通过扩大成整套训练器正确。

之后可以做一个短程对照:固定模型、数据与有效预算,只改变监督范围,并在相同回答目标上评价。若某方案只改善角色和标点,却没有减少字段错误,就把这一结果如实写出来。

两个检查理解的问题#

第一,提示标签全部忽略,为什么提示中的 token 仍可能影响参数更新?请分别从前向信息流和反向梯度说明。

第二,一段多轮记录里,早期助手回答错误,最后回答正确。若目标是学习纠错,你会保留哪些上下文、监督哪些位置,又怎样确认首个修正 token 没被漏掉?

监督位置明确以后,下一步要检查示范本身:哪些任务和错误类型应该覆盖,合成答案如何审核,以及近似重复会怎样改变训练权重。

文章概念网络

从章节进入正文概念。实线表示所属层级,虚线连接跨章节重复出现的概念,不代表因果关系。

50 / 50 个节点 · 正文标记术语与关键词概念

哪些 token 应该计算损失:回答监督、多轮对话与标签边界同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept同一概念 / Shared concept哪些 token 应该计算损失:回答监督、多轮对话与标签边界哪些 token 应该计算损失:回答监督、多轮对话与标签边界消息与模板消息与模板三种常见选择在教不同的东西三种常见选择在教不同的东西用八个位置看清首个回答 token用八个位置看清首个回答 token标签位置 5 保留答案甲,会让位置 4 的输出学习预测它标签位置 5 保留答案甲,会让位置 4 的输出学习预测它不计提示损失,模型仍然可以利用提示不计提示损失,模型仍然可以利用提示输入存在输入存在注意力可见注意力可见目标计分目标计分多轮里,错误历史能否保留多轮里,错误历史能否保留nullnull结束标记应该按实际生成协议监督结束标记应该按实际生成协议监督打包与边界打包与边界框架开关必须与模板和数据格式配套框架开关必须与模板和数据格式配套completiononlylosscompletiononlylossTRL SFT TrainerTRL SFT Trainerreturnassistanttokensmaskreturnassistanttokensmask分词器模板接口分词器模板接口为什么用字符串搜索助手标记容易出错为什么用字符串搜索助手标记容易出错assistantassistant截断后可能一条有效标签也没有截断后可能一条有效标签也没有只算回答以后,样本权重怎么变只算回答以后,样本权重怎么变一个最小标签检查可以怎样写一个最小标签检查可以怎样写两个检查理解的问题两个检查理解的问题检查示范本身检查示范本身实验实验SFTSFT选择选择tokentoken分词分词注意力注意力AttentionAttentiontokentoken选择选择因果因果EOSEOStokentoken推理推理tokentokenSFTSFT分词分词语义语义分词分词tokentokentokentoken采样采样策略策略tokentoken选择选择tokentoken
哪些 token 应该计算损失:回答监督、多轮对话与标签边界

哪些 token 应该计算损失:回答监督、多轮对话与标签边界

回到原文 ↗
BIBTEX

引用本文

@article{2026-10-20-llm-training-sft-03-loss-mask,
  author  = {枫语},
  title   = {哪些 token 应该计算损失:回答监督、多轮对话与标签边界},
  journal = {枫语},
  year    = {2026},
  month   = {oct},
  url     = {https://meiluosi.github.io/posts/2026-10-20-llm-training-sft-03-loss-mask/}
}
🌐

本篇知识星丛与滑动侧栈

哪些 token 应该计算损失:回答监督、多轮对话与标签边界 当前主轴

搜索

正在载入索引…