← cd ../posts

从 RNN 到 Transformer:让机器读懂顺序

2026-05-26

AI 系列第 5 篇。上一篇我们让机器"看见",这一篇让它"读懂顺序"。 你会看到一个有意思的现象:让机器读懂语言用了 31 年,而真正改变格局的,是其中最近 5 年的事。

0. "顺序"为什么特别难?

图像可以一眼看完。一张猫的照片你看 200ms 就知道是猫,不管你从哪个像素开始扫——猫还是猫。

但语言不行。

"我没说他偷了我的钱。"

把重音放在不同位置,意思完全不同:

  • 没说他偷了我的钱(别人说的,不是我)
  • 说他偷了我的钱(我根本没说)
  • 我没他偷了我的钱(我心里想但没说)
  • 我没说偷了我的钱(是别人偷的)
  • 我没说他了我的钱(是借的不是偷)
  • 我没说他偷了的钱(偷的不是我的)
  • 我没说他偷了我的(偷的不是钱,是别的)

同一个字符串,7 种意思。 区别在哪?在每个词所处的上下文位置

让机器理解语言,本质上要解决两件事:

  1. 顺序信息:词的先后关系不能丢。
  2. 上下文依赖:每个词的意思取决于它周围的词,甚至几十词外的词。

今天这篇就是看:30 多年里,人们怎么一步步把这两件事搞定的。

1986  RNN              ─┐
1997  LSTM              ├─ "逐字读书"时代
2014  seq2seq + attn   ─┘
─────────────────────────
2017  Transformer      ──── "整页扫读"时代开启
2018+ BERT / GPT 系   ──── 大模型时代

1. 1986 / 1997:RNN 和 LSTM——让神经网络"有记忆"

普通神经网络(上几篇讲的 CNN、感知机)有个致命问题:它没有时间感。给它一句话,它会一次性把所有词同时塞进去处理,完全不知道"今天"应该在"我"之后。

1986 年,神经网络派想出一个朴素的招——让网络回头看自己

RNN:把"上一个我"喂给"现在的我"

RNN(Recurrent Neural Network) 的结构长这样:

"我"        "爱"        "你"
  │           │           │
  ▼           ▼           ▼
[网络] ──▶ [网络] ──▶ [网络]
  ▲           ▲           ▲
  │           │           │
  h_0        h_1         h_2 (最终理解)

每读一个词,网络更新一次内部状态 h。处理下一个词时,把上一个 h 喂回来。这样网络就有了"我之前看过什么"的记忆。

听起来很妙。但实操有两个大坑:

坑 1:梯度消失/爆炸

记不记得第 3 篇讲的梯度消失?RNN 把这问题放大了 100 倍。

"今天 我 在 楼下 那家 三年前 开张 的 咖啡店 ... 喝了 一杯 ___"

要预测最后那个空,模型需要回看"咖啡店"这个词。但中间隔了 10+ 个词,梯度传 10 层就衰减到几乎为 0。RNN 实际上记不住很远的东西

坑 2:必须逐字处理

RNN 是严格串行的。你必须先处理"我",才能处理"爱",才能处理"你"。没法并行。GPU 是为并行计算设计的,串行任务跑 GPU 等于浪费。

1997:LSTM 给 RNN 装了"长期记忆"

1997 年,Hochreiter 和 Schmidhuber 提出 LSTM(Long Short-Term Memory),给 RNN 装上了三个"门":

  • 忘记门(forget gate):决定要忘掉哪些旧信息。
  • 输入门(input gate):决定哪些新信息要存进来。
  • 输出门(output gate):决定当前对外输出什么。
              ┌─── forget gate ───┐
旧记忆 ───────┤                    ├──▶ 新记忆
              └─── input gate ────┘
                       ▲
                       │
                  新输入信息

这三个门都是可训练的小神经网络,每个时间步自己决定开关。直觉上像人的工作记忆——你不会记住所有细节,只记住你"判断为重要"的部分。

LSTM 解决了大半的长距离依赖问题。1997 → 2014 这 17 年,所有 NLP 任务的 SOTA 基本都是 LSTM 系列(翻译、语音识别、文本生成)。

但 LSTM 没解决"串行"那个问题。GPU 时代来了,串行架构就成了瓶颈。

一句你可以拿去吹的话: LSTM 比 RNN 强 100 倍,但 LSTM 还是 RNN。它没改变"逐字读书"这个根本范式。


2. 2014:seq2seq——"先读完再翻译"

2014 年,Google 的 Sutskever(对,又是他)和 Cho 团队几乎同时提出了 sequence-to-sequence(seq2seq) 架构。这是机器翻译史上的一个关键拐点。

之前做翻译是字对字硬翻:

"I love you" → 查表 → "我 爱 你"

这种方式在长句、口语、惯用语上经常翻得稀烂。

seq2seq 改成了:

编码阶段:用 LSTM 把整句英文"读完",压缩成一个固定长度的"思想向量"。
解码阶段:用另一个 LSTM 把"思想向量"展开成中文。

      Encoder LSTM            Decoder LSTM
