从零理解Transformer:让大模型听懂人话的技术底层

GPT、ChatGPT、Claude、Gemini……这些大模型背后最核心的技术就是Transformer。本文用最通俗的语言,把Self-Attention、自注意力机制、位置编码、Multi-Head Attention这些概念讲透,并梳理它们如何一步步构建出现代大语言模型。

从零理解Transformer:让大模型听懂人话的技术底层

一个困惑很多人的问题

很多人用ChatGPT、Gemini、Claude的时候,会产生一种感觉:这东西好像真的理解我在说什么。

但当你问它"为什么你回答这么快",或者"你的注意力机制是怎么工作的",它会给你一段看起来很专业的回答,但如果你没有相关背景,大概率看不懂。

这篇文章的目的,就是把Transformer的每一块拼图,一块一块地拼起来,让任何有基本编程基础的人,都能理解:

1
2
3
4
5
→ Transformer到底是什么
→ 它为什么比之前的模型(RNN/LSTM)强这么多
→ Self-Attention(自注意力)到底在"注意"什么
→ 大语言模型(LLM)是怎么用Transformer构建出来的
→ GPT、BERT、Claude之间的技术区别是什么

不堆公式,不贴复杂推导,只讲为什么这样做


一、背景:为什么需要Transformer

1.1 RNN时代的问题——顺序处理的瓶颈

在Transformer出现之前,处理序列数据(比如一段文字)的主流方法是RNN(循环神经网络)和它的改进版LSTM(长短期记忆网络)

RNN处理句子的方式,就像人逐字阅读

1
2
3
4
5
"我  今   天   去   北   京   游   玩"

 从左到右,一个词一个词地处理
 某个词的含义,取决于前面所有词

这种方式有一个根本性的问题——无法并行处理

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
RNN的问题1:无法并行
  → 第5个词的计算依赖第4个词的计算结果
  → 第4个词的计算依赖第3个词……
  → 必须一个一个来,GPU的并行能力完全发挥不出来

RNN的问题2:长距离依赖困难
  → 句子开头和结尾的词,如果有关联,RNN很难捕捉到
  → "今天天气很冷,我穿了很多衣服,但妈妈说还要再加一件"
  → "妈妈说"和开头"今天天气很冷"有关联,但距离太远,RNN记不住

RNN的问题3:梯度消失/爆炸
  → 序列太长时,反向传播过程中梯度要么变成0,要么变成无穷大
  → 训练不稳定

2017年,Google发表了那篇改变整个AI行业格局的论文:《Attention Is All You Need》,提出了Transformer架构。论文下载地址:https://arxiv.org/abs/1706.03762

1.2 Attention——注意力机制的核心思想

Transformer的核心是Attention(注意力机制),它解决RNN问题的思路非常聪明:

不再逐字处理,而是让每个词同时"看"整个句子,然后决定哪些词对自己重要。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
RNN的处理方式(串行):
  词1 → 词2 → 词3 → 词4 → 词5 → ...
  处理词3时,只能看到词1和词2

Transformer的处理方式(并行):
  词1
  词2   → 同时处理所有词 → 每个词都能"看到"整个句子
  词3   → 哪个词重要,就多"注意"哪个
  词4
  词5

这就是为什么Transformer比RNN快得多——GPU可以同时处理所有词,不再有顺序依赖


二、词如何变成数字——Embedding

2.1 词向量(Word Embedding):让机器"认识"词

Transformer不能直接处理文字,它只能处理数字。所以第一步,是把每个词转换成一串数字

这个一串数字,就叫词向量(Word Vector)

1
2
3
"苹果" → [0.23, -0.45, 0.87, 0.12, -0.33, ...] (假设512维向量)
"香蕉" → [0.18, -0.52, 0.76, 0.09, -0.28, ...]
"电脑" → [-0.11, 0.67, -0.23, 0.55, 0.41, ...]

