训练与推理通路
训练时一步并行算完整句,推理时却要一词一词生成,本课讲清这两条通路。
先补两个特殊 token
逐词生成有两个细节问题:第一个词之前什么都没有,拿什么起步?生成到什么时候算结束? 答案是两个 特殊 token :
记号说明:它们就是「分词器实战」中提过的 <bos> / <eos> 。不同教材记号不同(bos / SOS、eos / EOS),含义相同;这里沿用 Transformer 资料中常见的 <SOS> / <EOS> 写法。
训练通路:错一位的输入与标签
现在回答「交叉注意力与解码器」留下的第一个问题:训练时解码器的输入是什么?以 I love you → 我 爱 你 为例:
输入是目标句 整体右移一位 、开头补 <SOS>,这就是 Transformer 论文图中标注的 shifted right 。两行上下对齐着看,位置 i 的任务恰好是: 「看到前 i 个词(含 <SOS>),预测第 i+1 个词」 。 这也解开了「掩码注意力」中的下标疑惑:位置 i「可以看到自己」,因为它自己是输入里的第 i 个词,要预测的是标签里的下一个词,并不矛盾。
配合因果掩码, 一次前向就并行算出所有位置的预测 ,再对这些位置求交叉熵损失(已学),一次反向传播完成一步训练。
还有一个关键设计:训练时解码器的输入用的是 真实 目标句, 而不是模型自己上一步的预测。即使前面预测错了,下一个位置仍然以正确的历史为条件继续学习。 这种做法叫 teacher forcing 。它让训练稳定高效,代价是训练和推理见到的历史并不一致: 训练时喂的全是正确目标词,推理时却要拿模型自己生成的词当历史,一旦某步生成错了,后面就会顺着错误继续。
推理通路:自回归循环
推理(真正做翻译)时没有答案可喂,流程变成一个循环:
- 编码器对原文 只前向一次 ,输出反复复用
- 解码器输入从 <SOS> 起步
- 每一步前向后,取 最后一个位置 的 logits,选概率最大的词( 贪心解码 ),拼接到解码器输入末尾
- 重复,直到生成 <EOS> 或达到长度上限
为什么只取最后一个位置?回想训练段,每个位置 i 预测的都是第 i+1 个词。推理时这条规则没变,只是此刻的输入是已经生成出来的那串词,靠前位置要预测的下一个词都已落在序列里、是已知的,唯独最后一个位置预测的才是还没出现的新词。所以每一步只读最后一个位置的 logits。
同一个模型,两种用法
这张表也顺带解释了一个日常现象:为什么大语言模型生成长回答时,文字是 一个词一个词往外蹦 的, 推理天生串行,每个新词都要等上一个词生成之后才能开始算。
贪心解码(每步选概率最大的词)只是最简单的策略,还有保留多个候选的 beam search、按概率随机采样等改进,留待后续课程。
把两条通路写成代码
训练单步:构造右移输入与标签、算损失。
贪心解码:自回归生成循环。
在随机初始化的模型上跑通这两个函数: train_step 能算出损失, greedy_decode 能生成出一串 token,内容是 乱码 。 这完全正常:流程通了,但模型还没训练。
万事俱备
架构有了(《交叉注意力与解码器》),通路有了(本课),只差最后一件事: 真实地训练一次 ,看着乱码一步步变成正确的翻译。 之后的《Transformer 实战》会从 0 到 1 走完全程。