Skip to content

Transformer 架构 (Transformer)

🏗️ 交互演示:Transformer 架构 (Interactive)

Section titled “🏗️ 交互演示:Transformer 架构 (Interactive)”

探索 Transformer 的 Encoder-Decoder 结构,观察数据如何流经各层。

🏗️ Transformer 架构

层数:2
Encoder
Input
Input Embedding
+ Positional Encoding
×2
Multi-Head Attention
Add & Norm
Feed Forward
Add & Norm
Encoder Output
Decoder
Output (shifted)
Output Embedding
+ Positional Encoding
×2
Masked Multi-Head Attention
Add & Norm
Cross Attention
Add & Norm
Feed Forward
Add & Norm
Linear
Softmax
Output Probabilities
图例
Embedding
Attention
FFN
Add&Norm

💡 鼠标悬停查看层说明,点击"播放"观察数据流动


一句话定义:Transformer 是 Google 在 2017 年提出的深度学习模型架构(论文《Attention Is All You Need》)。它抛弃了循环神经网络 (RNN) 的循环结构,完全基于 Attention 机制来处理序列数据,实现了并行计算,是现代 LLM(如 GPT, BERT)的祖师爷。

它主要由 Encoder(编码器)Decoder(解码器) 两部分组成。

  • Encoder: 理解输入(如 BERT)。
  • Decoder: 生成输出(如 GPT)。

  • RNN (老式厨房):只有一个厨师。他必须切完菜,才能炒菜,再摆盘。如果有 100 道菜,他得一道道做。前面切错菜了,后面全完蛋。而且他记性不好,做第 100 道菜时可能忘了第 1 道菜用的什么料。
  • Transformer (现代流水线)
    • 并行计算:雇了 100 个厨师(GPU 核心),同时处理 100 道菜。
    • Self-Attention:所有厨师之间有”心灵感应”。处理”鱼”的厨师,能瞬间知道处理”白酒”的厨师进度,并根据需要配合(上下文理解),不管他们隔得有多远(长距离依赖)。
    • Positional Encoding:每个盘子上贴了编号,防止上菜顺序乱掉(因为大家是同时做的)。


在 Transformer 之前,NLP 统治者是 LSTM/RNN。 RNN 的痛点

  1. :必须按时间步 t=1, t=2… 顺序计算,无法利用 GPU 并行加速。
  2. :序列太长时,前面的信息传到后面就丢了(梯度消失/长距离依赖问题)。

Transformer 的突破

  1. :一次性输入整个句子,矩阵运算并行处理。
  2. :Attention 机制直接建立词与词的连接,距离不再是问题。

🔢 交互演示:Self-Attention 分步计算 (新!)

Section titled “🔢 交互演示:Self-Attention 分步计算 (新!)”

小白必看! 逐步观察 Attention 是如何一步步计算出来的,理解 Q×K^T → Scale → Softmax → ×V 的完整过程。

🔢 Self-Attention 分步计算

Step 1: 准备 Q, K, V
输入经过线性变换得到 Query, Key, Value 三个矩阵
Q (Query)
1
0
1
0
0
1
0
1
1
1
0
0
K (Key)
1
1
0
0
0
0
1
1
1
0
1
0
V (Value)
1
0
0
0
0
1
0
0
0
0
1
0
Attention(Q,K,V) = softmax(QKT / √dk) V

💡 点击步骤按钮或使用自动播放,观察矩阵如何一步步变换


🎯 交互演示:Self-Attention 热力图

Section titled “🎯 交互演示:Self-Attention 热力图”

观察不同词之间的注意力分布,理解 Attention 如何建立上下文关联。

🎯 Self-Attention 热力图

(标准)
The
cat
sat
on
the
mat
K
The
0.20
0.17
0.17
0.16
0.15
0.15
Q
cat
0.17
0.19
0.17
0.16
0.16
0.16
sat
0.16
0.17
0.19
0.17
0.16
0.16
on
0.16
0.16
0.17
0.19
0.17
0.16
the
0.15
0.15
0.16
0.17
0.19
0.17
mat
0.15
0.15
0.16
0.16
0.17
0.20
Attention(Q, K, V) = softmax(QKT /√dk) × V
QKT = 相似度分数 | √dk = 缩放因子 (8) | softmax = 归一化为概率

💡 点击左侧 Query 词高亮其注意力分布 | 调节 Temperature 观察分布变化


观察 sin/cos 如何编码位置信息,理解不同频率的作用。

📍 位置编码可视化

速度:
PE(pos, 2i) = sin(pos / 100002i/d)
PE(pos, 2i+1) = cos(pos / 100002i/d)
0
4
8
12
16
20
24
28
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-1
+1
💡 观察要点:
  • 低维度 (左侧): 变化频率高,编码局部位置
  • 高维度 (右侧): 变化频率低,编码全局位置
  • 每行唯一: 每个位置有独特的编码
  • 可外推: 正弦/余弦可推广到未见过的位置

💡 点击位置/维度查看详情 | 蓝色=-1, 红色=+1


调节温度参数,观察 Softmax 输出如何从“硬”变“软”,这与 LLM 生成多样性直接相关。

🎲 Softmax 概率分布可视化

调整 Logits 和 Temperature,观察概率分布变化

⚖️ 均衡
更确定更随机
🐱 猫
60.9%
🐕 狗
22.4%
🐦 鸟
13.6%
🐟 鱼
3.0%
Softmax(zi) = ezi / Σezj
τ 越小 → 分布越"尖" (更确定) | τ 越大 → 分布越"平" (更随机)
📊 Logits
模型的"原始打分",可正可负,无界限
🎯 Probabilities
经 Softmax 转换后的概率,和为 1
💡 AI 应用:LLM 生成时调节 Temperature 控制创造力

Transformer 的主要组件:

  1. Positional Encoding: 给输入向量加上位置信息(因为 Attention 是无序的)。
  2. Multi-Head Attention: 多头注意力。让模型同时关注不同的语义空间(比如一个头关注语法,一个头关注指代关系)。
  3. Feed Forward Network (FFN): 简单的全连接层,用于加工信息。
  4. Add & Norm: 残差连接(防止退化)+ LayerNorm(稳定训练)。
残差连接与归一化
LayerNorm(x+Sublayer(x))\text{LayerNorm}(x + \text{Sublayer}(x))

每个子层(Attention 或 FFN)的输出都经过这个处理。

  • xx: 输入
  • Sublayer(x)\text{Sublayer}(x): 层处理后的结果
  • ++: 残差连接 (Short-cut)

每个 Transformer Block 中的 FFN 是两层全连接网络:

前馈网络公式
FFN(x)=GELU(xW1+b1)W2+b2\text{FFN}(x) = \text{GELU}(xW_1 + b_1)W_2 + b_2
  • W1W_1: 扩展矩阵,形状 [dmodel,dff][d_{model}, d_{ff}](通常 dff=4×dmodeld_{ff} = 4 \times d_{model}
  • W2W_2: 压缩矩阵,形状 [dff,dmodel][d_{ff}, d_{model}]
  • GELU\text{GELU}: 激活函数(GPT/BERT 使用,原始论文用 ReLU)
  • 作用:先扩展维度(提取特征),再压缩回来

import torch
import torch.nn as nn
# 定义一个标准的 Transformer 模型
# d_model: 词向量维度 (如 512)
# nhead: 多头注意力的头数 (如 8)
# num_encoder_layers: 编码器层数 (如 6)
# num_decoder_layers: 解码器层数 (如 6)
transformer_model = nn.Transformer(
d_model=512,
nhead=8,
num_encoder_layers=6,
num_decoder_layers=6
)
# 模拟输入数据
# [Sequence Length, Batch Size, d_model]
src = torch.rand(10, 32, 512) # 源语言句子 (10个词)
tgt = torch.rand(20, 32, 512) # 目标语言句子 (20个词)
# 前向传播
output = transformer_model(src, tgt)
print(f"Output shape: {output.shape}")
# [20, 32, 512] -> 输出 20 个词的向量