第 4 章 AI 算法Transformer大模型

第 4 章 生成与输出

第4章 生成与输出

本章围绕「生成」展开完整输出链路:自回归机制定义逐 token 生成循环,隐藏状态经线性投影与 Softmax 变为词表概 率分布,解码策略决定如何选择下一个 token,特殊 token 控制序列收尾。编码器输出作为对照,说明同一套末端表示因 架构选择而异。

4.1 自回归生成机制

自回归(Autoregressive)是解码器执行序列生成的基础方式。它定义了一种逐 token 递进的生成策略:每步的输出成为 下一步的输入。这一简单规则带来了训练与推理的根本不对称,并催生了 KV 缓存等关键工程优化。

4.1.1 逐词生成的流程

在推理阶段,解码器从起始符号(如 )开始生成。每一步将当前已有的前缀序列输入解码器,取最后 一个位置的输出经 Softmax 得到对词汇表中所有 token 的概率分布,然后从中采样或贪心选择下一个 token。 以一个简单的英译中任务为例,设源句为 “I love AI”,目标句为 “我爱人工智能”。推理流程如下:

  1. 输入 [] ,输出 "我"
  2. 输入 [, 我] ,输出 "爱"
  3. 输入 [, 我, 爱] ,输出 "人工"
  4. 继续直到生成 或达到最大长度 每一步都需要重新计算整个前缀序列的注意力。因果掩码保证了第 t 步的计算不受第 t + 1 步及之后的影响,但前缀部分 的计算是冗余的。 def autoregressive_generate(model, src, max_len=100): """ Generate target sequence one token at a time. src: source sequence (batch_size, src_len)
     """
     enc_out = model.encode(src)
     tgt = torch.tensor([[model.bos_token_id]])
     for _ in range(max_len):
         # Masked self-attention on target prefix
         # Cross-attention with encoder output
         logits = model.decode(tgt, enc_out)
         next_token = logits[:, -1, :].argmax(dim=-1)
         tgt = torch.cat([tgt, next_token.unsqueeze(0)], dim=1)
         if next_token.item() == model.eos_token_id:

break

4.1.2 教师强制策略

 return tgt

教师强制(Teacher Forcing)是训练自回归模型的默认策略。其核心思想是:在训练的第 t 步,解码器接收的输入不是 模型在第 t − 1 步的预测,而是训练数据中第 t − 1 步的正确 token。 这一策略使得训练时的损失函数 L 可以直接定义在完整序列上: N T 1 n ∑ ∑ log P (yt ∣ y<t , x(n) ) (n) (n) L=− N n=1 t=1 其中 N 为训练样本数,T 为第 n 个样本的目标序列长度,y 为正确的前缀。 n (n) <t 教师强制的最大优势是使训练完全可并行:因所有 y 已知,因果掩码下的并行计算得以实现。代价则是加剧了暴露偏差 问题——模型在训练中从未见过自己的错误,无法学习从错误中恢复的策略。 t

4.1.3 训练与推理的不一致

训练和推理之间的差异是自回归模型中一个结构性的矛盾,如图4-1 所示。训练时,完整的目标序列经教师强制一次性输 入,所有位置可以并行计算;推理时,目标序列未知,只能串行地每次前进一个 token。 这种不一致在学术文献中被称为暴露偏差(Exposure Bias):训练期间模型看到的始终是正确的历史前缀,而推理时模型 看到的是自己生成的、可能带有误差的前缀。一旦某一步产生了偏差,后续步骤的输入分布将逐渐偏离训练分布,误差累 积使生成质量劣化。 Inference Input: [bos] Predict: 'I' Input: [bos, I] Predict: 'love' ... Training Input: [bos, I, love, AI] Predict all positions in par allel Compare with ground trut h: I love AI eos 图4-1 训练与推理的流程对比 缓解暴露偏差的方法包括计划采样(Scheduled Sampling),在训练时以一定概率用模型自身的预测替代正确的前缀; 但计划采样改变了优化目标,可能引入偏差。当前主流的大语言模型实践倾向于接受这种不一致,转而通过增大训练数据 规模和精细化 RLHF 对齐来弥补。

4.1.4 KV 缓存与推理效率

推理时的串行重计算是效率瓶颈。每次前进一步,之前所有 token 的 Key 和 Value 向量都要重新计算一遍。对长度为 t 的序列,第 t + 1 步的重计算量为 O(t )(因为注意力矩阵随 t 平方增长),总推理计算量为 O(n )。 2 3 KV 缓存(KV Cache)解决了这一冗余问题。其核心思路是:因果掩码保证了过去 token 的 Key 和 Value 不受未来 token 的影响,因此它们只需计算一次并缓存,后续步直接复用。当生成第 t + 1 个 token 时,只需计算当前 token 的 q 、 k 、v ,然后将 k 、v 追加到缓存中,用 q 与所有缓存的 Key 计算注意力:

                                                                                                                          t+1
t+1
          t+1
                        t+1
                                  t+1
                                                            t+1
                                                                      qt+1 ⋅ [k1 , … , kt+1 ]T

Attention(qt+1 ) = Softmax ( ) ⋅ [v1 , … , vt+1 ] dk KV 缓存将每步推理的计算复杂度从 O(t ) 降至 O(t),总复杂度从 O(n ) 降至 O(n )。代价是显存开销:对 L 层、每层缓 2 3 2 存 n × d 维 tensor,总计约 2Lnd 个浮点数。在长序列或大 batch 场景中,KV 缓存的显存消耗可能超过模型参数 model model 本身,成为推理优化的新焦点。 KV 缓存已成为推理引擎(vLLM、SGLang、TensorRT-LLM)的核心优化对象:分页注意力(PagedAttention)将缓存 按页管理以消除显存碎片,GQA/MLA 等注意力变体从源头压缩缓存体积。投机解码(Speculative Decoding)则通过小 模型草稿-大模型验证的方式,在不改变输出分布的前提下将解码速度提升 2-3 倍,是自回归串行瓶颈下的关键加速手 段。

