跳到主要内容

数据截至 (上游 commit eb980a5c9eea)

文本怎么变成数 — 四十年弯路,与注意力的由来

这一章讲三件事: 计算机为什么不能直接读文字;四十年里人们试过哪四种办法、 每一种死在哪;以及为什么最后必须换掉整个零件。 读完你会拿到全书的第一条论证链——这条链后面八章都在往下接。 不需要任何基础,遇到的生词都在当场解释。

1. 先看现象:这一行到底在干什么活

「自然语言处理」就是让计算机去做那些原本只有懂语言的人才能做的活。 这个名字听着虚,活儿其实很具体。

书里列了九件1。先扫一眼,不用记——后面每一章都会回来用到其中的一两件:

输入 → 输出难在哪
中文分词「雍和宫的荷花开的很好」→ 雍和宫 | 的 | 荷花 | 开 | 的 | 很 | 好中文词与词之间没有空格,切错一次后面全错2
把词再切碎一点unhappiness → un | happi | ness见下一小节,这一条对后面最重要
标出每个词是名词还是动词,这叫词性标注playing → 动词现在分词同一个词在不同句子里的词性会变
文本分类一段新闻 → 「体育」要真的读懂意思,不能只看关键词
实体识别「李雷和韩梅梅是北京市海淀区的居民」→ 人名、地名同名的人和地怎么分
关系抽取「比尔·盖茨是微软公司的创始人」→(比尔·盖茨,创始人,微软)关系常常不写在字面上
文本摘要一篇报道 → 三句话抽原句容易但不通顺,重写通顺但容易失真
机器翻译「今天天气很好」→ The weather is very nice today两种语言的造句规则不一样,文化背景也不一样
自动问答一个问题 → 一个答案答案可能要从检索、知识库、或者推理里来

这张表里有一件事值得单独拎出来:把一个词再切碎成几截。 切出来的那些碎片,这一行就叫子词。

为什么「切成词」不够,还要切成「子词」

想让机器认识 unhappiness 这个词。最直接的办法是把它整个记下来。 记在哪儿?记在一张清单上,这张清单叫词表——模型认得的所有片段,全在这张表里; 表上没有的东西,模型就当没见过。

可是英文里这类合成词是无限多的,词表永远补不齐。 遇到词表里没有的词,行话就叫未登录词。

子词切分的做法是把它拆成 un + happi + ness: 否定前缀、happy 的词根变体、名词后缀。即使模型从来没见过 unhappiness 这个完整的词, 它也能从三个见过的碎片里拼出「不幸福的状态」这个大致意思3

这一条现在还是每个大模型的入口。 常见的几种切法(BPE、WordPiece、Unigram)第 07 章第 3 节会各给一个例子说清差别, 并且拿一份五个词的迷你语料把 BPE 的合并过程一轮一轮走一遍。 你现在只要记住一句话:

模型吃进去的最小单位不是「字」也不是「词」,而是「标记」—— 可能是一个完整的词,也可能只是词的一小截。英文里管它叫 token,你在别处会经常看到。

往后本文一律说「标记」,只在讲直觉的地方才说「词」——那时说的是同一件事。

2. 先认识那台机器:神经网络

这一节是补课,而且非补不可。 从下一节起,这本书里几乎每一句话都绕不开三个字—— 神经网络。书里默认你已经知道它是什么,我们不默认 (这一整节是我们补的:补充,不在书里,来自通用知识)。

先看它要干的是什么活

你一眼就认得出一个手写的「7」,哪怕它写得歪、笔画连在一起、还被涂改过。 可你说不出你是怎么认出来的——没有哪条你能写下来的规则, 盖得住全世界所有人写「7」的方式。

这类活有一个共同点:人做得到,但规则写不出来。 认字、听懂一句话、翻译、把话接着往下写,全在这一类里。

规则写不出来,就只剩一条路: 造一台带着一大堆可调设定的机器,让它自己去凑出一套能把答案算对的设定。 神经网络就是这样一台机器。

为什么它得排成一层一层的

这台机器不能只做一次加工。 一次加工只做一件事——把一堆数按固定比例混一混,再掰一下弯,仅此而已。 可要认出一个「7」,得先认出「有一横」「有一撇」,再拿这两样拼成一个字。

所以它被排成一层一层的:前面的层做粗活,后面的层拿前面的结果做细活。 下面这张图画的就是这个形状。

它长什么样:一排一排的数值加工站

输入(一串数)

第 1 层 ○ ○ ○ ○ ○ ○ ○ ○ ← 每个圆圈叫一个「单元」
│ ↘ ↓ ↙ 每个单元把上一层送来的每个数各按一个比例混一混,再往下送
第 2 层 ○ ○ ○ ○ ○ ○ ○ ○

第 3 层 ○ ○ ○ ○ ○ ○ ○ ○

输出(还是一串数)

图说:数只朝一个方向流。同一层的圆圈同时算,层与层之间必须排队——
没有哪一层能跳过它前面那一层。

单元就是图里那一个个圆圈,层就是排成一排的一堆单元。 这三个词到这里全部定死,后面全书只用这三个说法:

它的意思
单元就是图里的一个圆圈。它只干两件事:把上一层送来的每个数各乘一个自己的数、加起来;再做一次简单的掰弯——比如把负数一律归零
就是排成一排的一堆单元。同一层里的单元同时算,这是它能跑得快的原因
参数(这一行里也叫权重)上面那句「各乘一个自己的数」里的那些数。它们是可以调的,这台机器的全部本事就存在这些数里

表里「再做一次简单的掰弯」那一步必须有,不是可有可无的装饰: 少了它,不管你排多少层,每一层做的都只是「按固定比例混一混」, 几十层叠起来合并同类项之后,和只有一层完全等价——层数就白加了。 (掰弯的那个规则叫什么、为什么非它不可,第 03 章讲。)

「参数」和「权重」是同一样东西的两个名字,本文两个都会用到,意思永远是这一个。 你以后看到「70 亿参数的模型」,说的就是「这台机器里有 70 亿个这样的可调数」; 而「参数量」就是「这样的数一共有多少个」。