词向量是如何生成的?现代LLM用的是**预训练(Pre-training)**的方式,通过在大规模文本上训练,让语义相近的词,在向量空间里靠得近。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
词向量的空间分布(简化示意):

       水果类
     苹果 🍎
   香蕉 🍌    电脑 💻
              手机 📱
       科技类

"苹果"和"香蕉"在向量空间里距离很近(都是水果)
"电脑"和"手机"距离很近(都是科技)

词向量是通过训练学出来的,不是人工设定的。训练目标是:让出现在相似上下文的词,有相似的向量。

2.2 Embedding在Transformer中的位置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
Transformer输入处理流程:

原始句子:"今天天气很好"

    ↓ Tokenize(分词)
["今", "天", "天", "气", "很", "好"]

    ↓ Embedding(词向量嵌入)
[
  [0.23, -0.45, 0.87, ...],  # 今 → 512维向量
  [-0.11, 0.67, -0.23, ...],  # 天 → 512维向量
  [-0.11, 0.67, -0.23, ...],  # 天(同一个词,同一个向量)
  [0.55, 0.12, -0.78, ...],   # 气 → 512维向量
  [0.89, -0.34, 0.12, ...],   # 很 → 512维向量
  [0.34, 0.78, -0.45, ...],   # 好 → 512维向量
]
6个512维的向量 → 送入Transformer Encoder/Decoder

三、位置编码(Positional Encoding):让机器知道词的顺序

3.1 一个严重的问题

Transformer并行处理所有词,带来的新问题是:并行处理丢失了顺序信息。

1
2
3
"狗咬人" vs "人咬狗"
→ 词完全一样,顺序不同,意思相反
→ 如果不告诉机器词的位置,它无法区分这两个句子

RNN天然知道顺序(逐字处理),但Transformer同时处理所有词,不知道谁先谁后。

解决方案:人为给每个词添加一个"位置信息",这就是位置编码(Positional Encoding)。

3.2 位置编码的设计——用数学表达顺序

论文中使用的是正弦余弦函数来生成位置编码:

$$ PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$$$ PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d_{model}}}\right) $$

不要被公式吓到,它的直观含义很简单:

1
2
3
4
5
6
第0个位置:PE = [sin(0), cos(0), sin(0), cos(0), ...]
第1个位置:PE = [sin(1), cos(1), sin(1/10000), cos(1/10000), ...]
第2个位置:PE = [sin(2), cos(2), sin(2/10000), cos(2/10000), ...]

每个位置的PE都是不同的!
而且PE是一个和词向量维度相同的向量,可以直接相加。

为什么用正弦余弦? 因为它们有两个优点:

1
2
3
4
5
优点1:任意两个位置的PE可以"相加"得到中间位置的大致PE
  → 模型可以推断任意位置的相对位置关系
  → PE(pos+1) ≈ PE(pos) + 变化量

优点2:PE的值域在[-1, 1],不会干扰词向量的数值范围

3.3 位置编码加到词向量上

1
2
3
4
5
最终输入 = 词向量 + 位置编码

Embedding(词向量)    [0.23, -0.45, 0.87, ...]  ← 词的语义
+  Position(位置)    [0.13,  0.87, 0.15, ...]  ← 词的位置
=  Input Vector      [0.36,  0.42, 1.02, ...]  ← 语义 + 位置 = 最终输入

这样,Transformer就知道每个词是谁、在哪个位置了。


四、Self-Attention——Transformer的核心

4.1 Attention的计算过程(三步走)

Self-Attention(自注意力)是Transformer的灵魂。它的计算过程分为三步:Query(查询)、Key(键)、Value(值)

每个输入向量,同时扮演三个角色:

1
2
3
Query(查询):"我在找什么" → 我这个词,想去"匹配"句子里的哪些词
Key(键):"我是什么"      → 代表每个词的"身份",用来被Query匹配
Value(值):"如果匹配上了,我贡献多少信息" → 实际要读取的信息