4.2 从隐藏状态到词表分布

自回归生成的核心语句只有一句话:「取最后一个位置的输出经 Softmax 得到对词汇表中所有 token 的概率分布」。本节 把它完整展开:隐藏状态如何产生、如何被投影为 logits、如何归一化为分布。整个变换链是一条纯粹的维度游戏:从 d 维向量空间出发,穿过词表大小的 V 维分数空间,最终落在 V 个非负概率上,每一处形状变化都对应一个明确的设计意 图。

4.2.1 最后位置的表示

解码器堆叠 L 层后,最后一层输出是一个维度为 d 的向量序列 H ∈ R ,n 为当前序列长度。自回归的目标是预测下一 L n×d 个 token 而非为整段序列打分,因此模型只需消费序列最后一个位置的表示 h = H [n − 1, :] ∈ R 。这里的「最后位置」 L d 不是某个特殊记号,而是当前前缀在序列中的末位索引,每生成一个新 token,它就是新的最后一个位置。 因果掩码保证了最后一个位置已聚合全部前缀信息:它是 n 个 token 经逐层自注意力与前馈变换后,对整段前文的压缩 摘要。这一摘要并非简单的平均,而是由注意力权重决定的加权聚合,越相关的历史 token 贡献越大。位置信息在多层 变换中已被编码进向量,因此输出投影无需再显式感知位置,它对任何位置的向量施加同一变换,这正是「逐位置投影」 称谓的由来。 训练与推理在「取哪个位置」上存在不对称。训练时完整目标序列已知,所有位置并行预测(教师强制),每个位置都扮 演一次「最后位置」,交叉熵损失在整段序列上求和,模型因此在每个前缀长度上都学会了预测下一个 token。推理时目 标序列未知,借助 KV 缓存只需为新 token 计算一个位置。位置索引只是取数的坐标,但它指向的向量携带整段上下文, 这正是「序列 → 下一个 token」映射的载体。这一设计使模型具备长度自适应的预测能力:无论前缀长短,最后一个位 置都给出等价的「下一步信念」。

4.2.2 线性投影与 logits

向量 h ∈ R 需要映射回词表空间。输出投影(Output Projection)是一个线性层,权重 W ∈ R ,V 为词表大小: d out V ×d z = Wout h 结果 z ∈ R 称为 logits,即词表每个 token 的未归一化得分。投影选择线性层而非多层网络并非偷懒:输出侧需要的只 V 是「每个词表候选一个分数」,词与词之间不需要非线性交互,线性变换恰好给出维度从 d 到 V 的最小映射。这是输出侧 维度从 d 扩张回 V 的唯一一步:d 通常在 512–8192,V 通常在 32K–200K,相差一到两个数量级,因此投影本身也是模 型中参数最多的单层算子之一(约 V × d)。 现代实现普遍省略偏置(bias=False):词表打分本质是比较大小,偏置整体平移所有分数而不改变相对排序,省略后输 出矩阵与嵌入矩阵形状一致,也为权重绑定创造了条件。投影逐位置独立进行,不跨 token 交互,与输入侧嵌入查表逐 token 进行形成对称。以下代码展示投影与 Softmax 的标准实现:

4.2.3 Softmax 归一化

 import torch
 import torch.nn as nn
 import torch.nn.functional as F
 class LMHead(nn.Module):
     def __init__(self, d_model, vocab_size):
         super().__init__()
         self.proj = nn.Linear(d_model, vocab_size, bias=False)
     def forward(self, hidden):
         return self.proj(hidden)          # (batch, seq_len, vocab_size)
 # inference: predict from the last position only
 hidden = model(prefix_ids)                # (batch, n, d)
 h_last = hidden[:, -1, :]                 # (batch, d)
 logits = lm_head(h_last)                  # (batch, vocab_size)
 probs = F.softmax(logits, dim=-1)         # (batch, vocab_size)

logits 是无界实数分数,需归一化为概率分布。对第 i 个 token: exp(zi ) pi = ∑Vj=1 exp(zj ) Softmax 保证分布非负、和为 1,同时保持相对排序不变,logits 最大的 token 概率也最大。数值上 exp 在 z 偏大时溢 出,实现先减去最大值再做指数(log-sum-exp 技巧),PyTorch 的 F.softmax 内部已处理,无需使用者操心。 logits 与分布的分工值得明确:logits 是模型内部原始接口,携带幅度信息,直接反映「模型对每个候选的把握」; Softmax 产物是对外接口,是解码算法的输入。温度缩放发生在 Softmax 之前、作用于 logits,改变分布的陡峭度而不 改变相对排序,是决策层加在输出侧的调节旋钮。 整体链路如图4-2 所示。自注意力、前馈网络、层归一化都是 d 维空间内的内部运算,两侧外部接口都锚定词表:输入侧 以 token ID 进入,输出侧以 token 分布离开。Transformer 无论内部多复杂,对外始终是一个「词表到词表」的映射 器。这一视角统一了理解架构的框架,中间的一切层、头、投影,都服务于把「已知 token 的历史」翻译成「下一个 token 的信念」。 Decoder Stack Output Last Position h Linear Projection W_out Logits z in R^V Softmax Distribution p over V Next-token Decision 图4-2 从隐藏状态到词表分布的链路

4.3 去嵌入与输入输出对称