顺带把图里那种连法定死:图上每个圆圈都和上一层的所有圆圈连着,一根不落—— 这种连法叫全连接。 后面第 9 节会看到,还有别的连法。

它是怎么「学会」的:没人教,是试出来的

做法笨得出奇:

给它一道有标准答案的题 → 看它答得离答案差多远
→ 把每个参数朝「差得少一点」的方向挪一丁点 → 换下一道题

图说:重复几十亿、几万亿次。规则不是被教进去的,是这么试出来的副产品。

这个反复调参数的过程就叫训练训练完参数就定下来了,拿去干活的时候不再变。

「深度学习」只是「层数很多」

层叠得多(几十层、上百层),这件事就叫深度学习—— 「深」指的仅仅是层数多,没有别的意思。今天这一行说的几乎所有模型都属于这一类。

层多了为什么更强?回到上面那句话:一层只做一次加工—— 把上一层送来的数按比例混一混、再掰一下弯,仅此而已。 但叠起来之后,前面的层可以先认出笔画,后面的层再拿笔画去认字—— 复杂的判断被拆成了很多步简单加工。

3. 顶层全景:四十年,四代做法,一条死链

这一章真正的主线不是第 1 节那张任务表,而是一个更底层的问题:文字怎么变成数。

神经网络只认数字 → 文字必须先变成一组数(叫「文本表示」)

├─ ① 一个词占一个格子(向量空间模型,1975)
│ └ 死穴:任意两个词都「毫无关系」,而且维度爆炸
├─ ② 数共现次数(N-gram)
│ └ 死穴:N 一大数据就不够,N 一小就看不见远处
├─ ③ 让模型自己学出一组数(Word2Vec,2013)
│ └ 死穴:一个词只有一组固定的数,一词多义没法表示
├─ ④ 让这组数随上下文变(ELMo,2018)
│ └ 思路对了,但用的零件(循环神经网络)串行、且远处会衰减
└─ ⑤ 换掉零件 ⟹ 注意力机制(第 02 章)

图说:每一代都不是「更先进」,而是「上一代的死穴绕不过去了」。
看懂这条链,你就知道注意力为什么非出现不可。

这一节剩下的篇幅都在填这张图。

主走查:全章只跟着「苹果」这一个词走

四代做法各讲各的,读者很容易读完只记住四句评语。所以这一章挑一个词,从头跟到尾:

「苹果」。 它出现在两句话里——「我吃了个苹果」和「苹果发布会」。 每一代做法,我们都问同一个问题:这两句话里的「苹果」,变成的数一不一样?

后面第 5 到第 9 节,每一节末尾都有一小段**「苹果」走到这一代**, 写出这个词在那一代里具体变成了哪些数。四代之后,这个问题的答案会从「一样」变成「不一样」。

先声明:这些小段里的数值,凡不是书里给的,全是为演示编的,不是真实数值。 编的是数值,不是做法——做法和真实模型一模一样。

4. 先弄清楚一件事:为什么不能直接给词编号

这一节回答一个几乎所有人第一反应都会想到的办法,为什么行不通。

计算机内部只有加法和乘法。要让它处理文字,必须先把文字变成数—— 这件事有个正式名字叫文本表示4

最省事的办法:准备一张表,「猫」= 7,「狗」= 8,「西瓜」= 3000。

问题在于这些数字之间的关系是假的。

  • 机器会算出「猫」和「狗」差 1,「猫」和「西瓜」差 2993;
  • 换一张表,这些距离全变了。编号是任意的,而模型会当真。

所以真正的要求不是「变成数」,而是:

变成一组数,并且让这组数之间的关系,反映词与词之间真实的关系。

语义就是词和句子所表达的意思本身;上面说的「词与词之间的关系」,主要指的就是语义上的远近。

这句话是后面四代做法共同的靶子。 谁离这个目标更近一点,谁就赢一代。

先立一个词:「一组数」正式叫向量

这个词从下一节开始到全书最后一页都在用,现在一次说清:

一串按顺序排好的数,就叫一个向量。这串数里有几个数,就说它是几维; 这个「几」就叫维度。

比如 (1, 0, 0, 1) 是一个四维向量;(0.31, -1.2, 0.07) 是一个三维向量。 顺序是有意义的——第一个位置代表什么、第二个位置代表什么,一经约定就不能换。 「几维」说的仅仅是这一串里有多少个数,没有别的意思,跟科幻片里的「四维空间」无关。

两个向量之间可以算距离、可以算夹角,这正是我们要的: 只要每个词都摊成一个向量,「意思像不像」就变成了「两串数离得近不近」这种能算的事。

5. 第一代:一个词占一个格子(向量空间模型)

先看它怎么做

准备一张词汇表——所有可能出现的词的集合。 每个词对应表里的一个位置。一句话就是一个跟词表一样长的向量:出现过的词那一位记 1,其余全记 05

书里给的例子很直观:词表 16384 个词,「雍和宫的荷花很美」切出五个词, 于是这句话就摊成一个 16384 维的向量(照上面的说法:这一串里排着 16384 个数), 其中只有 5 个位置是 1,剩下 16379 个位置都是 0——空了 99.97%6

比 0/1 更讲究一点的做法是给每一位填一个「重要度」——就是这个词在这段文字里有多重要。 怎么算出这个重要度?靠一套写死的计算步骤,这一行管这种东西叫算法—— 一步接一步、每次照做都得到同样结果的那种规程。

这里最常用的那套算法叫 TF-IDF——中文全称是「词频和逆文档频率」,规则一句话: 一个词在这篇里出现得越多、在别的文章里出现得越少,重要度越高7

为什么它当年是有效的

因为它把「文本相似度」变成了一件能算的事:两个向量夹角小,两篇文章就像。 检索、分类、聚类(把相似的东西自动归成一堆)一下子全都有办法做了——这是信息检索这门学科的起点。

它死在哪:三个问题,一个比一个致命

先交代一个词:算力就是可用的计算能力——一台机器每秒能做多少次运算。 算力永远有限,所以花在没用的地方,就是白花。

