深入理解 Transformer:从 Attention 到大语言模型

目录


为什么我们需要 Transformer?

前言

这几年,Transformer 几乎已经成为人工智能领域绕不开的一个名字。

无论是我们熟悉的大语言模型,还是文本生成、机器翻译、图像理解、多模态模型,背后都能看到 Transformer 的影子。

当我们第一次接触 Transformer 时,很容易看到这样一堆名词:

Attention
Self-Attention
Multi-Head Attention
Q、K、V
Positional Encoding
Encoder
Decoder
Transformer Block

然后打开论文或者各种源码,很快会产生一种感觉:

Transformer 好像就是由一堆复杂的矩阵运算拼起来的。

如果只是停留在这个层面,我们确实可以把 Transformer 的公式背下来,甚至把代码实现出来。

但是,这样并不能真正理解 Transformer。

因为一个更加根本的问题还没有回答:

为什么我们需要 Transformer?

Transformer 并不是人工智能领域凭空出现的一个新架构。

在 Transformer 出现之前,我们已经有了能够处理文本序列的神经网络,例如 RNN、LSTM、GRU,以及基于 Encoder-Decoder 的机器翻译模型。

既然这些模型已经可以处理文本了,为什么还需要重新设计一个 Transformer?

要理解这个问题,我们不能直接从 Transformer 开始。

我们需要先回到 Transformer 出现之前,看看当时的模型究竟遇到了什么问题。


一、让机器理解一句话,并没有想象中那么简单

我们先从一个最简单的问题开始:

如果让计算机处理一句话,它到底应该怎么处理?

例如:

我 喜欢 学习 人工智能

对于我们人类来说,这句话非常简单。

我们能够自然地理解:

  • “我”是主语;
  • “喜欢”表示一种行为;
  • “学习”是具体行为;
  • “人工智能”是学习的对象。

甚至当一句话变得更加复杂时,我们仍然可以通过上下文理解其含义。

例如:

小明把书放在桌子上,因为他马上要出门。

这里的“他”指谁?

很明显,我们知道“他”指“小明”。

但是对于计算机来说,问题就没有这么简单了。

计算机看到的并不是“意义”,而是一串离散的符号:

小明
把
书
放
在
桌子
上
因为
他
马上
要
出门

因此,对于一个能够处理文本的模型而言,真正困难的问题并不是:

“我能不能看到这些词?”

而是:

“我应该如何理解这些词之间的关系?”

这其实就是整个 NLP(Natural Language Processing,自然语言处理)领域长期以来都在解决的问题。


二、最直接的想法:按照顺序一个一个处理

既然文本本身就是一个序列,那么一个非常自然的想法就是:

按照文本出现的顺序,一个一个处理。

例如:

我 → 喜欢 → 学习 → 人工智能

处理“我”的时候,模型获得一个信息。

处理“喜欢”的时候,在“我”的基础上继续理解。

处理“学习”的时候,再结合前面的信息。

最后处理“人工智能”。

这种思路非常符合我们对“阅读”的直觉:

读到第一个词
    ↓
记住一些信息
    ↓
继续读第二个词
    ↓
结合之前的信息
    ↓
继续读第三个词
    ↓
……

在早期的神经网络模型中,RNN(Recurrent Neural Network,循环神经网络)就是按照这样的思想设计出来的。


三、RNN:让神经网络拥有“记忆”

我们先不考虑复杂的数学公式,只从直觉上理解 RNN。

假设输入是一句话:

我 喜欢 学习 人工智能

RNN 会按照顺序处理这些词。

可以简单理解为:

         h₁
        ↗
我 → RNN

                h₂
               ↗
喜欢 → RNN ────┘

                         h₃
                        ↗
学习 → RNN ─────────────┘

                                  h₄
                                 ↗
人工智能 → RNN ──────────────────┘

这里的 h 可以理解成:

模型读到当前位置时,对前面信息进行总结后形成的一份“记忆”。

例如:

读到“我”
    ↓
得到 h₁

读到“喜欢”
    ↓
