为什么交叉注意力矩阵通常不是方阵
围绕 Encoder-Decoder Attention 的描述,解释源序列长度、目标序列长度、Q/K/V 形状和交叉注意力矩阵的行列含义。
相关工具
自注意力和交叉注意力连接的序列不同
Self-Attention 的 Query、Key、Value 通常来自同一序列。序列长度为 L 时,Q 和 K 都有 L 个位置,关系矩阵自然容易写成 L×L。
交叉注意力连接的是目标序列和源序列:Query 来自解码器当前目标表示,Key 和 Value 来自编码器源记忆。源长度和目标长度本来就可以不同,因此矩阵也不必是方阵。

自注意力连接同一序列,交叉注意力连接目标 Query 和源 Key/Value。
用 T 和 S 表示两侧长度
假设当前目标前缀有 T 个位置,源序列有 S 个有效位置。目标端会产生 T 个 Query,源端会提供 S 个 Key 和 S 个 Value。Q 与 K 做点积后,得到的主要关系矩阵形状就是 T×S。
矩阵的行数由 Query 数量决定,列数由 Key 数量决定。只有当 T 和 S 恰好相等时,它才会看起来像方阵;这不是交叉注意力的必要条件。
矩阵的每一行是一个目标位置的问题
第 i 行对应目标端第 i 个 Query。它表示当前目标位置正在查询源序列中的哪些位置。行内的 S 个分数经过缩放和 Softmax 后,形成该目标位置对源序列的权重分布。
不同目标位置的 Query 不同,因此每一行的关注分布也可能不同。生成一个动词、名词或标点时,解码器当前状态不同,查询源记忆的方式也会变化。

交叉注意力矩阵每一行对应一个目标位置,表示它对全部源位置的查询分布。
矩阵的每一列是一个源记忆位置
第 j 列对应源序列第 j 个 Key/Value 位置。纵向查看一列,可以看到不同目标位置对同一个源位置的关注情况。某个源词可能只影响一个目标位置,也可能被多个目标位置读取。
列不是目标词的对应编号,也不要求与某一行一一匹配。翻译中的语序变化、词形变化和短语表达,都需要允许目标位置从源序列不同区域组合信息。
Q、K、V 的形状如何对上
如果目标 Query 形状看成 T×d_k,源 Key 形状看成 S×d_k,转置后 QKᵀ 就是 T×S。源 Value 可以看成 S×d_v,权重矩阵乘以 V 后得到 T×d_v 的目标侧输出。
这里必须匹配的是 Q 和 K 的最后一维 d_k,而不是两侧序列长度。T 和 S 可以不同,只要投影后的特征维度适合做点积,交叉注意力就能建立关系。

目标 Q 的位置数为 T,源 K/V 的位置数为 S,QKᵀ 形成 T×S,乘 V 后回到目标位置。
目标前缀变长时,矩阵只增加行
推理时源序列通常保持不变,源长度 S 不变;目标前缀从 BOS 开始逐步变长,Query 数量 T 逐步增加。因此,交叉注意力的关系矩阵会增加行,列数通常保持为源序列长度。
缓存源端 Key 和 Value 可以避免重复编码源序列,但不能让当前目标 Query 提前出现。每轮新增一个目标位置,就需要为它计算一行对源序列的注意力关系。
源 Padding 会屏蔽矩阵列
批量源序列需要 Padding 时,统一张量长度可能大于某条真实源句长度。源端无效位置对应交叉注意力矩阵的列,因此 Padding Mask 通常在列方向屏蔽它们,Softmax 后这些列的权重接近零。
目标端的 Padding 可能影响无效行,目标未来掩码则主要属于目标自注意力。看交叉注意力矩阵时,先确认行是目标、列是源,再判断掩码应该落在哪一侧。

交叉注意力矩阵的源端无效位置位于列方向,需要在 Softmax 前被屏蔽。
为什么非方阵更适合翻译关系
翻译不要求源句和目标句长度相同。源句可能较长,目标句可能较短;也可能目标语言需要更多词元表达同一内容。T×S 矩阵允许每个目标位置查询全部源位置,不强迫两侧长度或位置一一对应。
这正是交叉注意力和简单逐词替换的区别之一。模型保留两侧各自的序列结构,再用一个可变形的关系矩阵建立目标到源的软连接。
用四个问题检查矩阵方向
第一,Query 来自目标还是源;第二,Key 和 Value 来自哪一侧;第三,矩阵行数是否等于 Query 数量;第四,矩阵列数是否等于 Key 数量。确认这四点后,形状通常就不会弄反。
记住一句话:交叉注意力的行是目标查询,列是源记忆。目标长度决定行,源长度决定列;Q 和 K 的特征维度要匹配,序列长度不必相同。
常见问题
交叉注意力矩阵一定是 T×S 吗?
在标准目标 Query、源 Key 的写法下,主要分数矩阵是 T×S;具体实现可能增加批次、头等额外维度,但行列语义仍然对应目标和源。
源序列和目标序列必须一样长吗?
不需要。交叉注意力正是为了处理两侧长度不同的关系,目标长度决定行数,源长度决定列数。
为什么源 Padding 是列方向屏蔽?
因为源端 Key 和 Value 对应矩阵的列,源端无效位置会出现在这些列中。