问题具体表现
稀疏(就是绝大多数位置都是 0)算力全花在算 0 上
维数灾难词表越大向量越长;而中文常用词就有几十万8
词与词毫无关系这条最致命——「猫」和「狗」的位置是两个不同的格子,和「猫」与「西瓜」的差别完全一样

还有两条书里也点了:这套表示丢掉了词序(「我喜欢你」和「你喜欢我」的向量一模一样), 而且它默认各个词之间互相独立——可这一节开头刚说过, 让数反映词与词的关系正是全部要求所在,这个假设等于把要求直接放弃了9

「苹果」走到这一代:16383 个 0 和 1 个 1

沿用书里那张 16384 个词的表。假设「苹果」排在第 3000 位:

苹果 = [ 0, 0, …, 0, 1, 0, …, 0 ] ← 第 3000 位是 1,其余 16383 位全是 0
梨 = [ 0, 0, …, 1, 0, 0, …, 0 ] ← 第 3001 位是 1
板凳 = [ 0, 0, …, 0, 0, …, 1, …, 0 ] ← 第 9000 位是 1

「苹果」和「梨」的点积 = 0(两个 1 不在同一位上,相乘全是 0)
「苹果」和「板凳」的点积 = 0(同上)

图说:两个数都是 0,一模一样。这一代眼里,「苹果」离「梨」和离「板凳」一样远。
而这三个位置号(3000 / 3001 / 9000)是按拼音排出来的,换一本词典就全变了。

至于「我吃了个苹果」和「苹果发布会」里的那两个「苹果」—— 它们查的是同一张表的同一行,数完全一样。 (第 3000 位这个编号是为演示编的,不是真实数值;16384 和 99.97% 来自书里。)

这一步的教训要记住: 光把文字变成数是不够的。 这组数里必须装得下「词与词的关系」,否则后面所有的计算都建在沙子上。

6. 第二代:数共现(N-gram)

先看它解决什么问题

上一代完全没有「关系」。那就直接去统计关系里最简单的一种:哪个词后面爱跟哪个词。

怎么做

假设一个词出现的概率(它出现的可能性有多大)只跟它前面 N-1 个词有关,更早的一概不管10:

N叫什么看几个词
1unigram谁也不看,只看这个词本身有多常见
2bigram看前一个词
3trigram看前两个词

有了这些条件概率,一整句话的概率就是把它们连乘起来。 这是历史上第一个真正意义上的「语言模型」——它能给任意一句话打一个「像不像人话」的分。

为什么它有效

简单、可解释、算得快,而且它抓住了一个真实的规律:语言是有局部惯性的。 语音识别(把说出来的话转成文字)、拼写纠错、输入法联想,今天很多地方还在用它。

它死在哪:两条,而且互相打架

第一条,N 一大数据就不够。 词表几万个词,三个一组的组合数是天文数字, 绝大多数组合在你手上的语料里一次都没出现过——统计出来的概率是 011。 书里的说法是:参数空间急剧增大,同样的 N 元组合出现的概率变得非常低,模型无法有效学习。

第二条,N 一小就看不见远处。 它「忽略了词之间的范围依赖关系,无法捕捉到句子中的复杂结构和语义信息」12。 拿一句话看最清楚:

「他昨天在巴黎的一家老书店里买的那顶帽子, …… 丢了。」
└────────────── 隔了十几个词 ───────────────┘
「丢了」的主语是「帽子」,而 trigram 只看得见「那顶」「帽子」两个词

这两条是互相打架的:要看得远就得把 N 调大,调大就没数据。 这个矛盾在这一代内部无解。

「苹果」走到这一代:两个条件概率,和一个数不出来的三连

这一代不再给「苹果」一串数,而是给它一堆「在谁后面出现过几次」的统计。 假设手上这份语料里:

「吃」一共出现 12000 次,其中后面紧跟「苹果」的有 240 次
→ P(苹果 | 吃) = 240 ÷ 12000 = 0.02
「苹果」一共出现 5000 次,其中后面紧跟「发布会」的有 50 次
→ P(发布会 | 苹果) = 50 ÷ 5000 = 0.01

图说:两个数不一样——这一代终于摸到了一点「关系」。
「苹果」在「吃」后面出现的可能性,是「发布会」在「苹果」后面出现的两倍。

但它抓到的只是「谁挨着谁」,不是「这个苹果是哪个苹果」。 真要分清那两句话,得往前多看一个词,也就是把 N 从 2 调到 3:

「昨天 吃 苹果」这个三连,在这份语料里出现了 0 次 → 概率算出来是 0
「一场 苹果 发布会」同上,也是 0 次 → 概率也是 0

图说:两句话都被判成「不可能出现」,又变得没有区别了。
这就是上面那个矛盾落到一个具体的词上的样子。

(12000、240、5000、50 这四个数是为演示编的,不是真实数值。)

7. 第三代:让模型自己学出一组数(Word2Vec)

这一节是全书第一个转折点,慢一点看。

先看现象:人是怎么知道两个词像的

你没有背过「国王和王后是一对」。你是从无数句子里感觉出来的—— 它们出现的位置可以互换,前后跟的词也差不多。

这个观察就是整代技术的地基:出现环境相似的词,意思就相近。

上面那句「出现环境」,这一行有个正式的叫法,就叫上下文——一个词前后跟着的那些词。 这个词后面每一章都会用到,意思永远是这一个。

怎么把这个观察变成一组数

2013 年 Mikolov 等人给的办法很巧,分两步13:

  1. 不直接教它「什么和什么像」,而是让它去做一个有海量数据的小任务;
  2. 任务做完之后,把网络中间那一层的数截出来——那串数就叫词向量

任务有两种拼法:

拼法干什么适合
CBOW(连续词袋)挖掉中间那个词,拿周围的词去猜它小型数据集14
Skip-Gram反过来,拿中间那个词去猜周围的词大型语料

为什么这样能学到「关系」: 因为要答对这道题,模型不得不在内部把「经常出现在同样那些邻居旁边的词」 放到相近的位置上。它没被教过语义,但它为了答题被迫做出了语义判断。

