mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
3585 字
10 分钟
Transformer架构详解

引言:Transformer的革命性意义#

2017年,Google提出的Transformer架构彻底改变了深度学习领域。它抛弃了RNN和CNN,完全基于Self-Attention机制构建,成为现代NLP的基石。

为什么Transformer如此重要?#

三大突破

  • 并行化:不再依赖顺序处理,训练速度大幅提升
  • 长距离依赖:通过Self-Attention直接建立任意距离的连接
  • 可扩展性:催生了BERT、GPT、T5等大规模预训练模型

核心思想:用Attention机制替代循环结构,让模型能够同时关注序列中的所有位置。


一、Transformer整体架构#

Transformer 结构 Transformer采用经典的Encoder-Decoder结构,但完全基于Attention机制。

架构概览#

输入序列 → Encoder → 编码表示 → Decoder → 输出序列

核心组件

  • Encoder:将输入序列编码为上下文表示
  • Decoder:基于编码表示生成输出序列
  • Multi-Head Attention:多头注意力机制
  • Feed-Forward Network:前馈神经网络
  • Positional Encoding:位置编码

Encoder-Decoder结构#

Encoder(编码器)

  • 由N个相同的层堆叠(原论文N=6)
  • 每层包含:Multi-Head Self-Attention + Feed-Forward Network
  • 输出:输入序列的上下文表示

Decoder(解码器)

  • 同样由N个相同的层堆叠
  • 每层包含:Masked Self-Attention + Cross-Attention + Feed-Forward Network
  • 输出:目标序列

二、Encoder详解#

alt text Encoder负责理解输入序列,提取上下文信息。

Encoder层结构#

alt text 每个Encoder层包含两个子层:

1. Multi-Head Self-Attention#

作用:让每个位置关注输入序列的所有位置

