第二篇讲了一组 Q、K、V 怎么工作:发起提问的词拿自己的 Q 去和每个词的 K 比,按分数取 V。可是真实的 Transformer 并不只用一组,原论文同时用了 8 组。每一组叫一个「头」,这种做法叫多头注意力(Multi-Head Attention)。这一篇讲为什么要这样做。
想先看个大概,可以先播放下面的动画讲解,两分钟把整条线过一遍,再往下读正文。
第二篇讲了一组 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 再接上去,排成一串更长的数字。拼接以后,每个头的内容各占一段位置:前一段是谁借的,中间一段是借的什么,后一段是借给谁。
拼接完还有最后一步:乘一个输出矩阵。它有两个作用:把拼接出来的长串变回原来的长度,方便送进下一层;让几个头的信息互相配合,组合成「小明 → 书 → 小红」这样完整的理解。
下面可以自己试一试:先用一个头,切换两句意思相反的话,看「借」拿到的内容有没有区别;再换成三个头比一比。
百分比是示意,真实的头由训练自己学出分工。
四、不同的头学到了什么
上面说「头 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 个各看一种关系的头。
这里有一个取舍:每个头只有 64 个数,能装的信息比 512 少。但每个头只负责一种关系,64 个数够用。
顺带对上了第二篇的一个数字。第二篇说点积要除以 √d,「Q 有 64 个数时就除以 8」,这个 64 就是原论文里每个头的长度。
后来的大模型沿用了这个做法,只是数字更大。比如 GPT-3 每个词是 12288 个数,分成 96 个头,每个头 128 个数。
检验一下
「借」只用一组 Q、K、V,同时关注小明、书、小红,会出什么问题?
一组注意力只能得到一组百分比,按比例把各个词的 V 混成一份。三个词都关注到了,但混在一起,分不清各自的角色。
几个头各算出一份结果以后,怎么合成一份?
取平均和加起来都会把几份内容重新混在一起。拼接让每个头各占一段,输出矩阵再把它们合成一份、变回原来的长度。
多头注意力里,每个头看什么是怎么定下来的?
每个头的矩阵一开始都是随机的,训练时各自朝不同方向调整,最后自然分了工。研究者是事后拆开观察才知道的。
原论文用 8 个头,计算量为什么和一个头差不多?
512 个数拆成 8 份,每个头 64 个,总的数字个数没变。注意每个头看的还是句子里的所有词,变少的是 Q、K、V 的长度。
想深入可以看
- Transformer 原论文:Attention Is All You Need(2017),第 3.2.2 节讲多头注意力
- 拆开 BERT 144 个头的研究:What Does BERT Look At? An Analysis of BERT’s Attention(2019)
- 去掉大部分头也几乎不影响的研究:Analyzing Multi-Head Self-Attention: Specialized Heads Do the Heavy Lifting, the Rest Can Be Pruned(2019)
- 图解 Transformer 的经典文章:The Illustrated Transformer,其中「The Beast With Many Heads」一节专门讲多头