跳到主要内容

注意力与标准结构 — 让任意两个位置直接说上话

这一章讲三件事: 一句话里相关的东西不挨着,老办法为什么撑不住; 「柔性查字典」这个想法怎么一次解决两个瓶颈; 以及三种搭法之间真正的差别只有一处——注意力能不能向后看。

它在全书链条里的位置:第 01 章说「统一底座的出现」是这一轮的第一件事, 这一章就是那个底座本身。第 04 章讲它后来怎么被改造, 第 05 章往后所有内容都建立在它之上。

顶层全景:一次注意力在算什么

一句话:那只猫没过马路,因为它 太累了
↑ 正在处理这个位置

① 这个位置发出一个「我要找什么」 ── §2 查询

② 前面每个位置各拿出一个「我是什么」── §2 键
│ 两两算一次匹配分数
├─ 猫 2.8 因为 0.6 那只 0.3 没 0.2 过 0.1 马路 0.1 , 0.0

③ 分数变成加起来等于 1 的权重 ── §3 缩放 + Softmax
├─ 猫 0.68 因为 0.076 那只 0.056 …

④ 按权重把每个位置的「内容」混起来 ── §2 值

⑤ 混出来的这份新表示,接着往上走 ── §7 一层的其余部件

图说: 整章都在讲这五步。第 §4 节说明为什么让查询和键来自同一句话就足以解决远距离问题, 第 §5 节说明为什么这五步要同时跑八份。

1. 相关的东西不挨着

在处理一串有先后的信息时,最难的问题之一是:相关的东西往往并不挨在一起1

读一句长句子时,当前这个词的含义可能取决于前面很远处的主语; 写代码时,某个名字代表什么,可能要回到几十行前才看得清; 做对话理解时,用户此刻的一句补充说明,可能是在修改几轮之前提出的需求。

第 02 章那种「按顺序把信息一点点往下传」的办法有自然的一面, 因为语言和时间本来就是线性的。但它有两个致命局限。

第一个是信号会衰减。 信息要从很远的地方传到当前位置,必须经过很多步变换, 一路穿过矩阵乘法和弯折,越传越弱。第 02 章那张表算过:每步乘 0.8, 30 步之后只剩千分之一2

第二个是没法并行。 这条路本质上是串行的:必须算完第 t 步才能算第 t+1 步。 对训练效率来说这是灾难。显卡最擅长的是并行(成千上万件同样的小事同时做), 可一个 1000 词的句子必须一步一步往前推,999 步完成后才能算最后一步3

两个问题的解法其实很相似:跳出「一步一步传」的模式,让它一次性看到所有位置, 然后自己决定该关注哪些。

这个灵感来自人的阅读经验。你读长文章时会根据当下想回答的问题有选择地聚焦: 看到「第三段提到了什么」,眼睛会跳回第三段;思考「主人公的动机」, 你会关注描写他动作和对话的段落4

注意力(按相关程度给每个位置分配权重,再按这个权重把它们的内容混起来) 就是把这种「有选择地看」的能力,做成了一个可以被训练的数学操作。

这里要先立一条边界,免得后面读岔:注意力不是「理解」的同义词。 给某些位置更高的权重,并不等于它像人一样真的懂了那部分内容。 它首先是一种信息路由机制——决定哪些内容会被当前这一步更多地用上5。 至于最终有没有形成稳定、可迁移的理解,还取决于表示、训练目标、数据质量和整体结构。

2. 柔性查字典:查询、键、值

理解这套机制最好的比方是查字典6

想象你有一本字典。每一条包含两部分:一个(词条的标签,用来被匹配) 和一个(词条的内容,真正要被取走的东西)。 你手上那个要找的词,叫查询

普通字典只做精确匹配:查询必须完全等于某个键,才能取出对应的值。 但现实中我们常常需要更柔的匹配。比如你搜「machine learning」, 字典里可能根本没有这一条,但有「artificial intelligence」「neural networks」 「deep learning」——这些相关条目都应该有一部分被返回。

柔性查询的想法是:查询和每个键比一下「像不像」,越像的键对应的值就越重要, 最后按相似程度加权求和,得到一个「综合答案」。 这正是注意力的做法。

怎么量「像不像」?最常用的是点积——把两个等长的数串对应位置相乘再全部加起来。 比如 [1, 2, 3][2, 0, 1] 的点积是 1×2 + 2×0 + 3×1 = 5。 两串数指向的方向越接近,这个数就越大7

现在把这三个角色对回一句话。处理「那只猫没过马路,因为它太累了」里的「它」时: 「它」这个位置发出一个查询,前面每个位置各拿出自己的键去和它比一次, 比出来的分数决定了「它」这一步要从每个位置的值里各取走多少。

关键在于三份东西都是算出来的,不是查表得来的。 每个位置各自过三个可学习的矩阵,分别变换出自己的查询、键和值8。 换句话说,「我要找什么」「我是什么」「我能提供什么内容」这三件事, 是训练过程中自己学出来的分工。

3. 那张 N × N 的关系表

把上一节压成一个式子:每个位置的输出,等于所有位置的值按权重加起来; 而权重来自「查询和每个键的点积,除以一个数,再过一次 Softmax」。 这就是整套结构里最核心的那条算式,行话叫缩放点积注意力9

如果算式看起来吓人,只记住一件事就够了: 查询乘键会生成一张「谁该看谁」的关系表。 一句话里有 N 个位置,每个位置都要和其他 N 个位置比一遍, 所以这张表有 N × N 个格子10

这张表就是这套结构全部力量和全部麻烦的来源。 好处是任意两个位置都能直接联系; 代价也在这里:句子越长,表膨胀得越快——长度翻倍,格子数变四倍。

用行话说,这叫它的复杂度:算完一次要花多少工夫,随着输入规模怎么涨。

按时间算的那一种叫时间复杂度;在这里它是长度的平方级。 第 04 章那半章要处理的,几乎全是这张表带来的账。

那个「除以一个数」是干什么的?这是一个很容易被跳过、却必须讲清的细节。 每个位置的键和查询都是一串数,这串数有多长叫它的宽度。 宽度越大,点积的结果天然越容易变得很大——因为要加的项更多。

一旦点积变得很大,Softmax 就会被推到极端:几乎所有权重都跑到分数最高的那一个位置上, 其余全部接近 0。这不但丢掉了「柔性」,还会让训练信号几乎消失。 所以要先除以宽度的平方根,把分数拉回一个温和的范围11

Softmax 在这里还有一个不能替换的性质:它是可微分的—— 每一步都是连续可导的,所以整套机制可以从头到尾一起用第 02 章那套办法训练。 如果改成「硬」查询(只选一个最相关的键),操作就不可导了,主流优化方法根本用不上12

4. 自注意力:让一句话内部互相看

前面描述的机制里,查询可以来自一个地方,键和值来自另一个地方—— 比如翻译时,查询来自正在写的译文,键和值来自原文。

自注意力的想法很大胆:让查询、键、值全都来自同一句话13

具体地说,对一句长度为 N 的话,每个位置通过三个可学习的矩阵变换出自己的三份东西; 然后每个位置用自己的查询去和所有位置的键算一次相似度, 按相似度把所有位置的值加权聚合起来,得到这个位置的新表示。

结果是:每个位置的输出都综合了整句话的信息,而且不同位置综合的方式可以不同。 一个词可以同时参考句首的另一个词和句尾的某个词。

现在把它和第 02 章那条老路对比一下,两个瓶颈的解法一目了然:

一步步往下传自注意力
位置 1 的信息传到位置 100要经过 99 步传递,每步都有损耗一次点积直接建立联系
能不能并行不能,第 t 步依赖第 t−1 步的输出能,每个位置的输出只依赖输入

距离不再是障碍,串行也不再是枷锁。 这两个突破让训练大规模模型第一次变得可行—— 没有它们,今天这些机器很难以这样的规模和形态出现14

顺带把一个词补上。每个位置在进入这套机制之前,先要从一串编号变成一串数; 这一步叫嵌入(给每个词元配一串数,让意思相近的词元在数值上也靠得近)。 这串数才是后面所有计算的原料。

5. 多头:同一句话的几个视角

一次注意力只能从一个「视角」看关系。但一个词的含义可能有多层: 谁修饰谁、意思上的相关、指代关系、位置关系——每一层需要不同的相似度尺子15

多头注意力就是让它同时从多个「头」看。 每一头有自己独立的三个矩阵,产生一套自己的权重和输出; 多个头的结果拼起来,再过一次线性变换得到最终输出。

书里那个比方很好记:像不同专家从各自角度对同一段文字做分析,最后综合意见。 一个头可能关注谁是主语谁是宾语,另一个头关注哪些词在意思上相近 (意思这件事的行话叫语义),第三个头关注「它」指谁。 多个视角合起来,表达能力比单头强得多。

最初那篇论文用 8 个头,后来常用 12、16、32 甚至更多。 要注意一个设计细节:每个头的宽度相应变小,让参数总数不随头数线性增长16。 八个头不是把计算量乘以八,而是把同样的宽度切成八份、各看各的。

6. 位置编码:打乱词序结果不变,所以顺序得塞进去

这套机制解决了「该看哪里」,但它并不会天然告诉机器「先后顺序是什么」。

一切的起点是一个看起来古怪、但一验就懂的事实:自注意力对顺序不敏感。 把一句话里的词打乱,它算出来的结果完全一样17。 道理很直白:每个位置只和别的位置两两比分数,而这些分数不看谁在前谁在后。

可「狗咬人」和「人咬狗」在词的集合上没有区别,意思却完全不同。 对语言、代码和时间序列来说,顺序本身就是结构的一部分。

于是有了位置编码:既然它接收的是一串数,那就把「第几个」这件事也编成一串数, 和词本身的那串数一起送进去18。这样它在处理每个位置时, 既知道「这里是什么词」,也知道「这个词处在什么位置」。

讲具体做法之前先补一个词:外推——训练时只见过短的,用起来却要处理长得多的输入, 它还撑不撑得住,就叫外推能力。位置方案的好坏,很大程度上就看这一条。

具体做法换过几代,书里给了一条很清晰的演化线19:

做法怎么给位置签名代价
三角波形用一组周期不同的波算出来值域有界、能往更长处推,但表达较粗
可学习的每个位置配一个可训练的数串训练时见过多长就只能处理多长
相对位置直接把「相差几个位置」编进分数里往更长处推更稳,但实现更复杂
旋转式把位置信息编成对查询和键的一次旋转兼具前两者的长处,当代主流

最后那一种今天最常用,全名叫旋转位置编码——它把位置信息编成对查询和键做一次旋转, 于是两个位置的查询和键一做点积,自然就带上了它们相差多远。

这条演化线要记住的不是名字,而是那个转向:从「你是第 3 个」变成「你和我差 3 个」。 因为很多任务里真正重要的是相对距离,「前面一个词」远比「整句的第三个词」关键。 这也直接决定了模型能不能自然扩展到更长的输入——第 04 章会把这件事展开。

7. 同样的积木,三种搭法

现在把一整层拼出来。一层由四个部件按固定顺序串起来20:

  1. 多头自注意力——让任意两个位置直接交互(§4、§5 讲过);
  2. 前馈网络——每个位置各自过一个小的两层网络,在聚合了跨位置信息之后做一次「深加工」;
  3. 残差连接——每个子模块的输入直接加到输出上(第 02 章 §12 那条跨层近路);
  4. 层归一化——在每次子模块计算前做一次规范化,稳住数值。

顺序是:规范化 → 多头自注意力 → 残差相加 → 规范化 → 前馈 → 残差相加。 把这个模块反复堆叠几十上百层,就是今天所有大模型的共同骨架。

这种标准化带来一个巨大的工程好处: 同一个模块可以反复堆到很深, 方便搜索那些要人来定的可调项、方便放大缩小、也方便切到很多台机器上跑21。第 09 章讲怎么把它铺到上万张卡上时, 靠的正是这份「结构高度均匀」。

同样的积木,组合方式不同,能完成不同类型的任务。书里分了三种22:

先说只用前半边的那种。 编码器(把一整段输入读进来、 给每个位置各产出一份带前后关系的新表示的那半边) 的注意力没有任何方向限制,任意位置都能看其他任意位置,是真正的「双向」。 训练时用「填空」的方式:随机遮住输入里的一部分,让它根据左右两边的语境把被遮的猜回来。 2018 到 2020 年间,这一支在分类、问答、实体识别这类「读懂」任务上是主力。

再说只用后半边的那种。 解码器(从左到右一个位置一个位置往下生成的那半边) 为了让训练时每个位置只能看到自己和之前的位置、不能「偷看」后面, 会在注意力分数上加一个遮挡:所有「向后看」的分数都被置成负无穷,过 Softmax 后权重变成 023。 这样训练时仍可并行算所有位置的预测,但每个位置只看得到前文。

最后是两半都用的。 编码器理解输入,解码器生成输出, 中间用一次「解码器去查编码器」的注意力把两边连起来。 它在翻译、摘要这类「从一种形式转成另一种形式」的任务上有天然优势。

这一节真正要带走的只有一句:三种搭法的底层积木完全一样, 差的只是注意力能不能向后看。24 只用编码器的能看两边、所以擅长读懂却不擅长续写; 只用解码器的只能看前面、所以天生适合一个字一个字往下写。 至于后来为什么是「只用解码器」那一支成了主流,那是训练目标的事,第 05 章 §4 讲。

8. 它内部到底在想什么

一个看起来不过是「注意力 + 前馈」堆叠的东西,居然能写诗、写代码、做数学。 一个自然的问题是:它内部到底发生了什么?书里把研究路线分成三类25

第一类是把权重画出来。 最直接的方法是把注意力权重可视化,看每个位置在「看」什么。 研究者确实发现了有意义的模式:一些头关注句子结构,一些关注指代,一些关注实体边界。 但这里要非常谨慎:注意力高不等于因果上重要, 它实际依赖的信号未必体现在权重上26