MultiHead(Q,K,V)=Concat(head1,...,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O

特点

  • 并行计算,无顺序依赖
  • 捕捉序列内部的依赖关系
  • 多个头关注不同的模式

并行化的物理基础:矩阵运算

Transformer 能够并行计算的根本原因是所有操作都是矩阵运算

RNN 的串行瓶颈

h_1 = f(x_1)
h_2 = f(x_2, h_1) ← 必须等待 h_1 计算完成
h_3 = f(x_3, h_2) ← 必须等待 h_2 计算完成

Transformer 的并行计算

Q = X · W^Q ← 所有位置同时计算
K = X · W^K ← 所有位置同时计算
V = X · W^V ← 所有位置同时计算
Attention = softmax(QK^T / √d_k) · V ← 矩阵乘法,GPU 高度优化

关键洞察

  • 矩阵乘法天然并行:GPU 可以同时计算所有元素
  • 无数据依赖:每个位置的 Q/K/V 计算互不依赖
  • 批量处理:整个序列作为一个矩阵,一次性处理

这就是为什么 Transformer 训练速度远超 RNN 的根本原因!

2. Feed-Forward Network#

作用:对每个位置独立进行非线性变换

FFN(x)=max(0,xW1+b1)W2+b2\text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2

特点

  • 两层全连接网络,中间使用ReLU激活
  • 对每个位置使用相同的参数
  • 增加模型的表达能力

残差连接与层归一化#

每个子层后都有:

LayerNorm(x+Sublayer(x))\text{LayerNorm}(x + \text{Sublayer}(x))

作用

  • 残差连接:帮助梯度传播
  • 层归一化:稳定训练过程

为什么用 Layer Norm 而不是 Batch Norm?#

这是一个重要的设计选择,背后有深刻的原因。

Batch Norm 的问题

  • Batch 维度做归一化:BN(x)=xμbatchσbatch\text{BN}(x) = \frac{x - \mu_{batch}}{\sigma_{batch}}
  • 在 NLP 任务中,句子长度不一(有的长,有的短)
  • 短句子需要 Padding,Padding 的值会影响统计量
  • Batch 大小变化时,归一化效果不稳定

Layer Norm 的优势

  • 单个样本的特征维度做归一化:LN(x)=xμfeatureσfeature\text{LN}(x) = \frac{x - \mu_{feature}}{\sigma_{feature}}
  • 不受 Batch 大小影响
  • 不受句子长度影响(Padding 不会干扰)
  • 每个样本独立归一化,更稳定

直观对比

Batch Norm: 对一个 Batch 内所有句子的"同一个位置"做归一化
→ 受 Padding 和 Batch 大小影响
Layer Norm: 对单个句子的"所有维度"做归一化
→ 只关注句子内部,不受外部影响

关键洞察:Layer Norm 更适合序列模型(RNN/Transformer),因为它不依赖 Batch 统计量,训练和推理时行为一致。


三、Decoder详解#

alt text Decoder负责生成输出序列,同时利用Encoder的编码信息。

训练 vs 推理:Decoder的两种工作模式#

这是Transformer最容易让人困惑的地方,理解这个区别至关重要。

推理(Inference):串行生成#

工作方式alt text

  • 自回归(Autoregressive):一个词一个词地生成
  • 上一步的输出是下一步的输入
  • 必须等待前一个词生成完才能生成下一个词

示例

步骤1: <START> → "我"
步骤2: <START> "我" → "爱"
步骤3: <START> "我" "爱" → "学习"
步骤4: <START> "我" "爱" "学习" → <END>

停止机制: 标记

Decoder 如何知道什么时候停止生成?答案是 (End of Sequence)标记

工作原理

  • 词表中包含特殊标记 <EOS>(或 <END></s> 等)
  • Decoder 每步输出一个词的概率分布:P(wtw1,...,wt1)P(w_t | w_1, ..., w_{t-1})
  • 当模型输出 <EOS> 的概率最高时,生成停止

具体流程

步骤1: softmax([0.8(我), 0.1(你), 0.05(他), 0.001(<EOS>), ...]) → 选择"我"
步骤2: softmax([0.7(爱), 0.2(是), 0.05(在), 0.002(<EOS>), ...]) → 选择"爱"
步骤3: softmax([0.6(学习), 0.3(编程), 0.08(<EOS>), ...]) → 选择"学习"
步骤4: softmax([0.05(。), 0.02(!), 0.85(<EOS>), ...]) → 选择<EOS>,停止

关键洞察

  • <EOS> 是模型学习到的”句子结束信号”
  • 训练时,正确答案的最后一个词后面就是 <EOS>
  • 推理时,模型自己决定何时输出 <EOS>

问题

  • 串行处理:无法并行,速度慢
  • 误差累积(Error Propagation):一步错,步步错

训练(Training):并行计算#

工作方式

  • Teacher Forcing:把正确答案直接喂给模型
  • 配合 Masked Attention,所有位置可以同时计算
  • 虽然结构是串行的,但训练时是并行的

示例

输入(正确答案): <START> "我" "爱" "学习"
目标输出: "我" "爱" "学习" <END>
通过 Mask 确保:
- 位置1只能看到 <START>
- 位置2只能看到 <START> "我"
- 位置3只能看到 <START> "我" "爱"
- 位置4只能看到 <START> "我" "爱" "学习"

优势

  • 并行训练:所有位置同时计算损失和梯度
  • 训练效率高:这是Transformer相比RNN的核心优势
  • 稳定训练:使用正确答案,避免误差累积

关键洞察:Decoder在训练和推理时的行为完全不同!训练时的并行化是Transformer训练速度快的根本原因。

Decoder层结构#

每个Decoder层包含三个子层:

1. Masked Multi-Head Self-Attention#

alt text alt text 作用:让每个位置只能关注之前的位置,防止”看到未来”

实现:通过掩码矩阵将未来位置的注意力分数设为-\infty

位置1: 只能看到位置1
位置2: 只能看到位置1, 2
位置3: 只能看到位置1, 2, 3

2. Cross-Attention(Encoder-Decoder Attention)#

alt text alt text 作用:让Decoder关注Encoder的输出

机制

  • Query来自Decoder
  • Key和Value来自Encoder
  • 建立输入和输出之间的对应关系

生动理解:读书找线索

把 Encoder 的输出想象成**“一本读完的书(上下文)”**:

  • 书里记录了输入序列的所有信息
  • 每个词的表示就是书中的一个”知识点”

Decoder 每生成一个字(Query),就像是**“拿着放大镜去书里找线索”**:

  • Query(当前状态):决定了”我要找什么”

    • 例如:正在翻译”机器学习”,Query 就是”当前翻译进度和需求”
  • Attention Score:决定了”我从书里提取多少信息”

    • 高分:这个位置的信息很重要,多看看
    • 低分:这个位置的信息不太相关,略过
  • 加权求和:把找到的线索综合起来

    • 最终输出 = 从书中提取的相关信息的加权组合

关键洞察:Cross-Attention 是 Decoder 和 Encoder 之间的”桥梁”,让生成过程能够动态地参考输入信息。

3. Feed-Forward Network#

与Encoder中的FFN结构相同。


四、关键组件详解#

1. Positional Encoding#

问题:Self-Attention不知道词的顺序

解决方案:在输入嵌入中加入位置信息

PE(pos,2i)=sin(pos100002i/d)PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right)PE(pos,2i+1)=cos(pos100002i/d)PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right)

特点

  • 使用正弦和余弦函数
  • 可以处理任意长度的序列
  • 相对位置关系可以通过三角函数性质表示