三个向量(Q/K/V)都是从原始输入向量,通过三个不同的权重矩阵 $W_Q$、$W_K$、$W_V$ 线性变换得到的。

1
2
3
4
5
6
Q = X · W_Q   (Query矩阵)
K = X · W_K   (Key矩阵)
V = X · W_V   (Value矩阵)

X = [x1, x2, x3, ...]  所有词的输入向量堆叠在一起
W_Q, W_K, W_V = 可学习的权重矩阵(模型训练出来的)

4.2 第一步:计算相似度——Query和Key做点积

用"我"这个词举例,Query向量和所有词的Key向量做点积,得到相似度分数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
以"我 爱 学 习"为例(简化版,假设向量维度=4):

词"我"的Query:   Q_我 = [1.0, 0.5, 0.2, 0.1]
词"爱"的Key:     K_爱 = [0.9, 0.3, 0.1, 0.2]
词"学"的Key:     K_学 = [0.1, 0.8, 0.6, 0.3]
词"习"的Key:     K_习 = [0.2, 0.7, 0.5, 0.4]

相似度计算(点积):

Score_我→爱 = Q_我 · K_爱 = 1.0×0.9 + 0.5×0.3 + 0.2×0.1 + 0.1×0.2 = 1.05
Score_我→学 = Q_我 · K_学 = 1.0×0.1 + 0.5×0.8 + 0.2×0.6 + 0.1×0.3 = 0.71
Score_我→习 = Q_我 · K_习 = 1.0×0.2 + 0.5×0.7 + 0.2×0.5 + 0.1×0.4 = 0.75

→ "我"和"爱"的相似度最高(1.05),"我"和"学习"次之
→ 说明"我"在找"爱"这个词

4.3 第二步:归一化——Softmax缩放

点积的结果可能会很大或很小,需要归一化,并除以 $\sqrt{d_k}$ 做缩放(防止点积值过大导致Softmax梯度消失):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
d_k = 向量维度 = 4
缩放:Score = Score / √d_k = Score / 2

Scaled_我→爱 = 1.05 / 2 = 0.525
Scaled_我→学 = 0.71 / 2 = 0.355
Scaled_我→习 = 0.75 / 2 = 0.375

Softmax归一化(所有值变成概率,和为1):

exp(0.525) / [exp(0.525) + exp(0.355) + exp(0.375)] = 0.397
exp(0.355) / [exp(0.525) + exp(0.355) + exp(0.375)] = 0.303
exp(0.375) / [exp(0.525) + exp(0.355) + exp(0.375)] = 0.300

→ "我"对"爱"的注意力权重:39.7%
→ "我"对"学"的注意力权重:30.3%
→ "我"对"习"的注意力权重:30.0%

4.4 第三步:加权求和——Value的加权平均

用注意力权重,对所有词的Value向量加权求和:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
注意力权重:["爱": 0.397, "学": 0.303, "习": 0.300]

V_爱 = [0.5, 0.2, 0.8, 0.1]   ← "爱"的Value向量
V_学 = [0.3, 0.6, 0.4, 0.9]   ← "学"的Value向量
V_习 = [0.4, 0.5, 0.3, 0.7]   ← "习"的Value向量

"我"的输出 = 0.397 × V_爱 + 0.303 × V_学 + 0.300 × V_习

= [0.397×0.5 + 0.303×0.3 + 0.300×0.4,
   0.397×0.2 + 0.303×0.6 + 0.300×0.5,
   0.397×0.8 + 0.303×0.4 + 0.300×0.3,
   0.397×0.1 + 0.303×0.9 + 0.300×0.7]

= [0.1985 + 0.0909 + 0.1200,
   0.0794 + 0.1818 + 0.1500,
   0.3176 + 0.1212 + 0.0900,
   0.0397 + 0.2727 + 0.2100]

= [0.409, 0.411, 0.529, 0.522]