第二类是拿探针去测。 训一个很小的探针模型,拿它的中间表示去猜一些语言特征 (这个词是名词还是动词、这句话的主干是什么、说话人是褒是贬)。 结果发现不同层确实自发学到了层次化的语言知识: 浅层学表层特征,中层学句子结构,深层学抽象意思。 这验证了第 02 章那句「深度即抽象」不是比喻,它真的在内部发生着27

第三类最有野心,叫回路分析。 试图找到内部实现特定功能的那条「回路」: 哪些单元、哪些头合作完成「算加法」「识别指代」「续写引语」这些具体任务。 这是离「真正读懂它在想什么」最近的一条路,也最难—— 一个 70 亿参数的模型有上千亿个可能的连接,光是「在哪里看」就是一个巨大挑战28

书里在这里花了不少篇幅介绍作者所在团队的工作,值得单独说一下, 因为它示范了这条路怎么从「画一张漂亮的图」变成可积累的实证工作29

早期的可解释性工作多集中在单个单元上,但很快发现单个单元往往是「多义」的: 同一个单元可能同时对 Python 代码、法语词汇、数学公式这些毫不相关的概念都有反应。 他们用的办法是把某一层那份「每一位都非零、挤在一起」的表示拆开,分解成「少数活跃的、各自只有一个意思的特征」, 好比把一个混杂的彩色像素拆成几种主导颜色。

在这个基础上,他们发布了一份覆盖多层的开放特征字典, 研究者可以挑出任意一个特征,看它在什么样的输入上被激活、激活时模型在生成什么—— 相当于给一个 80 亿参数的网络配了一本「它自己的词典」30。 后续工作又把这套办法延伸到注意力那一侧,把单个头进一步拆成更原子的子单元。

判断(我们的,不是书里的): 这条路线目前最大的价值不在「解释了什么」, 而在「让解释这件事变得可复现、可叠加、可被别人推翻」。 一份能被复现的特征字典,比一百张漂亮的注意力热力图更有分量。 如果错,会错在: 如果特征字典本身高度依赖分解方法的选择, 换一套方法就得到另一组「单义特征」,那它的客观性就要打折扣。

至于知识存在哪里,书里的答案很克制:一些实验发现前馈层常常是事实知识的重要载体之一, 某些位置可以被看成「键值记忆体」。但模型的知识不像图书馆那样一本书放一个架子, 更像一张巨大的关系网——这也解释了为什么改一个事实往往会波及许多看似无关的回答31

9. 上下文学习:不改参数,只改输入

有一件事一直让人困惑:为什么它能从几个例子就学会新任务?

先把词说清楚。上下文指的是这一次推断时,它面前那段能看见的输入 (你的问题、之前的对话、你贴进去的资料,合起来都算)。 而上下文学习说的是:不更新任何参数,只在这段输入里给它几个示范, 它就能照着去完成一个全新的任务32

这件事第一次被广泛注意到是在 2020 年。当时那个千亿参数的模型让人震动的, 其实不是参数数字本身,而是这种「看几眼例子就上手」的本事: 不改一个数,只在提示(你发给它的那整段输入,包括指令、例子和贴进去的资料) 里给几个示范,它就开始按同样的格式做新题33

一个流行的假设是:它在预训练中隐式地学会了「做学习」本身。 也就是说,参数某种程度上编下了「遇到少量例子后如何推广」这种元本事。 当你给它「2 + 3 = 5、4 + 1 = 5、6 − 2 = 4」再问「7 − 3 = ?」时, 它不是在查记忆,而是在内部模拟一个学习过程34

这个假设有一些实验支持:研究者发现,在输入里提供例子时, 它的部分计算模式和「在小数据上做几步梯度下降」惊人地相似。

但这还不是定论。 书里的措辞很克制:更像一盏手电照到的局部轮廓, 我们看见了形状,却还没看清整台机器35

如果这个假设对,那意味深长:参数里不只有事实知识,还包含学习机制本身。 预训练学到的既有「知道什么」,也有「如何快速学新东西」—— 这可能是理解第 01 章那个「涌现」的关键,也呼应了第 06 章会反复出现的一个直觉: 很多看起来在「教它新本领」的训练,其实是在调用它已经具备的元本事。

10. 几个看起来可有可无的小设计

除了主流程,这套结构里还有几个容易被忽略、但每一个背后都压着反复打磨的细节。

第一,为什么非得用 Softmax。 它让权重加起来等于 1,于是「注意力」变成一个真正的分配: 把我的关注按比例分给各个位置。没有这种归一,权重可能爆炸或消失,训练会不稳。 它还有一个很妙的性质:输入越尖锐(最大值和其他值差距大),关注越集中; 输入越平缓,关注越分散。这让它能自适应地决定「这次是精确匹配一个词, 还是综合考虑多个词」36

