Transformer 的注意力(Attention)到底怎么计算?——一篇给普通读者都看得懂的深度解读
导语:当你在手机上跟 ChatGPT 对话,或者刷到自动生成的推荐文章,背后很可能就是 Transformer 在“悄悄地”计算注意力。别被“注意力”这个词吓到——它实则是模型在给每个词“分配视线”的数学方法。本文从直觉讲起,逐步深入,最后用一个完整的数值例子把每一步都算清楚(我会把关键算术一步步写清),直接看懂实现要点。
1)直觉:注意力是什么?为什么要算注意力值
把注意力想象成“谁在听谁”。当模型在处理一句话的某个词(列如“它”),它需要判断句中哪些其它词对理解“它”最重大。注意力值就是对这些其它词的重大性打分,打分越高,模型“听得越用力”。
这项机制让 Transformer 能在全局范围内灵活建模长距离依赖(列如主谓关系、代词指代),比传统 RNN 要强劲且并行化友善。
2)关键角色:Query、Key、Value(Q、K、V)
Attention 的计算只靠三样东西:
- Query(查询):当前“听”的那个词发出的询问。
- Key(键):每个候选词身上的“标签”,用来匹配查询。
- Value(值):每个候选词携带的信息,最后按注意力权重加权求和得到输出。
直觉:Query 去对每个 Key 做“类似度匹配”,得到一组分数(越类似分数越高),把这些分数归一化后作为权重去加权各自的 Value,结果就是“关注后的信息”。
3)数学公式(最核心:Scaled Dot-Product Attention 缩放点积注意力)
最常见、也是 Transformer 原始论文使用的注意力计算是 Scaled Dot-Product Attention:
给定矩阵
,计算流程:
- 1、计算类似度(点积):
.
这里 S 的维度是
,第
个元素是第
个 query 与第
个 key 的点积。
- 2、缩放(scale):
。
这个
是为了避免点积在维度大时数值过大,导致 softmax 梯度很小(不稳定)。
- 3、归一化(softmax): 对每行做 softmax,得到注意力权重矩阵 A:
。
- 4、加权求和值: 输出
。
每个 Query 的输出是候选 Value 的加权和,权重就是对应的注意力分布。
4)一步一步的数值例子(完整演算)
下面用最小尺寸的数来把整个过程算清楚(数字运算会逐位写出关键步骤,便于核对)。
场景:句子有 3 个 token,维度
。我们只计算针对第 1 个 query 的注意力(也可同理算其它)。
给定:
- Query 矩阵(每行是一个 token 的 query):

- Key 矩阵(同维度):

- Value 矩阵(每行为 value,维度
):