这就是"我"这个词经过Self-Attention后的输出向量——它融合了"爱、学习、习"三个词的信息,融合的比例由注意力权重决定。

4.5 Self-Attention的完整公式

把上面的三步合在一起,就是完整的Self-Attention公式:

$$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$
1
2
3
4
QK^T            → 第一步:计算所有Query和Key的相似度矩阵
/ √d_k          → 第二步:缩放,防止梯度消失
softmax(...)    → 第三步:归一化,变成概率分布
× V             → 第四步:用概率对Value加权求和

4.6 从直觉上理解Self-Attention

用通俗的话说:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Self-Attention在做的事情:

→ 给句子里的每个词,发一张"调查问卷"
→ "你是谁?你和其他词有什么关系?"
→ 每个词给出自己的Query(我在找什么)、Key(我是什么)、Value(我携带什么信息)
→ 通过Query和Key的匹配,找出谁和谁关系近
→ 用匹配结果(注意力权重)对Value加权
→ 每个词的输出 = 融合了"所有词的信息",融合比例由"关系远近"决定

"我 爱 学 习"这句话里:
→ "我"的输出,重点融合了"爱"的信息(因为"我"在找"爱")
→ "学"的输出,重点融合了"习"的信息(因为"学习"是一个整体)
→ 每个词都在"看"整个句子,而不是只看到前面的词

五、Multi-Head Attention——多角度理解

5.1 为什么需要多个"头"

一个Self-Attention层,只从一个角度来理解词与词之间的关系。但语言是复杂的,词之间的关系也是多维度的。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
"苹果 是 一 家 好 公司"

"苹果"这个词,在这个句子里有多种关系:

关系1(语义关系):
  "苹果"和"公司"关系近 → 说的是Apple Inc.

关系2(主语谓语关系):
  "苹果"和"是"关系近 → "苹果"是主语

关系3(情感关系):
  "苹果"和"好"关系近 → 正面评价

关系4(语境关系):
  整个句子的语境都在暗示"苹果"=公司

**Multi-Head Attention(多头注意力)**的思路是:同时运行多组Self-Attention(每组叫一个"头"),每组从不同角度理解词的关系,然后把结果拼接起来。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
Multi-Head Attention的结构:

输入X
分成h个头(假设h=8,即8组Q/K/V)
每组独立计算Self-Attention
8个输出向量拼接(Concat)
乘以一个输出权重矩阵 W_O
最终输出

每组Q/K/V是通过不同的 W_Q_i, W_K_i, W_V_i 得到的
这些权重矩阵都是可学习的

5.2 多头的直观理解

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
单头Attention:一个人从窗户看世界,只看到一个角度
多头Attention:八个人从八个窗户同时看世界,信息更全面

比如看一张人脸:
  头1:看眼睛的大小和形状
  头2:看鼻子的高低
  头3:看嘴巴的形状
  头4:看整体轮廓
  ……
  八个头的结论拼起来 = 对这张脸的完整理解

5.3 Multi-Head Attention的公式

$$ \text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h)W^O $$

其中:

$$ \text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) $$

GPT-3有96层多头,ChatGPT(GPT-4的后端)同样层次很深——层数越多,模型能从越多角度理解语言。


六、Transformer的完整架构

6.1 Encoder(编码器)和Decoder(解码器)

Transformer有两种基本结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Transformer(完整版):Encoder + Decoder
  → 用于:机器翻译(先理解源语言,再生成目标语言)
  → 论文原图就是这种结构

Encoder-Only(仅编码器):
  → 用于:文本分类、情感分析、文本理解
  → BERT就是这个架构

Decoder-Only(仅解码器):
  → 用于:文本生成(从左到右,一个词一个词预测)
  → GPT系列就是这种架构

6.2 Encoder的结构