"I" "love" "you" "<eos>"    "<sos>" "我" "爱" "你"
  │   │     │      │           │     │   │   │
  ▼   ▼     ▼      ▼           ▼     ▼   ▼   ▼
  ┌─┐ ┌─┐  ┌─┐   ┌─┐   →    ┌─┐  ┌─┐ ┌─┐ ┌─┐
  └─┘─└─┘──└─┘───└─┘──[c]──→└─┘──└─┘─└─┘─└─┘
                       ▲
                这个 c 就是"思想向量"

这个范式叫 encoder-decoder,今天的 BERT(only encoder)、GPT(only decoder)、T5(encoder-decoder)全是这条线下来的。

但 seq2seq 有个明显的瓶颈

整句话被压成一个固定长度的向量。短句没事,长句就开始丢信息——你怎么把一段 50 词的段落压进一个 256 维向量里,还指望它包含所有细节?

这个瓶颈,催生了 attention。


3. 2014:attention——"读到哪里查到哪里"

2014 年 9 月,Bengio 团队(蒙特利尔大学)发表 Neural Machine Translation by Jointly Learning to Align and Translate。这篇论文提出了 attention(注意力机制)。

它的洞察非常朴素:翻译"我爱你"的"爱"这个字时,模型应该重点看英文那边的"love",不是"I" 和 "you"。

解码器在生成"爱"时:
  看 "I"     ──── 关注度 5%
  看 "love"  ──── 关注度 80%  ◀── 主要靠这个
  看 "you"   ──── 关注度 15%

这个"关注度"就叫 attention weight。它是模型自己学出来的——训练时它会发现"翻译动词时主要看英文动词"这种规律。

直觉理解:attention = 一个加权平均

output = w_1 × h_1  +  w_2 × h_2  +  w_3 × h_3  +  ...
         (5%)         (80%)        (15%)

每个 h_i 是源句子里某个词的向量表示。w_i 是这次该多关注它的权重。所有权重加起来 = 1(用 softmax 归一化)。

这玩意有点像你写论文时"翻参考资料"——每次需要某个观点,你不是把整本书都重新读一遍,你是翻到对应的那一页重点看一下

加上 attention 之后,机器翻译的 BLEU 分数立刻提升了好几个点。attention 成了 seq2seq 的标配

但—— 当时大家都觉得 attention 是 LSTM 的辅助工具。没人意识到它能单独工作

直到 2017 年 6 月。


4. 2017 年 6 月 12 日:Attention is All You Need

这一天,Google Brain 八个研究员往 arXiv 上扔了一篇 8 页论文。标题特别狂:

Attention is All You Need.

翻译过来:"注意力,就够了。"

意思是:我们把 RNN / LSTM 全踢掉,只用 attention,看看会怎样。

结果:比 LSTM 快几十倍,效果还更好。

这篇论文提出的架构就是 Transformer。今天 ChatGPT、Claude、Gemini、Llama、DeepSeek—— 全部都是 Transformer 的变种。

Transformer 干掉 RNN 的两个关键招

招 1:self-attention——让每个词"自己看自己"

之前的 attention 是"解码器看编码器"。Transformer 把它推广成:句子里的每个词,都和句子里所有其他词做一次 attention

"今天 我 在 楼下 那家 三年前 开张 的 咖啡店 喝了 一杯 ___"

要预测 ___ 时,模型同时看所有词:
  "今天"      ──── 20%
  "我"        ──── 5%
  "咖啡店"    ──── 50%  ◀── 主关注
  "喝了"      ──── 15%
  "一杯"      ──── 10%

这就叫 self-attention——一句话里所有词互相"投票"决定谁该多关注谁。距离再远也是一步直达,没有 RNN 那种"传 10 步衰减"的问题。

所以 Transformer 解决了长距离依赖。

招 2:完全并行

RNN 必须 h_1 → h_2 → h_3,串行。 Transformer 可以所有词同时算。一句 100 词的话,100 个词的 attention 一次性并行算完。GPU 终于能 100% 跑满了。

所以 Transformer 训练速度比 LSTM 快几十倍。

Transformer 长什么样?

简化版结构:

    输入词 → 加 position 编码 → 转成向量
                       │
                       ▼
              ┌──────────────────┐
              │  Self-Attention   │  ◀── 词和词互相看
              └──────────────────┘
                       │
                       ▼
              ┌──────────────────┐
              │  Feed Forward     │  ◀── 全连接处理
              └──────────────────┘
                       │
                       ▼
                  重复 N 层
                       │
                       ▼
                  最终输出

每个"块"由 self-attention + 全连接组成,可以叠任意层数。GPT-3 叠了 96 层,GPT-4 推测叠了 120 层。

为什么需要"position 编码"?

self-attention 有个天然缺陷:它不知道词的顺序。所有词同时被处理,相对位置信息丢了。

