Transformer 的心脏是怎么算的?自注意力机制与多头注意力原理拆解
大模型、翻译、代码补全,背后都立着一台叫 Transformer 的引擎,而这台引擎的心脏,是一套叫"自注意力"(Self-Attention)的机制。它解决的是一个朴素却要命的问题:一个词的语义,得看它身边的词才能定。
"苹果"在"吃苹果"里是水果,在"苹果发布了新机"里是公司。模型要想搞对,就得让每个词在编码时"看一眼"句子里其他词,还要根据相关程度分配注意力。这篇把自注意力一步步拆开,看它的 Q、K、V 到底在忙什么,公式又为什么长那样。
每个词都带着三个角色:Q、K、V

自注意力的起步动作,是让每个词(token)的表征,乘上三个可训练的权重矩阵,变出三个向量,分别叫 Query(查询)、Key(键)、Value(值)。
可以先借用"查资料"的直觉来记:Q 是"我想找什么",K 是"我能提供什么标签",V 是"我身上真正的内容"。一个词拿着自己的 Q,去和别的词的 K 比一比,看谁跟自己相关,再按相关程度去取对方的 V。
这三个向量是同一个词的表征分别乘 Wq、Wk、Wv 得来的,矩阵是训练出来的,模型自己学会"该按什么标准去关注别人"。
算注意力分数:先点积,后缩放
有了 Q 和 K,怎么量化"两个词多相关"?自注意力用的是点积:拿当前词的 q,逐一和每个词的 k 做点积,得到一个标量分数,分数越大,代表两者越相关。
但点积有个隐患:当 K 的维度 d_k 变大时,点积结果的数值会跟着膨胀。而下一步要套 softmax,数值一膨胀,softmax 会把概率挤进很陡的区域,梯度变小,训练变难。
所以公式里多了一步"缩放"——把点积结果统一除以 sqrt(d_k),把数值拉回一个更平稳的区间。这个看似不起眼的除法,正是公式里那个根号 d_k 的来历。
softmax 归一化,再把 V 加权求和
缩放完的分数,套一层 softmax,变成一列加起来等于 1 的权重。这时,每个词"该分多少注意力给别的词",就有了量化结果。
收尾的一步是加权求和:拿这些权重,去对每个词的 V 做加权平均。于是每个词都得到一个新的表征——它不再是孤零零的"自己",而是"按相关程度吸收了整个句子的信息"之后的自己。
整套计算,压成一行公式就是:
Attention(Q, K, V) = softmax( Q · Kᵀ / √d_k ) · V
其中 Q 是所有词的查询堆成的矩阵,Kᵀ 是键矩阵的转置,`Q·Kᵀ` 得到的就是"每个词和每个词"的两两相关分数矩阵,softmax 按行归一,再乘 V 得到加权输出。
为什么叫「自」注意力
"自"(Self)这个词,点的是 Q、K、V 三路都来自同一个输入序列。
对比一下更早的注意力:有些结构里,Q 来自一处,K、V 来自另一处,比如翻译里"用目标语言去查询源语言"。而自注意力里,句子里的词既当查询者、又当被查询者,彼此两两交互,所以叫"自"。正因为每个词都对每个词算关联,句子里的长距离依赖——比如"那个昨天在会上发了言的人"里,"人"和"发言"隔了老远——也能一步到位被关注到。
一条注意力不够看,就上多头
单头注意力有个局限:它只能形成"一种"关注方式。可同一个词,有时需要关注"谁修饰谁"的语法关系,有时需要关注"指代谁"的语义关系,一个注意力头顾不过来。
多头注意力(Multi-Head Attention)的思路就是并行开好几条:把 Q、K、V 分别切成多组,每组独立算一遍注意力,各学各的关注角度;算完之后,再把几路的输出拼接起来,过一个线性层整合。
这么做的效果,相当于让模型在多个不同的子空间里"各看各的风景",有头盯着语法、有头盯着指代、有头盯着位置关系,再拼成一张更立体的理解。这也是"多头"这两个字的全部含义——不是算更多次,而是从更多角度算。
它还得和位置编码打配合
如果只看上面的公式,会发现一个漏洞:自注意力本身的运算里,不管词排在前排在后,点积和加权的方式都一样,它"看不到顺序"。
这正是为什么 Transformer 要额外喂位置信息——把位置编码混进去,让"谁在前、谁在后"有迹可循。自注意力负责"谁和谁相关",位置编码负责"谁在哪个位置",两者合起来,才拼出完整的文本理解。
小结
把自注意力收一下:它解决的是"词的语义依赖上下文"这件事;做法是每个词生成 Q、K、V 三个向量,用点积量化相关度、除以根号 d_k 稳住数值、softmax 转权重、再对 V 加权求和;因为 Q、K、V 都来自同一序列,所以叫"自"注意力;单头不够用,就多头并行、各看一个子空间再拼起来;它天生不感知顺序,得靠位置编码补上这环。
看懂这行 `softmax(QKᵀ/√d_k)V`,大模型文本能力的底层,就撬开了一块核心的地基。
