从0训练LLM · 现代大模型体系 阅读+实验 ≈ 30 分钟 页内实验 ×1
C0 序章:为什么是 Transformer + 预测下一个词 第 2 课

怎么记住任意长的历史?

RNN:一个状态传到底
不存表格,只存一个固定大小的状态、一路传下去——RNN 在原理上能看到任意远的前文。但训练时梯度每往回一步都要乘一次,0.9 乘 100 次只剩 2.66×10⁻⁵。

本课一问:怎么记住任意长的历史? 「小明 把 苹果 给了 ___」——要猜出下一个词,得记得 4 个词之前的「小明」。上一课的 bigram 只看前 1 个词。

这一课先不碰:输入一句、输出另一句的翻译结构(L3);注意力(L3、L4);LSTM 各个门的完整公式(只讲梯度走哪条路)。

从已有出发

贯穿例句「小明 把 苹果 给了 小王」:要在最后一格猜出「小王」,得记得 4 个词以前的「小明」。上一课的 bigram 只看得到「给了」。

上一课的计数模型输出的是同一个东西——下一个词的概率(流水线最右端),失败在两处:没见过的组合概率为 0;窗口只有前 1 个词。第一处要靠词向量解决(C1);这一课处理第二处。

从已有出发 · 累计数据流 点已学环节看形状与参数
解码层

这条流水线的「解码层」里今天放的是注意力;这一课讲的 RNN 不在其中——但它的一个想法在 2025-2026 年又回到了锚点模型的 64 层里的 48 层(岔路 B1)。

先自己设计:窗口不够,那就加大窗口?

最直接的想法:bigram 只看前 1 个词,那就看前 n−1 个词。

  1. ① 朴素方案
  2. ② 它在哪失败
  3. ③ 改进方案
朴素方案加大窗口:n-gram 看前 n−1 个词
窗口计数表格子数 Vn(锚点 V = 248,320,现算)
看前 1 个词(n = 2)6.17×10¹⁰
看前 2 个词(n = 3)1.53×10¹⁶
看前 4 个词(n = 5)9.44×10²⁶

即使把计数换成上一课预告的词向量(C1 的 NPLM),输入仍是「前 n−1 个词的向量拼起来」,窗口照样是写死的。

改进:能传下去,不等于学得会

先把 RNN 的一步看清楚:

RNN 的一步
= tanh( +
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
状态只有一条通路:第 1 个词的信息要影响第 100 步的预测,必须穿过 99 次 W 和 99 次 tanh。

训练用反向传播(沿时间展开,叫 BPTT):第 T 步的 loss 对第 T−n 步状态的梯度,是中间每一步的「局部导数」连乘。取最简单的标量 RNN(状态只有 1 个数,权重是一个数 w)看得最清楚:

梯度沿时间往回传(标量 RNN)
=
👆 公式里带下划线的每一项都可以点——点哪项,讲哪项。
矩阵情形把 w 换成雅可比矩阵 W·diag(tanh′),「小于 1 / 大于 1」换成它的谱半径与奇异值——结论相同:连乘要么消失,要么爆炸。

这就是 梯度消失 / 爆炸:Hochreiter 1991 年的学位论文最早分析了它,Bengio, Simard & Frasconi 1994 把它写成「用梯度下降学长期依赖是困难的」 。

⚠

常见误解:「RNN 能记住任意长的历史。」 它能表示:状态一路传下去,理论上第 1 个词可以影响第 100 步。但它学不会用:第 100 步的 loss 传回第 1 步时,只剩 2.66×10⁻⁵ 倍(w = 0.9 时;把 tanh′ 算进去更小)。梯度小到这个程度,早期的词对参数更新几乎没有贡献。

⚠

常见误解:「w > 1 梯度就一定爆炸。」 只在状态停留在 tanh 的线性区时才会。状态一旦被推到 ±1 附近,tanh′ 很小,w·tanh′ 反而小于 1——下面实验台里把 w 设成 1.1、再调大输入强度 u 就能看到真实曲线往下走。

改进一:LSTM(1997)。 Hochreiter & Schmidhuber 给状态加了一条加法通路(细胞状态 c):ct = ct−1 + (门控后的新内容)。梯度沿这条路往回传时,每步乘的系数是 1,不再被迫乘 w·tanh′——原文把它叫作「恒定误差传送带」,并报告能跨越 1,000 步以上的时间间隔 。

但原版的系数恒为 1,状态只能累加、不会清空。 今天说的 LSTM 里「每步乘遗忘门 f」是 Gers, Schmidhuber & Cummins 2000 加的,让网络自己学会什么时候忘 。于是细胞通路上的梯度又变回连乘:fn。f 是由数据算出来的、可学习,训练可以把需要记住的地方的 f 学到接近 1——但 f = 0.99 时 100 步剩 0.366,f = 0.9 时就和普通 RNN 一样了。

改进二:梯度裁剪。 爆炸那一侧,Pascanu, Mikolov & Bengio 2012 提出按梯度范数裁剪:范数超过阈值就等比例缩小 。今天训练 LLM 仍然默认开着它(C5 细讲)。

⚠

常见误解:「LSTM 解决了长依赖。」 它把强制的 w·tanh′ 换成了可学习的门 f,大大缓解了消失,但梯度仍然是连乘;而且下面两个问题它一个都没动。

还剩两个问题,RNN 家族都解决不了:

  1. 必须逐步串行。 要算 ht 必须先算完 ht−1,一个 4,000 词的序列在训练时也要一步一步走 4,000 步,没法沿序列并行。串行步数、最长路径与每层计算量的真实计数,见 C3 的岔路课「为什么不用 RNN?」,L4 会看到 Transformer 怎样把它变成 1 步。
  2. 所有信息都挤在一个固定长度的状态里。 读一句话时还好;要把一整句翻译成另一句时,整句的意思都得压进这一个向量——下一课的问题。

RNN 的历史角色。 从 2010 年的 RNN 语言模型到 2017 年之前,循环网络是神经网络处理语言的主干:语言模型、字符级生成、2014 年的 seq2seq 翻译,以及 2015 年第一次「先用语言模型预训练、再微调」的尝试(Dai & Le 用的就是 LSTM,L5 会讲)都建在它上面。今天纯 RNN 已经退出 LLM 的主干,但「一个固定大小的状态」这个想法,在 2024-2026 年以线性注意力的形式回来了——锚点模型的 64 层里有 48 层就是这种层,见岔路 B1。

极小真数字:拖动 w,看梯度一步步消失

算法模拟器 · 真标量 RNN 前向 + 梯度连乘(浏览器里现算)
横轴:从第 T 步往回数的步数;纵轴:梯度还剩多少(对数刻度,每格 ×10)。 虚线 = 只看权重 wn 实线 = 真实前向算出的 ∏ w·tanh′
序列条:每格 = 一个时间步,颜色 = 从最后一步回传到这里还剩多少梯度
打开 LSTM 细胞通路:把「乘 w·tanh′」换成「乘遗忘门 f」
🎯

试三件事: ① 保持 w = 0.9、T = 100:左卡是 0.9100 = 2.66×10−5,中卡是真实前向算出的连乘——更小,因为 tanh′ 的平均值小于 1。点「逐步回传」,看颜色从右往左一格格变淡。 ② 把输入强度 u 拖到 0、w 设成 1.1:状态一直是 0,tanh′ 恒为 1,两条线重合,100 步后放大到 13,781 倍——这是爆炸。再把 u 慢慢拖大,看真实曲线掉头往下:状态进了饱和区。 ③ 展开下面的 LSTM 细胞通路:f = 1(1997 原版)是一条水平线;f = 0.99 时 100 步剩 0.366;f = 0.9 时和 RNN 的 0.9100 重合——还是连乘。

🔍 为什么叫「沿时间反向传播」 把 RNN 按时间展开,它就是一个 T 层深、每层共享同一组权重的前馈网络;对它做普通的反向传播,就叫 BPTT(backpropagation through time)。「梯度连乘」和深层前馈网络里梯度逐层相乘是同一件事,只是 RNN 的层数等于序列长度,而且每层用的是同一个 W,连乘的是同一个矩阵——这让指数行为更加极端。深层前馈网络怎么用初始化、残差与归一化对付同一个问题,见 C4 与 C8。

证据三问

问本课的回答(以 LSTM 为例)
① 它解决什么问题?普通 RNN 的梯度沿时间被 w·tanh′ 连乘,100 步后只剩 2.66×10⁻⁵ 或更少,长距离依赖学不会
② 数学上为什么可能有效?细胞通路是加法,每步乘的系数变成可学的门,能接近 1
③ 实验上为什么被选中?在长间隔合成任务、后来的语言与翻译任务上明显好于普通 RNN;没有最优证明,2017 年以后在语言上被注意力取代(L4)

本课每条结论的证据等级:

结论证据等级依据
梯度沿时间是局部导数的连乘可证明 BPTT 推导
真实连乘 ≤ ∣w∣n(标量)可证明 导数上界
连乘导致长依赖难学可证明 + 实验 Hochreiter 1991;Bengio et al. 1994
RNN 语言模型优于回退 n-gram实验验证 Mikolov et al. 2010
LSTM 缓解消失理论动机 + 实验 LSTM 1997;遗忘门 Gers 2000
范数裁剪能控制爆炸理论动机 + 实验 Pascanu et al. 2012

一句话

📌

RNN 用一个固定大小的状态记住任意长的历史;但梯度每往回一步都要乘一次,0.9 乘 100 次只剩 2.66×10⁻⁵。

🚦

先停在这里:记住 0.9100 = 2.66×10−5 这一个数,进 L3。
再深一层:岔路 B1 · 固定状态为什么又回来了(建议读完 L4 再去),或展开上面「沿时间反向传播」的 Dig。

下一个缺口

语言模型只需要「读到哪、猜到哪」。可要是任务是读完一整句法语、再写出一整句英语呢?编码器 RNN 读完整句,手里只剩最后那一个状态;解码器只能从这一个向量里把整句话的意思还原出来。长句会怎样? → L3 · 输入一句、输出一句,长句为什么丢

你可能会问

这一课还没有真实提问记录。先列几个最常见的: