all_lessons/数学的逻辑/41第 42 课 / 共 44 课

第十一部分 · 从一个神经元到现代 AI

注意力与 Transformer:现代 AI 的引擎

上一课,卷积把"局部性"这个先验写进了网络——每个神经元只盯着一小块固定的邻域。可语言不是这样的:一句话里的"它",指代的名词可能在十几个词之外,而且每句话指向的地方都不一样。模型能不能自己决定"该看哪里"?本课就造出这台能自己找联系的引擎——而你会发现,它整台机器全是本课程学过的老零件拼出来的。

线性回顾
上一课:卷积(第 40 课)给网络装了一个强先验——局部性:每个输出只由一个固定的小邻域算出,权重还全图共享。这对图像绝妙,因为相邻像素本就相关。
留下的问题:语言要的恰恰相反——长程、而且随内容而变的连接。"猫累了,因为跑了一天"里的"它"要连到很远的"猫";下一句这个词可能又连到别处。固定邻域看不了那么远,一层层顺着传(早期的 RNN)又慢又容易把远处的信息传丢。模型怎么自己决定每个词该看哪些词?
本课新增:注意力——一种基于内容的"软查表":用一个 query 去和所有位置的 key 算内积(第 20 课!),过一道 softmax(第 33 课)变成一组权重,再对 value 做加权平均自注意力让每个位置一步就能看到所有位置;把它和 MLP 堆起来就是 Transformer——GPT、BERT 和今天几乎所有大模型的骨架。而它没有一件新零件:内积、softmax、加权平均,全是老朋友。
本课路线
(1) 该看哪里?——固定窗口(卷积)和顺序传递(RNN)都难搞定长程、随内容而变的连接,我们想让模型自己学该关注谁。(2) 注意力 = 软字典查表:query 与 key 的内积 → softmax → 对 value 加权平均。(3) 自注意力:q、k、v 都来自同一句话,人人一步看到人人,路径长度 O(1)。(4) Transformer = 自注意力 + MLP + 位置编码 + 残差 + 层归一化,堆几十上百层就是 GPT/BERT。(5) 注意力的归纳偏置——最弱、最灵活:几乎不设限,把"该连什么"完全交给数据;代价是要海量数据与算力,这就是"规模"成为关键词的原因。

该看哪里?

先把上一课的先验摆正。卷积的赌注是局部性:一个输出只看它周围固定的一小圈邻居。这个先验对图像近乎完美——相邻像素往往属于同一条边、同一块颜色。可一旦换成语言,这个假设就绷不住了。看这句:

"猫 累了,因为 它 跑了 一天。"

要理解"它",模型必须把它连到句首的"猫"——两者隔着好几个词。更麻烦的是,这种连接随内容而变:换一句"狗追猫,因为它饿了","它"又该连到"狗"。没有一个固定的邻域能同时接住所有这些情况。

早期处理序列的做法是 RNN:像读书一样从左到右一个词一个词地读,把"读到现在的记忆"一路往后传。可要把"猫"的信息传到很远的"它",得穿过中间每一个词——路径长、信息容易在传递中被稀释甚至丢掉,而且天生是串行的(必须读完前一个才能读下一个),没法并行,训练慢。

我们真正想要的是一台能自己判断"每个词此刻该看哪些词"的机器:连接不是写死的邻域,而是根据内容临时算出来的;而且最好每个词一步就能够到任何一个别的词。这台机器叫注意力(attention)

注意力 = 软字典查表

想象一本字典(查找表):你拿一个键(key)去查,命中了就取回对应的值(value)。普通字典是"硬"的——要么精确命中,要么查不到。注意力把它变"软":不再要求精确命中,而是按相似程度,把所有条目的值加权混合起来返回。