收益:意义第一次变成了距离

第一代(向量空间模型)第三代(Word2Vec)
一个词用几个数表示(即多少维)几万到几十万几百
每一位有没有值绝大多数是 0(稀疏)稠密(就是每一位都有值,没有白占的格子)
词与词的关系没有「国王」和「王后」在向量空间里挨得很近15
没见过的词完全没辙换个没见过的词也对付得了——因为它学的是「一个词周围都跟着哪些词」,不是死背词典16

上面那一行说的本事,这一行有个专门的词,当场说清:

泛化就是:在没见过的数据上也表现得好。 反面是「只会背它见过的那些」——题库里的题全对,换一道新题就完蛋。 这个词后面每一章都会用到,意思永远是这一个。

「稀疏」和「稠密」这两个词后面还会反复出现,记住它们的意思: 稀疏 = 大部分位置是 0;稠密 = 每一位都有值。

它死在哪:一个词只有一组数

这条很好记:词向量是查表查出来的,一个词永远是同一组数。

把主走查那两句话摆出来看,这句话的分量就出来了:

「我吃了个苹果」里的苹果 → [ 0.31, -0.02, 0.88, … ] (一共 300 个数)
「苹果发布会」里的苹果 → [ 0.31, -0.02, 0.88, … ] (一共 300 个数)

图说:上下两行原样抄了两遍,一个数都没改——因为它们本来就是同一行表。
水果和公司,在这一代眼里是同一个东西。

(这三个数是为演示编的,不是真实数值;「几百维」这个量级来自书里。)

  • 「苹果」在「我吃了个苹果」和「苹果发布会」里,数值完全一样;
  • 而且它学的只是局部窗口里的共现,「无法捕捉到长距离的依赖关系」, 在复杂的语义任务上表现不佳17

一词多义,这一代表示不了。

8. 第四代:让词向量随上下文变(ELMo)

怎么做

既然固定的一组数不够,那就别给数,给一个函数

ELMo 的做法分两个阶段18:

阶段一(预训练):在大型语料上训一个语言模型
└ 用的是双向的循环神经网络——从左往右读一遍,从右往左再读一遍
阶段二(用的时候):把整句话喂进去,从模型里现取这个词在这句话里的表示
└ 同一个词在不同句子里,取出来的数不一样

图说:第三代交付的是一张查询表;第四代交付的是一台现算的机器。

它实现了「一词多义、静态词向量到动态词向量的跨越式转变」19——这是书里的原话。

「苹果」走到这一代:同一个词,两串不一样的数

把上一节那两行再抄一遍,这次它们不一样了:

整句「我吃了个苹果」喂进去,从模型里取第 5 个位置 → [ 0.31, -0.02, 0.88, … ]
整句「苹果发布会」 喂进去,从模型里取第 1 个位置 → [-0.44, 0.61, 0.09, … ]

图说:同一个「苹果」,前三位一个都对不上。
差别不是查表查出来的,是「把整句话读一遍之后现算的」。
上一代交付一张查询表,这一代交付一台现算的机器——落到数上就是这两行。

(这六个数是为演示编的,不是真实数值。)

它顺带带来了一个更大的东西:预训练加微调

预训练就是:先在海量没人标注过的文本上,让模型做一道自己出题、自己对答案的练习。 因为不用人来标注,互联网上所有文字都能拿来用。

比动态词向量更重要的是这一步的范式:

先在海量无标注文本上练一个通用底子(预训练), 再在具体任务上用少量标注数据调一下(微调)。

这句话是接下来十年整个领域的组织方式。 第 04 章讲 BERT(读作「伯特」,是 2018 年 Google 发布的一个模型的名字, 不是缩写含义要紧,记住它是「只读不写、专门负责读懂一句话」的那一类就行)时会看到, 它正是把这一步推到了极致。

它死在哪:思路对了,零件不对

复杂度就是「算起来有多费劲」。 书里给的缺陷是「模型复杂度高、训练时间长、计算资源消耗大」20

下面这句引文里有一个词先讲清:

LSTM 是一种循环神经网络——这类网络一个词一个词往下递,后一步要等前一步算完; 它的英文缩写是 RNN(Recurrent Neural Network),下文两个说法混着用,指的是同一样东西。 第 9 节整节拆它。

书里明确点出:基于 LSTM 的 ELMo 训练时间长, 而「怎么把文字里的线索提取得更好」才是这条路往上走的关键21

注意这句话的分量:问题不在思路,在它用的那个零件。 下一节就拆这个零件。

9. 那个零件是什么:三种神经网络,以及为什么选了最慢的那种

这一节回答:循环神经网络是什么,以及它为什么必须被换掉。

深度学习从计算机视觉(让机器看懂图像的那一行)那边发展起来,核心结构有三种22这三种的差别只有一件事:层与层之间的单元怎么连(层、单元、参数量这三个词见第 2 节):

怎么连于是它有什么脾气擅长什么
全连接(第 2 节讲过):每个单元和上一层的所有单元都连上,一根不落信息只往前走,不回头通用,但连线太多,参数量大得吓人
卷积:每个单元只连上一层里挨着的一小片,不像全连接那样全连上靠一小片一小片扫过去,先认出局部的形状图像——相关的像素通常挨在一起;而且连线少,参数量远小于全连接
循环:多出一条回到自己的连线——算这个词的时候,把上一个词算出来的结果也当成输入于是历史信息能一站一站往后带一句话这种前后有次序的东西——一个词一个词往下递

这三种分别叫全连接网络、卷积网络、循环网络; 卷积网络还有个到处都能见到的英文缩写,叫 CNN(Convolutional Neural Network)。

表里最后一栏说的「前后有次序的东西」,这一行统称为序列。 一句话是序列(字有先后),一段语音是序列,一串股价也是序列; 共同点是次序本身带着意思,换了位置就不是原来那件事了。

文字天然是序列,所以循环网络在这一行长期是霸主,ELMo 用的双向 LSTM 就是它的加强版23

LSTM 是什么: 循环网络的一个改良版本,加了几道开关来决定哪些历史信息留、哪些忘, 用来缓解「传得太远就模糊」的问题。注意是缓解,不是解决——这一点马上就是重点。

两个缺陷,而且都是结构性的

书里给得非常明确,只有两条,但每一条都致命24:

缺陷一:必须串行,显卡的本事用不上。

循环网络: 词1 → 词2 → 词3 → … → 词100
└ 算完词1 才能算词2,算完词2 才能算词3

而显卡的全部本事,是同时算几万件事。
图说:结构上强制排队,再多的卡也只能干等。

「并行」就是同时算很多件事。 书里的原话是:「序列依序计算的模式能够很好地模拟时序信息,但限制了计算机并行计算的能力」—— 结果就是 RNN 系模型「参数量不算特别大,但计算时间成本却很高」

缺陷二:距离越远,关系越难被捕捉。

信息要一站一站往后传,传得越远越模糊。而且整个序列必须读进内存依次计算,这也限制了序列能有多长25。 LSTM 的门控(就是几道开关,决定哪些历史信息留、哪些忘)已经改良过一次, 但书里说得很直白:对于较远距离相关关系的捕捉,RNN 依旧是不如人意的26

「苹果」走到这里:两条缺陷落到这一个词上是什么样

上一节那串 [-0.44, 0.61, 0.09, …] 是「现算」出来的。这一节问:算它要付什么代价。

把那句话铺长一点:「昨天下午我在公司楼下的水果店买了一个苹果,晚上把它吃掉了。」 按「昨天 | 下午 | 我 | 在 | 公司 | 楼下 | 的 | 水果店 | 买 | 了 | 一个 | 苹果 | ,| 晚上 | 把 | 它 | ……」 数下来,「苹果」排第 12,「它」排第 16。

缺陷一(必须排队):
要算第 12 位的「苹果」,得先把第 1 到第 11 位一个个算完 —— 11 次等待,躲不掉。
哪怕你有 100 张显卡,这 11 步还是只能一步一步来。

缺陷二(远处会衰减):
第 16 位的「它」要用到「苹果」那串数,信息得从第 12 站传到第 16 站 —— 4 站。
每传一站都要和新来的词混一次,传到「它」那里时,「苹果」那份已经被冲淡了。
这句话只隔 4 站还撑得住;换成一篇文章隔一百个词回指,基本就找不回来了。

图说:第一条是「算得慢」,第二条是「算不准」;
而两条都不是代码写得差,是「循环」这两个字的定义本身。
(第 12、第 16 这两个位置是按上面那句话数出来的,不是编的。)

这两条为什么修不好: 它们不是「实现得不好」,是结构定义本身—— 「循环」的意思就是「后一步依赖前一步」,而「一站一站传」的意思就是「距离会衰减」。 要解决,只能换结构。

10. 换成什么:注意力

2017 年,Vaswani 等人做了一件当时看很激进的事: 把上一节那三种连法里的循环和卷积全部扔掉, 搭了一个完全由注意力机制构成的神经网络——Transformer(直译是「变换器」, 但中文材料一律用它的英文原名,本文也一样)27

书里给它的定位是:大语言模型(能对话、能写文章的那类机器)的核心架构, 注意力机制由此「一跃成为深度学习最核心的架构之一」。

这里有个容易记错的出身,书里特意提醒了:注意力机制是在计算机视觉领域被提出的, 只是在自然语言处理这边被发扬光大28。它最初的直觉也来自看图: 你看一张照片时不会看清全部内容,只会把注意力集中在重点部分。

注意力具体怎么算、公式怎么一步步推出来,是第 02 章整章的内容。 你现在只需要带走一句话:

注意力做到的事是——让序列里任意两个位置一步之内直接相连。 上面那两个缺陷,它一次解决两个:不用排队了,也不用一站一站传了。

11. 作者的判断与证据

这一节把「书里给了证据的」和「书里只是这么说的」分开。

说法书里给了什么该怎么看
循环网络有两个致命缺陷给了机制层面的解释,而且解释成立可以直接采信——这是结构决定的,不是经验观察
Word2Vec 让语义相近的词距离更近给了例子(国王/王后),没给数字结论正确,但书里的证据只到「举例」这一层
CBOW 适合小数据集、Skip-Gram 适合大语料只有一句「实践验证」,没有出处也没有实验这是流传很广的经验说法,当经验用,别当结论引
向量空间模型「最早由哈佛大学 Salton 提出」参考文献列的是 1975 年那篇 ACM 论文见下面的边界一节,这里书里有一处不严谨

判断(我们的,不是书里的): 这一章最值得带走的不是任何一代具体做法, 而是它们排成一条链之后显出来的那个规律—— 每一次跃迁,都有人指着上一代的死穴说「这个绕不过去,得换个东西」。 注意力不是因为「更先进」才取代循环网络,是因为循环网络那两个缺陷改不掉。 以后遇到一个新方法,先问的不该是「它有多强」,而是**「它替掉的那个东西,死在哪」**。 答不上来,说明它可能只是换了个写法。 如果错,会错在: 有些进步确实只是量变(数据更多、算力更大), 没有前一代的结构性死穴可指。硬要给这类进步安一个「被解决的缺陷」,就会编出一个不存在的故事。

12. 边界与局限

这一节说三件事:书里略过了什么、哪里不严谨、以及哪些说法今天要修正。

① 书里没交代来历的地方

这是这本书作为「教程」的一贯风格——给结论,不给出处。这一章有三处值得补:

书里怎么写的补上的一手来源
「Word2Vec……由 Tomas Mikolov 等人在 2013 年提出」,参考文献只列了当年 12 月那篇提出 CBOW 和 Skip-Gram 这两个架构的其实是同年 1 月的另一篇29
「子词切分……常见的有 BPE、WordPiece……」BPE 用于自然语言的原始出处是 2015 年的机器翻译论文,动机正是书里说的未登录词问题30
「Vaswani 等学者……创新性地搭建了 Transformer」,参考文献把年份写成 (2023)那是这篇论文在预印本平台上最后一次修订的年份;它首次公开是 2017 年 6 月31

