🧠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三要素:

  1. 自注意力 = “每个token看其他所有token”
  2. 位置编码 = “告诉模型token顺序”
  3. 层归一化 = “稳定训练过程”

典型应用场景:

  • 机器翻译:序列到序列任务
  • 文本生成:自回归生成
  • 多模态:跨模态注意力
  • 长文本:各种优化变体