副标题 / 摘要
Self-attention 在同一序列内建模元素关系,Cross-attention 在两个序列之间做对齐。本文用公式、示例与最小可运行代码解释两者差异,并给出工程场景建议。
- 预计阅读时长:14~18 分钟
- 标签:
attention、self-attention、cross-attention - SEO 关键词:Self-Attention, Cross-Attention, 注意力机制, Transformer
- 元描述:系统对比 self-attention 与 cross-attention 的机制差异与应用场景。
目标读者
- 想理解 Transformer 关键机制的入门读者
- 需要区分编码器/解码器注意力的工程实践者
- 从事多模态应用、关注对齐策略的开发者
背景 / 动机
注意力机制是 Transformer 的核心。
但很多工程误用来自于“分不清 self 和 cross”。
理解两者的计算图和适用场景,能直接减少模型设计与性能调优的试错成本。
核心概念
- Query / Key / Value(Q/K/V):注意力的三元组。
- Self-attention:Q、K、V 来自同一序列。
- Cross-attention:Q 来自目标序列,K、V 来自源序列。
- 对齐(Alignment):跨序列的语义匹配。
A — Algorithm(题目与算法)
用通俗语言说明主题内容
- Self-attention:自己“看自己”,适合建模序列内部依赖。
- Cross-attention:一个序列“看另一个序列”,适合对齐或条件生成。
基础示例(1)
- 机器翻译的解码器在生成当前词时,需要关注源语言句子 → cross-attention。
基础示例(2)
- 语言模型内部每个 token 关注上下文 → self-attention。
实践指南 / 步骤
- 明确是否需要跨序列对齐:是 → cross-attention。
- 仅建模单序列依赖:用 self-attention。
- 组合使用:编码器 self-attn + 解码器 self-attn + 交叉注意力。
可运行示例(最小注意力计算)
import torch
import torch.nn.functional as F
def attention(q, k, v):
scores = q @ k.transpose(-2, -1) / (q.size(-1) ** 0.5)
weights = F.softmax(scores, dim=-1)
return weights @ v
# Self-attention: Q/K/V 同源
x = torch.randn(2, 4, 8) # batch, seq, dim
self_out = attention(x, x, x)
print(self_out.shape)
# Cross-attention: Q 来自目标序列, K/V 来自源序列
q = torch.randn(2, 3, 8)
kv = torch.randn(2, 5, 8)
cross_out = attention(q, kv, kv)
print(cross_out.shape)
解释与原理
- Self-attention 输出与输入序列长度一致。
- Cross-attention 输出长度与 Query 序列一致。
- 在编码器-解码器结构中,cross-attn 是桥梁。
C — Concepts(核心思想)
方法类型
Self-attention 属于序列内部建模,cross-attention 属于跨序列对齐。
关键公式
给定 Q/K/V:
$ \text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^\top}{\sqrt{d}})V $
区别在于 Q/K/V 的来源:
- Self-attention:
Q=K=V=X - Cross-attention:
Q=Y, K=V=X
解释与原理
- Self-attn 学习序列内部结构(语法、长依赖)。
- Cross-attn 学习序列之间对齐(翻译、图文匹配)。
E — Engineering(工程应用)
场景 1:机器翻译(编码器-解码器)
- 背景:解码器生成词时需要对齐源语言。
- 为什么适用:cross-attn 把源序列信息注入目标序列。
- 代码示例(Python):
import torch
q = torch.randn(1, 4, 16) # decoder states
kv = torch.randn(1, 6, 16) # encoder states
scores = q @ kv.transpose(-2, -1)
print(scores.shape)
场景 2:多模态图文对齐
- 背景:文本需要关注图像区域。
- 为什么适用:文本 token 作为 Query,视觉特征作为 Key/Value。
- 代码示例(Python):
import torch
text = torch.randn(2, 10, 32)
image = torch.randn(2, 49, 32)
attn = text @ image.transpose(-2, -1)
print(attn.shape)
场景 3:检索增强生成(RAG)
- 背景:模型需要对齐外部文档。
- 为什么适用:query 序列对检索文档做 cross-attn。
- 代码示例(Python):
import torch
query = torch.randn(1, 8, 64)
doc = torch.randn(1, 50, 64)
scores = query @ doc.transpose(-2, -1)
print(scores.shape)
R — Reflection(反思与深入)
- 时间复杂度:
- Self-attn:
O(n^2)(序列长度 n)。 - Cross-attn:
O(n*m)(目标长度 n,源长度 m)。
- Self-attn:
- 空间复杂度:注意力矩阵同样为
O(n^2)或O(n*m)。 - 替代方案:
- 局部注意力或稀疏注意力降低成本。
- 用检索或缓存缩短源序列。
- 工程可行性:跨序列对齐是必须成本,优化重点是序列长度。
常见问题与注意事项
- 误用 cross-attn 会导致模型“看错对象”。
- 不同序列的维度必须对齐(或通过线性投影对齐)。
- 长序列 cross-attn 容易成为瓶颈。
最佳实践与建议
- 先明确 Q/K/V 的来源,再写结构。
- 用可视化检查注意力矩阵是否合理。
- 长序列任务优先考虑稀疏或分块注意力。
S — Summary(总结)
核心收获
- Self-attention 解决单序列依赖建模问题。
- Cross-attention 解决跨序列对齐问题。
- 两者差异来自 Q/K/V 的来源与注意力矩阵维度。
- 工程落地时优先关注序列长度带来的成本。
推荐延伸阅读
- Attention Is All You Need
- The Annotated Transformer
- 多模态 Transformer 相关综述
参考与延伸阅读
小结 / 结论
理解 self-attention 与 cross-attention 的差异,就是理解 Transformer 的核心计算图。
这也是多模态与生成系统设计的第一原则。
行动号召(CTA)
把你的任务写成 Q/K/V 关系图,再决定用哪类注意力结构。