近年也有人尝试用不带 Softmax 的做法,把那张 N × N 表的开销从平方级降到线性, 对长输入友好;但代价是表达能力和训练稳定性都打了折扣。 这是一个「效率换表达力」的经典折中,第 04 章 §8 会展开。

第二,前馈网络为什么那么宽。 典型配置是前馈中间层的宽度等于注意力宽度的 4 倍。 这个设计让大部分参数集中在前馈里,而不是在注意力里37。 第 02 章 §6 说过同一件事,这里给出了原因:许多知识线索似乎和前馈层强相关。

这也解释了为什么第 04 章那个「把一层拆成很多专家、每次只用几个」的做法 是拿前馈开刀:前馈是「胖」的那部分,把它拆开收益最大38

第三,规范化放在子模块之前还是之后。 最初那篇论文放在之后, 后来发现这种设计在深层网络里训练不稳,梯度分布会越来越不均衡,深的网络容易学崩。 现代主流改成放在之前,训练更稳,能训深得多的网络39看起来只是「挪了一下位置」,对训练动态的影响却是根本性的—— 这种「小改动、大影响」是这套结构演化的典型节奏。

第四,位置这件事还有残余问题。 即使用了当代主流的位置方案, 当训练时只见过较短的输入、测试时突然面对长得多的材料,仍会出现各种怪现象: 只关注开头和结尾、忽略中间(行话叫「中间丢失」); 位置越靠后的内容权重莫名变大或变小;长文本上质量下降40。 解决这些要一整套技巧,第 04 章 §4 会讲。

主走查:处理「那只猫没过马路,因为它太累了」里的「它」

这条走查贯穿本章。 我们只跟一个位置走一步,把每个数都写出来。 下面这组分数是为演示编的,不是真实数值;但从分数到权重那一步的算术是真的, 你可以自己拿计算器验一遍。

① 切成词元并变成数。 假设切成 8 块: 那只 / 猫 / 没 / 过 / 马路 / , / 因为 / 它。 每一块经过嵌入变成一串数(比如各 64 个数),再加上位置编码。 现在处理最后那个「它」。

② 生成三份东西。 「它」这个位置过三个矩阵,得到自己的查询; 前面七个位置各自过同样的矩阵,得到各自的键和值。

③ 查询和七个键各算一次点积。 得到七个分数。 这里直接给出已经除过宽度平方根之后的分数(所以下一步只剩 Softmax):

位置那只马路,因为
缩放后的分数0.32.80.20.10.10.00.6

「猫」的分数最高,这正是我们希望的:「它」指的是猫,不是马路。

④ 过 Softmax,变成加起来等于 1 的权重。 先各自取指数:

e²·⁸ ≈ 16.44、e⁰·⁶ ≈ 1.82、e⁰·³ ≈ 1.35、e⁰·² ≈ 1.22、 e⁰·¹ ≈ 1.11(两个)、e⁰ = 1.00。

把这七个数加起来:16.44 + 1.82 + 1.35 + 1.22 + 1.11 + 1.11 + 1.00 = 24.05。 再各自除以 24.05:

位置因为那只马路,
权重0.680.0760.0560.0510.0460.0460.042

七个加起来是 1.00(四舍五入后差 0.003)。 「猫」拿走了 68% 的关注,「马路」只有 4.6%,差了将近 15 倍。

⑤ 按权重把值混起来。 假设值向量的某一维上,「猫」那一份是 +0.9、 「马路」那一份是 −0.4、其余都接近 0(这三个数是为演示编的)。 那么「它」这一步在这一维上的新表示就是: 0.68 × 0.9 + 0.046 × (−0.4) ≈ 0.612 − 0.018 = 0.594这个数几乎完全来自「猫」。 所以它后面接的词才像在说猫,而不是在说马路。

⑥ 八个头各干一遍,再拼起来。 上面这一整套在 8 个头里同时发生, 每个头用自己的三个矩阵、得到自己的一组权重。也许第二个头把最高分给了「因为」 (它在看因果关系),第三个头把最高分给了「那只」(它在看限定词)。 八份结果拼接后过一次线性变换,合成一份。

⑦ 走完这一层剩下的部件。 这份新表示先和进来时的表示相加(残差), 再过一次规范化,然后过前馈网络做一次「深加工」,再加一次残差。 一层结束,把结果交给下一层——同样的事情再来一遍,总共几十上百层

