第二篇讲了一组 Q、K、V 怎么工作:发起提问的词拿自己的 Q 去和每个词的 K 比,按分数取 V。可是真实的 Transformer 并不只用一组,原论文同时用了 8 组。每一组叫一个「头」,这种做法叫多头注意力(Multi-Head Attention)。这一篇讲为什么要这样做。

想先看个大概,可以先播放下面的动画讲解,两分钟把整条线过一遍,再往下读正文。

动画讲解多头注意力,两分钟看一遍12 步 · 约 2 分钟 · 可以随时暂停、跳步
1 / 12

第二篇讲了一组 Q、K、V 怎么工作。真实的 Transformer 不只用一组,原论文同时用了 8 组,每一组叫一个头,这种做法叫多头注意力。

朗读用的是浏览器自带的语音,不同设备声音不一样;没有语音的浏览器只显示字幕。

开始之前,先补一个前两篇默认大家都懂、但很容易卡住的基础。

一、先补一个基础:词向量

前两篇反复说「Q 是一串数字」「每个词是一串数字」。这到底是什么意思?

先想想怎么用数字描述一个人:身高 175、年龄 30、体重 70,排成一串 [175, 30, 70],就是这个人的一种描述。数字越多,描述得越细。

模型描述词用的是同一个办法。第二篇的例子里,每个词用 3 个数描述,「法国」是 [1, 1, 0],三个数分别表示「跟语言有关」「是长大的地方」「是一个动作」。这样的一串数字,数学里叫向量,每个数是一个维度。描述一个词的向量叫词向量(word embedding)。

真实模型的词向量长得多。原论文里每个词是 512 个数,也就是 512 维的向量,相当于从 512 个角度给这个词打分。

词向量:每个词是一串数字,「猫」和「狗」的数字相近,和「汽车」差得远

意思相近的词,词向量也相近。「猫」和「狗」对应位置上的数一起大、一起小,乘起来再加,点积就大;「猫」和「汽车」的数一个大一个小,点积就小。第二篇用点积给词打分,靠的就是这一点。

二、一组 Q、K、V 不够用

换一个句子:

小明把书借给了小红。

如果只有一组 Q、K、V,「借」只能发出一个 Q,经过 softmax 得到一组百分比,再按这组百分比把各个词的 V 混成一份内容。想把三件事都照顾到,注意力大概只能这样分:小明 30%、书 30%、小红 30%,其他词 10%。

问题出在「混成一份」上。三个词的信息按差不多的比例混在一起,「借」只知道小明、书、小红都和自己关系很紧密,却分不清谁是借出的人、谁是借到的人。换成「小红把书借给了小明」,混出来的结果几乎一样,可意思正好反过来。

还有一个限制:百分比加起来只有 100%。想把「小明」看清楚,就得把注意力集中到他身上,比如给他 90%,那「书」和「小红」就只剩一点。一组注意力只能把一件事看清楚,看清了这件,就顾不上别的。

三、多头注意力怎么做

解决办法很直接:不只用一组 Q、K、V,而是同时用好几组。每组叫一个头,有自己的三个矩阵,算出自己的 Q、K、V,独立做一遍第二篇讲的四个动作。比如用三个头,就可以一个看「谁借的」,一个看「借的什么」,一个看「借给谁」,每个头都把注意力集中在自己那件事上,看得清清楚楚。

每个头各拿到一份内容以后,怎么合成一份送进下一层?做法是拼接:头 1 的结果放最前面,头 2 接在后面,头 3 再接上去,排成一串更长的数字。拼接以后,每个头的内容各占一段位置:前一段是谁借的,中间一段是借的什么,后一段是借给谁。

拼接完还有最后一步:乘一个输出矩阵。它有两个作用:把拼接出来的长串变回原来的长度,方便送进下一层;让几个头的信息互相配合,组合成「小明 → 书 → 小红」这样完整的理解。

多头注意力:「借」的 512 个数分别交给三个头,每个头改写出 64 个数的 Q、K、V,各算一遍注意力,结果按顺序拼接,再乘输出矩阵变回 512 个数

下面可以自己试一试:先用一个头,切换两句意思相反的话,看「借」拿到的内容有没有区别;再换成三个头比一比。

动手试一试「借」用几个头,能分清谁借给谁?
「借」最后拿到的内容

百分比是示意,真实的头由训练自己学出分工。

四、不同的头学到了什么

上面说「头 1 看谁借的」,这只是为了好懂的假设。真实模型里,每个头该看什么,没有人安排过。每个头的矩阵一开始都是随机的,训练时各自朝不同方向调整,最后自然分了工。

那它们最后真的分工了吗?2019 年,斯坦福大学的研究者把 BERT 的 144 个头挨个拆开看。BERT 是 Google 2018 年发布的、基于 Transformer 的语言模型,有 12 层,每层 12 个头。他们发现确实有分工:

  • 有几个头几乎只看前一个词,还有几个几乎只看后一个词。
  • 有一个头专门让宾语去找它的动词,比如让「书」找到「借」,准确率约 87%。
  • 有一个头专门让名词前的修饰词(比如英文里的 the、a)去找它修饰的名词,准确率约 94%。
  • 有一个头专门处理指代,比如让「她」找到前面提到的「小红」。

同一年另一项研究发现,很多头去掉以后模型几乎不受影响:一个翻译模型的编码部分有 48 个头,去掉其中 38 个,翻译质量只下降了一点点。真正干重活的是少数几个分工明确的头。

五、头多了,计算量会翻倍吗

原论文就是这样安排的:8 个头,每个头的 Q、K、V 各 64 个数,8 × 64 = 512。拼接起来正好还是 512 个数,总计算量和一个 512 的头差不多,换来的是 8 个各看一种关系的头。

一个头用 512 个数;8 个头每个用 64 个数,拼接起来还是 512 个数,总计算量差不多

这里有一个取舍:每个头只有 64 个数,能装的信息比 512 少。但每个头只负责一种关系,64 个数够用。

顺带对上了第二篇的一个数字。第二篇说点积要除以 √d,「Q 有 64 个数时就除以 8」,这个 64 就是原论文里每个头的长度。

后来的大模型沿用了这个做法,只是数字更大。比如 GPT-3 每个词是 12288 个数,分成 96 个头,每个头 128 个数。

检验一下

「借」只用一组 Q、K、V,同时关注小明、书、小红,会出什么问题?

几个头各算出一份结果以后,怎么合成一份?

多头注意力里,每个头看什么是怎么定下来的?

原论文用 8 个头,计算量为什么和一个头差不多?

想深入可以看

← 全部文章