输入侧的四段链路为:原始信号 → 离散化 → 嵌入向量 → 位置注入 → 自注意力,其中嵌入层是把 token ID 变向量的第 一级,此后模型一直在 d 维空间内工作。输出侧完全对称:隐藏状态经投影回到词表、经 Softmax 得到分布,是输出侧 的第一级,它重新打开词表维度,把模型内部表示翻译回 token 身份。两侧链路各司其职:输入侧负责「理解进来的是 什么」,输出侧负责「决定出去的是什么」。 这一输出投影在文献中常被称为去嵌入(Unembedding)或词表投影。它与输入侧嵌入共享同一对端点:嵌入把 token 变成向量,去嵌入把向量变回 token。本节从映射方向、参数形态与架构意义三个层面,说明这种对称为何不是巧合,而 是序列模型的结构必然。理解去嵌入,等于理解了模型的记忆组织方式:词表上的每一个候选,都在向量空间中占有一个 可被检索的位置。

4.3.1 词表投影与逆映射

输出投影本质上是嵌入的逆映射。忽略偏置后,第 i 个 token 的 logit 是隐藏状态与输出矩阵第 i 行的点积: zi = h ⋅ w i , wi = Wout [i, :] logit 的高低取决于 h 与 w 在向量空间中的相似度(余弦相似度加权模长)。当 z 最大时,相当于模型认为「当前上下文 表示最接近第 i 个 token 的表示」,预测即检索。这解释了输出侧为何是「去嵌入」:嵌入在输入侧把 token 身份编码进向 i i 量空间,去嵌入在输出侧把上下文向量解码回 token 身份,两个方向共用同一套词表索引,恰如编码与解码共用同一本 码本。 点积检索的解释不依赖权重绑定:即使输出矩阵与嵌入独立,模型仍会学到相似的空间布局,因为两端共享同一个数据分 布,高频、语义相近的 token 在两侧都会被推向相近位置。因此,即使完全解绑,输出矩阵也常被观察到收敛出与嵌入 高度相似的结构,这是数据分布决定几何的又一例证。 点积视角还揭示了 logits 的几个固有属性: •logits 可正可负,本身只是相似度分数,没有概率含义,只有经过 Softmax 才成为概率;单个 logit 的绝对数值没有可 读含义,候选间的相对排序才有意义。 •向量模长影响 logits 幅度:隐藏状态模长偏大时 logits 整体被拉高,分布更尖锐,这一现象在归一化不充分的模型中尤 为明显,也是讨论归一化演化(RMSNorm 等)的动机之一。 •「检索」视角催生了 logit lens(logit 探针)这类可解释性工具,通过直接读取某一中间层输出经去嵌入的 logits,观 察该层「倾向预测什么词」,从而反推各层学到的信息。

4.3.2 参数形态对比

嵌入层与输出头在参数形态上完全同构,如表4-1 所示。 维度 嵌入层 输出头 映射方向 token ID → 向量 向量 → token 分数 权重矩阵 We ∈ RV ×d Wout ∈ RV ×d 前向操作 按 ID 查表取行 与 h 做矩阵乘法 参数量 V ×d V × d(未绑定时) 位置 输入侧第一级 输出侧第一级 表4-1 嵌入层与输出头的形态对比 两个矩阵形状相同、都按词表索引、都位于 d 维空间与词表空间的边界。差异在取数的方向:嵌入层是「稀疏取行」,一 次只取序列中出现的那些行,未出现的 token 不产生计算;输出头是「稠密全算」,一次对所有 V 行与 h 相乘,得到完整 打分向量。这一差异带来工程影响:输出头的计算量随词表线性增长,是推理中不可忽略的一次稠密矩阵乘(GEMM), 优化上常与批量、块切分结合。 偏置的历史也值得一提。早期模型为输出头保留偏置向量 b ∈ R ,它等价于给每个 token 一个与上下文无关的先验 out V 分:高频 token 学到正偏置、生僻 token 学到负偏置。现代模型省略这一偏置后,权重矩阵与嵌入矩阵形状一致,使权 重绑定成为直接可选项。输出头是唯一直接接触词表的输出侧参数,它把模型在 d 维空间学到的全部语义,浓缩回 V 维 词表打分。

4.3.3 输入输出对称的架构意义

输入输出对称是序列建模的自然要求。token 在两个端点进出模型:嵌入层是入口的唯一门,输出头是出口的唯一门,两 者夹住内部多层 d 维变换。这种对称设计带来两个好处: •端到端学习:若两端不对称,模型需要在内部表示与外部词表之间维护两套不一致的坐标体系,训练压力成倍增加;对 称使内部表示可以同时被输入语义与输出语义「拉扯」,梯度信号双向流动,学习更容易收敛。 •参数共享:两端操作都是「词表 × d 维」的线性映射,共享一份参数在数学上完全成立。权重绑定之所以有意义,正 是因为两端天然对称,若不对称,共享就无从谈起。 GPT 的架构图正是以对称的「Embedding → 解码器 → LM Head」三段式呈现计算流程,两侧的对称性一眼可见。整体 映射如图4-3 所示。 Input side Token ID Embedding W_e Vector space R^d Transformer Blocks Final Hidden h Output side Unembedding W_out Token Scores R^V 图4-3 嵌入与去嵌入的对称映射 对称性还提示了一个重要的调试视角:若输出分布质量异常,排查范围可以缩小到词表边界上的两处——输入嵌入是否正 确对齐词表顺序,输出矩阵是否与嵌入共享或独立。两侧在数据结构上的一致性,让端到端的问题定位变得直接:词表错 位、维度过大、共享失配,都会在分布层暴露出可观察的症状。这一对称只存在于「生成式」出口上:BERT 一类编码器 模型的出口是任务头而非词表投影,天然不具备这种对称性,两者的消费方式存在根本差异。