② 一处不严谨:Salton 和哈佛

书里说向量空间模型「最早由哈佛大学 Salton 提出」32

判断(我们的,不是书里的): 这里把人和机构对上了、但对得不准。 书里自己列的参考文献是 1975 年发表在 ACM 通讯上的《A vector space model for automatic indexing》, 署名是 Salton、Wong、Yang 三人——不是一个人,而且那时 Salton 已在康奈尔大学。 「哈佛」大概来自他早年的经历。 这处不影响任何技术结论,但它是个提醒:这本书里的人物与机构信息,别直接当引用源。 如果错,会错在: 如果书指的是 Salton 更早期(在哈佛时)的某项工作而非那篇 1975 年的论文, 那么「哈佛」的说法就有依据——但书里给的参考文献指向的是 1975 年那篇。

③ 书里没有讲、但今天必须知道的两件事

第一,这一章的时间线停在 2018 年。 从 ELMo 直接跳到 Transformer, 中间跳过了一整段:2018 到 2020 年间,预训练模型的规模和范式发生了根本变化。 这段在第 04、05 章补。

第二,「文本表示」这个框架本身已经被改写了。 这一章把词向量当成一个独立产出——先训好,再拿去用。 而今天的大模型里,它只是模型的第一层,和整个模型一起训练、不再单独交付。 书里第二章讲 Embedding 层时会看到这个转变,但没有明说这是范式的变化。

13. 可带走的

  1. 神经网络 = 一层层的数值加工站:一层里排着很多单元,每个单元把上一层送来的数各按一个可调的数混一混再往下送;层数很多就叫深度学习;
  2. 参数 = 权重 = 那些可调的数,机器的全部本事都存在这里;「参数量」就是它们一共有多少个;
  3. 神经网络只吃数,所以第一件事永远是把文字变成数——这件事叫文本表示;
  4. 给词编号不行,因为编号之间的距离是假的,而模型会当真;
  5. 真正的要求是:让数之间的关系,反映词之间的关系;
  6. 向量空间模型死在「任意两个词都毫无关系」,顺带死在稀疏和维数灾难;
  7. N-gram 死在一个自相矛盾:要看得远就得把 N 调大,调大就没数据;
  8. Word2Vec 的巧妙之处是「借道」——不直接教语义,而是让它做一个有海量数据的填空题,再从中间层截出词向量;
  9. 稀疏 = 大部分位置是 0;稠密 = 每一位都有值;泛化 = 在没见过的数据上也表现得好——这三个词后面一直会用;
  10. Word2Vec 死在「一个词只有一组固定的数」,一词多义没法表示;
  11. ELMo 思路对了(给函数不给数),还顺带确立了「预训练 + 微调」这个范式;
  12. 循环神经网络有两个结构性缺陷:必须串行、远处会衰减——注意是结构性的,改不掉;
  13. 注意力一次解决这两条:任意两个位置一步之内直接相连;
  14. 模型吃进去的最小单位是「标记」,可能只是半个词。

14. 原文地图