具体地,给序列里每个位置都算出三样东西(先只管含义,怎么算下一节说):一个查询 query(q)——"我想找什么";一个键 key(k)——"我能提供什么样的匹配";一个值 value(v)——"匹配上了就把我这份信息交出去"。现在某个位置发出它的 q,想知道该从别人那里取多少信息。第一步,量它和每个 key 有多像。用什么量相似?第 20 课的老工具——内积

相似度 sᵢ = q · kᵢ (读作"query 与第 i 个 key 的内积")

内积大,说明 q 和 kᵢ 方向一致、匹配度高(第 20 课:内积编码了夹角,方向越一致值越大)。这样每个位置都得到一串"匹配分数"。可这些分数有正有负、大小不一,不能直接当权重。我们要把它们变成一组和为 1 的权重——正是第 33 课的 softmax

wᵢ = softmax(sᵢ) = e^{sᵢ} / ∑ⱼ e^{sⱼ}

读作"第 i 个权重等于:把第 i 个分数取指数,再除以所有分数取指数之和"。softmax 把任意一串实数压成一个概率分布——每个 wᵢ ≥ 0,全部加起来正好等于 1,而且分数越大的位置分到的权重越大。最后一步,用这组权重对所有 value 做加权平均,就是这个位置的输出:

输出 = ∑ᵢ wᵢ · vᵢ = ∑ᵢ softmax(q · kᵢ / √d) · vᵢ

读作"输出等于:对每个位置,把'query 与它的 key 的内积除以 √d、再过 softmax'得到的权重,乘上它的 value,全部加起来"。这就是注意力的全部公式。翻译成人话:用 query 去匹配所有 key,按匹配程度决定从每个 value 里取多少,混合成一份答案。它是一本可微的字典——因为全程只有内积、指数、加权和,处处可导,于是能被反向传播(第 26 课)一路优化。

那个 √d 是干嘛的
公式里把内积除以了 √dd 是向量的维度)。原因很实际:维度一高,内积是很多项相加,数值容易变得很大;很大的数喂进 softmax 的指数里,会让输出几乎变成"非 0 即 1"的独热(一个位置吃掉几乎全部权重),梯度也随之趋近于 0、学不动。除以 √d 把分数的尺度拉回正常,softmax 才平滑好训。这就是它被叫作缩放点积注意力的由来——本质仍是内积,只是量了个合适的单位。

自注意力:人人都能看到人人

上一节的 q、k、v 从哪来?在自注意力(self-attention)里,它们全都来自同一句话。把每个词先变成一个向量(词嵌入),再各自乘上三个可学的线性映射(就是第 11 课的矩阵乘法,q = W_q xk = W_k xv = W_v x),就得到了这个词的 query、key、value。三个 W 是训练出来的参数——模型自己学会"该拿什么去匹配、该提供什么、该交出什么信息"。

于是发生了一件关键的事:句子里每一个词都发出自己的 query,去和所有词(包括自己)的 key 算内积、过 softmax、对所有 value 加权平均。也就是说——每个位置一步就能"看"到序列里任何其它位置。回到"它"和"猫":不管它们隔多远,"它"的 query 只要和"猫"的 key 内积够大,softmax 就会给"猫"分到大权重,一步把"猫"的信息取过来。

为什么这彻底解决了长程依赖
RNN 里"猫→它"要穿过中间每个词,路径长度随距离线性增长,信息越传越淡。自注意力里任意两个位置直接相连,路径长度恒为 O(1)——多远都是一步。而且所有位置的注意力可以同时算(一堆内积就是一次矩阵乘法),高度并行。这正是它能吃满 GPU、能靠"堆规模"取胜的根本原因:既看得远,又算得快。

Transformer = 注意力块堆起来

把自注意力当成一块积木,Transformer 就是用它搭起来的塔。一个标准块里除了自注意力,还有几样配件,每一样我们都见过:

一块 = 自注意力 + MLP(配上残差与层归一化),把这样的块堆几十到上百层,再喂进海量文本训练,就是 GPT、BERT 这些模型的骨架。名字听起来像黑科技,可请数一数用到的零件:

零件清单 · Transformer 里没有新魔法
相似度 = 内积(第 20 课);把相似度变权重 = softmax(第 33 课);取信息 = 加权平均;q/k/v = 线性映射(第 11 课);逐位置加工 = MLP(第 38 课);训练 = 反向传播 + 梯度下降(第 26 课)。整台"现代 AI 引擎",是本课程学过的老零件的一次精妙组装。

下面这个小实验,把注意力最核心的一步——"一个 query 在关注谁"——摊开给你看。

注意力热力图:Query 在关注谁
一句话 6 个词,每个词有一个固定的小向量(示意的词嵌入,特意让相似的词方向相近)。点上面的按钮选一个Query 词:它会用自己的向量当 q,和每个词的向量当 k 算内积,除以 √d 再过 softmax,得到一组和为 1 的注意力权重。柱子越高、颜色越亮 = 这个词被关注得越多。拖动"温度"滑块:温度小 → 权重变尖锐(几乎只盯一个词);温度大 → 权重被摊平(雨露均沾)。输出 = ∑ wᵢ · valueᵢ,就是按这些权重把各词的信息加权平均。
当前 Query
最关注的词
权重之和

注意力的归纳偏置:最弱、最灵活

把注意力和卷积摆到一起对比,才看得清它的真正特点。第 40 课说过,卷积带着一个很强的先验:局部性 + 权重共享——它假定了"重要的联系都发生在近邻之间"。这个假设省数据(结构已经替你规定好了),但也画了牢笼:远处的东西,它天生看不到。

注意力几乎反过来:它的归纳偏置是最弱的——"任何位置都可以关注任何位置"。它几乎不预设哪些连接重要,而是把"到底该连什么"这件事完全交给数据去学(通过那三个可学的 W)。灵活性拉满,代价也随之而来:先验越弱,模型能自由拟合的东西越多,就越吃数据、吃算力——你得用海量样本,才能让它从零学出那些卷积一开始就免费送你的结构。

为什么"规模"成了现代 AI 的关键词
正因为注意力把结构留给数据去学,它的表现随数据量和模型规模近乎持续地变好——喂得越多、堆得越大、算得越久,越强。这就是"大模型""规模定律"背后的直觉:不是找到了更聪明的先验,而是选了一个先验极弱、极其通用的架构,然后用规模去把结构灌进去。灵活的代价是昂贵,而算力恰好越来越便宜。

还有一处代价必须点破:自注意力里每个词都要和所有词算内积,n 个词就有 n × n 对,计算量是 O(n²)——序列一长就很贵。它之所以还能赢,是因为这 个内积高度并行,正好被 GPU 吃满;用"贵但可并行"换来了"看得远、堆得大"。这笔账,在规模时代划算。

常见误解

一句话带走
注意力 = 基于内容的软字典查表:query 与 key 的内积(第 20 课)→ softmax(第 33 课)→ 对 value 加权平均。自注意力让每个位置一步看到所有位置(路径 O(1)、高度并行),彻底解决长程依赖;把它和 MLP、位置编码、残差、层归一化堆几十上百层,就是 GPT/BERT——现代 AI 的引擎。它的归纳偏置是最弱、最灵活的(几乎不设限,把结构交给数据学),代价是吃数据吃算力,于是"规模"成了关键词。而这台引擎,全由本课程学过的老零件搭成,没有新魔法。
下一步
到这里,我们已经能造出极强的判别模型:给一个 x,预测它的 y(是不是垃圾邮件、图里是猫是狗、下一个词是什么)。可怎么让机器生成全新的数据——画一张没人见过的图、写一段新的文字?那需要直接对数据分布 p(x) 建模,并从中采样。这要把第 34 课的采样、以及一整套变分推断的思想拧到一起。→ 第 42 课《从判别到生成:VAE、扩散与变分推断》。