解决方案是在每个词的向量上加一个 position encoding(位置编码)——一个表示"这个词是第几个"的数字。最早用三角函数:

position 0: [sin(0/10000^0), cos(0/10000^0), sin(0/10000^2), ...]
position 1: [sin(1/10000^0), cos(1/10000^0), sin(1/10000^2), ...]
position 2: [sin(2/10000^0), cos(2/10000^0), sin(2/10000^2), ...]

这种编码让模型能感知到"哪个词在前哪个词在后"。后来 RoPE(旋转位置编码)、ALiBi 等等是这个的进化版。

Multi-head attention:用多组眼睛同时看

Transformer 还有一招叫 multi-head attention

"咖啡店" 用 12 组 attention 同时算:
  head 1: 关注语法("咖啡店"作主语)
  head 2: 关注语义("咖啡店"是地点)
  head 3: 关注情感(去咖啡店通常是放松)
  head 4: 关注共指(之前提到的"那家"指它)
  ...
  head 12: 关注押韵/节奏

12 组结果拼起来,模型对一个词的理解就丰富了 12 倍。这有点像人读书时眼睛同时关注语法、情感、上下文、伏笔——只是人是隐式做的,Transformer 是显式拆开做的。

一句你可以拿去吹的话: Transformer 的核心不是"很神奇的新算法",是"把 attention 这个 2014 年的辅助工具,认真做到极致"。LSTM 被踢掉的原因,不是它不够好,是它串行**——在 GPU 时代是死刑。**


5. 2018 之后:Transformer 全面接管 NLP

Transformer 发布后一年内:

  • 2018 年 6 月 —— OpenAI 用 Transformer 的 decoder 做了 GPT-1(1.17 亿参数)。
  • 2018 年 10 月 —— Google 用 Transformer 的 encoder 做了 BERT。BERT 在 11 个 NLP 任务上全面屠榜。
  • 2019 —— GPT-2、T5、RoBERTa、XLNet…… 一年内 RNN 系彻底退场。
  • 2020 —— GPT-3(1750 亿参数)。
  • 2022 —— ChatGPT。
  • 2023+ —— Claude、Gemini、Llama、Qwen、DeepSeek、o1、R1……
Encoder 派      ──▶ 理解为主(BERT、RoBERTa)
                      用于:分类、搜索、问答
Decoder 派      ──▶ 生成为主(GPT、Claude、Llama)
                      用于:对话、写作、代码
Encoder-Decoder ──▶ 翻译/摘要(T5、BART、mT5)
                      用于:seq2seq 任务

到 2026 年的今天,99% 的 NLP 任务都是 Transformer 变种。RNN/LSTM 只在一些非常受限的场景(边缘设备、低算力推理、流式语音)还能看到。


6. 那 attention 有什么缺点?

凡事不能只看好处。Transformer 也有它的痛点:

缺点 1:复杂度是 O(n²)

self-attention 里每个词都要和所有其他词算一次 attention。一句 N 词的话,就要算 N² 次。

  • 100 词 → 10,000 次计算
  • 10,000 词 → 1 亿次
  • 100,000 词 → 100 亿次

这就是为什么"长上下文"这么贵。

GPT-3 一开始只支持 2K context。后来 4K、8K、32K、128K、1M、2M…… 每提升一档都要做大量工程优化(flash attention、sparse attention、ring attention、infini-attention 等等)。

缺点 2:没有"真正的记忆"

LSTM 至少模拟了一个"长期记忆门"。Transformer 没有这个机制——它能看到的只是 context window 里的东西。一旦超出 context,就忘了。

这是为什么今天 LLM 还需要 RAG(下一篇... 不对,是第 13 篇会讲)、需要外挂记忆系统。Transformer 是个"有限注意力"机器,不是"无限记忆"机器。

缺点 3:训练数据饕餮

Transformer 性能依赖大量数据。GPT-3 训了 5000 亿 token。这等于把人类历史上写下的相当一部分文字喂进去。数据耗光了怎么办? 这是 2025-2026 年学术圈最焦虑的问题之一。


7. 给你的小作业

  1. 解释一下 self-attention 和 RNN 的本质区别。 提示:一个是"串行 + 衰减",一个是"并行 + 直达"。
  2. 为什么需要 multi-head?一头不够吗? 提示:考虑同一个词有多重含义。
  3. 如果 Transformer 复杂度是 O(n²),那 1M context 怎么实现的?查一下 flash attention 和 sparse attention 的思路。

下一篇钩子:到这里我们一直在说"把词输入到神经网络"——但词是字符串啊,神经网络只懂数字,怎么把"咖啡店"这三个字变成一个能算的向量? 这背后是一个被严重低估的小故事:从 1957 年的 one-hot 编码,到 2013 年那个让"国王 - 男人 + 女人 ≈ 女王"成为可能的 word2vec,再到今天 LLM 内部那个 1.2 万维的 embedding 空间。 下一篇我们专门看,机器眼里的"词"长什么样