为什么是相加而不是拼接?#

这是一个非常重要的问题:为什么位置编码要到词向量上,而不是拼接在一起?

直觉理解

在高维空间中,相加其实等同于一种特殊的拼接

假设词嵌入是 XRdX \in \mathbb{R}^d,位置编码是 PRdP \in \mathbb{R}^d

拼接方案[X,P]R2d[X, P] \in \mathbb{R}^{2d}

  • 需要更大的模型维度
  • 参数量翻倍

相加方案X+PRdX + P \in \mathbb{R}^d

  • 保持原有维度
  • 参数量不变

关键洞察:经过线性变换后,两种方案在数学上是等价的!

拼接:[X,P][WXWP]=XWX+PWP\text{拼接:} [X, P] \cdot \begin{bmatrix} W_X \\ W_P \end{bmatrix} = X \cdot W_X + P \cdot W_P相加:(X+P)W=XW+PW\text{相加:} (X + P) \cdot W = X \cdot W + P \cdot W

为什么相加不会”破坏”语义?

在高维空间(如512维)中,两个向量相加后:

  • 原始信息并不会丢失
  • 通过不同的投影矩阵(WQ,WK,WVW^Q, W^K, W^V),模型可以提取出词向量和位置编码的不同组合
  • 就像把两种颜料混合,虽然看起来是一种颜色,但通过光谱分析仍然可以分离出原始成分

优势

  • 参数效率:维度不变,参数量不增加
  • 维度一致性:所有层的输入输出维度保持一致
  • 信息融合:词义和位置在输入时就已经融合,模型可以直接使用

2. Multi-Head Attention#

核心思想:从多个角度理解序列

计算流程

  1. 将输入投影到多个子空间(多个头)
  2. 每个头独立计算注意力
  3. 拼接所有头的输出
  4. 通过线性变换融合信息

物理意义:不同的头学习不同的模式#

Multi-Head 不仅仅是”多做几次”,而是让模型在不同的子空间里互不干扰地学习不同的语法/语义模式

具体例子

Head 1:关注局部信息(Local)

  • 捕捉相邻词之间的关系
  • 例如:“机器学习”中,“机器”主要关注”学习”
  • 识别固定搭配、短语结构

Head 2:关注长距离依赖(Global)

  • 捕捉句子中远距离的语法关系
  • 例如:“我昨天把那台坏掉的电脑修好了”
    • “我”(主语)需要关注”修好了”(谓语)
    • 虽然中间隔了很多词,但主谓关系必须建立

Head 3:关注语义相似性

  • 捕捉语义相关的词
  • 例如:“深度学习是机器学习的一个分支”
    • “深度学习”和”机器学习”语义相关

Head 4:关注句法结构

  • 捕捉修饰关系、从属关系
  • 例如:“那只在公园里奔跑的狗”
    • “狗”需要关注”奔跑”(动作)和”公园”(地点)

关键洞察

  • 每个头在自己的子空间里成为”专家”
  • 不同类型的相关性不会互相干扰
  • 最后通过 WOW^O 矩阵融合所有头的发现

为什么需要多个头?

  • 单个头可能只关注一种模式,容易遗漏重要信息
  • 多个头可以同时捕捉语法、语义、位置等多种关系
  • 就像一个团队,每个人负责不同的视角,最后综合所有意见

3. Feed-Forward Network#

结构

FFN(x) = ReLU(xW1 + b1)W2 + b2

参数

  • 输入/输出维度:512(d_model)
  • 隐藏层维度:2048(d_ff)

五、训练技巧#

1. 学习率调度#

使用Warmup策略:

lr=dmodel0.5min(step0.5,stepwarmup_steps1.5)\text{lr} = d_{model}^{-0.5} \cdot \min(\text{step}^{-0.5}, \text{step} \cdot \text{warmup\_steps}^{-1.5})

特点

  • 前期学习率线性增加(warmup)
  • 后期学习率逐渐衰减

2. Label Smoothing#

作用:防止模型过度自信

ysmooth=(1ϵ)y+ϵKy_{smooth} = (1 - \epsilon)y + \frac{\epsilon}{K}

3. Dropout#

在以下位置应用Dropout:

  • 注意力权重
  • Feed-Forward Network的输出
  • 残差连接之前

六、PyTorch实现#

Transformer Block#