每个Encoder层包含两个子层:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Encoder层:
  ├── 子层1:Multi-Head Self-Attention
  │   → 每个词看整个句子,理解词与词的关系
  │   ↓
  │   + Add & Layer Norm(残差连接 + 层归一化)
  └── 子层2:Feed-Forward Network(前馈网络)
      → 对每个词独立做一个非线性变换
      → 全连接层 + ReLU/GELU激活函数
      + Add & Layer Norm

多个Encoder层堆叠(Transformer原论文:N=6层)

Add(残差连接):把输入直接加到输出上,防止层数太深时梯度消失。

1
2
3
输出 = Sublayer(输入) + 输入
  → 梯度可以顺畅地传回去
  → 训练深层网络成为可能

Layer Norm(层归一化):对每个样本的所有特征做归一化,让训练更稳定。

6.3 Decoder的结构

Decoder比Encoder多一个子层,且有一个关键机制——Masked Attention(掩码注意力)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Decoder层:
  ├── 子层1:Masked Multi-Head Self-Attention
  │   → "掩码"未来信息,确保只能看到前面的词
  │   ↓
  │   + Add & Layer Norm
  ├── 子层2:Multi-Head Cross-Attention(交叉注意力)
  │   → Decoder的Query 和 Encoder的 Key/Value 做Attention
  │   → 理解源语言和目标语言的对应关系
  │   ↓
  │   + Add & Layer Norm
  └── 子层3:Feed-Forward Network
      + Add & Layer Norm

多个Decoder层堆叠(N=6层)

Masked Attention的原理:在计算注意力时,把当前位置之后的所有词的Q·K分数设成负无穷,Softmax之后变成0。这样模型在预测第N个词时,绝对看不到第N个词之后的内容。

1
2
3
4
5
6
7
Masked Attention示意(预测第4个词时):

可以看到的词:  ✓ ✓ ✓ ✓ ✗ ✗ ✗ ✗
                 1   2   3   4   5   6   7   8

→ 不能作弊(不能提前看到答案)
→ 这就是为什么Decoder是"自回归"生成(Auto-regressive)

6.4 完整Transformer的数据流

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
输入:"我 爱 学 习"(中文翻译成英文)

Encoder部分:
  Input Embedding + Positional Encoding
  ×6层 Encoder
  Encoder Output(编码了"我 爱 学 习"的所有信息)

Decoder部分:
  Output Embedding + Positional Encoding(已经翻译的部分)
  Masked Self-Attention(只看已经翻译的词)
  Cross-Attention(参考Encoder的输出)
  ×6层 Decoder
  Linear + Softmax → 下一个词的概率分布

逐步生成:
  → 生成第1个词:"I"
  → 生成第2个词:"love"
  → 生成第3个词:"learning"
  → 生成第4个词:<EOS>(句子结束符)

七、从Transformer到大语言模型(LLM)

7.1 GPT——Decoder-Only的生成式模型

GPT(Generative Pre-trained Transformer)的架构,是仅有Decoder的Transformer,专注于文本生成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
GPT的工作方式(自回归生成):

用户输入:"今天天气很好,"
模型逐词预测下一个词:
  → "适合" ← 概率最高的词
  → "适合" + "出门" ← 继续预测
  → "适合出门" + "散步" ← 继续预测
  → …… ← 直到遇到< EOS >(句子结束符)

本质上:给定前文,预测下一个词的概率分布

GPT的训练分为两个阶段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
第一阶段:预训练(Pre-training)
  → 在海量互联网文本上做"语言模型"训练
  → 目标:给定前N-1个词,预测第N个词
  → 学习语言规律、世界知识、推理能力
  → GPT-3在约3000亿个词上训练

第二阶段:微调(Fine-tuning)
  → 在特定任务的数据上微调(问答、对话、代码等)
  → SFT(监督微调):用人工标注的问答对训练
  → RLHF(人类反馈强化学习):
      → 让模型生成多个回答
      → 人工排序哪个回答更好
      → 用排序结果训练Reward模型
      → 用Reward模型优化生成策略
  → ChatGPT就是用了RLHF