⑧ 如果没有第 ③ 步那个缩放会怎样? 假设不除以宽度的平方根, 七个原始分数变成 22.4、4.8、2.4、1.6、0.8、0.8、0.0(把上面每个乘以 8)。 再走一遍 Softmax:e²²·⁴ ≈ 5.4×10⁹,而 e⁴·⁸ ≈ 121。 「猫」的权重会变成 0.99999,其余六个加起来不到十万分之三。 关注塌成了一根针,「柔性」彻底消失,训练信号也几乎归零。 这就是那个「除以一个数」为什么不是可有可无的装饰。

作者的判断与证据

书里给了证据的地方:

  • 自注意力对顺序不敏感,这是可以自己验证的数学事实,书里直接给出17;
  • 大部分参数在前馈里而不是在注意力里,书里在第 2 章和第 3 章各说了一次37;
  • 不同层学到不同层次的语言知识,有探针实验支持27;
  • 规范化位置从「之后」改到「之前」,给了明确的原因(深层训练不稳)39

书里明确标成推测或有争议的地方:

  • 注意力权重高不等于因果重要,书里主动提醒了这一点,而不是拿热力图当证据26;
  • 上下文学习是「隐式做了几步梯度下降」,书里说「这还不是定论」, 并用了「一盏手电照到的局部轮廓」这个说法35;
  • 知识存在前馈层里,书里的措辞是「一些实验发现……常常是重要载体之一」, 紧跟着提醒「模型的记忆并不是一张整齐的抽屉清单」31

还有一处需要区分谁在说话:§8 里那部分机理可解释性工作, 是本书作者所在团队自己做的。书里没有隐瞒这一点,明确写了团队名字; 读者读到那一节时应当知道,这是作者在介绍自己的研究方向,不是中立的领域综述。

边界与局限

  • 这一章只讲标准结构,不讲它后来怎么被改。 长输入、稀疏激活、 压缩那张关系表的各种办法,全在第 04 章。
  • 书里没有推导任何一个公式。 反向传播怎么穿过注意力、 多头拼接后那次线性变换的作用,都只给结论。
  • 可解释性那一节停在「正在做」的状态。 书里自己说「离真正理解它在想什么 还有很长的路要走」,本组拆解沿用这个口径。
  • 关于「为什么只用解码器成了主流」,这一章只给结构上的一半答案。 另一半(训练目标塑造了什么)在第 05 章 §4,两节合起来才完整。

可带走的

  1. 要解决的是两件事:远处的信号会衰减、串行没法并行;自注意力让查询和键同源,距离不再是障碍。
  2. 柔性查字典有三个角色: 查询(我要找什么)、键(我是什么)、值(我能提供什么内容)。
  3. 查询乘键生成一张 N × N 的关系表。 这套结构全部的力量和麻烦都来自这张表;但权重高 ≠ 因果上重要,别拿热力图当证据。
  4. 除以宽度的平方根不是装饰。 不除,关注会塌成一根针,训练信号归零。
  5. 多头不是把计算量乘以头数,而是把宽度切成几份、各看各的。
  6. 打乱词序结果完全一样,所以顺序必须被显式塞进去。
  7. 一层由四个部件组成: 多头自注意力、前馈、残差、层归一化。反复堆叠就是全部。
  8. 三种搭法的底层积木完全一样,差的只是注意力能不能向后看。
  9. 大部分参数在前馈里。 这解释了为什么后来「拆专家」是拿前馈开刀。
  10. 上下文学习意味着参数里可能不只有知识,还有学习机制本身。 但这还不是定论。

原文地图

