二:Transformer 与 Decoding¶
来源:http://mp.weixin.qq.com/s?__biz=MzYyNTk3Njg1NA==&mid=2247483735&idx=1&sn=a8f760b339df8068351578b4e7abefec&chksm=f01eb22ec7693b38f72c04f4199854a8492d1c6a4aa1fd2f6f69712d62c15b75e167af54421a#rd
1. 学习定位¶
第一天已经学习了 self-attention 的核心原理。第二天要把 self-attention 放回完整 Transformer 架构中,理解输入如何变成 embedding,encoder 如何做双向上下文建模,decoder 如何做自回归生成,以及语言模型推理时如何从 logits 变成下一个 token。 今天的知识分成两条主线: - Transformer 结构线:Embedding -> Encoder -> Decoder -> 输出 logits。
- Decoding 策略线:logits -> 概率分布 -> temperature 调整 -> top-k/top-p 截断 -> 采样。
面试中,这一天的内容经常以这些角度被追问: - Transformer encoder 和 decoder 的结构差异。
-
为什么 encoder 可以双向看,decoder 必须 masked self-attention。
-
decoder-only LLM 和原始 encoder-decoder Transformer 的关系。
-
token embedding、position embedding、output embedding/LM head 的关系。
-
推理时 greedy、sampling、top-k、top-p、temperature 的区别。
-
为什么 temperature 降低会更确定,升高会更多样。
-
top-k 和 top-p 如何过滤候选 token,各自有什么缺陷。
2. Transformer 总体结构¶
Transformer 最早被提出为一个 encoder-decoder 架构,用于机器翻译等 sequence-to-sequence 任务。它用 attention 替代 RNN/CNN 的序列递推或局部卷积,使序列内部的任意位置可以直接交互,并且更适合并行训练。 经典 Transformer 可以抽象为:
source tokens
-> source embedding + position encoding
-> encoder stack
-> encoder memory
target tokens shifted right
-> target embedding + position encoding
-> decoder stack
- masked self-attention
- cross-attention over encoder memory
- FFN
-> linear / LM head
-> logits over vocabulary
3. Embedding 层¶
Transformer 不能直接处理文本字符串。文本首先经过 tokenizer 切分成 token,再映射成 token id。Embedding 层把离散 token id 映射成连续向量。 基本形式:
input_ids: [B, T]
embedding_table: [V, d_model]
token_embeddings = embedding_table[input_ids]
token_embeddings: [B, T, d_model]
B 是 batch size。
-
T是序列长度。 -
V是词表大小。 -
d_model是模型隐藏维度。
Embedding table 的每一行对应一个 token 的可学习向量。模型训练时,embedding 也会通过反向传播更新。
4. Token Embedding、Position Encoding 与 Segment Embedding¶
Transformer 的输入表示通常由多种 embedding 或位置机制组成:
在 BERT 这类 encoder-only 模型中,还可能包含 segment/token type embedding: token embedding 表示 token 内容。position encoding/embedding 表示 token 在序列中的位置。segment embedding 用于区分句子 A/B 或不同片段,在现代 decoder-only LLM 中通常不使用。 纯 self-attention 本身没有顺序意识。如果没有位置信息,模型难以区分“我爱你”和“你爱我”这类 token 集合相同但顺序不同的句子。 常见位置机制包括: - sinusoidal positional encoding:原始 Transformer 使用的固定正弦/余弦位置编码。-
learned absolute position embedding:可学习绝对位置 embedding。
-
RoPE:旋转位置编码,把相对位置信息注入 Q/K。
-
ALiBi:在 attention score 上加入与距离相关的 bias。
第二天重点理解 embedding 和位置编码的职责分工:token embedding 提供内容,位置机制提供顺序。
5. Embedding 与输出 LM Head¶
语言模型输出层通常把隐藏状态映射回词表维度:
hidden_states: [B, T, d_model]
lm_head: [d_model, V]
logits = hidden_states @ lm_head
logits: [B, T, V]
logits[b, t, :] 表示样本 b 在位置 t 对词表中每个 token 的未归一化分数。
很多语言模型会使用 weight tying,即输入 embedding table 和输出 LM head 共享权重:
这样可以减少参数量,并让输入 token 表示和输出 token 分类空间保持一致。weight tying 不是必须的,但在语言模型中非常常见。
6. Encoder 结构¶
Transformer encoder 是多个 encoder layer 的堆叠。每个 encoder layer 通常包含:
现在实现常用 pre-norm 变体: encoder 的 self-attention 通常是双向的。也就是说,位置i 可以看到同一输入序列中的所有有效 token。对于理解类任务,这种双向上下文是合理的,因为任务目标允许使用完整输入。
encoder 输出可以看作输入序列的上下文表示:
其中 S 是 source sequence length。
典型 encoder-only 模型包括 BERT、RoBERTa 等,常用于分类、匹配、检索、抽取、序列标注等理解任务。
7. Encoder Layer 的内部模块¶
encoder layer 的两个核心子层是 multi-head self-attention 和 position-wise feed-forward network。 multi-head self-attention 负责 token 间信息交互。它让每个位置根据内容相关性从其他位置读取信息。 feed-forward network 负责对每个位置独立做非线性变换。原始 Transformer FFN 形式为:
现代 LLM 常把 ReLU 替换成 GELU、SiLU 或 SwiGLU 等激活,并扩大中间维度。 Residual connection 保留原始信息并改善梯度流动。LayerNorm/RMSNorm 稳定训练。Dropout 在原始 Transformer 中用于正则化。 encoder 的整体效果是:每一层先做跨 token 信息混合,再做逐 token 非线性变换;堆叠多层后,每个位置获得更深层的上下文表示。8. Decoder 结构¶
Transformer decoder 也由多个 decoder layer 堆叠。原始 encoder-decoder Transformer 的 decoder layer 通常包含三类子层:
masked self-attention 让目标序列内部已经生成的 token 互相交互,但不能看到未来 token。cross-attention 让 decoder 当前状态读取 encoder 输出的 source memory。FFN 对每个位置做非线性变换。 原始机器翻译场景中: - encoder 输入源语言句子。-
decoder 输入右移后的目标语言 token。
-
decoder 每个位置预测目标语言的下一个 token。
decoder 输出经过线性层得到词表 logits。
9. Masked Self-Attention¶
decoder 的 self-attention 必须使用 causal mask。对于长度为 T 的目标序列,第 i 个位置只能关注 0..i 的位置,不能关注未来位置。
causal mask 形状示例:
k1 k2 k3 k4 k5
q1 1 0 0 0 0
q2 1 1 0 0 0
q3 1 1 1 0 0
q4 1 1 1 1 0
q5 1 1 1 1 1
10. Cross-Attention¶
cross-attention 出现在 encoder-decoder Transformer 的 decoder 中。它的 Q 来自 decoder 当前隐藏状态,K/V 来自 encoder 输出。 形式为:
decoder 通过 cross-attention 在生成目标 token 时读取源序列信息。机器翻译中,decoder 生成每个目标词时可以关注源语言句子的相关部分。 在 decoder-only LLM 中通常没有 cross-attention。模型把 prompt 和待生成文本放在同一序列中,用 masked self-attention 建模上下文。11. Encoder、Decoder、Decoder-Only 的区别¶
三类结构可以这样区分:
Encoder-only:
双向 self-attention
适合理解任务
例:BERT
Encoder-decoder:
encoder 双向编码 source
decoder masked self-attention + cross-attention
适合 seq2seq 任务
例:原始 Transformer、T5、BART
Decoder-only:
masked self-attention
自回归 next token prediction
适合开放式生成和通用 LLM
例:GPT、LLaMA、Qwen
12. Training 与 Inference 的差异¶
训练 decoder-only LM 时,输入是一整段 token:
模型一次性计算所有位置的 logits,并用 causal mask 保证每个位置不能看未来。 推理时,模型逐步生成: 每一步只使用当前上下文预测下一个 token。为了避免重复计算历史 token 的 K/V,推理系统通常使用 KV cache。第二天重点在 decoding 策略,KV cache 后续系统课再深入。13. Logits、Softmax 与下一个 Token 分布¶
语言模型最后一层输出 logits:
生成时通常只取最后一个位置: 再通过 softmax 得到词表概率分布: decoding 策略就是决定如何从这个分布中选出下一个 token。不同策略会影响输出的确定性、多样性、重复率、稳定性和创造性。 常见策略包括: - greedy search:每步选概率最高的 token。-
beam search:维护多个候选序列。
-
multinomial sampling:按概率分布随机采样。
-
top-k sampling:只从概率最高的 k 个 token 中采样。
-
top-p/nucleus sampling:只从累计概率达到 p 的最小候选集合中采样。
-
temperature scaling:改变概率分布的尖锐程度。
今天重点是 top-k、top-p 和 temperature。
14. Temperature¶
temperature 用来调整 logits 的尺度。公式为:
其中T 是 temperature,不要和序列长度混淆。
temperature 的效果:
- T = 1:保持原始分布。
-
T < 1:分布更尖锐,高概率 token 更突出,输出更保守、更确定。 -
T > 1:分布更平坦,低概率 token 更有机会被采样,输出更多样但更容易跑偏。 -
T -> 0:趋近 greedy decoding。
示例 logits:
当 temperature 降低时,A 与 B/C 的概率差距会变大;当 temperature 升高时,B/C 的相对机会会增加。 temperature 只改变分布形状,不直接删除候选 token。它通常与 top-k 或 top-p 组合使用。15. Top-k Sampling¶
top-k sampling 的流程是:
- 根据 logits 或概率选出分数最高的 k 个 token。
-
把其他 token 的概率设为 0,或 logits 设为
-inf。 -
对剩下的
k个 token 重新归一化。 -
从归一化后的分布中随机采样。
形式化地说,top-k 把候选集合限制为:
然后从S_k 中采样。
top-k 的优点是简单、有效,可以过滤掉大量低概率噪声 token。缺点是 k 是固定的,无法根据当前分布形状动态调整。
如果当前分布很尖锐,k=50 可能包含很多不必要 token。如果当前分布很平坦,k=10 可能过滤掉合理候选,损失多样性。
16. Top-p / Nucleus Sampling¶
top-p sampling 又叫 nucleus sampling。它不是固定保留 k 个 token,而是保留累计概率达到阈值 p 的最小 token 集合。
流程:
- 按概率从高到低排序 token。
-
从最高概率 token 开始累加概率。
-
找到累计概率达到
p的最小集合。 -
把集合外 token 概率设为 0。
-
对集合内 token 重新归一化并采样。
候选集合:
top-p 的优点是候选集合大小会随分布形状动态变化: - 当分布很尖锐时,只保留少量 token。- 当分布较平坦时,保留更多 token。
常见参数如 top_p=0.9 或 top_p=0.95。top-p 也不是越大越好。top_p 太高会引入更多低质量候选,太低会使输出过于保守。
17. Top-k 与 Top-p 的组合¶
实际生成中,top-k、top-p、temperature 常组合使用。一个典型流程是:
logits
-> temperature scaling
-> top-k filter
-> top-p filter
-> softmax / renormalize
-> sample next token
-
top-k 设置候选数量上限。
-
top-p 根据累计概率动态控制候选范围。
例如 temperature=0.7, top_p=0.9 通常会比纯随机采样更稳定,也比 greedy 更有多样性。具体参数要根据任务调试。
18. Decoding 策略与任务适配¶
不同任务适合不同 decoding 策略。 确定性任务更适合低温度、greedy 或较保守的 sampling: - 信息抽取
-
分类标签生成
-
JSON 格式输出
-
代码补全中的严格片段
-
数学推理的最终答案格式
开放式生成更适合适度 sampling: - 创意写作
-
头脑风暴
-
对话回复
-
多样化改写
需要注意,decoding 不能从根本上修复模型能力问题。它只能改变从概率分布中选择 token 的方式。模型不知道答案、prompt 不清晰、上下文不足、训练偏差严重时,调 top-k/top-p/temperature 的收益有限。
19. 常见实现参考¶
下面是一个简化的 top-k/top-p/temperature sampling 伪代码:
import torch
import torch.nn.functional as F
def sample_next_token(logits, temperature=1.0, top_k=None, top_p=None):
# logits: [V]
if temperature <= 0:
return torch.argmax(logits)
logits = logits / temperature
if top_k is not None and top_k > 0:
values, _ = torch.topk(logits, k=top_k)
threshold = values[-1]
logits = torch.where(
logits < threshold,
torch.full_like(logits, float("-inf")),
logits,
)
if top_p is not None and 0 < top_p < 1:
sorted_logits, sorted_indices = torch.sort(logits, descending=True)
sorted_probs = F.softmax(sorted_logits, dim=-1)
cumulative_probs = torch.cumsum(sorted_probs, dim=-1)
remove = cumulative_probs > top_p
remove[1:] = remove[:-1].clone()
remove[0] = False
sorted_logits[remove] = float("-inf")
logits = torch.full_like(logits, float("-inf"))
logits.scatter_(0, sorted_indices, sorted_logits)
probs = F.softmax(logits, dim=-1)
return torch.multinomial(probs, num_samples=1)
generate 接口,但面试中能写出这个流程可以说明理解了 decoding 的本质。
20. 常见易错点¶
embedding 相关易错点: - 把 token embedding 和 one-hot 编码混为一谈。one-hot 是离散索引表示,embedding 是可学习连续向量。
-
忽略位置编码,误以为 self-attention 天然知道顺序。
-
混淆 input embedding 和 output LM head。
-
不理解 weight tying 的作用。
encoder/decoder 相关易错点: - 认为所有 Transformer 都是 encoder-decoder。现代 LLM 多数是 decoder-only。
-
认为 decoder 只能用于翻译。decoder-only 已经成为通用生成模型主流架构。
-
混淆 masked self-attention 和 cross-attention。
-
不知道 decoder 训练时可以并行,推理时必须逐步生成。
decoding 相关易错点: - 把 top-k 当成“选 top-k 中最大的 token”,实际 top-k sampling 是从 top-k 候选中按概率采样。
-
把 top-p 理解成“保留概率大于 p 的 token”,实际是保留累计概率达到 p 的最小集合。
-
认为 temperature 会删除 token,实际它只缩放 logits。
-
认为 temperature 越高越好,实际过高会增加幻觉和无关输出。
-
忘记过滤后要重新归一化概率。
21. 知识闭环总结¶
第二天的知识闭环可以压缩为:
文本先经 tokenizer 得到 token id。
token id 经 embedding table 变成连续向量。
位置机制注入顺序信息。
encoder 用双向 self-attention 建模输入序列。
decoder 用 masked self-attention 保证自回归因果约束。
encoder-decoder decoder 还通过 cross-attention 读取 encoder 输出。
decoder-only LLM 省略 encoder 和 cross-attention,直接做 next token prediction。
模型输出 logits 后,decoding 策略决定如何选择下一个 token。
temperature 调整分布尖锐程度。
top-k 固定候选数量,top-p 按累计概率动态确定候选集合。
22. 参考资料¶
-
Attention Is All You Need: https://arxiv.org/abs/1706.03762
-
Hugging Face Transformers Generation Strategies: https://huggingface.co/docs/transformers/main/en/generation_strategies
-
Hugging Face Blog - How to generate text: https://huggingface.co/blog/how-to-generate
-
The Curious Case of Neural Text Degeneration: https://arxiv.org/abs/1904.09751
-
PyTorch Transformer API: https://docs.pytorch.org/docs/2.12/generated/torch.nn.Transformer.html
-
截图推荐:李宏毅老师讲解 Transformer: https://www.bilibili.com/video/BV1L142187HH
-
截图推荐:讲解的很清楚的大模型解码: https://www.zhihu.com/tardis/zm/art/647813179
-
截图推荐:有图有代码的大模型解码: https://blog.csdn.net/Mike0010/article/details/13832616
预览时标签不可点<div class="