🧠AI LLM 基础
Transformer与自注意力
面试回答
常见问法
Transformer 为什么能替代 RNN/CNN 成为大模型主流架构?自注意力解决了什么问题?
回答
Transformer 的核心优势是自注意力机制。它允许模型在处理一个 token 时直接关注序列中其他位置的信息,不像 RNN 那样必须按时间步串行传递状态,因此更适合并行训练,也更容易建模长距离依赖。
# 自注意力计算示意图
# 1. 计算Query、Key、Value矩阵
Q = X @ W_q # [batch, seq_len, d_k]
K = X @ W_k # [batch, seq_len, d_k]
V = X @ W_v # [batch, seq_len, d_v]
# 2. 计算注意力分数
scores = Q @ K.T / sqrt(d_k) # [batch, seq_len, seq_len]
attention_weights = softmax(scores) # 归一化
# 3. 加权求和得到输出
output = attention_weights @ V # [batch, seq_len, d_v]
追问
- 自注意力的计算代价主要来自哪里?(序列长度平方复杂度)
- 为什么位置编码是必须的?(序列顺序信息)
- 大模型为什么还会在长上下文场景下退化?(计算资源限制)
原理展开
RNN 的问题在于长距离依赖难学、训练难并行。Transformer 通过 Query、Key、Value 计算注意力分数,让每个位置动态聚合其他位置的信息。这样做让模型表达能力更强,也更适配 GPU 并行。
但自注意力代价与序列长度平方相关,所以长上下文会带来显著的算力和显存压力。这也是后续为什么会出现各种稀疏注意力、缓存 KV、长上下文优化技术的原因。
# 完整Transformer Block结构示例
class TransformerBlock(nn.Module):
def __init__(self, dim, num_heads, ff_dim):
super().__init__()
# 多头自注意力
self.attention = nn.MultiheadAttention(dim, num_heads)
# 前馈网络
self.feed_forward = nn.Sequential(
nn.Linear(dim, ff_dim),
nn.ReLU(),
nn.Linear(ff_dim, dim)
)
# 层归一化和残差连接
self.norm1 = nn.LayerNorm(dim)
self.norm2 = nn.LayerNorm(dim)
def forward(self, x, mask=None):
# 自注意力层
attn_output, _ = self.attention(x, x, x, mask)
x = x + attn_output # 残差连接
x = self.norm1(x)
# 前馈网络层
ff_output = self.feed_forward(x)
x = x + ff_output # 残差连接
x = self.norm2(x)
return x
易错点
- 只说 Transformer 更强,不解释为什么强
- 把注意力理解成简单加权平均,忽略它的动态条件化本质
- 混淆多头注意力和单头注意力的区别
记忆技巧
记住Transformer三要素:
- 自注意力 = “每个token看其他所有token”
- 位置编码 = “告诉模型token顺序”
- 层归一化 = “稳定训练过程”
典型应用场景:
- 机器翻译:序列到序列任务
- 文本生成:自回归生成
- 多模态:跨模态注意力
- 长文本:各种优化变体