结合 h₁
    ↓
得到 h₂

读到“学习”
    ↓
结合 h₂
    ↓
得到 h₃

读到“人工智能”
    ↓
结合 h₃
    ↓
得到 h₄

所以 RNN 最大的特点就是:

当前时刻的计算不仅依赖当前输入,还依赖之前保存下来的隐藏状态。

我们可以用一个更加简单的结构来表示:

xₜ + hₜ₋₁
      ↓
     RNN
      ↓
    hₜ

其中:

  • xₜ:当前输入;
  • hₜ₋₁:之前保存的隐藏状态;
  • hₜ:处理当前输入之后产生的新隐藏状态。

这使得神经网络第一次拥有了某种意义上的“记忆”。


四、RNN 的问题:它必须“一个一个来”

看到这里,我们可能会觉得:

RNN 不是挺好的吗?

它能够处理序列,也能够把之前的信息传递到后面。

但问题恰恰就出在这里:

它必须一个一个处理。

假设我们有:

x₁ → x₂ → x₃ → x₄ → x₅ → x₆ → … → x₁₀₀₀

RNN 必须:

x₁
 ↓
x₂
 ↓
x₃
 ↓
x₄
 ↓
……
 ↓
x₁₀₀₀

前一个时间步的计算没有完成,后一个时间步就很难开始。

也就是说:

RNN 的计算天然具有顺序依赖。

这一点在处理短文本时可能并不明显。

但是,当序列变得非常长时,这个问题就开始显现。

假设我们需要处理一万个 Token:

Token 1
Token 2
Token 3
……
Token 10000

传统 RNN 的计算必须沿着这条链依次进行。

这意味着:

序列越长,计算链越长。

而现代深度学习模型最喜欢的是什么?

并行计算。

GPU 擅长同时进行大量相似的数学运算。

但是 RNN 却告诉 GPU:

先算 1
算完以后再算 2
算完以后再算 3
……

这就有点像:

给一个拥有几千个工人的工厂安排任务,却规定所有工人必须排队,一个做完之后下一个才能开始。

GPU 再强,也很难完全发挥自己的优势。

所以 RNN 的第一个问题就出现了:

计算过程存在严重的顺序依赖,并行能力有限。


五、第二个问题:真的能记住很久吗?

RNN 的另一个问题更加关键。

那就是:

它真的能够记住很久以前的信息吗?

还是刚才那个例子:

小明把书放在桌子上,因为他马上要出门。

我们希望模型能够知道:

他 → 小明

但是假设一句话变得非常长:

小明……
……
……
……
……
……
……
……
他马上要出门。

此时“他”和“小明”之间可能隔着几十个、几百个甚至更多 Token。

RNN 理论上可以通过隐藏状态不断传递信息,

小明
 ↓
h₁
 ↓
h₂
 ↓
h₃
 ↓
h₄
 ↓
……
 ↓
h₁₀₀
 ↓
他

但这里有一个很现实的问题:

信息在传递的过程中,真的能够完整地保留下来吗?

答案通常是否定的。

因为每一次状态更新,本质上都在对之前的信息进行压缩。

你可以把 h 理解成一个不断更新的“记忆盒子”。

刚开始:

h₁:
“小明”

继续处理:

h₂:
“小明 + 把书……”

再继续:

h₃:
“前面大量信息的某种总结”

随着序列不断向后推进,模型需要把越来越多的信息压缩到一个固定维度的隐藏状态中。

这就引出了一个非常直观的问题:

如果前面有几百个词,最后真的能够把所有重要信息都塞进一个状态向量里吗?

显然很困难。


六、这就是所谓的“长距离依赖问题”

在 NLP 中,有一个非常重要的概念:

Long-Term Dependency,长距离依赖。

所谓长距离依赖,就是:

一个 Token 的含义,需要依赖距离它很远的另一个 Token。

例如:

我出生在中国……
……
……
……
……
……
……
所以我会说中文。

“中文”和“中国”之间存在语义上的联系。

再例如:

虽然今天下着很大的雨,而且路上非常堵,
但是我还是按时到达了公司。

“但是”后面的内容,与前面的“虽然”存在明显的逻辑关系。

对人类来说,理解这种联系并不困难。

但是对于 RNN 来说,这意味着:

前面的信息
   ↓
h₁
   ↓
h₂
   ↓
h₃
   ↓
……
   ↓
h₅₀
   ↓
当前 Token

信息必须穿过一条非常长的路径。

路径越长,信息在传播过程中丢失的可能性就越大。

这就是 RNN 面临的核心问题之一:

距离较远的两个 Token 之间,信息需要经过很多次状态传递才能建立联系。


七、LSTM:既然记不住,那就给它一个更聪明的记忆系统

既然普通 RNN 容易忘记前面的信息,那么一个非常自然的思路就是:

能不能设计一个更加聪明的记忆机制?

于是 LSTM(Long Short-Term Memory)出现了。

LSTM 可以理解成:

给 RNN 增加了一套更加精细的信息管理机制。

它会通过门结构控制:

什么信息应该留下?
什么信息应该删除?
什么信息应该输出?

也就是我们经常听到的:

  • Forget Gate
  • Input Gate
  • Output Gate

如果把普通 RNN 想象成一个人记笔记:

看到什么
记什么
继续往下看

那么 LSTM 更像是一个会整理笔记的人:

这个信息很重要
    ↓
保留下来

这个信息没用了
    ↓
删除

这个信息暂时没用
    ↓
先放着

这确实在很大程度上解决了 RNN 的长期依赖问题。

所以在很长一段时间里:

RNN
 ↓
LSTM / GRU
 ↓
Encoder-Decoder

成为了处理序列任务的重要技术路线。


八、但是,LSTM 真的解决了一切问题吗?

并没有。

这里需要特别强调一点:

LSTM 是对 RNN 的改进,但它并没有改变 RNN“按顺序处理”的根本结构。

不管是 RNN、LSTM 还是 GRU,本质上仍然是:

Token 1
   ↓
Token 2
   ↓
Token 3
   ↓
Token 4
   ↓
……

它们仍然需要依赖前面的隐藏状态。

因此:

计算上的顺序依赖

这个问题依然存在。

而且,当序列越来越长时,模型依然需要让信息沿着时间方向不断传递。

于是我们又遇到了一个问题:

有没有一种方法,可以让任意两个 Token 直接建立联系,而不需要让信息一个一个地传过去?

这个问题非常关键。

因为如果可以做到这一点:

Token 1 ───────────────→ Token 100
Token 2 ───────────────→ Token 100
Token 3 ───────────────→ Token 100
……

那么我们就不需要让信息:

Token 1
 ↓
Token 2
 ↓
Token 3
 ↓
……
 ↓
Token 100

一级一级地传递了。

这就是后来 Attention 思想真正重要的地方。


九、Encoder-Decoder:我们离 Transformer 已经很近了

在 Transformer 出现之前,还有一个非常重要的架构:

Encoder-Decoder。

其最经典的应用之一就是机器翻译。

例如:

I love artificial intelligence.

翻译成:

我喜欢人工智能。

一个很自然的设计是:

英文
 ↓
Encoder
 ↓
某种中间表示
 ↓
Decoder
 ↓
中文

Encoder 负责:

理解输入。

Decoder 负责:

生成输出。

这时候我们又遇到了一个问题。

假设输入句子非常长:

Token 1
Token 2
Token 3
……
Token 100

如果 Encoder 最后只把整个句子压缩成一个固定长度的向量:

Token 1
Token 2
……
Token 100
      ↓
一个固定向量
      ↓
Decoder

那么问题就又出现了:

这么多信息全部压缩到一个向量里,真的够吗?

答案显然是否定的。

于是研究人员开始思考:

Decoder 在生成每一个词的时候,为什么一定要把所有信息都压缩到一个固定向量里?

既然 Decoder 现在正在生成某个词,那么:

能不能让它直接回头看看输入序列,并决定自己应该重点关注哪些词?