import torch
import torch.nn as nn
class TransformerBlock(nn.Module):
def __init__(self, d_model, num_heads, d_ff, dropout=0.1):
super().__init__()
self.attention = nn.MultiheadAttention(d_model, num_heads, dropout=dropout)
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.ffn = nn.Sequential(
nn.Linear(d_model, d_ff),
nn.ReLU(),
nn.Dropout(dropout),
nn.Linear(d_ff, d_model)
)
self.dropout = nn.Dropout(dropout)
def forward(self, x, mask=None):
# Self-Attention
attn_output, _ = self.attention(x, x, x, attn_mask=mask)
x = self.norm1(x + self.dropout(attn_output))
# Feed-Forward
ffn_output = self.ffn(x)
x = self.norm2(x + self.dropout(ffn_output))
return x

完整Encoder#

class TransformerEncoder(nn.Module):
def __init__(self, num_layers, d_model, num_heads, d_ff, dropout=0.1):
super().__init__()
self.layers = nn.ModuleList([
TransformerBlock(d_model, num_heads, d_ff, dropout)
for _ in range(num_layers)
])
def forward(self, x, mask=None):
for layer in self.layers:
x = layer(x, mask)
return x

七、Transformer的影响与应用#

预训练模型时代#

Transformer催生了大规模预训练模型:

BERT(2018)

  • 只使用Encoder
  • 双向编码,适合理解任务
  • 应用:文本分类、问答、命名实体识别

GPT系列(2018-至今)

  • 只使用Decoder
  • 单向生成,适合生成任务
  • 应用:文本生成、对话、代码生成

T5(2019)

  • 完整的Encoder-Decoder结构
  • 统一的Text-to-Text框架
  • 应用:翻译、摘要、问答

跨领域应用#

计算机视觉

  • Vision Transformer (ViT)
  • DETR(目标检测)

语音处理

  • Speech Transformer
  • Wav2Vec 2.0

多模态

  • CLIP
  • DALL-E

八、Transformer 与其他模型的关系#

理解 Transformer 与传统模型的关系,有助于从更高的理论视角理解其设计。

Self-Attention vs CNN#

CNN 可以看作是一种受限的 Self-Attention

CNN 的局限性:

  • 固定的感受野:卷积核大小固定(如 3×3),只能看到局部信息
  • 权重共享:所有位置使用相同的卷积核
  • 需要堆叠多层:才能扩大感受野,捕捉长距离依赖

Self-Attention 的优势:

  • 全局感受野:每个位置可以直接关注所有位置
  • 动态权重:注意力权重根据输入内容动态计算
  • 一步到位(1) 复杂度建立任意距离的连接

直观对比:

CNN: 每个位置只能看到固定窗口内的邻居
[●]---[●]---[●] (3×3 卷积核)
Self-Attention: 每个位置可以看到所有位置,权重动态调整
[●]←→[●]←→[●]←→[●] (全连接,权重可学习)

关键洞察 通过归纳偏置(局部性)减少参数,但牺牲了灵活性;Self-Attention 用更多参数换取更强的表达能力。

Self-Attention vs GNN#

Self-Attention 本质上是一个全连接的图神经网络(GNN)

图神经网络视角:

  • 节点(Node):序列中的每个 token
  • 边(Edge):任意两个 token 之间都有连接(全连接图)
  • 边权重:注意力分数 Attention(Q,K,V)\text{Attention}(Q, K, V)
  • 消息传递:通过注意力机制聚合邻居信息

数学形式对比:

GNN 的消息传递:

hi(l+1)=Aggregate({hj(l)wij:jN(i)})h_i^{(l+1)} = \text{Aggregate}\left(\{h_j^{(l)} \cdot w_{ij} : j \in \mathcal{N}(i)\}\right)

Self-Attention:

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

关键区别:

  • GNN:图结构通常是稀疏的,只聚合邻居节点信息
  • Self-Attention:图结构是完全图,每个节点与所有节点相连

九、Transformer vs RNN/CNN#

特性RNNCNNTransformer
并行化不可并行可并行完全并行
长距离依赖困难需要堆叠多层O(1)直接连接
计算复杂度O(n·d²)O(k·n·d²)O(n²·d)
归纳偏置顺序性局部性
数据需求中等较少大量

关键洞察

  • Transformer用计算换灵活性
  • 需要大量数据学习有效的模式
  • 在大规模数据上表现最佳

九、总结#

Transformer架构的核心创新:

  • 完全基于Attention:抛弃RNN和CNN
  • 并行化训练:大幅提升训练效率
  • 可扩展性:支持大规模预训练

关键组件

  • Multi-Head Self-Attention:捕捉序列依赖
  • Positional Encoding:编码位置信息
  • Encoder-Decoder:统一的序列到序列框架

致谢#

本笔记在学习李宏毅老师的深度学习课程(LeeDL)时完成。感谢李宏毅老师对Transformer架构的详细讲解。

相关资源:

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Transformer架构详解
https://castorice.xin/posts/transformer/
作者
castorice
发布于
2026-02-09
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时