主题原书章原文位置
自然语言处理在做什么第一章 NLP 基础概念text/05-ch01-nlp.txt:12(搜「让计算机理解」) · text/05-ch01-nlp.txt:16(搜「词性标注、」)
早期探索与图灵测试第一章 NLP 基础概念text/05-ch01-nlp.txt:32(搜「1950年」) · text/05-ch01-nlp.txt:38(搜「乔姆斯基」)
符号主义与统计两大阵营第一章 NLP 基础概念text/05-ch01-nlp.txt:42(搜「符号主义」) · text/05-ch01-nlp.txt:46(搜「统计模型开始取代复杂的」)
深度学习阶段的三个节点第一章 NLP 基础概念text/05-ch01-nlp.txt:51(搜「2013年,Word2Vec」) · text/05-ch01-nlp.txt:52(搜「BERT模型的问世」)
中文分词与切错的后果第一章 NLP 基础概念text/05-ch01-nlp.txt:63(搜「Chinese Word Segmentation」) · text/05-ch01-nlp.txt:78(搜「错误切割」)
子词切分与未登录词第一章 NLP 基础概念text/05-ch01-nlp.txt:85(搜「Subword Segmentation」) · text/05-ch01-nlp.txt:86(搜「词汇稀疏问题」) · text/05-ch01-nlp.txt:98(搜「unhappiness」)
九项任务清单第一章 NLP 基础概念text/05-ch01-nlp.txt:103(搜「词性标注(Part-of-Speech」) · text/05-ch01-nlp.txt:136(搜「Text Classification」) · text/05-ch01-nlp.txt:156(搜「Named Entity Recognition」) · text/05-ch01-nlp.txt:172(搜「Relation Extraction」) · text/05-ch01-nlp.txt:186(搜「Text Summarization」) · text/05-ch01-nlp.txt:215(搜「Machine Translation」) · text/05-ch01-nlp.txt:231(搜「Automatic Question Answering」)
文本表示的目的第一章 NLP 基础概念text/05-ch01-nlp.txt:245(搜「数字化」)
向量空间模型与 TF-IDF第一章 NLP 基础概念text/05-ch01-nlp.txt:257(搜「Vector Space Model」) · text/05-ch01-nlp.txt:260(搜「TF-IDF」)
稀疏、维数灾难、独立性假设第一章 NLP 基础概念text/05-ch01-nlp.txt:268(搜「数据稀疏性和维数灾难」) · text/05-ch01-nlp.txt:269(搜「特征项之间的」) · text/05-ch01-nlp.txt:280(搜「稀疏率」)
N-gram 与马尔可夫假设第一章 NLP 基础概念text/05-ch01-nlp.txt:291(搜「N-gram」) · text/05-ch01-nlp.txt:293(搜「unigram」) · text/05-ch01-nlp.txt:294(搜「trigram」)
N-gram 的两个缺陷第一章 NLP 基础概念text/05-ch01-nlp.txt:301(搜「数据稀疏性问题」) · text/05-ch01-nlp.txt:303(搜「复杂结构和语义信息」)
Word2Vec 的两种架构与效果第一章 NLP 基础概念text/05-ch01-nlp.txt:309(搜「Tomas Mikolov」) · text/05-ch01-nlp.txt:314(搜「CBOW」) · text/05-ch01-nlp.txt:316(搜「Skip-Gram在」) · text/05-ch01-nlp.txt:318(搜「王后」)
Word2Vec 的局限第一章 NLP 基础概念text/05-ch01-nlp.txt:319(搜「泛化到未」) · text/05-ch01-nlp.txt:321(搜「复杂的语义任务上表现不佳」)
ELMo 与两阶段范式第一章 NLP 基础概念text/05-ch01-nlp.txt:324(搜「静态词向量到动态词向量」) · text/05-ch01-nlp.txt:326(搜「双向LSTM」) · text/05-ch01-nlp.txt:329(搜「两阶段过程」)
ELMo 的缺陷第一章 NLP 基础概念text/05-ch01-nlp.txt:330(搜「特征提取是ELMo」) · text/05-ch01-nlp.txt:334(搜「模型复杂度」)
三种神经网络结构第二章 Transformer 架构text/06-ch02-transformer.txt:8(搜「全连接神经」) · text/06-ch02-transformer.txt:12(搜「卷积神经」) · text/06-ch02-transformer.txt:16(搜「循环神经」)
RNN 的两个缺陷第二章 Transformer 架构text/06-ch02-transformer.txt:25(搜「依序计算」) · text/06-ch02-transformer.txt:26(搜「GPU」) · text/06-ch02-transformer.txt:28(搜「距离越远的输」) · text/06-ch02-transformer.txt:29(搜「较远距离相关关系的捕捉」)
Transformer 的诞生与注意力的出身第二章 Transformer 架构text/06-ch02-transformer.txt:31(搜「Vaswani」) · text/06-ch02-transformer.txt:32(搜「CV 领域被提出的」) · text/06-ch02-transformer.txt:37(搜「计算机视觉领域」)

Footnotes

  1. 出处:「第一章 NLP 基础概念」第 12 段(text/05-ch01-nlp.txt:12,搜「让计算机理解」)与第 16 段(text/05-ch01-nlp.txt:16,搜「词性标注、」)。原文对这门学科的定义是「一种让计算机理解、解释和生成人类语言的技术」;任务清单出现在同一段。

  2. 出处:「第一章 NLP 基础概念」第 63 段(text/05-ch01-nlp.txt:63,搜「Chinese Word Segmentation」)与第 78 段(text/05-ch01-nlp.txt:78,搜「错误切割」)。书里给了两种典型错法:一种把地名拆散(雍 | 和 | 宫的),一种词汇边界整个乱掉(雍和 | 宫 | 的荷 | 花开)。

  3. 出处:「第一章 NLP 基础概念」第 98 段(text/05-ch01-nlp.txt:98,搜「unhappiness」)与第 86 段(text/05-ch01-nlp.txt:86,搜「词汇稀疏问题」)。书里同时指出这套办法对拼写复杂、合成词多的语言(比如德语)尤其重要(text/05-ch01-nlp.txt:87,搜「德语」)。

  4. 出处:「第一章 NLP 基础概念」第 245 段(text/05-ch01-nlp.txt:245,搜「数字化」)。原文的定义是:把人类语言的自然形式转化为计算机可以处理的形式,也就是把文本数据数字化。

  5. 出处:「第一章 NLP 基础概念」第 257 段(text/05-ch01-nlp.txt:257,搜「Vector Space Model」)与第 283 段(text/05-ch01-nlp.txt:283,搜「词汇表」)。书里对词汇表的解释是:一个包含所有可能出现的词语的集合,每个词对应表里的一个位置。

  6. 出处:「第一章 NLP 基础概念」第 280 段(text/05-ch01-nlp.txt:280,搜「稀疏率」)。原文算的是 (16384-5)/16384 ≈ 99.97%。

  7. 出处:「第一章 NLP 基础概念」第 260 段(text/05-ch01-nlp.txt:260,搜「TF-IDF」)。原文管这个数叫「权重」,说它「反映了特征项在文本中的重要程度」。我们在正文里把它改称「重要度」——因为「权重」在这一行还有另一个意思(第 2 节说的那个「模型内部的可调参数」),而本文的规矩是一个词只留一个意思。

  8. 出处:「第一章 NLP 基础概念」第 268 段(text/05-ch01-nlp.txt:268,搜「数据稀疏性和维数灾难」)。「几十万」这个量级出自第二章讲分词器的一段(text/06-ch02-transformer.txt:543,搜「数万数」)。

  9. 出处:「第一章 NLP 基础概念」第 269 段(text/05-ch01-nlp.txt:269,搜「特征项之间的」)。原文:「由于模型基于特征项之间的独立性假设,忽略了文本中的结构信息,如词序和上下文信息,限制了模型的表现力」。

  10. 出处:「第一章 NLP 基础概念」第 291 段(text/05-ch01-nlp.txt:291,搜「N-gram」)与第 293 段(text/05-ch01-nlp.txt:293,搜「unigram」)、第 294 段(text/05-ch01-nlp.txt:294,搜「trigram」)。补充(不在书里,来自通用知识):「一个词只跟前面有限几个词有关」这个假设的正式名字叫马尔可夫假设,书里用了这个词但没有解释。

  11. 出处:「第一章 NLP 基础概念」第 301 段(text/05-ch01-nlp.txt:301,搜「数据稀疏性问题」)。

  12. 出处:「第一章 NLP 基础概念」第 303 段(text/05-ch01-nlp.txt:303,搜「复杂结构和语义信息」)。

  13. 出处:「第一章 NLP 基础概念」第 309 段(text/05-ch01-nlp.txt:309,搜「Tomas Mikolov」)。原文说它「旨在通过学习词与词之间的上下文关系来生成词的密集向量表示」。

  14. 出处:「第一章 NLP 基础概念」第 314 段(text/05-ch01-nlp.txt:314,搜「CBOW」)与第 316 段(text/05-ch01-nlp.txt:316,搜「Skip-Gram在」)。原文的说法是「实践验证 CBOW 适用于小型数据集,而 Skip-Gram 在大型语料中表现更好」——注意这是经验说法,书里没给实验依据。

  15. 出处:「第一章 NLP 基础概念」第 318 段(text/05-ch01-nlp.txt:318,搜「王后」)与第 317 段(text/05-ch01-nlp.txt:317,搜「One-Hot」)。原文的对比是:相比 One-Hot 这类高维稀疏表示,Word2Vec 生成的是低维(通常几百维)的密集向量。

  16. 出处:「第一章 NLP 基础概念」第 319 段(text/05-ch01-nlp.txt:319,搜「泛化到未」)。原文:「因为它是基于上下文信息学习的,而不是基于词典」。

  17. 出处:「第一章 NLP 基础概念」第 321 段(text/05-ch01-nlp.txt:321,搜「复杂的语义任务上表现不佳」)。

  18. 出处:「第一章 NLP 基础概念」第 329 段(text/05-ch01-nlp.txt:329,搜「两阶段过程」)与第 326 段(text/05-ch01-nlp.txt:326,搜「双向LSTM」)。

  19. 出处:「第一章 NLP 基础概念」第 324 段(text/05-ch01-nlp.txt:324,搜「静态词向量到动态词向量」)。这句是原文措辞,不是我们的概括。

  20. 出处:「第一章 NLP 基础概念」第 334 段(text/05-ch01-nlp.txt:334,搜「模型复杂度」)。

  21. 出处:「第一章 NLP 基础概念」第 330 段(text/05-ch01-nlp.txt:330,搜「特征提取是ELMo」)。

  22. 出处:「第二章 Transformer 架构」第 8 段(text/06-ch02-transformer.txt:8,搜「全连接神经」)、第 12 段(text/06-ch02-transformer.txt:12,搜「卷积神经」)、第 16 段(text/06-ch02-transformer.txt:16,搜「循环神经」)。

  23. 出处:「第二章 Transformer 架构」第 19 段(text/06-ch02-transformer.txt:19,搜「时序数据的 RNN」)与第 20 段(text/06-ch02-transformer.txt:20,搜「LSTM 是 NLP 领域当之」)。

  24. 出处:「第二章 Transformer 架构」第 25 段(text/06-ch02-transformer.txt:25,搜「依序计算」)与第 26 段(text/06-ch02-transformer.txt:26,搜「GPU」)。

  25. 出处:「第二章 Transformer 架构」第 28 段(text/06-ch02-transformer.txt:28,搜「距离越远的输」)。

  26. 出处:「第二章 Transformer 架构」第 29 段(text/06-ch02-transformer.txt:29,搜「较远距离相关关系的捕捉」)。

  27. 出处:「第二章 Transformer 架构」第 31 段(text/06-ch02-transformer.txt:31,搜「Vaswani」)与第 32 段(text/06-ch02-transformer.txt:32,搜「Transformer,也就是」)。补充(不在书里):这篇论文的正式标题是《Attention Is All You Need》,八位作者依次是 Vaswani、Shazeer、Parmar、Uszkoreit、Jones、Gomez、Kaiser、Polosukhin,首次公开于 2017 年 6 月 12 日。摘要里的自我定位就是「完全基于注意力机制,彻底摒弃循环与卷积」。来源:《Attention Is All You Need》 https://arxiv.org/abs/1706.03762(查阅于 2026-08-25)。

  28. 出处:「第二章 Transformer 架构」第 32 段(text/06-ch02-transformer.txt:32,搜「CV 领域被提出的」)与第 37 段(text/06-ch02-transformer.txt:37,搜「计算机视觉领域」)。原文特意加了括号提醒:虽然注意力机制在自然语言处理领域被发扬光大,但它确实是在计算机视觉领域被提出的。

  29. 出处:「第一章 NLP 基础概念」第 337 段(text/05-ch01-nlp.txt:337,搜「Distributed Representations」)——书里列的参考文献是 2013 年 10 月那篇《Distributed Representations of Words and Phrases and their Compositionality》。补充(不在书里):提出 CBOW 与 Skip-Gram 这两个架构的是同年更早的另一篇,标题《Efficient Estimation of Word Representations in Vector Space》,首次公开于 2013 年 1 月 16 日,第一作者同为 Tomas Mikolov;摘要里说这两个架构能「以低得多的计算代价取得大幅的准确率提升」。来源:https://arxiv.org/abs/1301.3781(查阅于 2026-08-25)。

  30. 补充(不在书里):BPE 用于自然语言的原始出处是《Neural Machine Translation of Rare Words with Subword Units》,第一作者 Rico Sennrich,首次公开于 2015 年 8 月 31 日。它的动机和书里说的完全一致——机器翻译面对的是开放词表,而以往的做法是遇到生词就退回查词典;这篇论文改成把罕见词和未知词编码成子词序列。来源:https://arxiv.org/abs/1508.07909(查阅于 2026-08-25)。书里提到 BPE 的地方见「第一章 NLP 基础概念」第 90 段(text/05-ch01-nlp.txt:90,搜「Byte Pair Encoding」)。

  31. 出处:「第二章 Transformer 架构」第 778 段(text/06-ch02-transformer.txt:778,搜「Ashish Vaswani」)——书里的参考文献把年份写成 (2023)。补充(不在书里):(2023) 是这篇论文在预印本平台上最后一次修订的年份,它首次公开的日期是 2017 年 6 月 12 日。来源:https://arxiv.org/abs/1706.03762(查阅于 2026-08-25)。

  32. 出处:「第一章 NLP 基础概念」第 258 段(text/05-ch01-nlp.txt:258,搜「Salton」)与参考文献第 352 段(text/05-ch01-nlp.txt:352,搜「Salton」)。书里列的那篇是 Salton、Wong、Yang 三人 1975 年发表于 ACM 通讯的《A vector space model for automatic indexing》。