4.4 权重绑定与参数效率

嵌入矩阵与输出头的参数量均为 V × d,大词表下仅词表相关参数就占模型参数的相当比重。权重绑定(Weight Tying) 让输入嵌入与输出头共享同一份参数,是削减这笔开销最直接的手段。本节从绑定原理、模型家族差异与训练稳定性三个 角度展开,并讨论低秩嵌入等补充方案,共同构成大词表模型的参数效率工具箱。

4.4.1 共享参数的原理

权重绑定令输出矩阵等于嵌入矩阵:W = W 。此时词表相关的参数量从 2 × V × d 压到 V × d,输出头不再占用独立 out 参数。以词表 V = 151,000、隐藏维度 d = 4096 的模型为例:解绑时嵌入与输出头合计约 1.2 × 10 参数,绑定后省去约 e 618M,占 7B 模型约 9%。在参数量受限的早期模型上,这一比例可达两成以上,是当时不可忽视的节省。 实现只需一行赋值:把输出头的权重句柄指向嵌入矩阵。前向时输入侧查表取行、输出侧用同一矩阵与 h 相乘,反向时 梯度同时累加到共享矩阵。共享打破了输入输出两端的参数独立性,但并未改变计算图结构,输出侧仍是一次独立的矩阵 乘,只是权重张量与嵌入是同一对象。推理时也无需特殊处理,模型结构、KV 缓存、量化方案全部不受影响。绑定关系 如图4-4 所示,PyTorch 实现见下方代码。 Input end Token ID Embedding = W Vector space R^d Transformer Blocks shared weight Hidden h Output end LM Head = W Logits R^V 图4-4 权重绑定中的参数共享

 class GPTModel(nn.Module):
     def __init__(self, vocab_size, d_model, num_layers):
         super().__init__()
         self.embedding = nn.Embedding(vocab_size, d_model)
         self.blocks = nn.ModuleList(

[DecoderBlock(d_model) for _ in range(num_layers)] )

4.4.2 GPT 系与 BERT 系差异

         self.lm_head = nn.Linear(d_model, vocab_size, bias=False)
         self.lm_head.weight = self.embedding.weight   # tie weights
     def forward(self, input_ids):
         h = self.embedding(input_ids)
         for block in self.blocks:
             h = block(h)
         return self.lm_head(h)   # same matrix on both ends

两类模型的绑定策略反映了不同的参数预算与目标结构。BERT 系(自编码)在预训练时将掩码语言模型输出层复用输入 嵌入权重,额外叠加一层 LayerNorm 与偏置以稳定输出分布,因为 MLM 的输出分布与输入嵌入共享,直接投影会产生 分布漂移,需要归一化补偿;而下游任务头(分类、抽取)则是在 [CLS] 表示上训练的独立线性层,与词表无关,谈不 上绑定。参数受限时代,这一共享让 BERT 得以在有限预算内把容量留给主体网络。 GPT 系(自回归)的经典模型 GPT-2、GPT-3 将 lm_head 与输入嵌入绑定,共享一份词表权重;这一选择在参数量受限 时代同时节省显存与训练成本。2023 年后的主流开源解码器(LLaMA、Qwen、Mistral)普遍选择解绑(Untied):嵌入 与输出头各自独立训练,以更大的参数量换取两端表示的自由优化空间。绑定收益相对主体参数占比缩小,且解绑让输出 头可以专门学习「如何打分」而不受输入语义牵制,成为新一代模型的主流做法。差异汇总如表4-2 所示。 维度 绑定(共享权重) 解绑(独立权重) 词表参数 1×V ×d 2×V ×d 典型模型 GPT-2/GPT-3、BERT MLM LLaMA、Qwen、Mistral 优点 参数省、结构对称 两端独立优化 缺点 表示被迫对齐 参数开销翻倍 表4-2 权重绑定与解绑的对比

4.4.3 训练稳定性与参数折中

绑定并非免费。嵌入矩阵被强制同时服务「接收输入」与「预测输出」两种角色,两个方向的梯度都会累加到同一份参数 上,可能相互冲突:输入侧希望嵌入反映「如何解读上下文」,输出侧希望它反映「如何成为预测目标」,二者并非天然一 致。这种拉扯使训练更易振荡,实践中通常需要配套手段稳定,如均匀缩放的初始化(让嵌入的数值范围与残差流匹 配)、更强的 Dropout 正则、更保守的学习率,或梯度裁剪。 解绑则获得自由度:两端可分别初始化、分别设置学习率,嵌入学习「理解」、输出头学习「预测」。输出头作为独立的浅 层线性层,其梯度路径更直接,容易吸收较大的学习率而不过度扰动主体;嵌入则受制于输入侧多层变换,需要更平滑的 更新。因此从 GPT-2 到 LLaMA,绑定策略的变化不纯粹是参数量的考量,它还反映了对训练稳定性与表示解耦的追求。 低秩嵌入(Low-rank Embedding)是另一条削减词表参数的路径:将高维嵌入先投影到低维子空间,再从低维展开为完 整词表,在保持容量的同时削减参数量。数学上相当于把 V × d 的稠密矩阵近似为两个低秩矩阵之积,压缩比取决于低维 子空间的维度选择。它与权重绑定不互斥,现代大词表、大隐藏维度模型常将两者结合,输出头与嵌入共享同一份低秩分 解后的表示,进一步压缩,甚至可将词表相关参数压到绑定方案的几分之一。 选择绑定还是解绑、是否叠加低秩,本质是参数预算与训练自由的权衡:绑定换来参数效率与结构对称,解绑换来表示解 耦;低秩嵌入则是不牺牲对称性的第三种折中。工程上,先评估词表参数占模型总参数的比例,占比高(如小模型配大词 表)时绑定或低秩收益显著,占比低(如大模型、小词表)时解绑的代价可忽略,再决定采用何种策略,是常见的决策路 径。

4.5 编码器输出的角色

解码器输出经 LM Head 词表投影,消费方式是词表分布。编码器最后一层的输出则有完全不同的角色:在编码器-解码器 架构中它是交叉注意力的 K/V 来源,在 BERT 系模型中它是任务头的输入。本节对比这两类输出的消费方式,说明输出侧 并非只有「词表分布」一条出口,同一套 Transformer 末端表示,因架构选择不同而服务于截然不同的下游。

4.5.1 交叉注意力的 K/V 来源

交叉注意力是解码器与源序列之间的唯一信息通道。编码器最后一层输出 H ∈ R (m 为源序列长度)经两组投影产 L m×d 生交叉注意力的 Key 与 Value: e Kcross = HLe Wcross K , Vcross = HLe Wcross V 编码器已对源序列完成双向上下文编码,因此每一行都携带对应位置及其完整上下文的语义表示,它不指向「某个 token 的身份」,而是指向「源序列在语义空间中的整体结构」。解码器每一步用当前目标侧表示作 Query,在这些 Key/Value 上检索最相关的源信息,再把检索结果融合进下一步的预测。这一消费方式的本质是条件化:解码器输出侧的一切预测, 都被交叉注意力注入的源信息所调制。交叉注意力不加掩码,解码器每一步都能自由访问源序列任意位置,注意力分数矩 阵是完整的 n × m 而非下三角。 从计算视角看,这一角色带来两点工程含义: •交叉注意力的开销随源序列长度 m 线性增长:推理时每一步只需计算当前 Query 与全部源 Key 的相似度,复杂度 O(m),因此源序列越长,交叉注意力在单步推理中的占比越高,这与解码器自注意力依赖 KV 缓存降为 O(1)(每步) 形成互补。 •编码器输出对整个源序列只计算一次,跨所有解码步复用,这是翻译等任务中显著的算力摊销:源序列的编码成本被目 标序列的所有生成步均摊,越长的目标序列,摊销越充分。 推理时编码器输出的 K/V 常被整体缓存,与 KV 缓存互补:后者缓存解码器自注意力,前者缓存交叉注意力,共同构成 Encoder-Decoder 推理的全部记忆。T5 等模型的架构差异主要体现在注意力变体与归一化上,但「编码器输出充当 K/V 来源」这一角色是统一的。

4.5.2 两种输出的消费方式

编码器输出与解码器输出的消费方式差异,如表4-3 所示。 维度 编码器输出 解码器输出 来源 最后一层编码器 最后一层解码器 消费主体 交叉注意力 K/V、任务头 LM Head 词表投影 计算时机 一次、全程复用 每步更新 消费方向 模型内部 模型外部(词表) 典型归属 Encoder-Decoder、BERT 自回归生成模型 表4-3 编码器输出与解码器输出的消费对比 编码器输出被内部消费:它不直接对词表打分,而是喂给注意力机制或任务头,进一步参与表示计算;解码器输出被外部 消费:经 LM Head 变成词表分布,直接决定下一个 token。这一差异决定了两种输出的信息形态:编码器输出保留的是 「源序列的稠密摘要」,解码器输出保留的是「下一个 token 的预测依据」。 换言之,编码器输出的归宿是「别处」,解码器输出的归宿是「此处」——前者继续参与计算,后者离开模型成为结果。 以机器翻译为例,编码器输出的每一行对应源句一个位置的全部语义(含双向上下文),解码器每一步取目标侧当前前 缀,通过交叉注意力「挑出」源句中最相关的位置,再连同自身历史一起预测下一个词。两种输出在这一流程中各司其 职,缺一不可,这种分工也是「编码器理解、解码器生成」这一架构原则的具体落点。

4.5.3 BERT 与 GPT 的输出对比

BERT 系(编码器)与 GPT 系(解码器)的输出侧差异,直接决定其能力边界。BERT 的最终表示不接词表投影:分类任 务取 [CLS] 位置的输出经池化与线性层得到类别分数,序列标注任务则对每个位置输出接独立的标签头,问答任务在序 列上预测答案跨度(start/end)的边界位置。任务头是任务相关的小参数层,随微调一起训练,与预训练目标解耦,每 个新任务都要新增或重训一个任务头。池化方式也有讲究: [CLS] 首 token 池化适合句子级分类,而平均池化(mean pooling)在部分任务上更稳,工程上常两者对比选择。 GPT 的最终表示接 LM Head:词表分布即输出,无需任务头,预训练目标(语言建模)与推理目标(生成)共享同一出 口。因此 GPT 可以零成本地续写、对话、补全,而 BERT 需要为每个新任务配备新的任务头。两种消费路径如图4-5 所 示。 Source Sequence Encoder Stack Encoder Output H_e^L Decoder Hidden Cross-Attention K/V Task Head (BERT-style) Cross-Attention Q Cross-Attention Decoder Output LM Head + Softmax Next-token Distribution 图4-5 编码器输出的两种消费路径 编码器输出的每一条支路,都对应一类下游任务或一个信息通道;解码器输出则只有一条主干道,通往词表分布。这条 「编码器多出口、解码器单出口」的架构差异,是理解两类模型生态的分水岭:前者擅长判别与抽取,后者擅长生成与续 写。出口决定了模型的定位:是分类器还是生成器,在架构选型那一刻就已注定。

4.6 解码策略

自回归机制在每个时间步都产出词表上的一个概率分布。如何从该分布选择下一个 token 本身是一个独立的算法层,即 解码策略。它是自回归生成机制的自然延伸,也是 LLM 日常使用与推理服务中最关键的工程决策之一。本节从贪心与随 机的谱系出发,依次讨论温度调节、截断采样与 Beam Search,最后给出面向任务类型的选型建议。

4.6.1 贪心解码与确定性权衡

贪心解码(Greedy Decoding)是最简单的解码策略:每一步直接选取概率最大的 token: yt = arg max P (y ∣ y<t ) y 这一策略完全确定:给定相同的输入前缀,输出序列始终相同,因此易于复现与调试。代价是它没有任何回退能力,一旦 在早期选择了次优 token,后续生成将沿错误的局部路径持续累积误差,且模型无法修正。 贪心解码在翻译、摘要等答案高度确定的封闭式任务中表现尚可,但在对话、故事生成等开放式任务中容易退化为重复、 空洞的文本。原因是贪心选择使高概率 token 被反复命中,生成陷入循环,这是自回归误差累积(暴露偏差)在解码层 的直接体现。 与贪心相对的是随机采样(Sampling):从完整概率分布中抽取 token,同一输入可产生不同输出。两者构成确定性与多 样性的根本权衡——确定性解码可复现、可控、便于评测与工程调试;随机解码牺牲可复现性以换取多样性。如图4-6 所 示,logits 经 Softmax 变为概率分布后,可分叉为贪心与随机两条路径。 argmax selection Deterministic path Logits over vocabulary Softmax probability distrib ution sample from distribution Stochastic path 图4-6 贪心解码与随机采样的分叉 贪心解码的实现代价极低,只需一次 argmax 即可完成选择,因此常作为基线或推理引擎的默认回退。不过,贪心的 「确定」并不等于「最优」:每一步的局部最优拼不出全局最优序列,这一缺陷在序列较长、歧义较多的任务中尤为突 出。实践中,贪心仍被广泛用于评测基准,因为它消除了随机种子带来的结果波动,使不同方法在同一输入上可比。

4.6.2 随机采样与温度

温度(Temperature)是控制采样分布陡峭程度的标量。其原理是在 Softmax 之前将 logits 除以温度参数 T : exp(zi /T ) pi = ∑∣V ∣ j=1 exp(zj /T ) 其中 z 为词表第 i 个 token 的 logit,∣V ∣ 为词表大小。 i 温度取值的极限行为决定了采样的走向。当 T = 1 时分布保持不变;当 T → 0 时,Softmax 退化为 one-hot,采样等价 + 于贪心;当 T → ∞ 时分布趋于均匀,所有 token 等概率出现。温度因此成为「确定性与多样性」之间的连续旋钮。 低温使分布尖锐,模型倾向选择高概率 token,生成更连贯、事实性更强,但多样性下降、重复增多。高温使分布平坦, 低概率 token 获得更多机会,输出更富创造力,但语法错误与逻辑跳跃随之上升。这种权衡在推理场景尤为明显:数学 与代码等精确推理任务依赖低温抑制错误累积,但温度过低会固化解法模式,在需要探索多步路径时反而增加死循环风 险。 实际配置中,事实性问答常用 T ≈ 0.1–0.3 甚至直接贪心,通用对话约 0.6–1.0,创意写作可至 1.2 以上。温度只改变分布 陡峭度,并不截断低概率长尾,即使低温,长尾 token 仍保有非零概率,因此需与 Top-K 等截断策略配合使用。

4.6.3 Top-K 与 Nucleus 采样

Top-K 采样将采样范围限制在概率最高的 K 个 token,其余 token 概率置零后重新归一化,K 通常取 40–50。它排除了 长尾中大量低质量候选,使采样集中在合理范围内。 固定 K 存在结构性局限。当分布尖锐时,前 K 个 token 已覆盖绝大多数概率,Top-K 会不必要地排除语义合理的候选; 当分布平坦时,Top-K 又把概率很低、与上下文无关的 token 纳入采样范围,引入噪声。理想截断应随分布形状自适 应,这催生了 Nucleus 采样。 Nucleus 采样(top-p)动态确定截断集合:选择累积概率首次超过 p 的最小 token 子集,在其中重新归一化采样,p 通 常取 0.9–0.95。当分布尖锐时集合很小,近似贪心;分布平坦时集合扩大,保留多样性。相比固定 K ,它无需针对每种 分布人工调参,成为开放生成场景的默认选择之一。以下代码给出两者的典型实现:

 import torch
 def top_k_top_p_sampling(logits, temperature=1.0, top_k=50, top_p=0.9):
     logits = logits / temperature
     scores = torch.softmax(logits, dim=-1)
     if top_k > 0:
         kth = torch.topk(scores, top_k).values[:, -1, None]
         scores = scores.masked_fill(scores < kth, 0.0)
     if 0.0 < top_p < 1.0:

sorted_scores, sorted_idx = scores.sort(dim=-1, descending=True)

         cumsum = torch.cumsum(sorted_scores, dim=-1)
         keep = cumsum - sorted_scores <= top_p
         sorted_scores = sorted_scores.masked_fill(~keep, 0.0)
         scores = torch.zeros_like(scores).scatter_(-1, sorted_idx, sorted_scores)
     scores = scores / scores.sum(dim=-1, keepdim=True)
     return torch.multinomial(scores, num_samples=1)

