在上一篇文章中,我们从整体上介绍了大语言模型的发展路线。

大语言模型并不是突然出现的,它背后经历了一个长期演进过程:

统计语言模型
  ↓
神经网络语言模型
  ↓
RNN / LSTM / GRU
  ↓
Seq2Seq
  ↓
Attention
  ↓
Transformer
  ↓
BERT / GPT / T5
  ↓
大语言模型

如果想真正理解大语言模型,不能一上来就只看 GPT、LLaMA、Qwen 或 DeepSeek。我们需要先理解一个更基础的问题:

为什么早期的 RNN、LSTM、Seq2Seq 结构不够用了?
为什么后来 Transformer 会成为大语言模型的核心架构?

这一章我们就沿着这个问题展开。

本文不急着深入 Transformer 的完整结构,而是先从历史背景出发,理解从 RNN 到 Transformer 的技术演进逻辑。

一、语言建模最早要解决什么问题?

语言模型最基本的任务是:根据前面的词,预测下一个词。

例如给定一句话:我今天下午准备去

模型需要预测后面可能出现:

上课
吃饭
图书馆
公司

从概率角度看,语言模型要估计一个文本序列的概率:

                              P(x_1, x_2, \ldots, x_n) = \prod_{i=1}^{n} P(x_i | x_1, x_2, \ldots, x_{i-1})

也就是说,一个句子的整体概率,可以拆成每个 token 在前文条件下出现的概率。

对于 GPT 这类自回归语言模型来说,核心训练目标就是:

                                      P(x_i \mid x_1, x_2, \ldots, x_{i-1})

这就是 next token prediction。

问题在于:模型如何有效利用前面的上下文?

早期统计语言模型通常使用 n-gram。比如 bigram 只看前一个词,trigram 只看前两个词:

                        P(x_i \mid x_1, x_2, \ldots, x_{i-1}) \approx P(x_i \mid x_{i-2}, x_{i-1})

这种方法简单,但上下文窗口太短。

例如下面这个句子:我昨天在图书馆借了一本关于深度学习的书,今天终于把它看完了。

这里的“它”指的是“书”。如果模型只看前两个或前三个词,很难判断“它”到底指代什么。

所以语言建模从一开始就面对一个核心问题:如何建模长距离上下文依赖?

二、RNN:按顺序读取文本

RNN,全称是 Recurrent Neural Network,循环神经网络。

它的基本思想非常自然:既然文本是一个序列,那就按顺序一个词一个词地读。

假设输入序列为:

                     x_1, x_2, \ldots, x_n

RNN 在第 t 个时间步读取当前输入x_t,同时保留前一个时间步的隐藏状态h_{t-1},然后更新得到新的隐藏状态h_t
    ​             h_t = f(W_x x_t + W_h h_{t-1} + b)

其中:
       ​x_t是当前输入 token 的向量表示;
        h_{t-1}是上一时刻的隐藏状态;

       W_h h_t是当前时刻的隐藏状态;
        W_x是输入权重矩阵;
        是隐藏状态权重矩阵;
       b 是偏置;
       f 通常是 tanh 或其他非线性激活函数。

从直觉上看,RNN 的隐藏状态 h_t就像模型的“记忆”。

例如模型依次读入:

我 / 今天 / 去 / 学校 / 上课

每读一个词,隐藏状态就更新一次。理论上,最后的隐藏状态可以包含整个句子的历史信息。

RNN 的优势是明显的:

它适合处理变长序列
它可以复用同一套参数
它能够逐步积累上下文信息

所以在早期 NLP 任务中,RNN 曾经非常重要。

但是,RNN 也有一个非常关键的问题:它必须按顺序计算。

也就是说,要计算h_t,必须先算出h_{t-1};要算出h_{t-1},必须先算出h_{t-2}

计算链条是:

h1 → h2 → h3 → ... → hn

这导致 RNN 很难充分并行。对于短句子,这个问题不明显;但对于大规模语料和超长文本,顺序计算会严重限制训练效率。

1、RNN 的第一个问题:长距离依赖困难

RNN 理论上可以记住所有历史信息,但实际上很难。