主题原书节原文位置
相关信息不挨在一起3.1text/04-ch03-3-transformer.txt:33(搜「最难的问题之一是相关信息往往并不挨在一起」)
注意力的基本想法3.1text/04-ch03-3-transformer.txt:43(搜「注意力机制提供了一种更直接的思路」) · text/04-ch03-3-transformer.txt:48(搜「它的关键在于按相关性分配权重」)
更容易并行3.1text/04-ch03-3-transformer.txt:68(搜「它更容易并行」)
注意力不是理解的同义词3.1text/04-ch03-3-transformer.txt:74(搜「注意力不是」)
RNN 两个痛点3.1.1text/04-ch03-3-transformer.txt:84(搜「长距离依赖弱」) · text/04-ch03-3-transformer.txt:91(搜「无法并行」)
字典查询比喻3.1.2text/04-ch03-3-transformer.txt:105(搜「理解注意力机制最好的比喻是字典查询」)
点积与缩放3.1.2text/04-ch03-3-transformer.txt:128(搜「最常用的相似度函数是点积」) · text/04-ch03-3-transformer.txt:131(搜「缩放点积注意」)
N² 关系表3.1.2text/04-ch03-3-transformer.txt:139(搜「会生成一张」)
Softmax 与可微分3.1.2text/04-ch03-3-transformer.txt:143(搜「Softmax 把权重平滑化」)
自注意力3.1.3text/04-ch03-3-transformer.txt:151(搜「自注意力」) · text/04-ch03-3-transformer.txt:161(搜「两个痛点的解决方案变得一目了然」)
多头3.1.3text/04-ch03-3-transformer.txt:181(搜「多头自注意力」) · text/04-ch03-3-transformer.txt:188(搜「让总参数量不随头数线性增长」)
位置编码3.2text/04-ch03-3-transformer.txt:195(搜「这就是位置编码的由」) · text/04-ch03-3-transformer.txt:219(搜「自注意力对顺序不敏感」)
位置方案的演化3.2.1text/04-ch03-3-transformer.txt:223(搜「原始 Transformer 用正弦和余弦函数编码位置」) · text/04-ch03-3-transformer.txt:233(搜「旋转位置编码」)
四个标准积木3.3.1text/04-ch03-3-transformer.txt:291(搜「一个完整的 Transformer 层」) · text/04-ch03-3-transformer.txt:304(搜「这种标准化带来一个巨大的工程优势」)
三种范式3.3.2text/04-ch03-3-transformer.txt:310(搜「仅编码器」) · text/04-ch03-3-transformer.txt:323(搜「因果掩码」) · text/04-ch03-3-transformer.txt:336(搜「三种范式的底层积木完全一样」)
可解释性三条路线3.4.1text/04-ch03-3-transformer.txt:479(搜「注意力可视化」) · text/04-ch03-3-transformer.txt:482(搜「力高不等于因果重要」) · text/04-ch03-3-transformer.txt:483(搜「探针实验」) · text/04-ch03-3-transformer.txt:487(搜「回路分析」)
作者团队的工作3.4.2text/04-ch03-3-transformer.txt:498(搜「稀疏自编码器」) · text/04-ch03-3-transformer.txt:512(搜「就像给一个 80 亿参数的网络配了一份」)
知识怎么存储3.4.3text/04-ch03-3-transformer.txt:538(搜「事实知识的重要载体之」) · text/04-ch03-3-transformer.txt:544(搜「更像一张巨大的关系网」)
上下文学习3.4.4text/04-ch03-3-transformer.txt:550(搜「上下文学习」) · text/04-ch03-3-transformer.txt:552(搜「模型在预训练中隐式地学会了」)
几个小设计3.5text/04-ch03-3-transformer.txt:574(搜「为什么非得这样」) · text/04-ch03-3-transformer.txt:585(搜「典型配置是 FFN 中间维度」) · text/04-ch03-3-transformer.txt:598(搜「后规范化」) · text/04-ch03-3-transformer.txt:610(搜「中间丢失」)