2024 年后出现了一批新的截断变体。min-p 采样仅保留概率不低于 p ⋅ p 的 token,其中 p 为当前最高概率:它以 max max 峰值概率为参照而非累积概率,在分布高度集中的生成中后期表现更稳定。类似的还有 locally typical sampling,它依 据信息熵筛选「典型」token,用于降低重复与退化文本。这些变体与 top-p 的取舍通常是经验性的,实践中常以人工偏 好或对齐评测结果为准。 Top-K 与 Nucleus 可以同时启用:先按 top-K 硬截断,再在剩余集合内执行 top-p 累积截断,两层过滤互为补充。推理 框架通常将两者作为独立参数暴露,允许用户自由组合。截断只影响采样阶段,贪心与 Beam Search 不使用这些参数。

4.6.4 Beam Search 与长度惩罚

Beam Search 介于贪心与随机之间,同时跟踪多条候选序列,既保持确定性,又通过更广的搜索空间缓解贪心的局部最 优问题。它维护 B 条候选序列(beam),每一步对每条序列展开整个词表,保留总体对数概率最高的 B 条,直至所有 beam 均产生 或达到最大长度。当 B = 1 时它退化为贪心解码。 增大 beam 宽度 B 提升搜索质量,但计算量随之线性增长,且更大的 beam 更易产出重复内容。在机器翻译中 B 常取 4– 8,兼顾质量与成本;在开放式生成中 Beam Search 因易致重复而较少使用。 Beam Search 常与两类惩罚配合使用: •长度归一化:总对数概率是各 token 对数概率之和,序列越长惩罚越大,因此朴素 Beam Search 天然偏好短句。长度 惩罚(Length Penalty)以长度归一化解除此偏差,GNMT 采用 lp = (5 + n) /6 ,其中 α > 0 鼓励长句、α < 0 鼓励 α α 短句;另一种做法是直接以长度的幂次对分数归一化。 •重复惩罚:presence penalty 对已出现 token 的对数概率施加恒定惩罚,frequency penalty 的惩罚与出现次数成正比 (两者均为 OpenAI API 参数);Hugging Face 的 repetition_penalty 则直接按重复程度缩放对应 logits。 Beam Search 确定性高,适合翻译、摘要、语音识别等近似唯一答案的任务;在这些任务中它通常优于贪心。而在需要 多样性的开放生成中,应改用温度采样等随机策略。 Beam Search 还有若干工程细节。最小长度约束强制序列先积累一定长度,避免生成过早收敛;多候选的副产品是「近 重复」,不同 beam 的差异仅在一个 token,可用 n-gram 阻断(no repeat ngram)抑制。这些细节说明 Beam Search 与其说是单纯算法,不如说是一组可组合的约束集合。

4.6.5 解码策略选型

解码策略的选择取决于任务属性。封闭式任务(翻译、摘要、代码修复)的答案高度确定,优先贪心或 Beam Search; 开放式任务(对话、故事、头脑风暴)追求多样性,应选 Nucleus、Top-K 或纯采样。表4-4 汇总了各策略的定位: 表4-4 解码策略对比 策略 适用场景 生成质量 输出多样性 贪心解码 翻译、摘要等唯一答案任务 较高但易重复 极低 Beam Search 翻译、摘要、语音识别 高,全局更优 低 随机采样 故事、头脑风暴 中等,有错误风险 高 Top-K 需抑制长尾噪声的对话 中等偏高 中 Nucleus 开放生成默认选择 较高 中偏高 min-p 分布集中的长对话 较高 中 2026 年主流推理引擎与 API 以「无截断」为解码默认:vLLM 默认 temperature=1.0、top_p=1.0、top_k=-1(不启用截 断),OpenAI Chat Completions 同样默认 temperature=1、top_p=1。生产环境通常显式覆盖这些默认值:通用对话常 用 temperature=0.7、top_p=0.9,事实性任务降至 0.2 以下并配合 repetition_penalty 抑制重复。 当输出必须符合特定格式(JSON、函数调用参数、SQL 查询)时,纯概率解码无法保证结构合法。约束解码 (Constrained Decoding)在每一步将候选 token 限定为符合目标语法(EBNF、JSON Schema)的集合,从机制上保 证输出合法,而非事后修复。vLLM 通过 guided decoding 集成 XGrammar(NVIDIA)与 Outlines 等库,lm-format- enforcer 提供同类能力。这是 2024 年后 Agent 类应用中结构化输出的标准实现方式,与函数调用、工具使用流程直接衔 接。 温度、top_p、重复惩罚等参数可同时启用,推理框架通常提供统一采样配置项。事实性、创意与结构化是三种经过生产 验证的典型组合: •事实性场景:低温 + 高截断 •创意场景:高温 + 宽截断 •结构化场景:低温 + 约束解码 选型并非一次定死,应针对具体任务做小规模评测后固定配置。综合建议可归纳为: •默认采用 Nucleus(top_p=0.9)叠加适度温度 •需要严格格式时叠加约束解码 •追求推理精度时降至低温或贪心 •翻译与摘要类任务再考虑 Beam Search

4.7 序列结束与特殊 token

特殊 token(Special Token)在输出侧承担关键职责:EOS 触发停止、BOS 播种生成、PAD 维持批次形状。它们是词表 中预留的固定位置,与普通 token 走完全相同的嵌入与输出投影链路,模型对它们同样计算 logits、同样分配概率。本节 从 EOS 的停止机制、特殊 token 的体系与 Beam Search 中的处理三个角度展开。

4.7.1 EOS 的语义与停止机制

