EECS498 · Transformer III · 11
Encoder, Decoder, and Cross-Attention
Encoder 把题目变成可查询的 memory;decoder 先理解 answer-so-far,再用当前 answer state 去读取那份 memory。三次 attention 的 Q/K/V 来源决定三种信息流。
30-second recall
30 秒回忆
你实现了 EncoderBlock、DecoderBlock、get_subsequent_mask 与完整 encoder–decoder。
- decoder 为什么需要两次不同 attention?
- cross-attention 的 row/column 分别是哪组 sequence?
- mask 为什么必须在 softmax 之前施加?
Before We Start
Cross-attention 中谁提供 Q?
A shape=[N,5,9],row 4 是?
未来 score 应在什么时候屏蔽?
BOS NEGATIVE 30 subtract NEGATIVE 34 EOSAnswer
BOS POSITIVE 0 4 EOSProblem · 一组 representations 不够
题目和答案扮演不同角色。题目是完整可见的 source;答案是在生成中的 target。若把它们无条件拼成一组双向 self-attention,答案位置可能直接读取未来 label。若完全隔开,decoder 又无法根据题目作答。需要一条有方向的桥。
Stage 1 · Encoder self-attention
question tokens shape [N,Kq] 经 embedding+position 变成 [N,Kq,M]。encoder self-attention 的 Q/K/V 都来自这组 states,所有 question positions 可互相读取。
Conceptual walkthrough(不是对 checkpoint attention pattern 的事实声明):
position: subtract
query: 当前 operator 需要理解哪些 operands/signs?
keys: 所有 question positions 提供可匹配特征
values: NEGATIVE, 3, 0, NEGATIVE, 3, 4 ... 的可传递内容
new subtract state may combine:
operator identity + sign 1 + operand 1 + sign 2 + operand 2encoder output 不是一个 answer,也不是一条压缩成单 vector 的 summary。它仍是 Kq 个 contextual states:[N,Kq,M],可供 decoder 按需读取。
把 source sequence 变成一排“已经相互沟通过、仍保留位置”的 memory slots。
Stage 2 · Decoder masked self-attention
假设当前训练/生成前缀是 BOS POSITIVE 0。decoder 首先要回答“我已经输出了什么?”因此 Q/K/V 都来自 answer prefix,但位置 i 不能读取 i 之后的答案。
reader \ source BOS POSITIVE 0 4 EOS
BOS ✓ ✕ ✕ ✕ ✕
POSITIVE ✓ ✓ ✕ ✕ ✕
0 ✓ ✓ ✓ ✕ ✕
4 ✓ ✓ ✓ ✓ ✕
EOS ✓ ✓ ✓ ✓ ✓
mask 把非法 score 设为近似 -∞,再做 softmax。于是未来位置得到 0 probability,剩余合法位置重新归一化。
未来 scores 已参与 denominator,合法位置的 weights 被压低;清零后 row sum 也不再是 1。mask 必须改变 normalization 的候选集合。
Stage 3 · Cross-attention
masked self-attention 之后,decoder state 已表示 answer-so-far。接着它问:“基于我已经生成的内容,现在该从题目哪里取信息?”
Q = decoder states [N,Ka,M]
K = encoder contextual states [N,Kq,M]
V = encoder contextual states [N,Kq,M]
scores / A [N,Ka,Kq]
cross-attention output [N,Ka,M]
row i = answer/query position i
column j = question/memory position j
对于 answer prefix BOS POSITIVE 0,最后一个 query 可以按当前需要读取题目中的操作符、符号或个位数字。它不必每一步读取同样位置:A 是随 decoder state 和 source 内容动态计算的。
因此 cross-attention 后的 decoder state 同时包含:
answer-so-far information
+
selected question informationInline check. 若 Ka=5,Kq=9,A[:,3,7] 是?
反向思想实验 · 如果 Q 来自 encoder 呢?
设 Q=encoder、K,V=decoder。数学上完全可算,matrix shape 变为 [N,Kq,Ka],语义变成“每个 question position 去查询 answer representations”。但当前生成任务需要更新 decoder states 以预测下一个答案 token;反向连接更新的是 source-side queries,信息流方向不合目标。
Your Code · 来源由调用参数直接表达
Your code · 2023
win22/A5/transformers.py · DecoderBlock.forward()
out_1 = self.attention_self(dec_inp, dec_inp, dec_inp, mask)
out_2 = self.layer_norm_1(out_1 + dec_inp)
out_3 = self.attention_cross(out_2, enc_inp, enc_inp)
out_4 = self.layer_norm_2(out_3 + out_2)第一行三次 dec_inp 表示 answer 内部交流;第三行第一个参数是 Q source,后两个是 K/V source。它不是 encoder/decoder concat,而是有方向的 memory read。
Your code · 2023
win22/A5/transformers.py · get_subsequent_mask()
mask = torch.triu(
torch.ones((K, K), dtype=torch.bool), diagonal=1
)
mask = mask.expand(N, K, K)上三角 j>i 正是 reader i 的未来 source j。扩展后的 mask 与 self-attention score [N,K,K] 对齐。
为什么还需要 Residual、Norm、MLP?
- Attention 在 positions 间搬运 information。
- Residual 把原状态与新读取结果相加,保留 identity path。
- LayerNorm 稳定每个 token 的 feature scale(历史代码采用相应 block ordering)。
- Position-wise MLP 对每个 token 的 features 做 nonlinear transformation。
每层必须完全用当前 attention/MLP 重写状态,缺少直接保留旧 representation 与 gradient 的路径。模型仍可能训练,但深层优化与信息保留更困难。
“Self-attention 是自己看自己”太模糊。准确说:一组 states 同时提供 Q/K/V,因此每个位置从同一组 positions读取。Cross-attention 则是 query group 与 memory group 不同。
Deep Dive · Historical mismatch 与今天的 debug 顺序
保存的 Notebook 中 DecoderBlock check 与 repository implementation 存在较大 mismatch。它应标作历史 caveat,不能据此虚构用户当年意图。
- 固定 N=1、短 K,打印每个 sublayer 的 expected/actual shape。
- 把 attention 暂时替换为 identity-like deterministic output,隔离 residual/norm。
- 检查调用参数顺序是否真是 Q,K,V。
- 检查 mask 的 True 语义与 softmax 前后位置。
- 逐个对齐 block ordering,而不是直接查看最终最大误差。
End-of-Lesson Deep Checks
Decoder 的两次 attention 各回答什么问题?
Masked self:我已经生成了什么?Cross:基于当前 answer state,我该从 source memory 读取什么?
为什么 encoder states 同时作为 K 和 V,但仍承担不同角色?
进入 attention head 后分别经过 WK/WV;同一 source activation 被投影为寻址 feature 与 payload feature。
若完全删除 cross-attention,模型还能条件于 question 吗?
按当前架构不能;decoder 只见 answer prefix,问题信息没有计算路径进入 logits。
causal mask 与 padding mask 是否同一目的?
不是。causal mask 阻止未来 label leakage;padding mask 阻止读取非内容 positions。二者都作用于 score,但屏蔽理由不同。
Transfer Questions
- 图像 captioning 中,Q 来自 caption prefix,K/V 可来自什么?cross matrix 两个轴是什么?
- 如果 source length=196 个 image patches、target length=12,A shape 是什么?
- 如果把 encoder memory 压成一个 slot,cross-attention 还具有按 source position 选择的能力吗?
闭卷解释
- 用“answer-so-far + question information”解释一个 decoder block。
- 不用“看”这个字,精确说明 self 与 cross attention 的 Q/K/V sources。
- 解释为什么 mask 在 softmax 前。
- 若 Q/K/V 来源反转,信息流语义如何改变?
Then I implemented: masked self-attention → residual/norm → cross-attention → residual/norm → MLP.
Now I understand: decoder 先形成 prefix-aware query,再把 encoder 的 contextual states 当可寻址 memory;当前状态因此同时携带答案历史与题目信息。
Connection · 结构有了,监督信号从哪里来?
下一课把 answer 整体右移,让每个 position 预测下一个 token,并追踪一个错误 token 的 loss 如何穿过 decoder、cross-attention、encoder,直到 embedding rows。
Based on your implementation
- EECS498 WI22 · A5 · EncoderBlock
- DecoderBlock · mask