这就是 Attention。


十、Attention:不要把所有信息都记住,只需要“关注重要的信息”

Attention 的核心思想其实非常直观。

我们可以把它理解成:

当我处理当前信息时,不需要平均地看待所有信息,而应该把注意力放在真正重要的地方。

例如:

小明把书放在桌子上,因为他马上要出门。

当模型看到:

它真正关心的可能是:

小明

而不是:

把
书
放在
桌子
上
因为
马上
要
出门

所以模型需要做的其实是:

“他”
 ↓
寻找相关信息
 ↓
“小明” ← 重点关注

我们甚至可以把它想象成一个“注意力分配器”。

对于当前 Token:

模型可能给不同 Token 分配不同的权重:

小明      0.72
把        0.01
书        0.03
放        0.01
桌子      0.02
因为      0.04
马上      0.03
出门      0.14

这些数字并不是说“小明”这个词本身有 0.72 的意义。

这些权重表达的是:

当模型理解“他”时,应该在多大程度上参考其他 Token。

这样一来,模型就不需要把所有信息都压缩到一个固定的隐藏状态中。

而是能够:

需要谁的信息,就直接去关注谁。

这就是 Attention 最核心的思想。


十一、Attention 真正解决了什么?

到这里,我们就可以重新回头看 RNN 的问题。

RNN 的信息传递方式是:

Token 1
   ↓
Token 2
   ↓
Token 3
   ↓
……
   ↓
Token 100

而 Attention 更像是:

             Token 1
             ↗
Token 100 ← Token 2
             ↖
             Token 3
             ↖
             ……

也就是说:

当前 Token 可以直接关注序列中的其他 Token。

这带来了一个非常重要的变化。

假设:

Token 1 ─────────────────── Token 100

在 RNN 中:

Token 1
 ↓
Token 2
 ↓
……
 ↓
Token 100

需要经过很多步才能传递信息。

而在 Attention 中:

Token 1 ─────────→ Token 100

可以直接建立联系。

这就是为什么 Attention 对长距离依赖问题如此重要。


十二、但是 Attention 还不够

到这里,我们似乎已经解决了所有问题。

RNN:

依赖前面的隐藏状态。

Attention:

直接关注其他 Token。

看起来已经非常完美。

但研究人员又发现了一个新的问题:

既然我们可以让 Token 之间直接建立联系,那么为什么还要按照顺序一个一个处理?

这其实是一个非常重要的转折。

Attention 本身并不要求:

Token 1
处理完
↓
Token 2
处理完
↓
Token 3

相反,我们可以把整个序列:

x₁ x₂ x₃ x₄ x₅

一起放进模型。

然后通过矩阵运算,一次性计算所有 Token 之间的关系。

于是:

RNN:

x₁ → x₂ → x₃ → x₄ → x₅

逐渐变成:

Attention:

x₁ ─────┐
x₂ ─────┤
x₃ ─────┼→ 同时计算彼此之间的关系
x₄ ─────┤
x₅ ─────┘

这意味着:

序列模型第一次真正有机会充分利用 GPU 的并行计算能力。

这就是 Transformer 最重要的出发点之一。


十三、2017 年,Transformer 出现了

2017 年,Google Research 团队发表了一篇后来影响整个 AI 行业的论文:

Attention Is All You Need

论文提出了 Transformer。

它最核心的一句话,其实可以概括成:

Attention Is All You Need。

也就是说:

我们能否不再依赖 RNN,而只使用 Attention 来构建序列模型?

Transformer 给出的答案是:

可以。

它不再把 RNN 作为核心计算单元,而是以 Attention 为核心,构建了全新的网络架构。

简单来看:

传统序列模型:

RNN
 ↓
RNN
 ↓
RNN
 ↓
RNN


Transformer:

Attention
    ↓
Attention
    ↓
Attention
    ↓
Attention

当然,真正的 Transformer 并不是简单地把 RNN 删除,然后换成几个 Attention 层。

它还包含:

Multi-Head Attention
Positional Encoding
Feed Forward Network
Residual Connection
Layer Normalization
Encoder
Decoder

这些模块共同组成了完整的 Transformer 架构。


十四、为什么 Transformer 最终能够改变整个 AI?

现在,我们可以重新回答最开始的问题:

为什么我们需要 Transformer?

答案并不是一句简单的:

“因为 Transformer 比 RNN 强。”

真正的原因是:

第一,Transformer 摆脱了 RNN 的强顺序依赖

RNN:

x₁ → x₂ → x₃ → x₄ → x₅

Transformer:

x₁
x₂
x₃
x₄
x₅
 ↓
Attention
 ↓
统一计算关系。

这使 Transformer 更容易进行大规模并行计算。


第二,Transformer 更容易建立长距离依赖

RNN:

Token 1
 ↓
Token 2
 ↓
……
 ↓
Token 100

Attention:

Token 1 ─────────→ Token 100

两个距离非常远的 Token 也可以直接建立联系。


第三,Transformer 非常适合扩展

这是一个非常重要,但初学者容易忽略的特点。

Transformer 的结构非常规则:

输入
 ↓
Embedding
 ↓
Transformer Block
 ↓
Transformer Block
 ↓
Transformer Block
 ↓
……
 ↓
输出

当我们希望模型变得更强时,可以增加:

参数量
训练数据
计算资源
网络深度
隐藏维度
Attention Head

于是模型可以不断扩展。

这为后来大语言模型的发展提供了非常重要的基础。


十五、从 Transformer 到今天的大语言模型

如果我们把整个发展过程串起来,就会发现一条非常清晰的路线:

RNN
 ↓
解决序列数据问题
 ↓
LSTM / GRU
 ↓
缓解长期依赖问题
 ↓
Encoder-Decoder
 ↓
解决输入到输出的序列任务
 ↓
Attention
 ↓
让模型能够直接关注重要信息
 ↓
Transformer
 ↓
摆脱 RNN 的顺序计算
 ↓
BERT / GPT / T5 等模型
 ↓
大规模预训练
 ↓
Large Language Model
 ↓
今天的大语言模型

所以,当我们今天使用各种大语言模型时,真正应该记住的并不是

“这个模型有多少亿参数。”

而是

它为什么能够发展到今天?

而这条技术路线的一个重要起点,就是 Transformer。


十六、我们真正需要理解的,不是 Transformer 的公式

写到这里,我们还没有真正开始推导:

Q
K
V

也没有开始计算:

Attention(Q, K, V) = softmax(QK^T / √d_k) V

这是故意的。

因为如果现在直接把公式扔出来,我们很容易陷入一个误区:

Q 是什么?
K 是什么?
V 是什么?
为什么要点乘?
为什么要除以 √d?
为什么要 Softmax?

最后可能把公式背下来了,却不知道:

为什么要这么设计?

而这一篇真正想建立的认知只有一个:

Transformer 的出现,本质上是在解决传统序列模型在“信息传递、长距离依赖以及并行计算”方面的问题。

我们可以把整个过程浓缩成一句话:

RNN:
让信息沿着序列一步一步传递


Attention:
让信息可以直接建立联系


Transformer:
让 Attention 成为整个模型的核心

这也是理解 Transformer 最重要的第一步。


十七、小结

在这一篇中,我们没有急着进入 Transformer 内部,而是先回答了一个更加重要的问题:

为什么需要 Transformer?

我们首先看到,文本本身就是一种序列数据。

为了处理序列,我们曾经使用 RNN,让模型通过隐藏状态保存之前的信息。

但是 RNN 存在两个明显的问题:

  1. 计算存在严重的顺序依赖,并行能力有限;
  2. 当两个 Token 距离较远时,信息需要经过很多次状态传递,长距离依赖较难处理。

随后,LSTM、GRU 等模型通过更复杂的门控机制改善了记忆能力,但它们仍然没有从根本上摆脱 RNN 的顺序计算方式。

于是 Attention 出现了。

Attention 不再要求信息必须一级一级地传递,而是允许:

