EECS498 · Transformer III · 11

Encoder, Decoder, and Cross-Attention

Encoder 把题目变成可查询的 memory;decoder 先理解 answer-so-far,再用当前 answer state 去读取那份 memory。三次 attention 的 Q/K/V 来源决定三种信息流。

100–120 分钟WI22 A5Self · Masked Self · Cross

30-second recall

30 秒回忆

你实现了 EncoderBlock、DecoderBlock、get_subsequent_mask 与完整 encoder–decoder。

  1. decoder 为什么需要两次不同 attention?
  2. cross-attention 的 row/column 分别是哪组 sequence?
  3. mask 为什么必须在 softmax 之前施加?

Before We Start

Cross-attention 中谁提供 Q?

A shape=[N,5,9],row 4 是?

未来 score 应在什么时候屏蔽?

同一真实任务:Question BOS NEGATIVE 30 subtract NEGATIVE 34 EOS
Answer BOS POSITIVE 0 4 EOS

Problem · 一组 representations 不够

题目和答案扮演不同角色。题目是完整可见的 source;答案是在生成中的 target。若把它们无条件拼成一组双向 self-attention,答案位置可能直接读取未来 label。若完全隔开,decoder 又无法根据题目作答。需要一条有方向的桥。

Encoder memory每个 question position 的 contextual representation
Decoder state每个 answer position 对 prefix 的理解
Cross-attentiondecoder state 作为 Q,encoder memory 作为 K/V

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 2

encoder output 不是一个 answer,也不是一条压缩成单 vector 的 summary。它仍是 Kq 个 contextual states:[N,Kq,M],可供 decoder 按需读取。

Mental model · Encoder

把 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,剩余合法位置重新归一化。

为什么不能 softmax 后再把未来 weights 清零?

未来 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 information

Inline 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()

View source →
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()

View source →
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?

  1. Attention 在 positions 间搬运 information。
  2. Residual 把原状态与新读取结果相加,保留 identity path。
  3. LayerNorm 稳定每个 token 的 feature scale(历史代码采用相应 block ordering)。
  4. Position-wise MLP 对每个 token 的 features 做 nonlinear transformation。
没有 residual 会怎样?

每层必须完全用当前 attention/MLP 重写状态,缺少直接保留旧 representation 与 gradient 的路径。模型仍可能训练,但深层优化与信息保留更困难。

Misconception diagnosis

“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,不能据此虚构用户当年意图。

What would I debug first today?
  1. 固定 N=1、短 K,打印每个 sublayer 的 expected/actual shape。
  2. 把 attention 暂时替换为 identity-like deterministic output,隔离 residual/norm。
  3. 检查调用参数顺序是否真是 Q,K,V。
  4. 检查 mask 的 True 语义与 softmax 前后位置。
  5. 逐个对齐 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

  1. 图像 captioning 中,Q 来自 caption prefix,K/V 可来自什么?cross matrix 两个轴是什么?
  2. 如果 source length=196 个 image patches、target length=12,A shape 是什么?
  3. 如果把 encoder memory 压成一个 slot,cross-attention 还具有按 source position 选择的能力吗?

闭卷解释

  1. 用“answer-so-far + question information”解释一个 decoder block。
  2. 不用“看”这个字,精确说明 self 与 cross attention 的 Q/K/V sources。
  3. 解释为什么 mask 在 softmax 前。
  4. 若 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