7.2 BERT——Encoder-only的双向理解模型

BERT(Bidirectional Encoder Representations from Transformers)用的是仅有Encoder的架构,专注于理解任务。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
BERT vs GPT 的核心区别:

BERT(理解):
  → "我 爱 学 习" → 同时看全部5个词
  → 适合:文本分类、情感分析、实体识别、问答理解

GPT(生成):
  → "我 爱 学" → 只能看"我 爱 学",预测"习"
  → 适合:文本生成、对话、代码补全

BERT的创新点:MLM(Masked Language Model,掩码语言模型)
  → 随机遮住15%的词
  → 让模型根据上下文预测被遮住的词
  → 这样每个词都能"看到"左右两边的上下文

7.3 GPT系列的技术演进

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
GPT-1(2018):1.17亿参数,12层,BooksCorpus数据集
GPT-2(2019):15亿参数,48层,Reddit链接网页
GPT-3(2020):1750亿参数,96层,3000亿Token
  → 涌现能力(Emergent Abilities)开始出现
  → 突然能做一些训练时没有专门教过的任务
GPT-3.5(2022):在GPT-3基础上加入RLHF
  → ChatGPT的基础
GPT-4(2023):参数规模未公开(估计万亿级)
  → 多模态(接受图像输入)
  → 更强的推理能力
  → 更长的上下文窗口(128K Token)
GPT-4o / Claude 3.5 / Gemini 2.0(2024-2025)
  → 原生多模态
  → 实时语音和视频理解
  → 更强的Agent能力

7.4 Scaling Law——规模的力量

大语言模型背后最重要的发现之一,是Scaling Law(缩放定律)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
Scaling Law的发现:

当模型的参数量、数据量、计算量增加时,
模型的能力会系统性地提升。

具体规律:
  → 参数量翻倍 → 性能大致线性提升
  → 数据量翻倍 → 性能大致线性提升
  → 计算量(参数量×数据量)翻倍 → 性能可预测地提升

这意味着:只要不断增大模型,就能不断提升能力。
这就是为什么大模型公司都在"烧钱"拼规模。

但Scaling Law也揭示了另一个事实:模型能力的提升是有上限的,取决于投入的计算量。


八、Transformer的工程实现——代码视角

8.1 PyTorch实现Self-Attention

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import torch
import torch.nn as nn
import torch.nn.functional as F
import math

class SelfAttention(nn.Module):
    """简化的Self-Attention实现"""

    def __init__(self, d_model, n_heads):
        super().__init__()
        self.d_model = d_model    # 词向量维度(如512)
        self.n_heads = n_heads    # 注意力头数(如8)
        self.d_k = d_model // n_heads  # 每个头的维度

        # Q/K/V的投影矩阵(可学习参数)
        self.W_Q = nn.Linear(d_model, d_model)
        self.W_K = nn.Linear(d_model, d_model)
        self.W_V = nn.Linear(d_model, d_model)

        # 输出投影矩阵
        self.W_O = nn.Linear(d_model, d_model)

    def forward(self, X, mask=None):
        """
        X: [batch_size, seq_len, d_model]
        mask: [batch_size, seq_len, seq_len]  # 可选,用于遮住未来信息
        """

        batch_size, seq_len, _ = X.shape

        # 1. 线性变换得到Q, K, V
        Q = self.W_Q(X)  # [batch, seq_len, d_model]
        K = self.W_K(X)
        V = self.W_V(X)

        # 2. 分成多个头(把最后一个维度分成n_heads份)
        Q = Q.view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)
        K = K.view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)
        V = V.view(batch_size, seq_len, self.n_heads, self.d_k).transpose(1, 2)

        # 3. 计算注意力分数:Q · K^T / sqrt(d_k)
        scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
        # scores: [batch, n_heads, seq_len, seq_len]

        # 4. 应用掩码(Decoder时遮住未来信息)
        if mask is not None:
            scores = scores.masked_fill(mask == 0, -1e9)

        # 5. Softmax归一化
        attn_weights = F.softmax(scores, dim=-1)  # 每行和为1

        # 6. 加权求和:attn_weights · V
        context = torch.matmul(attn_weights, V)
        # context: [batch, n_heads, seq_len, d_k]

        # 7. 拼接多头
        context = context.transpose(1, 2).contiguous()
        context = context.view(batch_size, seq_len, self.d_model)

        # 8. 输出投影
        output = self.W_O(context)

        return output, attn_weights


