Transformer 训练时为什么要右移目标序列:Teacher Forcing 与并行预测
从目标序列右移、Teacher Forcing、Padding Mask 和 Sequence Mask 出发,解释 Transformer 为什么训练时可以并行预测,而推理时必须逐步生成。
相关工具
先看一个容易混淆的训练样本
假设目标句子是“我喜欢机器学习”。解码器在生成这句话时,真正要学习的不是把整句话一次性背下来,而是在每个位置根据已经出现的内容预测下一个词。于是,训练样本通常会被拆成两排:解码器输入是“<BOS> 我 喜欢 机器 学习”,监督标签是“我 喜欢 机器 学习 <EOS>”。
两排内容只错开一个位置。输入中的 <BOS> 只负责告诉模型从句子开头开始,输入中的“我”对应标签里的“喜欢”,输入中的“喜欢”对应标签里的“机器”。模型在位置 t 看到的是位置 t 之前的目标内容,损失则比较位置 t 的输出与真正的下一个词。这个错位动作通常称为右移目标序列。
如果不做右移,输入和标签会在同一个位置对齐,模型很容易学成“看到答案再复述答案”。那样的损失可能下降得很快,却没有真正训练出下一词预测能力。

解码器输入与监督标签错开一个位置,每个位置负责预测下一个 token。
Teacher Forcing 到底做了什么
Teacher Forcing 的核心做法,是在训练时把真实的历史目标词送给解码器,而不是把模型上一时刻预测出的词送回去。模型预测“机器”之前,输入的是数据中的真实前缀“我喜欢”,而不是模型自己刚刚猜出的结果。这样做能让每个训练位置都直接获得相对可靠的上下文。
这种方法的好处很实际:训练信号清楚,梯度可以从多个位置同时计算,错误不会在句子开头就被放大。假设第一个词预测错了,如果立刻把这个错误作为下一个位置的输入,后面所有位置都会在错误上下文里继续学习;Teacher Forcing 把这些位置暂时分开,先让模型学会每个局部的下一词关系。
它也留下了一个需要正视的差异。训练时上下文来自真实标签,推理时上下文来自模型自己的输出。模型在训练集上表现很好,并不代表它能承受一次错误后的后续生成,这就是常说的训练与推理之间的暴露偏差。
为什么训练时可以并行预测
乍看之下,下一词预测似乎必须从第一个词开始,一个位置接一个位置地计算。Transformer 的关键在于:训练时所有真实前缀都已经摆在输入序列里,因此每个位置的条件信息可以一次性构造出来。只要遮住未来位置,位置 1、位置 2、位置 3 就能在同一轮前向计算中分别给出预测。
这种并行并不是让位置 3 偷看了位置 4,而是让每个位置都只读取自己之前允许看到的内容。注意力矩阵中的上三角区域被屏蔽后,整个序列可以一起送进网络,最后在各位置分别计算交叉熵,再把有效位置的损失汇总。
因此,Transformer 训练效率高的原因不只是矩阵运算快,还在于它把“顺序依赖”放进了可并行的掩码规则中。顺序关系仍然存在,只是没有用循环把所有位置锁成一条计算链。

右移后的目标序列一次性进入解码器,各位置同时产生预测并分别计算损失。
Sequence Mask 为什么不可缺少
目标序列右移只解决了输入和标签如何对齐,不能单独阻止未来信息泄漏。以“我喜欢机器”为例,在训练位置“喜欢”时,解码器的输入序列中仍然包含后面的“机器”和其他位置。若没有 Sequence Mask,当前位置可以通过自注意力直接读取未来词,损失就不再代表真实的自回归预测。
Sequence Mask 通常表现为一个上三角被遮挡的矩阵。第一个位置只能关注自己;第二个位置可以关注前两个位置;第三个位置可以关注前三个位置。被遮挡的位置在 Softmax 前加上很大的负数,归一化后注意力权重接近于零。
这正是 文中所说的 Sequence Mask:它只出现在解码器的 Self-Attention 中,用来保证当前位置看不见未来信息。编码器对完整输入做双向建模,因此不需要同样的因果遮挡。