当前 Token 直接关注序列中与自己相关的其他 Token。

在此基础上,Transformer 进一步摆脱了 RNN,将 Attention 作为整个模型的核心,并利用矩阵运算充分发挥 GPU 的并行计算能力。

最终形成了:

RNN
 ↓
LSTM / GRU
 ↓
Attention
 ↓
Transformer
 ↓
BERT / GPT
 ↓
大语言模型

这条技术路线。


Transformer 核心结构图

在了解了 Transformer 为什么会出现之后,让我们先直观地看一下它的整体架构。下图展示了一个简化的 Transformer Encoder-Decoder 结构:

Decoder (N×)

Encoder (N×)

输入序列
(已编码)

Multi-Head
Attention

Add & Norm

Feed Forward
Network

Add & Norm

Encoder 输出

目标序列
(已编码)

Masked Multi-Head
Attention

Add & Norm

Cross Multi-Head
Attention

Add & Norm

Feed Forward
Network

Add & Norm

Decoder 输出

Linear
Layer

Softmax

输出概率分布

核心模块说明

1. Encoder(编码器)

  • 作用:将输入序列(如源语言句子)转换为一系列富含上下文信息的向量表示。
  • 结构:由 N 个相同的层堆叠而成(图中用 N× 表示),每层包含:
    • Multi-Head Attention:让输入序列中的每个位置都能同时关注序列中所有其他位置,捕获丰富的上下文关系。
    • Feed Forward Network:对每个位置独立进行非线性变换,增强模型的表达能力。
    • Add & Norm:残差连接(Add)和层归一化(Norm),帮助训练更深的网络。

2. Decoder(解码器)

  • 作用:基于 Encoder 的输出和已生成的部分目标序列,预测下一个 Token。
  • 结构:同样由 N 个相同的层堆叠而成,但比 Encoder 多一个 Attention 层:
    • Masked Multi-Head Attention:防止当前位置关注到未来的 Token(确保自回归生成)。
    • Cross Multi-Head Attention:让 Decoder 关注 Encoder 的输出,实现“编码-解码”的信息传递。
    • Feed Forward NetworkAdd & Norm:与 Encoder 类似。

3. 信息流向

  1. 输入序列Encoder → 得到上下文丰富的表示。
  2. 目标序列(已生成部分)Decoder
  3. Encoder 输出Decoder 的 Cross Attention → Decoder 知道该关注输入序列的哪些部分。
  4. Decoder 输出Linear + Softmax → 得到下一个 Token 的概率分布。

4. 为什么需要这么多模块?

  • Multi-Head Attention:从多个角度(多个“头”)同时计算注意力,捕获不同类型的关系。
  • Feed Forward Network:为每个位置提供独立的非线性变换,增加模型的表达能力。
  • Add & Norm:残差连接缓解梯度消失,层归一化稳定训练过程。
  • Positional Encoding:为模型提供序列中 Token 的位置信息(图中未单独画出,通常加在输入 Embedding 上)。

这个架构的核心思想是:让模型能够并行处理整个序列,同时让任意两个位置都能直接建立联系,从而解决了 RNN 的顺序依赖和长距离依赖问题。

下一篇:Transformer 究竟是什么?

现在我们已经知道:

Transformer 是为了解决什么问题而出现的。

但是新的问题马上又来了:

Transformer 到底长什么样?

为什么一张 Transformer 的结构图里会同时出现:

Encoder
Decoder
Multi-Head Attention
Feed Forward
Add & Norm
Positional Encoding

这些模块又分别负责什么?

尤其是:

为什么 Attention 明明已经能够建立 Token 之间的联系,Transformer 还需要这么多其他模块?

下一篇,我们正式进入 Transformer 内部。

我们先不急着推导 Q、K、V,而是从整体架构开始,把 Transformer 的每一个组成部分逐层拆开,先建立一张完整的“地图”。

只有先知道每个模块在整个系统中负责什么,后面真正开始推导 Self-Attention 时,才不会迷失在公式里。

更多推荐