第四章 训练目标与自回归生成
网络结构定义了如何把输入变成 logits;训练目标定义了哪些 logits 是好的;生成算法定义了如何把概率分布变成文本。把这三者连接起来,才能理解为什么同一个模型在训练、Prefill 和 Decode 中呈现不同执行形态。
1 从最大似然到交叉熵
给定训练序列 $x_1,\ldots,x_n$,希望提高数据在模型下的概率。根据第一章的链式分解,最大化对数似然等价于最小化负对数似然:
$$ \mathcal L(\theta)=-\sum_{t=1}^{n}\log p_\theta(x_t\mid x_{<t}) $$
对单个预测位置,设真实 token ID 为 $y$,词表 logits 为 $z\in\mathbb{R}^{V}$,则:
$$ \ell=-\log\frac{e^{z_y}}{\sum_ve^{z_v}}=-z_y+\log\sum_ve^{z_v} $$
这就是目标为 one-hot 分布时的交叉熵。它不要求模型只给出一个 token,而是要求真实 token 在整个条件分布中获得更高概率。
对第 $v$ 个 logit 求导:
$$ \frac{\partial\ell}{\partial z_v}=p_v-\mathbf1[v=y] $$
该结果解释了训练信号的方向:对真实类别,梯度下降倾向于提高其 logit;对其他类别,倾向于压低它们的相对概率。梯度还会通过输出层、各 block 和 Embedding 传播,改变整套表示方式。
实际损失通常按有效预测位置求均值。padding、被排除的上下文段或其他不计损失的位置,需要用 loss mask 排除;loss mask 与 Attention mask 功能不同,一个决定算哪些监督损失,一个决定输入可以看见哪些信息。
2 右移输入与 Teacher Forcing
假设文本 token 是 $[A,B,C,\mathrm{EOS}]$,加入起始符号后,训练输入与标签可以排列为:
输入位置 0 1 2 3
输入 token BOS A B C
监督标签 A B C EOS
位置 2 的表示可以读取 BOS、A、B,但不能读取 C;它要预测的正是 C。因此需要正确的标签偏移和因果 mask。只使用因果 mask,却把同位置输入 ID 当作标签,会把目标变成另一种错误任务。
训练时使用真实的已知前缀作为条件,称为 Teacher Forcing。模型不需要先采样出 A,再等 A 计算完才获得 B;数据集已经提供了整段输入。
3 为什么训练能并行而生成仍逐步进行
矩阵 $X$ 的所有行在训练开始时已知。在某一层,Q/K/V 都可以通过批量矩阵乘法生成,然后由 mask 保证每行只使用合法前缀。于是同一层的多个位置可以同时计算。
这里的并行没有违反自回归概率分解。自回归限制的是条件信息:位置 $t$ 的预测不能依赖真实的未来 token。它不要求训练程序按 Python 循环逐个位置执行。
生成时,未来 token 不在数据集中。模型必须先根据当前前缀形成分布,再决定下一 token,随后才能构造更长前缀。因此“同层已知位置可以并行”和“未知生成结果需要逐步获得”可以同时成立。
4 一次训练迭代实际做什么
一个典型步骤包括:准备分词后的输入与标签;执行前向得到损失;沿计算图反向传播获得梯度;按优化器规则更新权重;清理或复用中间状态。
例如梯度下降用 $\theta\leftarrow\theta-\eta\nabla_\theta\mathcal L$ 更新参数。实际大模型训练常采用带状态的优化器、学习率调度、混合精度和分布式切分,但它们没有改变“根据预测误差调整参数”这条基本链路。
反向需要访问前向中的某些信息,所以训练通常要保存中间激活,或在反向阶段重新计算。推理不更新参数,也通常不需要保留这张反向图。这是训练显存与推理显存模型不同的根源,不能只拿参数字节数解释两者差异。
注意力在训练中仍有三条学习路径:Q/K 决定权重如何分配,Value 决定传递什么,FFN 和残差则决定聚合信息如何转换并传到后续层。最终损失将这些模块联结成一个端到端系统。
5 预训练与后训练改变什么
自回归预训练通常在大量文本上学习 next-token 条件分布。指令监督微调把输入组织为任务与回答,常只对指定回答位置计损失。偏好优化等后训练方法进一步改变模型输出行为的学习信号。
这些阶段可以使用相同的基础网络结构,但训练数据、损失、参与更新的参数范围不同。一个聊天模型的对话模板、角色边界和工具调用格式,也需要编码成模型能识别的 token 序列。
因此,理解 Transformer 架构并不等于已经理解全部聊天行为。架构提供可学习的函数族,参数中的行为来自训练过程和数据,部署时的系统逻辑又决定怎样组织上下文。
6 从 logits 选择下一个 token
最简单的 greedy decoding 每次取概率最大的 token。它得到局部最大概率选择,但不保证整段序列的联合概率全局最大。
随机采样按模型分布选择。温度 $\tau>0$ 通过缩放 logits 改变分布:
$$ p_v^{(\tau)}=\frac{\exp(z_v/\tau)}{\sum_u\exp(z_u/\tau)} $$
较小温度使分布更集中,较大温度使其更平缓;温度趋近 0 时趋向最大值选择,存在并列最大值时还要看具体选择规则。
Top-k 保留概率最大的 k 个候选并重新归一化;top-p 保留按概率从大到小累计达到阈值的一组候选,再归一化采样。这些规则作用于输出分布,不会为每个生成 token 创建新模型权重。
Beam search 保留多个候选前缀,需要维护多条状态路径。推测解码则先提出多个候选再验证,改变了每步处理 token 的方式。后续性能主线先限定为每条序列每次普通 Decode 产生一个预测 token。
7 KV Cache 为什么是正确的复用
考虑一层因果注意力。旧位置 $i$ 的表示只能依赖位置 $\le i$。追加一个新 token 不会改变旧位置的可见前缀,所以在固定参数、固定位置规则且关闭随机 dropout 的标准推理中,旧位置的 K/V 可以保留。
这个理由可以沿层数归纳:第一层旧位置输入不变,因此旧 K/V 不变;若上一层旧位置输出不变,下一层旧位置的投影也不变。由此每一层都可以缓存自己的历史 K/V。
处理新位置时,只需为该位置计算新的 Q/K/V,将 K/V 追加到本层缓存,然后执行:
$$ o_{\rm new}=\operatorname{softmax}\left(\frac{q_{\rm new}[K_{\rm old};k_{\rm new}]^\top}{\sqrt{d_h}}\right)[V_{\rm old};v_{\rm new}] $$
方括号分号表示沿序列维拼接。新 Query 仍然要读取历史 KV;缓存省去了旧位置的重算,没有消除当前 Query 对历史的注意力计算。
这一复用要求上下文、模型权重与位置处理等保持兼容。若编辑了旧前缀、改变了模型,或某种动态位置缩放使旧位置表示依赖新总长度,必须重新检查缓存有效性。双向 Encoder 在追加新输入后旧位置可能读取到新内容,也不能直接照搬这个证明。
8 Prefill 与 Decode 的完整时序
假设 prompt 为 $[x_1,\ldots,x_S]$:
Prefill: 处理 x1 ... xS,建立每层 KV,最后位置预测 y1
Decode 1: 输入 y1,追加它的 KV,预测 y2
Decode 2: 输入 y2,追加它的 KV,预测 y3
...
Prefill 处理一组已知位置,与训练前向一样具有同层位置并行性,但不需要计算梯度。Decode 通常每条序列只有一个新输入位置,历史内容通过 KV 读取。
生成 N 个输出 token,通常是一次 Prefill 加 N−1 次 Decode;最后一个输出若不再用于后续预测,可以不用再次送入模型。这也说明“采样到一个 token”和“模型处理并缓存一个 token”在时间上不是同一个动作。
9 模型质量与系统性能的边界
交叉熵和 perplexity 描述特定数据分布上的预测质量。若用自然对数、平均每 token 损失为 $\bar\ell$,则 perplexity 为 $\exp(\bar\ell)$。不同 tokenizer 下每个 token 对应的内容量不同,不能随意直接比较这一数值。
吞吐、TTFT、显存则描述执行这套模型的资源成本。缓存、算子融合等优化可以在保持目标计算语义的条件下改变成本;量化或某些近似算法还可能改变数值结果,需要同时评估质量。
下一章:现代语言模型的结构演进。