因果掩码遮挡未来位置,填充掩码排除补齐位置,两者解决的是不同问题。
Padding Mask 处理的不是未来,而是空位
一个批次里的句子长度通常不同。为了组成规则的矩阵,较短句子需要在末尾补上 <PAD>,较长句子则可能被截断。补齐位置只是为了对齐形状,并不承载语义。如果模型把注意力分配给这些位置,就会把无意义的符号当成上下文的一部分。
Padding Mask 的作用就是标记这些补齐位置,并在注意力计算中将它们排除。它与 Sequence Mask 的区别可以这样记:Padding Mask 回答“哪些位置根本没有内容”,Sequence Mask 回答“哪些内容虽然存在,但当前时刻还不能看”。
在解码器里,两种掩码可能同时存在。当前位置既不能看未来词,也不能看序列末尾的 <PAD>。如果只实现其中一种,模型仍有可能学到错误的注意力关系,尤其是在批次内句长差异较大时。
训练损失应该如何对齐
右移之后,模型会在多个位置产生输出,每个输出都对应一个标签。常见做法是对有效目标位置计算交叉熵,再忽略 <PAD> 对应的损失。这样,句子长度不同的样本可以放在同一批次里训练,而补齐符号不会把平均损失带偏。
例如目标标签是“我 喜欢 机器 学习 <EOS> <PAD>”,前五个位置应该参与损失,第六个位置应当被忽略。这里的“忽略”不等于把模型输出删除,而是让该位置不参与参数更新。掩码既可能作用在注意力上,也可能作用在损失汇总上,二者不要混为一谈。
如果标签偏移一位、忽略位置不对,训练曲线仍然可能看起来正常,但模型会出现句尾重复、提前结束、对补齐符号敏感等问题。检查样本对齐,比盯着某一个损失数值更重要。
推理时为什么必须逐步生成
推理时没有完整的目标句子可供使用。模型只能从 <BOS> 开始,先预测第一个词,把这个词接回输入,再预测第二个词,直到生成 <EOS> 或达到长度上限。此时不能把真实标签提前放入序列,否则得到的只是带答案的评估结果。
这就是训练和推理速度差异的来源。训练可以把一整段目标序列并行计算,推理则要反复执行解码过程。缓存已经计算过的 Key 和 Value 可以减少重复工作,但不能消除生成步骤之间的依赖。
生成策略也会在这里介入。贪心解码每次选择当前概率最大的词,Beam Search 保留多个候选,温度和采样则改变候选分布。无论采用哪种策略,输入都来自已经生成的前缀,因果掩码仍然保证每一步只使用过去的信息。
Teacher Forcing 的优点与边界
Teacher Forcing 让训练过程稳定、并行且容易计算,是序列到序列模型中非常常见的训练方式。对于较长序列,它能避免早期错误迅速扩散,使每个位置都得到清晰的监督。Transformer 的训练效率,正是建立在这种真实前缀加因果掩码的组合上。
但它不能保证模型在自由生成时同样稳定。训练中模型几乎总能看到正确历史,推理中却要面对自己的错误。随着序列变长,前面一个不合适的词可能改变后续上下文,造成重复、跑题或提前结束。
这不是说 Teacher Forcing 本身有问题,而是要把训练指标和真实使用场景区分开。评估时可以加入自由生成、不同长度、不同主题的样本,观察模型在没有真实前缀帮助时是否仍然保持连贯。
如何检查一批数据是否对齐
第一步,随机抽取一条样本,把解码器输入和标签并排打印。输入的第一个位置应是 <BOS>,标签的最后通常是 <EOS>;除开特殊符号,标签应当比输入向右错开一位。不要只检查张量形状,形状正确并不代表语义对齐。
第二步,检查掩码。Padding Mask 应该覆盖所有补齐位置,Sequence Mask 的上三角应该被遮挡。可以拿一条只有三个有效词的短句手算矩阵,确认第一、第二、第三个位置各自能看到哪些内容。
第三步,确认损失忽略了 <PAD>。如果补齐比例较高,错误地把填充位置纳入损失会让模型学到大量无意义的目标,训练集损失可能下降,实际生成却变差。
最后,分别看训练模式和推理模式。训练时使用真实前缀并行计算,推理时只把已经生成的内容送回模型。只要这四个检查点都成立,后续再讨论学习率、正则化或解码策略才有意义。
把几个概念放回 Transformer 主线
Transformer 的编码器先把输入序列变成上下文表示,解码器再根据已经生成的目标前缀逐步输出结果。训练时,目标序列右移后一次性送入解码器,Sequence Mask 阻止未来泄漏,Padding Mask 排除补齐位置,交叉熵则在每个有效位置比较预测与标签。
这条链路里,每个机制都只负责一件事:右移定义输入与标签的对应关系,Teacher Forcing 提供稳定的历史上下文,Sequence Mask 保证因果性,Padding Mask 保证补齐位置不干扰计算,损失掩码保证无效位置不参与更新。理解它们各自的边界,才能解释训练结果到底出了什么问题。
当你再次看到“Transformer 可以并行训练、逐步推理”这句话时,可以把它还原成一个具体过程:训练阶段有完整目标序列,所以多个位置可以同时计算;推理阶段没有答案,只能依靠已生成前缀继续向后走。并行与自回归并不矛盾,它们分别对应训练和生成两个阶段。
常见问题
目标序列为什么要右移一位?
为了让每个位置的输入代表已知前缀,标签代表下一个要预测的词。这样模型学习的是下一词预测,而不是把输入原样复述出来。
Teacher Forcing 和 Sequence Mask 是一回事吗?
不是。Teacher Forcing 决定训练时使用真实历史词还是模型预测词,Sequence Mask 决定当前位置能不能读取未来位置;前者管理输入来源,后者管理注意力范围。
Padding Mask 和损失中的 ignore index 有什么区别?
Padding Mask 通常用于注意力计算,避免模型关注补齐位置;ignore index 用于损失汇总,避免补齐标签参与参数更新。它们可能同时使用,但作用阶段不同。