Transformer 与文本生成:从数对子到注意力
这一章讲三件事: 「生成文本」这个问题怎么被驯化成「预测下一个标记」;注意力机制到底是什么(它是全书的最高点,我们会从检索三件事一步步搭出来);以及完整 Transformer 解码器块里每个零件分别在解决什么。 位置:Part 2 开门章。前九章的零件——嵌入、线性层、跳连、归一化——在这里全部召回。
1. 生成问题:没有标准答案的学习
1960 年代,MIT 的 ELIZA 程序就能和人「聊天」:你说「I am sad」,它回「Why are you sad?」——认关键词、套固定句式。很多人被骗了,但它对对话内容一概不懂:同一句话,不管你前面解释过什么,它都那样回1。
ELIZA 的短板指出了生成和前几章的本质差别:分类有标准答案(鸟或飞机),回归有目标数值,而生成的输出理论上有无穷多个——「像样的名字」没有一张标准答案表。这类任务的出路是换目标:不学「正确答案是什么」,改学训练数据本身 的分布,然后从这个分布里采样(按分布里各候选的概率随机抽一个)出新的、像模像样的样本。这类模型叫生成模型(generative model:学出数据的分布、能从中造新样本的模型)2。
文本生成被进一步驯化成一个具体形式:给定前面所有标记,预测下一个标记的概率分布(给词表里每个候选各配一个「多大可能」的数,全部加起来正好是 1),从里面抽一个,接上去,再来一遍。 「抽一个」就是照着这组数掷一次骰子——数大的容易被抽中,数小的偶尔也能中。
这就是第 01 章 GPT-2 演示的那件事。这种「一个接着一个、后一个依赖前一个」的生成方式有个名字,叫自回归(autoregressive)2。
2. 主走查第一棒:bigram,数出来的名字
任务:生成像样又虚构的英文人名。数据是美国社保局公布的 31915 个婴儿名字。词汇表 27 个符号:26 个小写字母加 $(名字的开始/结束标记)。名字「ada」就是序列 [0, 1, 4, 1, 0](0 是 $)3。
最朴素的生成:每个字母等概率瞎抽,出 来的是 zrcgahwsalcydnvq——不可读也不可读出来3。
改进一:bigram 模型——数遍所有名字,统计「每个字母后面各接过什么字母」,得到一张 27×27 的概率表;生成时,看上一个字符是几,就从表的第几行抽下一个。生成结果:liahuli、deiannnis、cl、de——能读了,但还是不像名字4。
bigram 撞墙的地方值得细看,因为它是后面所有升级的理由4:
- 组合爆炸:27 个字符有 27²=729 对——还行;但看前两个字符就要 27³=19683 项;换成几十万词的词表,「前两个词」就是天文数字。
- 数据稀疏:绝大多数组合从来没在数据里出现过,概率表一大片零,零的地方模型无话可说。
而且注意这里发生了一件范式转移的事:训练数据没有「标注」。 输入是 $ada,目标就是错位一格的 ada$——标签从数据自己身上长出来。前几章那种「人给每张图标好类别」的学法叫监督学习;这种「答案本来就写在数据里、只需换个看法」的学法叫自监督(self-supervised)。它是大模型时代最重要的一个词:人工标注贵且慢,自监督让全部互联网文本都变成训练材料5。
3. 第二棒:嵌入 + 线性层,参数不再随词表爆炸
第 03 章的嵌入在这里正式上岗:每个字符不再是孤零零的编号,而是先查表换成一串浮点数(书里演示用 3 维),这张表本身是参数、跟着任务一起学6。
模型(书里叫 SequenceMLP):对序列里每个位置,取「开头到该位置」的前缀 → 每个字符查嵌入 → 拉直 → 线性层 → ReLU → 输出 27 个 logits(第 07 章定义过:softmax 之前的裸分数)。损失 2.61→2.34,生成的名字:jatini、ceney、keisvta——形态和长度都像名字了6。
副产品漂亮:训练后的 3 维嵌入画出来,元音聚成一堆、辅音聚成一堆、$ 独自站远处——没人告诉它什么是元音,这是「在名字里的用法」相似被学成了「位置相近」6。第 03 章那句「意思变距离」第一次有了肉眼可见的样子。
4. 注意力:让每个位置自己去查前文
嵌入+线性层还有个结构性缺陷:同一个字符,不管出现在哪,嵌入都一样——「car」里的 a 和「care」里的 a 发音不同、作用不同,静态嵌入没法区分7。我们需要一个能「看场合」的机制。
先给直觉:聚光灯与检索
书里的比喻是剧场的聚光灯:没有注意力时,灯光均匀洒在所有人身上;有了注意力,灯跟着当前最重要的角色走7。
机制本身借的是信息检索的三个词。查询(query):这个位置「在找什么」;键(key):每个位置「我有什么」;值(value):匹配上了之后,真正被取走的内容。Google 搜索就是这套:你的查询文本,对上网页的索引,返回的是结果7。