原因在于,信息需要通过隐藏状态一步一步传递。

假设一个句子很长:

小明昨天在书店买了一本关于人工智能发展历史的书,回家之后认真读了很久,最后发现它非常有启发。

这里的“它”指的是前面的“书”。

如果模型要正确理解“它”,就需要把很早之前的信息一路传递到后面。

但是 RNN 中的信息传递路径很长:书 → ... → ... → ... → 它。

中间经过很多时间步后,早期信息可能会逐渐衰减。

这就是长距离依赖问题。

在训练时,这个问题通常和梯度消失、梯度爆炸有关。反向传播需要沿着时间步一层层传回去,如果链条太长,梯度可能越来越小,导致模型很难学习远距离关系。

可以直观理解为:

短距离依赖:模型容易记住
长距离依赖:模型容易遗忘

例如:我喜欢吃苹果,因为它很甜。

这里“它”距离“苹果”很近,比较容易处理。

但如果句子变成:

我昨天在超市买了一袋苹果,回家以后放在桌子上,晚上看电视时突然想起来,于是拿了一个出来吃,发现它很甜。

这里“它”距离“苹果”较远,RNN 就更难稳定建模。

三、LSTM:为了解决 RNN 的记忆问题

为了解决普通 RNN 难以建模长距离依赖的问题,LSTM 被提出。

LSTM 的全称是 Long Short-Term Memory。Hochreiter 和 Schmidhuber 在 1997 年提出 LSTM,用来缓解普通循环网络在长时间跨度任务中由于误差信号衰减导致学习困难的问题。

LSTM 的核心思想是:给模型增加一个更稳定的记忆单元,让信息可以更长时间地保留下来。

普通 RNN 只有隐藏状态 h_t,而 LSTM 额外引入了 cell state:

                                                   c_t

1. 遗忘门:决定忘掉什么

遗忘门决定上一时刻的记忆c_{t-1}中哪些信息需要保留,哪些需要丢弃

                             f_t = \sigma(W_f [h_{t-1}, x_t] + b_f)

其中:

f_t是遗忘门;
σ 是 sigmoid 函数,输出范围在 0 到 1 之间;
越接近 1,表示越保留;
越接近 0,表示越遗忘。

2. 输入门:决定写入什么新信息

输入门决定当前输入中哪些信息应该写入记忆:

                                    i_t = \sigma(W_i[h_{t-1}, x_t] + b_i)

同时生成候选记忆:

                                    \tilde{c}_t = \tanh(W_c[h_{t-1}, x_t] + b_c)

3. 更新记忆状态

LSTM 的记忆更新为:

                               c_t = f_t \odot c_{t-1} + i_t \odot \tilde{c}_t

这个公式非常关键。

它表示:新的记忆 = 保留下来的旧记忆 + 写入的新记忆.

4. 输出门:决定输出什么

输出门决定当前隐藏状态输出哪些信息:

                                 o_t = \sigma(W_o[h_{t-1}, x_t] + b_o)

通过这种门控机制,LSTM 比普通 RNN 更擅长保留长期信息。

可以简单理解为:

                               h_t = o_t \odot \tanh(c_t)

RNN:每一步都重新混合全部信息,容易遗忘
LSTM:有专门记忆通道和门控机制,更容易保留长期依赖

因此,在 Transformer 之前,LSTM 是 NLP 中非常重要的结构。

四、GRU:更简化的门控循环网络

除了 LSTM,还有一种常见结构叫 GRU,Gated Recurrent Unit。

GRU 可以理解为 LSTM 的简化版本。

它没有单独的 cell state,而是通过更新门和重置门来控制信息流动:

更新门 update gate
重置门 reset gate

GRU 的参数通常比 LSTM 少,结构更简单,训练速度可能更快。

在很多早期 NLP 任务中,LSTM 和 GRU 都是非常常用的序列建模结构。

但是,不管是普通 RNN、LSTM,还是 GRU,它们都有一个共同特点:

计算过程仍然是按时间顺序递推的。

也就是说,它们仍然很难彻底摆脱顺序计算瓶颈。

五、Seq2Seq:从单句建模到序列转换

随着机器翻译、摘要、对话生成等任务发展,NLP 需要处理一种更复杂的问题:

输入是一个序列,输出也是一个序列。

例如机器翻译:

输入:I love machine learning.
输出:我喜欢机器学习。

文本摘要:

输入:一篇长文章
输出:一段简短摘要

对话生成:

输入:你今天感觉怎么样?
输出:我感觉还不错。

这类任务被称为 sequence-to-sequence,简称 Seq2Seq。

Seq2Seq 的基本结构是:

Encoder 读取输入序列
Decoder 生成输出序列

早期 Seq2Seq 模型通常使用 LSTM 作为 Encoder 和 Decoder。Sutskever、Vinyals 和 Le 在 2014 年提出的 Seq2Seq 方法使用多层 LSTM 将输入序列编码为固定维度向量,再用另一个 LSTM 从该向量解码目标序列,并在机器翻译任务中取得了重要结果。

基本流程如下:

输入序列 x1, x2, ..., xn
  ↓
Encoder LSTM
  ↓
固定长度向量 c
  ↓
Decoder LSTM
  ↓
输出序列 y1, y2, ..., ym

用公式表示,Encoder 将输入序列压缩成一个上下文向量:

                                 c = Encoder(x_1, x_2, \ldots, x_n)

Decoder 根据 ccc 生成输出:

                               P(y_1, y_2, \ldots, y_m | x_1, x_2, \ldots, x_n) = \prod_{t=1}^{m} P(y_t | y_{<t}, c)

这里的 ccc 非常重要。它是整个输入序列的压缩表示。

早期 Seq2Seq 有一个明显问题:

不管输入句子多长,Encoder 都要把它压缩成一个固定长度向量。

这在短句子中还可以接受。

例如:I love you.

压缩成一个向量问题不大。

但如果输入句子很长:

Although the weather was terrible and the traffic was heavy, we still arrived at the conference on time and gave our presentation successfully.

要把这么长的信息全部压缩进一个固定长度向量,难度就很大。

这就像让一个人读完一整篇文章后,只能用一个固定容量的小纸条记录所有信息,然后再根据这张小纸条完整翻译文章。

显然,输入越长,信息压缩损失越严重。

Bahdanau、Cho 和 Bengio 在 2014 年提出注意力机制时,就明确指出早期 encoder-decoder 模型把源句子编码成固定长度向量可能成为性能瓶颈,并提出让模型在生成每个目标词时自动搜索与当前预测相关的源句子部分。

这个问题最终推动了 Attention 机制的出现。

六、Attention:让 Decoder 每一步都能回看输入序列

Attention 的核心思想可以概括为:Decoder 在生成每个词时,不再只依赖一个固定向量,而是可以动态关注输入序列中最相关的位置。

还是以翻译为例。

输入英文句子:I love machine learning.

输出中文:我 喜欢 机器 学习

当 Decoder 生成“我”时,它应该重点关注 “I”。

当生成“喜欢”时,它应该重点关注 “love”。

当生成“机器 学习”时,它应该重点关注 “machine learning”。

也就是说,生成不同目标词时,模型关注的源词应该不同。

Attention 就是为了解决这个问题。

在带 Attention 的 Seq2Seq 中,Encoder 不再只输出一个固定向量,而是输出每个输入位置的隐藏状态:

                       h_1, h_2, \ldots, h_n

Decoder 在第 t步生成目标词时,会根据当前解码状态 s_t​ 和所有 Encoder 隐藏状态计算相关性分数:

               e_{t,i} = score(s_t, h_i)

然后通过 softmax 得到注意力权重:

             \alpha_{t,i} = \frac{\exp(e_{t,i})}{\sum_{j=1}^{n} \exp(e_{t,j})}

再对 Encoder 隐藏状态做加权求和,得到当前时刻的上下文向量:

                 c_t = \sum_{i=1}^{n} \alpha_{t,i} h_i

这里的 c_t不再是整个句子唯一固定的表示,而是 Decoder 在第 t 个输出位置动态生成的上下文。

可以这样理解:

没有 Attention:
输入句子 → 一个固定向量 → 输出句子

有 Attention:
输入句子 → 每个词的隐藏状态
Decoder 每生成一个词,都动态选择要关注哪些输入词

Attention 的引入极大缓解了固定长度向量瓶颈。

这也是 Transformer 出现前最关键的一步。

七、Attention 为什么重要?

Attention 机制至少带来了三个重要变化。

1. 缓解长句压缩问题

原来的 Seq2Seq 需要把整个输入压缩成一个向量。Attention 让 Decoder 每一步都可以访问 Encoder 的所有隐藏状态,因此不再完全依赖单一固定向量。这对长句翻译特别重要。

2. 提供了软对齐能力

在机器翻译中,Attention 权重可以看作源语言和目标语言之间的软对齐关系。例如生成中文“机器”时,模型可能会对英文 “machine” 赋予较高权重。Bahdanau Attention 论文也强调,其模型能够自动学习 soft alignment,并且定性分析显示模型找到的软对齐结果与直觉一致。

3. 让模型从“压缩表示”转向“动态检索”

没有 Attention 时,Decoder 只能依赖压缩后的句子表示。有 Attention 后,Decoder 更像是在生成每个词时,从输入序列中动态检索相关信息。这对后来的 Transformer 非常重要。因为 Transformer 可以看作把 Attention 机制进一步推广:

不只是 Decoder 关注 Encoder,序列内部的每个 token 都可以关注其他 token。

这就是 Self-Attention。

八、从 Attention 到 Self-Attention

前面讲的 Attention 通常发生在 Encoder 和 Decoder 之间。

例如机器翻译中,Decoder 在生成目标词时关注 Encoder 的输入隐藏状态。

而 Self-Attention 的思想是:同一个序列内部的 token 之间互相关注。

例如句子:

The animal didn't cross the street because it was too tired.

为了理解 “it”,模型需要关注前面的 “animal”。

在 Self-Attention 中,每个 token 都可以和句子中其他 token 建立联系。

对于每个 token,模型会生成三个向量:

Query
Key
Value

然后通过 Query 和 Key 计算相关性,再用相关性权重对 Value 加权求和。

Self-Attention 的公式是:

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

这个公式看起来简单,但意义非常大。它让模型可以一次性计算序列中所有 token 两两之间的关系。

例如一个长度为 n 的句子,Self-Attention 可以得到一个 n×n 的注意力矩阵:

A \in \mathbb{R}^{n \times n}

其中A_{ij},表示第 i 个 token 对第 j 个 token 的关注程度。这意味着模型不再需要像 RNN 那样一步一步传递信息。任意两个 token 之间都可以直接建立联系。

九 RNN 和 Self-Attention 的本质区别

现在我们可以清楚地比较 RNN 和 Self-Attention。

1. RNN 的信息传递方式

RNN 的信息传递是链式的:

x1 → h1 → h2 → h3 → ... → hn

如果第一个词要影响最后一个词,信息需要经过很多步传递。

路径长度是:

                  O(n)

当序列很长时,远距离依赖就很难建模。

2. Self-Attention 的信息传递方式

Self-Attention 中,任意两个 token 可以直接交互:

xi ↔ xj

理论上,从第一个 token 到最后一个 token,只需要一层 attention 就可以建立联系。

路径长度是:

           O(1)

当然,实际模型还需要多层 attention、MLP 和残差连接来学习复杂表示,但从结构上看,Self-Attention 更容易建模全局依赖。

3. 并行能力不同

RNN 需要按时间步顺序计算:

先算 h1
再算 h2
再算 h3
...

Self-Attention 可以一次性计算整个序列的 Q、K、V 和注意力矩阵:

所有 token 同时计算

因此,Self-Attention 更适合 GPU 并行训练。这也是 Transformer 能够扩展到大规模模型的重要原因。

十、Transformer:彻底摆脱 RNN

Transformer 的核心思想是:完全基于 Attention,不再使用 RNN 或 CNN。