EOS(End of Sequence)是词表中的一个普通 token ID,模型对它同样分配概率,但它承载的特殊语义是「序列在此收 尾」。自回归模型经训练学会在语义完整处抬高 EOS 的概率:训练语料中每条序列都以 EOS 结尾,模型因此在「把话说 完」的语境下给 EOS 高分。这是模型「知道何时结束」的能力来源,也是 EOS 与普通 token 的本质差别:普通 token 的 概率由上下文语义驱动,EOS 的概率还额外受「完整性」驱动。 贪心解码下,EOS 只有在概率登顶时才会被选中,输出序列因此是确定的;采样下 EOS 以一定概率被选中,序列长度成 为随机变量,高温下模型可能在句子未完成时提前结束,实践中常以 min_length 约束前若干步禁止 EOS。实现层面, PAD token 的输出概率必须被抑制为负无穷,否则填充符号可能被当作有效预测产出,污染生成内容。特殊 token 的停 止流程如图4-7 所示。 Seed with BOS Decode Next Token Next Token is EOS? No Yes Append to Prefix Stop Generation Return Sequence 图4-7 特殊 token 与生成停止流程

4.7.2 特殊 token 的体系

特殊 token 在输入侧与输出侧承担对称职责。输入侧 BOS 标记序列起点,生成循环的初始输入就是一个 [BOS] 向量, 模型据此预测第一个真实 token;EOS 在语料中标记文档边界(序列打包中的文档分隔);PAD 将变长序列补齐为批次形 状。输出侧 EOS 触发停止,PAD 被禁止产出,BOS 通常不会也不应被生成。若模型连续输出 BOS,说明它把「开头」当 成了「下文」,通常是训练数据或提示构造有问题的信号。 不同模型家族的命名略有差异,但角色一致:GPT-2 用 <|endoftext|> ,LLaMA 用 / ,LLaMA 3 用 <|begin_of_text|> / <|end_of_text|> ,BERT 用 [CLS] / [SEP] 。两侧共用同一词表与分词器,特殊 token 的 ID 固定不变,这一约定使训练与推理完全一致。若推理时意外改动了特殊 token 的 ID 或词表顺序,嵌入查表与输出投影会 同时错位,生成结果整体失真,这类事故常被归为「词表污染」。 除 EOS/BOS/PAD 外,聊天模型还引入了角色标记,如 <|im_start|> 与 <|im_end|> (Qwen)、 <|user|> 与 <|assistant|> (LLaMA 3.1) ,它们把多轮对话的边界显式编码进 token 流。这些控制 token 是特殊 token 的广义形 式:指令标记、工具调用标记在输出侧的职责同样由生成循环在 logits 层面控制,例如约束解码会屏蔽非法候选,只允许 模型在工具调用标记后产出结构化参数。

4.7.3 Beam Search 中的 EOS 处理

Beam Search 中 EOS 的处理比单路解码复杂。每条 beam 在某一时刻生成 EOS,视为该条序列完成,移入完成集合,不 再参与后续扩展;搜索持续到所有 beam 完成或达到最大长度。提前停止(Early Stopping)在所有 beam 完成后终止搜 索,降低计算开销。与单路解码不同,Beam Search 允许已完成的序列「占位」,在多数实现中,完成序列保留在 beam 中占住名额,直至其他 beam 也完成,防止短序列过早垄断 top-B。 长度惩罚与 EOS 取舍存在相互作用:朴素 Beam Search 偏好短句,未加长度惩罚时模型倾向早出 EOS;加入惩罚后,短 句与长句的比较基准被拉平,EOS 的选择由语义完整度而非长度驱动。可见 EOS 不只是结束标志,它还是解码策略中一 个被反复权衡的决策点——结束时机、序列长度与输出质量三者在此交汇,任何一方的变动都牵动另两方。

4.8 输出与解码策略的衔接

输出侧与决策侧的分界线,就在「分布就绪」这一点——此前的所有计算都是模型自身的表示变换,此后的一切选择都属 于决策层。解码策略消费的输入正是词表上的概率分布,这一分布如何由 logits 供给、又如何交给采样器,是二者衔接的 核心。 贪心与 Beam Search 只消费 logits 的相对排序,无需显式 Softmax;采样路径则必须得到概率分布。推理引擎因此把 「输出分布」设计为可选计算:仅当采样启用时才实例化 Softmax,否则直接以 logits 走确定性分支,省去整张 V 维分 布的显存与算力。这一设计也解释了输出侧为何同时暴露 logits 与分布两个接口:不同解码算法对精度的需求不同,输出 侧按需供给。实际推理框架中,一次前向统一返回 logits,再由采样器决定后续处理,输出侧与决策侧因此解耦:模型不 关心用户选什么策略,用户也无需关心 logits 如何被计算。 工程上,采样算法以 sample(logits, temperature, top_k, top_p) 为统一接口:接收 logits 与策略参数,内部完 成温度缩放、Softmax、截断与重归一化,返回 token ID。输出侧只需保证 logits 正确,即幅度、形状与词表顺序与 tokenizer 严格一致,即可交付任意解码算法。词表顺序尤为重要,任何错位都会让模型「说的是一个 token,输出是另 一个 token」,这类 bug 在微调模型与基座模型混用时尤为隐蔽。 重复惩罚作用在 logits 上:对已出现 token 的 logit 施加惩罚后再走采样。约束解码则把约束前移到采样之前,将非法 token 的 logit 置为负无穷,使输出天然符合目标语法。决策层对输出的所有定制,最终都落在「修改 logits」这一个动 作上:改温度是缩放,改截断是清零,改约束是屏蔽,改惩罚是加减。因此 logits 是输出侧与决策层之间的主总线,一切 策略都是总线上的变换器。 至此输出侧完整闭环:解码器隐藏状态 → logits → 分布 → 解码策略 → token ID,每一步的接口都锚定在词表空间,与 输入侧链路一一对称。理解输出侧,就理解了生成模型「知道说什么」与「选择说什么」的分界:前者是模型在分布中编 码的信念,是学习的结果;后者是决策层从分布中抽取的行动,是部署时的选择。两者在 logits 这一接口上相遇。