(这个例子把 Q、K 设置成一样矩阵,便于理解类似度含义;Value 给不同信息)
第 1 步 — 计算点积 S = Q Kᵀ
我们只算第 1 个 query(第一行
)与所有 keys 的点积:
.
.
.
所以第 1 行类似度向量
。
第 2 步 — 缩放:除以 
这里 d=2,所以
。我们把每个得分除以 1.414213562:
逐项计算(保留小数):
.
.
.
(这一步常见于实现中,用 scores /= math.sqrt(d))
第 3 步 — softmax(按行归一化)
softmax 的定义:
.
我们先计算
:
. 指数值:0.7071 的自然指数约等于 2.028114981.(这是用标准指数表或计算器的结果。)
.- 第三个同第一个:
.
把三项相加(逐位相加展示):
先把前两项相加:
2.028114981 + 1.000000000 = 3.028114981.
再加第三项: 3.028114981 + 2.028114981 = 5.056229962.
所以分母(指数和)约等于 5.056229962。
目前逐项除以总和得到注意力权重:
- 权重 1:
. - 我们做除法(逐位说明):
- 先近似:2.028114981 ÷ 5.056229962 ≈ 0.401.
- 更准确计算可以用长期除法,得到
(四舍五入到三位小数为 0.401)。 - 权重 2:
(约 0.198)。 - 权重 3: 与第 1 项一样,
.
检验:0.401 + 0.198 + 0.401 = 1.000(近似满足归一化)。
直观解释:第1个和第3个 key 与 query 类似度高(点积为1),所以被分配到更高的权重;第2个 key 不类似,权重小。
第 4 步 — 用注意力权重加权 Value:输出 = A V
Value 行为:
.
把权重乘到每个 value 并相加(逐分量计算):
输出向量
.
逐分量算第一个分量(x):
- 第一个分量贡献:
. - 第二项对第一个分量:
. - 第三项对第一个分量:
.
相加得到第一个分量:
.
第二个分量(y):
- 第一个 value 在 y 上是 0:
. - 第二 value 在 y 上是 2:
. - 第三 value 在 y 上是 1:
.
相加: 0 + 0.396 + 0.401 = 0.797.
所以最终输出
。
这就是 第 1 个 Query 在注意力层的输出:把其它 token 的信息按类似度混合后得到的聚合表明。
5)扩展:Multi-Head Attention(多头注意力)为啥厉害
上面的演算是单头注意力(单个 Q/K/V 投影)。实际的 Transformer 会把 Q、K、V 分成若干个“头”(head),每个头在低维空间独立做注意力,然后把各头的输出拼接、再经过线性变换。缘由:
- 不同头可以专注不同的语义关系(一个头学语法、一个头学指代、另一个头学实体关系)。
- 分头后每个头维度更小,计算上能并行,模型表达更丰富。
实现上看起来像:
- 先用三组不同的线性变换把输入投影到 h 个 head 的小维度上;
- 每个 head 独立做上面那套 scaled dot-product;
- 把 h 个输出拼起来做最终线性投影。
6)工程实现要点与优化技巧(程序员看这里)
- 数值稳定性:softmax 前常常做
后,再减去每行的最大值(scores -= scores.max(dim=-1, keepdim=True))防止 exp 溢出。 - 掩码(mask):在自回归(生成)任务,用上三角 mask 屏蔽未来 token,避免看到后文。掩码一般把被屏蔽的位置得分设为极小(例如 -1e9)。
- 并行化与内存:注意力是
的时间/空间(n = 序列长度),对长序列成本高。常用稀疏注意力、局部窗口、或低秩近似来缩小复杂度。 - 实现接口:深度学习框架(PyTorch/TF)里有高性能实现(列如 torch.nn.MultiheadAttention),底层已做了许多优化。
7)把“注意力”解释给非技术读者
想象你在听一个故事,每一句话里有些关键词比其他词更重大。Transformer 的注意力机制就像一组极其勤奋的听众:每当它要理解某个词(列如“它”),它会在心里问:“和我正在看的这个词最有关联的词是谁?”然后把注意力分配给这些词,最后把它们的信息综合起来理解当前词的含义。这个过程在机器里被写成了矩阵乘法和概率分布——但本质上就是“挑重大的、把重大信息加起来”。
8)常见误区 & 总结
- 误区一:注意力等同于人类理解的“注意力”。不是完全一样,但有类似的权重分配思想。
- 误区二:注意力权重直接等于“因果”或“可解释性”。有时高权重的确 指示模型在用某个词,但并不简单等于“模型理解了因果关系”。
- 总结要点:
- 注意力 = 用 Query 对 Key 做类似度匹配,并用 softmax 得到权重,再加权 Value。
- 缩放因子
和 softmax 是稳定训练与归一化的关键。 - Multi-head 让模型能并行学到多种关系。
- 实际工程要注意数值稳定、掩码和复杂度问题。
9)给程序员的快速伪代码(PyTorch 风格思路)
# 假设 Q, K, V 已经是形状 (batch, seq_len, d)
scores = torch.matmul(Q, K.transpose(-2, -1)) # (batch, seq_len, seq_len)
scores = scores / math.sqrt(d) # scale
scores = scores.masked_fill(mask == 0, -1e9) # optional mask
A = torch.softmax(scores, dim=-1) # attention weights
O = torch.matmul(A, V) # output
10)结语
注意力机制让模型能把“谁重大”变成可计算的数字,并以并行、高效的方式捕捉语言中的长距离关联。这也是 Transformer 能在 NLP、语音、视觉等多领域大放异彩的核心缘由之一。
#transformer# #注意力机制# #attention#