# 使用示例
batch_size = 2
seq_len = 10
d_model = 512
n_heads = 8

attention = SelfAttention(d_model, n_heads)
X = torch.randn(batch_size, seq_len, d_model)
output, weights = attention(X)

print(f"输入形状: {X.shape}")
print(f"输出形状: {output.shape}")
print(f"注意力权重形状: {weights.shape}")
# 注意力权重矩阵:[batch, n_heads, seq_len, seq_len]
# 权重[i][j] = 第i个词对第j个词的注意力分数

8.2 Transformer块的标准实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
class TransformerBlock(nn.Module):
    """一个完整的Transformer Encoder块"""

    def __init__(self, d_model, n_heads, d_ff, dropout=0.1):
        super().__init__()

        # 子层1:Multi-Head Self-Attention
        self.attention = SelfAttention(d_model, n_heads)
        self.norm1 = nn.LayerNorm(d_model)

        # 子层2:前馈网络
        self.ff = nn.Sequential(
            nn.Linear(d_model, d_ff),   # 扩张维度(512 → 2048)
            nn.GELU(),                  # GPT-3之后常用GELU替代ReLU
            nn.Dropout(dropout),
            nn.Linear(d_ff, d_model),  # 收缩回原维度
            nn.Dropout(dropout)
        )
        self.norm2 = nn.LayerNorm(d_model)

        self.dropout = nn.Dropout(dropout)

    def forward(self, X, mask=None):
        # Self-Attention + 残差连接 + LayerNorm
        attn_output, _ = self.attention(X, mask)
        X = self.norm1(X + self.dropout(attn_output))

        # Feed-Forward + 残差连接 + LayerNorm
        ff_output = self.ff(X)
        X = self.norm2(X + self.dropout(ff_output))

        return X


# 一个Transformer Encoder由多个Block堆叠而成
class TransformerEncoder(nn.Module):
    def __init__(self, n_layers, d_model, n_heads, d_ff, dropout=0.1):
        super().__init__()
        self.layers = nn.ModuleList([
            TransformerBlock(d_model, n_heads, d_ff, dropout)
            for _ in range(n_layers)
        ])

    def forward(self, X, mask=None):
        for layer in self.layers:
            X = layer(X, mask)
        return X

九、大模型的核心技术——RLHF

9.1 为什么大模型能"听懂人话"

GPT-1和GPT-2虽然能生成文字,但经常"一本正经地胡说八道"(幻觉问题)。ChatGPT之所以能让用户感觉"真的在对话",核心技术是RLHF(Reinforcement Learning from Human Feedback,人类反馈强化学习)

9.2 RLHF的三步流程

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
第一步:SFT(监督微调)
  → 收集人类写的"好答案"数据集
  → 用这些数据微调GPT
  → 模型学会了"什么样的回答是好的"

第二步:训练Reward模型
  → 让模型对同一个问题生成多个回答
  → 人工给这些回答排序(哪个更好)
  → 用排序数据训练一个Reward模型
  → Reward模型学会了"给回答打分"

第三步:PPO强化学习
  → 用Reward模型评估模型生成的回答
  → 用PPO算法更新GPT的参数
  → 目标是:生成更高Reward分数的回答
  → 反复迭代,越生成越好

9.3 为什么RLHF有效

1
2
3
4
5
6
7
8
没有RLHF的模型:
  → 目标是"预测下一个词"
  → 不关心回答是否有帮助、是否安全、是否真实