Footnotes

  1. 出处:「3.1 注意力机制」第 33 段 (text/04-ch03-3-transformer.txt:33,搜「最难的问题之一是相关信息往往并不挨在一起」)。

  2. 出处:同节第 40 段(text/04-ch03-3-transformer.txt:40,搜「信号容易衰减」); 那个 0.8 的三十步算例来自第 2 章(text/03-ch02.txt:602,搜「每层平均乘 0.8」)。

  3. 出处:「3.1.1 从 RNN 困境到注意力的灵感」第 91 段 (text/04-ch03-3-transformer.txt:91,搜「无法并行」)。

  4. 出处:同节第 98 段(text/04-ch03-3-transformer.txt:98,搜「这个灵感来自人的认知经验」)。

  5. 出处:「3.1」第 74 段(text/04-ch03-3-transformer.txt:74,搜「注意力不是」)。

  6. 出处:「3.1.2 字典查询」第 105 段 (text/04-ch03-3-transformer.txt:105,搜「理解注意力机制最好的比喻是字典查询」)。

  7. 出处:同节第 128 段(text/04-ch03-3-transformer.txt:128,搜「最常用的相似度函数是点积」)。

  8. 出处:「3.1.3 自注意力」第 153 段(text/04-ch03-3-transformer.txt:153,搜「三个可学习的矩阵变」)。

  9. 出处:「3.1.2」第 131 段(text/04-ch03-3-transformer.txt:131,搜「缩放点积注意」)。

  10. 出处:同节第 139 段(text/04-ch03-3-transformer.txt:139,搜「会生成一张」)。 书里紧跟着写:「它的好处是任意两个位置都能直接联系;代价也在这里,上下文越长,这张表膨胀得越快。」

  11. 出处:同节第 131 段(text/04-ch03-3-transformer.txt:131,搜「当向量维度」)。 书里给的理由是「当向量维度很大时点积会很大、Softmax 梯度消失」。

  12. 出处:同节第 143 段(text/04-ch03-3-transformer.txt:143,搜「Softmax 把权重平滑化」)。

  13. 出处:「3.1.3 自注意力」第 151 段(text/04-ch03-3-transformer.txt:151,搜「自注意力」)。

  14. 出处:同节第 161 段(text/04-ch03-3-transformer.txt:161,搜「两个痛点的解决方案变得一目了然」)。

  15. 出处:同节第 180 段(text/04-ch03-3-transformer.txt:180,搜「一次自注意力只能从一个」)。

  16. 出处:同节第 188 段(text/04-ch03-3-transformer.txt:188,搜「让总参数量不随头数线性增长」)。

  17. 出处:「3.2.1 从正弦编码到 RoPE」第 219 段 (text/04-ch03-3-transformer.txt:219,搜「自注意力对顺序不敏感」)。 2

  18. 出处:「3.2 位置编码与序列建模」第 195 段 (text/04-ch03-3-transformer.txt:195,搜「这就是位置编码的由」)。

  19. 出处:「3.2.1」第 223 段起(text/04-ch03-3-transformer.txt:223,搜「原始 Transformer 用正弦和余弦函数编码位置」), 四种做法分列到第 236 段。

  20. 出处:「3.3.1 Transformer 积木的四个部件」第 291 段 (text/04-ch03-3-transformer.txt:291,搜「一个完整的 Transformer 层」)。

  21. 出处:同节第 304 段(text/04-ch03-3-transformer.txt:304,搜「这种标准化带来一个巨大的工程优势」)。

  22. 出处:「3.3.2 三种架构范式」第 310 段起(text/04-ch03-3-transformer.txt:310,搜「仅编码器」)。

  23. 出处:同节第 323 段(text/04-ch03-3-transformer.txt:323,搜「因果掩码」)。

  24. 出处:同节第 336 段(text/04-ch03-3-transformer.txt:336,搜「三种范式的底层积木完全一样」)。 书里在这一句之后接的是「只是组合方式、训练目标不同」; 「为什么只解码器成了主流」这句判断本组拆解按审读意见整句让给第 05 章 §4,这里只留结构上的一半。

  25. 出处:「3.4.1 可解释性研究的三条路线」第 478 段 (text/04-ch03-3-transformer.txt:478,搜「大致可分三类」)。

  26. 出处:同节第 482 段(text/04-ch03-3-transformer.txt:482,搜「力高不等于因果重要」)。 2

  27. 出处:同节第 483 段(text/04-ch03-3-transformer.txt:483,搜「探针实验」)。 2

  28. 出处:同节第 487 段(text/04-ch03-3-transformer.txt:487,搜「回路分析」)。

  29. 出处:「3.4.2 机理可解释性研究」第 498 段 (text/04-ch03-3-transformer.txt:498,搜「稀疏自编码器」)。 书里明确写了这是「本书作者所在的 OpenMOSS 团队」的工作。

  30. 出处:同节第 512 段(text/04-ch03-3-transformer.txt:512,搜「就像给一个 80 亿参数的网络配了一份」)。

  31. 出处:「3.4.3 知识是怎么存储的」第 538 段 (text/04-ch03-3-transformer.txt:538,搜「事实知识的重要载体之」) 与第 544 段(text/04-ch03-3-transformer.txt:544,搜「更像一张巨大的关系网」)。 2

  32. 出处:「3.4.4 上下文学习的机制」第 550 段(text/04-ch03-3-transformer.txt:550,搜「上下文学习」)。

  33. 出处:「3.3.5」第 453 段(text/04-ch03-3-transformer.txt:453,搜「看几眼例子就上手」)。

  34. 出处:「3.4.4」第 552 段(text/04-ch03-3-transformer.txt:552,搜「模型在预训练中隐式地学会了」)。

  35. 出处:同节第 558 段(text/04-ch03-3-transformer.txt:558,搜「更像是一盏手电照到的局部轮廓」)。 2

  36. 出处:「3.5.1 为什么用 Softmax 注意力」第 576 段 (text/04-ch03-3-transformer.txt:576,搜「温度敏感」)。

  37. 出处:「3.5.2 前馈网络的宽度」第 585 段 (text/04-ch03-3-transformer.txt:585,搜「典型配置是 FFN 中间维度」)。 2

  38. 出处:同节第 592 段(text/04-ch03-3-transformer.txt:592,搜「拿 FFN 开刀」)。

  39. 出处:「3.5.3 LayerNorm 的位置」第 598 段(text/04-ch03-3-transformer.txt:598,搜「后规范化」) 与第 603 段(text/04-ch03-3-transformer.txt:603,搜「现代主流是前规范化」)。 2

  40. 出处:「3.5.4 位置编码的残余问题」第 610 段(text/04-ch03-3-transformer.txt:610,搜「中间丢失」)。