Vaswani 等人在 Transformer 论文中明确提出了一种只基于注意力机制的结构,完全去掉 recurrence 和 convolution;论文还指出 Transformer 更容易并行化,并且在机器翻译任务上训练时间明显更少。

Transformer 的完整结构包括:

Input Embedding
Positional Encoding
Multi-Head Self-Attention
Feed Forward Network
Residual Connection
LayerNorm
Encoder-Decoder Attention
Output Softmax

但是从历史演进角度看,它最关键的变化是:

RNN:顺序递推
Seq2Seq:Encoder-Decoder 压缩输入
Attention:Decoder 动态关注输入
Transformer:所有 token 通过 self-attention 并行交互

所以 Transformer 不是凭空出现的。它是在 RNN、Seq2Seq、Attention 的基础上,把“注意力”从辅助模块变成了模型主体。

十一、为什么 Transformer 适合大语言模型?

Transformer 之所以成为大语言模型的核心架构,主要有四个原因。

1. 并行训练能力强

RNN 必须顺序计算,Transformer 可以并行处理整个序列。这对于大规模语料训练至关重要。如果要训练数千亿 token 的语料,训练效率就非常关键。Transformer 的并行特性使它更适合现代 GPU/TPU 计算架构。

2. 长距离依赖建模能力强

Self-Attention 让任意两个 token 可以直接建立关系。这对于理解长文本、代码、数学证明、多轮对话都很重要。

3. 架构统一,容易扩展

Transformer 可以构建不同模型形态:

Encoder-only:BERT
Decoder-only:GPT / LLaMA / Qwen / DeepSeek
Encoder-Decoder:T5 / BART

也就是说,同一个基本结构可以派生出多种模型路线。

4. 适合规模化

Transformer 的结构简单、模块重复、工程上容易堆叠。大语言模型通常就是不断堆叠 Transformer block:

Embedding
  ↓
Transformer Block × N
  ↓
LM Head

这让模型规模可以从几亿参数扩展到几十亿、几百亿,甚至更大。

十二、从 RNN 到 Transformer 的技术脉络总结

现在我们可以把这条发展路线总结成一张表。

阶段 代表结构 核心思想 主要问题
统计语言模型 n-gram 用局部词频估计下一个词 上下文短、稀疏严重
RNN Vanilla RNN 用隐藏状态顺序建模文本 长距离依赖困难、难并行
LSTM / GRU 门控循环网络 用门控机制保留长期记忆 仍然是顺序计算
Seq2Seq Encoder-Decoder 输入序列编码为向量,Decoder 生成输出 固定长度向量瓶颈
Attention Bahdanau Attention Decoder 动态关注输入不同位置 Attention 仍是辅助模块
Transformer Self-Attention 完全基于注意力并行建模序列 注意力复杂度为 (O(n^2))

这条路线的核心变化是:

从局部统计
到顺序递推
到门控记忆
到编码-解码
到动态注意力
到全局并行 self-attention

本文我们梳理了从 RNN 到 Transformer 的技术演进过程。

早期语言模型需要解决的核心问题是:如何根据上下文预测下一个词,并建模长距离依赖?

RNN 通过隐藏状态按顺序读取文本,但它存在长距离依赖困难和难以并行的问题。

LSTM 和 GRU 通过门控机制增强了记忆能力,但它们仍然无法摆脱顺序计算。

Seq2Seq 把输入序列编码成固定长度向量,再由 Decoder 生成输出序列,推动了机器翻译、摘要等任务的发展。但固定长度向量成为长句建模的瓶颈。

Attention 机制让 Decoder 在生成每个词时动态关注输入序列中的不同位置,缓解了固定向量压缩问题。

Transformer 则进一步把 Attention 从辅助模块提升为模型主体,完全去掉 RNN 和 CNN,通过 Self-Attention 实现并行的全局序列建模。Transformer 论文明确提出该结构完全基于注意力机制,并且比循环结构更容易并行训练。

从这个角度看,大语言模型的发展可以理解为:

RNN 解决了序列建模问题
LSTM 解决了部分长期记忆问题
Seq2Seq 解决了序列到序列转换问题
Attention 解决了动态对齐问题
Transformer 解决了并行全局建模问题

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