有RLHF的模型:
  → 目标变成了"最大化人类偏好"
  → 模型学会了隐式地"讨好"人类
  → 回答更有帮助、更安全、更符合对话习惯

十、Transformer的局限与未来

10.1 当前Transformer的局限

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
局限1:计算复杂度随序列长度平方增长
  → Attention的计算量 = O(n² × d)
  → 序列越长,计算量增长越快
  → 10000个词的序列,计算量是1000个词的100倍

局限2:上下文窗口有限
  → 虽然现在有128K甚至1M的上下文
  → 但本质上还是有限的长度
  → 超出窗口的信息难以利用

局限3:幻觉问题
  → 模型会自信地生成错误信息
  → 本质上是"下一个词预测"的统计特性
  → RAG(检索增强生成)是当前主流的缓解方案

局限4:推理成本高
  → 1750亿参数的模型,推理一次耗电量惊人
  → 延迟是实际应用的瓶颈

10.2 Transformer的替代者——Mamba和SSM

2023-2024年,出现了一些Transformer的潜在挑战者:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
状态空间模型(SSM):
  → Mamba(2023):选择性状态空间模型
  → 处理长序列时计算量是O(n),而不是O(n²)
  → 在某些任务上接近Transformer性能
  → 但在复杂推理任务上仍不如Transformer

混合架构:
  → Hybrid Mamba-Transformer
  → 结合SSM的效率和Attention的能力
  → 一些大模型开始尝试这种架构

10.3 多模态Transformer

2024-2025年的重大突破是原生多模态

1
2
3
4
5
6
7
8
9
传统方法:
  → 图像 → CLIP编码 → 文本Token空间 → LLM处理
  → 多模态是"嫁接"上去的

原生多模态(如GPT-4o、Gemini 2.0):
  → 图像、视频、音频、文本共用同一个Transformer处理
  → 音频直接转Token,不需要中间层
  → 端到端训练,所有模态一起优化
  → 延迟更低,理解更准确

十一、总结:Transformer的完整拼图

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Transformer解决的问题:

RNN的问题:
  ✗ 串行处理,无法并行
  ✗ 长距离依赖困难
  ✗ 梯度消失/爆炸

Transformer的解法:
  ✓ 完全并行处理
  ✓ 每个词都能直接"看到"所有其他词
  ✓ 通过残差连接和LayerNorm,训练深层网络成为可能

Transformer的核心组件:

1. Embedding:词 → 数字(让机器认识词)
2. 位置编码:位置信息 → 数字(让机器知道词的顺序)
3. Self-Attention:词 → 上下文感知(让每个词"看"整个句子)
4. Multi-Head:多角度理解(从不同维度理解词的关系)
5. Feed-Forward:非线性变换(增加表达能力)
6. Add & Norm:残差+归一化(让深层训练稳定)

从Transformer到大模型:

Transformer Base
    ↓ + 堆叠层数
Deep Transformer
    ↓ + 巨大规模(百亿/万亿参数)
LLM(大语言模型)
    ↓ + 海量数据预训练
Pre-trained LLM
    ↓ + SFT(监督微调)
Chat Model(ChatGPT类)
    ↓ + RLHF(人类反馈强化学习)
对齐人类偏好的助手模型(Claude/GPT-4)
    ↓ + Agent能力 + 多模态
现代AI助手(Claude/GPT-4o/Gemini)

Transformer不是终点,但它是我们目前能找到的最好的起点。 2017年那篇论文,用"Attention is All You Need"做标题,确实没有夸张——注意力机制,是让机器真正"理解"语言的关键一步。


关联文章:

  • 《编程语言的自举:Java和C语言如何用自己的语言写出自己的编译器》——底层原理的深度延伸
  • 《万物基于C语言:丹尼斯·里奇与C语言帝国的兴起与永恒》——计算机科学底层知识的入门
CC BY-NC-SA 4.0
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计