想象你是一家跨国集团的信息协调专员。上级递给你一张任务单(Query):“找出上季度销冠团队报告里,最值得全公司推广的经验。”你走进档案室,看到一排排贴满标签(Key)的资料盒:有的写“营销策略”,有的写“客户留存”,有的写“成本控制”。你按任务单的指示,与每张标签比对“契合度”、打分,然后按分数高低翻阅正文(Value),把最相关的内容摘出来,加权拼成一份汇报。这份汇报,就是注意力机制的输出。 Transformer 的自注意力正是这套流程的数学化:输入一句话,模型先为每个词生成三样东西——Q(在找什么)、K(能答什么)、V(真正的内容),再用 Q 和 K 做点积打分,经过缩放与 softmax 归一化成权重,最后对 V 加权求和。本文会用这套“档案室找资料”的故事,带你一步步拆开 QKV 矩阵计算的每一个环节,让小白也能看懂 Transformer 内部最核心的数学原理。

岗位关联

对 AI 从业者而言,理解 QKV 计算是调试注意力权重、优化推理性能、解释模型行为的根基;面试中被问“Transformer 为什么这样设计”,答案就藏在这套矩阵运算里。

目录
  1. 可视化演示
  2. 认识QKV:任务单、标签与正文
  3. 线性变换:如何从X得到QKV
  4. 缩放点积:打分、归一化与加权求和
  5. 缩放因子:为什么除以根号dk
  6. 多头注意力:八位专家并行协作
  7. 权重可视化:查看注意力热度排行榜
  8. 计算优化:档案馆的提速之道
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

步进式对比四种稀疏注意力模式:局部窗口、步幅、块状、全局+局部,展示注意力矩阵的稀疏结构与复杂度差异。

本节配有交互动效(进入视口后自动加载,约 3KB)。

稀疏注意力模式 局部窗口:Onw带宽限制 步幅稀疏:Ons周期采样 块状/全局:Onw混合模式 Sparse = O(n*k) 降低二次复杂度

认识QKV:任务单、标签与正文

故事从档案室开始。你手上拿着老板的任务单(Query, Q),上面写着“找值得推广的销冠经验”;档案室里每份资料盒都有封面标签(Key, K),写着“营销策略”“客户留存”“成本控制”;而盒子里的正文(Value, V)才是你真正要读的内容。注意一个关键点:任务单、标签、正文是三种不同的东西——任务单决定你要找什么,标签决定这份档案能否回答你,正文决定你最终摘到什么。三者缺一不可。

翻译成 Transformer 的语言:一段文本有 n 个词,每个词被表示成一个 d 维向量,所有词拼成输入矩阵 X。自注意力要做的事情,就是让每个词“向其他词提问、其他词回应、再把回应内容按相关度汇总”。于是每个词都要生成自己的 Q(提问向量)、K(回应标签向量)、V(回答内容向量),这就是 QKV 三个矩阵的来历。

“注意力本质是加权求和”这句话,是理解一切的总纲。假设“销冠”这个词的 Q 与“经验”这个词的 K 高度匹配,那么在最终汇总时,“经验”的 V 就会被赋予更大的权重。加权求和意味着输出不是简单复制某个词,而是把上下文里所有相关信息按比例糅合到一起——就像你把三份档案的精华段落按 0.11、0.64、0.26 的比例剪贴成一份新汇报。这个比例,就是注意力权重。

回到故事里,你之所以能高效完成汇报,正是因为脑子里有一套清晰的流程:拿任务单、对标签、翻正文、按重要性拼装。Transformer 把这套流程压缩成几个矩阵运算,而 QKV 正是流程的起点——没有这三个角色,后面的所有计算都无从谈起。

线性变换:如何从X得到QKV

档案室有条铁律:员工不能拿着原始任务单直接进档案库,必须先去“文印室”把任务单、标签、正文各自印成标准格式的卡片。Transformer 也一样:输入 X 不能直接被拿去打分,它要先经过三个不同的线性变换——分别乘以三个权重矩阵 W_Q、W_K、W_V,才能变成 Q、K、V。打个比方,W_Q 是“任务单打印机”,W_K 是“标签打印机”,W_V 是“正文复印机”。

为什么非要变换,直接用 X 不行吗?因为 X 携带的信息是“混合杂糅”的,同一个向量既要当提问者又要当回答者,角色会打架。线性变换的本质是把每个词的原始向量投影到三个不同的“语义空间”里:Q 空间专门存放“我在找什么”,K 空间专门存放“我能回答什么”,V 空间专门存放“我实际提供什么”。这样角色分离后,点积打分才有意义。

公式非常简洁,就是三个矩阵乘法:

文印室的比喻还能帮你理解“学习”:刚入职时打印机是初始随机设置的,打出来的任务单、标签、正文都一塌糊涂;但经过上万份档案的练习(训练),打印机逐渐调校到最佳状态——知道任务单该侧重哪些关键词、标签该怎么概括内容、正文该保留哪些细节。训练结束后,这三台打印机就是训练好的 W_Q、W_K、W_V。

Q=XWQ,K=XWK,V=XWVQ = XW_Q,\quad K = XW_K,\quad V = XW_V
输入的每一行都是一个词向量,分别乘上三个“角色打印机”权重矩阵,就得到各自的 Q/K/V 矩阵。W 的参数来自训练,是模型“学会的做事偏好”。
  1. X 是什么X 是所有词向量堆成的矩阵,有 n 行(n 个词)、d 列(每个词的维度)。
    X∈Rn×dX \in \mathbb{R}^{n \times d}
  2. W 是什么W_Q、W_K、W_V 是三个形状为 d×d 的可学习权重矩阵。所谓“可学习”,就是训练时不断调整的旋钮。
    WQ,WK,WV∈Rd×dW_Q, W_K, W_V \in \mathbb{R}^{d \times d}
  3. 矩阵乘法做了什么X 的每一行(一个词向量)与 W 的每一列做内积,得到新向量的一个分量。这等价于把每个词向量在 W 张成的空间里重新定向。
    (XW)ij=∑k=1dXikWkj(XW)_{ij} = \sum_{k=1}^{d} X_{ik} W_{kj}

缩放点积:打分、归一化与加权求和

现在你手上有三套卡片:任务单 Q、标签 K、正文 V。接下来是核心动作——为每份档案打分。你会把任务单上的每一个需求点和档案标签的每一个描述点“逐项比对”,累加出一个总契合度。在数学上,这个逐项比对累加叫点积(内积):两个向量对应位置相乘再求和,数值越大代表方向越一致、越相关。

不过你不是只查一份档案,而是要把任务单和整排档案的标签都比对一遍。把所有 Q 和所有 K 两两打分,就得到一张“Q 对 K 的契合度矩阵”。在 Transformer 中,一次矩阵乘法 QKᵀ 就能完成全部两两比对。得到分数后还不能直接用——分数有高有低、可能为负,需要先经过 softmax 归一化,把每一行的分数变成“和为 1、且都是正数”的权重,再拿着这些权重去翻阅正文 V。最终每个词的输出,就是所有 V 的加权求和。

完整公式如下:

回到找资料的故事:softmax 就是把“粗分数”换算成“优先级百分比”。三份档案原始得分是 1.2、3.0、2.1,听起来差距不大;但经过指数放大和归一化,实际提取比例变成大约 0.11、0.64、0.26——第二份档案成了绝对主角。这就是注意力“聚焦”的威力:它能让模型在长文本里果断地重点看某几个词。

Attention(Q,K,V)=softmax(QK⊤dk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V
这个公式是自注意力的总开关:先算 Q 与 K 的契合度,缩一下尺度,归一化成权重,最后用权重把 V 汇总成一个新向量。
  1. QKᵀ 点积打分Q 与 K 的转置相乘,得到一个 n×n 的矩阵,第 i 行第 j 列就是“词 i 的词向量与词 j 的标签向量”的点积。
    (QK⊤)ij=qi⋅kj=∑l=1dkqi,l kj,l(QK^\top)_{ij} = q_i \cdot k_j = \sum_{l=1}^{d_k} q_{i,l}\, k_{j,l}
  2. 除以 √d_k 缩放每个分数除以√d_k,防止维度越大分数越虚高(下一节细讲)。
    QK⊤dk\frac{QK^\top}{\sqrt{d_k}}
  3. softmax 归一化对每一行做指数归一,让所有分数变成正数且之和为 1,这就是“注意力权重”。
    softmax(z)i=ezi∑j=1nezj\text{softmax}(z)_i = \frac{e^{z_i}}{\sum_{j=1}^{n} e^{z_j}}
  4. 加权求和用归一化权重对 V 的每一行做加权组合,得到输出向量。
    outputi=∑j=1naij vj\text{output}_i = \sum_{j=1}^{n} a_{ij}\, v_j

缩放因子:为什么除以根号dk

细心的人会问:QKᵀ 算完分数直接 softmax 不行吗?为什么要多此一举除以 √d_k?这要从 softmax 的“脾气”说起。softmax 里有指数运算,如果输入分数太大或太小,指数会迅速推向极端——比如分数是 10,e¹⁰ 已经超过两万;如果一堆分数都很大,softmax 输出的分布会变得非常尖锐:最大值接近 1,其余接近 0。这种状态叫“softmax 饱和”,它的梯度趋近于零,模型几乎学不动。

什么情况下分数会变得很大?点积是 d_k 个乘积项相加。假设每个乘积项正负波动,但 d_k 越大,累加结果的浮动范围就越大——就像音响的音量旋钮,旋钮刻度(维度)越多,音量能飙到的峰值越高。这会导致分数方差随 d_k 线性增长。为了让分数回到“舒适音区”,我们需要除以 √d_k 来做音量校正。

为什么是 √d_k 而不是 d_k?因为点积的方差恰好等于 d_k,而标准差是 √d_k——除以标准差,才能把方差拉回 1 左右。数学上可以这样看:

用音量旋钮来理解:假设每个频道的音量在 -1 到 1 之间抖动,30 个频道叠加,峰值音量可能窜到 5;300 个频道叠加,峰值可能到 15。如果你不调音量,softmax 直接过载。除以 √d_k 就是“按频道数的平方根调音”,让 30 个频道和 300 个频道的系统听起来音量差不多。这样无论维度多大,softmax 都工作在敏感区间,梯度信号才能顺畅回传。

Var(q⋅k)=∑i=1dkVar(qiki)=dk\mathrm{Var}(q \cdot k) = \sum_{i=1}^{d_k} \mathrm{Var}(q_i k_i) = d_k
在 q、k 各分量独立且方差为 1 的假设下,d_k 个乘积项的方差相加,得到总方差 d_k。除以 √d_k 相当于把标准差压回 1,分数分布就不会随维度增长而失控。
  1. 假设基础假定 q 和 k 的每个分量独立,期望为 0、方差为 1,这样每个乘积项围绕 0 波动。
    E[qi]=E[ki]=0,Var(qi)=Var(ki)=1\mathbb{E}[q_i] = \mathbb{E}[k_i] = 0, \quad \mathrm{Var}(q_i) = \mathrm{Var}(k_i) = 1
  2. 单项方差独立随机变量乘积的方差,等于各自方差的乘积,所以每个乘积项方差为 1。
    Var(qiki)=Var(qi) Var(ki)=1\mathrm{Var}(q_i k_i) = \mathrm{Var}(q_i)\, \mathrm{Var}(k_i) = 1
  3. 总方差累加d_k 个独立项的方差相加,得到点积总方差 d_k。
    Var(∑i=1dkqiki)=∑i=1dk1=dk\mathrm{Var}\left(\sum_{i=1}^{d_k} q_i k_i\right) = \sum_{i=1}^{d_k} 1 = d_k

多头注意力:八位专家并行协作

单人格找资料有个致命弱点:视角单一。老板只让你找“值得推广的经验”,你可能满脑子都是营销方案,忽略了财务风险。公司于是改派一个八人专家团:营销专家拿“营销”任务单、财务专家拿“风险”任务单、HR 专家拿“团队”任务单……大家并行进入档案室,各找各的,最后把八份子汇报拼成一份总汇报。这就是多头注意力:与其用一个 Q 空间,不如拆成 h 个低维子空间并行处理。

Transformer 的具体做法是:把 d 维的 Q/K/V 各切成 h 份,每份维度 d_h = d/h,对应一个“头”。每个头拥有自己独立的小权重矩阵 W_i^Q、W_i^K、W_i^V,在自己的低维空间里做一次完整的缩放点积注意力。因为维度变低了,每个头只能“看到”输入的一部分特征——这反而逼着不同的头去学习不同的关注模式:有的头专门关注代词指代,有的头关注语法依赖,有的头关注词义相关性。

计算完 h 个头的输出后,需要把它们合成一份总汇报。做法是把所有头的输出在特征维度上拼接(Concat)起来,然后再乘一个输出投影矩阵 W^O 做融合。

专家团的妙处在于“分而治之,合而用之”。每个头只负责一个侧面,训练时梯度会自然引导各头分化;拼接融合又保证最终输出仍然携带完整信息。想象一下,如果八位专家的结论直接用简单平均,那“财务风险”的声音会被“营销方案”稀释掉;而拼接+投影的方式,相当于在汇总会上给每位专家一个独立席位,再由一位总编决定每个观点占多少版面——信息保留度远高于平均。

headi=Attention(QWiQ,KWiK,VWiV)\text{head}_i = \text{Attention}(QW_i^Q, KW_i^K, VW_i^V)
MultiHead(Q,K,V)=Concat(head1,…,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h) W^O
每个头是低维子空间里的独立注意力专家,各算各的关注重点;最后把 h 份结果拼接成 d 维,再过一层输出投影,让信息在头之间流通融合。
  1. 低维投影每个头把 d 维的 Q/K/V 各自投影到 d_h 维,d_h = d/h,所以每个头只处理一部分特征。
    WiQ,WiK,WiV∈Rd×dh,dh=d/hW_i^Q, W_i^K, W_i^V \in \mathbb{R}^{d \times d_h}, \quad d_h = d/h
  2. 独立注意力每个头在自己的子空间里执行完整的缩放点积注意力,用的是头自己的缩放因子 √d_h。
    headi=softmax(QWiQ(KWiK)⊤dh)VWiV\text{head}_i = \text{softmax}\left(\frac{QW_i^Q (KW_i^K)^\top}{\sqrt{d_h}}\right) VW_i^V
  3. 拼接把 h 个头的输出按列拼接起来,恢复成 n×d 的形状。
    Concat(head1,…,headh)∈Rn×d\text{Concat}(\text{head}_1, \ldots, \text{head}_h) \in \mathbb{R}^{n \times d}
  4. 输出投影拼接后的矩阵再乘 W^O,完成跨头信息融合,得到多头注意力的最终输出。
    MultiHead(Q,K,V)=Concat(head1,…,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \ldots, \text{head}_h) W^O

权重可视化:查看注意力热度排行榜

档案室工作结束后,你手头有一张“档案引用热度排行榜”:每份档案被引用了百分之多少,一目了然。Transformer 里这张排行榜就是注意力权重矩阵——前面算出来的 softmax 结果,就是 n×n 的矩阵 A,A[i][j] 表示词 i 在生成自己的表示时,给了词 j 多少注意力。把矩阵画成热力图,深色代表高权重,浅色代表低权重,模型“在看什么”立刻无所遁形。

为什么这对从业者特别有用?因为神经网络通常是个黑盒,但注意力权重是少有的、可以“直接读出来”的内部信号。训练一个翻译模型时,你可以画“英文词对中文词”的注意力热力图,如果绝大多数对齐都落在对角线上,说明模型学得很正;如果某个词疯狂关注句号、逗号或填充符(padding token),说明注意力可能被噪声污染了。

几种常见的可视化模式值得记住:对角线型——每个词主要关注自己,常见于浅层网络,表示模型还在“做局部加工”;带状对角线型——关注相邻词,说明模型在学局部语法依赖;远端聚集型——某个词跨越大段距离去关注另一个词,这往往是长程依赖的关键信号。如果你发现模型在关键代词的权重乱成一团,就可以怀疑是位置编码或训练数据出了问题。

调试时,你可以把注意力头逐个画出来对比:8 个头里,哪几个头语法性强、哪几个头语义性强、哪几个头几乎退化成均匀分布(所有词权重一样)——后者意味着该头没学到东西,可以考虑剪枝或加大正则。热力图还能帮你验证缩放因子有没有生效:如果所有分数都集中在 0.99 以上,说明 softmax 已经饱和,可能是缩放不够,需要检查实现里的 √d_k 是否写对了。

回到档案室的比喻:老板看完你的“引用排行榜”,一眼就能发现你过度依赖某一档案、忽视了另一份同等重要的资料。注意力可视化就是给 AI 从业者一面“照妖镜”——模型有没有偷懒、有没有走偏、有没有学到反直觉的关联,画一张热力图,心里就有底了。

计算优化:档案馆的提速之道

随着业务扩张,档案室从几百份变成了几百万份。这时你发现一个可怕的问题:每次拿新任务单查资料,都要和所有档案的标签比对一遍,哪怕你上一分钟刚查过同一个档案室。自注意力也有同样的困境:对于长度为 n 的序列,QKᵀ 矩阵是 n×n 的——这意味着要算 n² 个点积,计算量和内存开销都随序列长度平方级增长。这也是为什么 Transformer 处理长文档时又慢又费显存。

复杂度可以这样估算:QKᵀ 需要 n² 次点积,每次点积要 d 次乘法,所以主要计算量是 O(n²·d)。再加上 softmax 后的 attention 矩阵与 V 的乘法同样是 n²·d,整个自注意力的乘法运算量大约在 O(n²·d) 量级。当 n 从 512 涨到 4096,计算量涨了近 64 倍——这就是为什么各大模型都在想方设法优化注意力。

两种最实用的优化手段,正好呼应你查资料的痛点。第一是因果掩码:生成文本时,每个词只能看它左边的词、不能看右边的词(否则就作弊了)。实现方式很简单,把矩阵右上角的所有分数设成 -∞,softmax 后这些位置的权重自动变成 0。就像档案室的规矩:只能引用已经归档的早期档案,未来的档案还没归档,不许偷看。第二是KV 缓存:推理时每次只生成一个新词,但新词要和历史上所有词的 K、V 做注意力计算。与其每次把历史 K/V 重新算一遍,不如存到缓存里直接复用——这就是 KV Cache,能让长文本生成提速数倍。

其实这两种优化都可以在档案室故事里找到影子:因果掩码是“不能看未来”的制度约束,KV 缓存是“把看过的标签和正文装进口袋”的聪明做法。理解 QKV 矩阵计算,不只是为了看懂公式,更是为了在实际工程里知道瓶颈在哪、优化从何入手——当你看到推理服务显存告急时,脑子里应该立刻浮现出“n² 的内存占用”和“KV Cache 命中率”这两件事。

AI 应用场景

场景一:训练大模型时用注意力热力图排查 loss 不降

阶段:模型训练与调试

解决的问题:训练 10B 参数模型时 loss 长时间不下降,传统做法是盲调学习率或数据比例,效率极低。利用注意力权重可视化,可以直接检查模型内部是否把注意力浪费在无效 token 上,从而精准定位问题。

具体案例:某团队训练指令微调模型,发现 loss 震荡。绘制某层注意力热力图后,发现大量注意力集中在对齐用的 padding token 上——原因是代码里漏传了 attention_mask,模型把“空位”也当成有效信息在加权。补上掩码后,loss 立刻回落。QKV 的可解释性在这里成了调试的“听诊器”。

场景二:用注意力权重做抽取式摘要

阶段:推理与应用开发

解决的问题:给长篇财报生成摘要时,抽取式方法传统上靠词频统计,抓不住语义重点。利用自注意力的权重分布,可以直接找出“被其他 token 关注最多”的句子,把它们作为候选摘要句,质量远高于词频法。

具体案例:对一份 8000 字的财报跑一遍自注意力编码,统计每个句子获得的平均注意力权重,排名前三的句子恰好覆盖了营收、利润、风险三项核心信息。RNN 时代需要专门训练抽取模型,而现在一次前向传播的注意力矩阵就能当“重要性打分器”用。

场景三:推理引擎用 KV Cache 加速对话

阶段:模型推理与性能优化

解决的问题:对话场景每轮都要重新计算所有 token 的 K/V,传统实现响应时延随对话轮次线性增长。用 KV Cache 缓存历史 K/V 后,每轮只算新 token 的增量,大幅降低时延。

具体案例:某对话服务在接入 KV Cache 后,20 轮长对话的平均首字时延从 680ms 降到 210ms,显存占用虽然增加(因为要存 K/V),但换来了 3 倍左右的吞吐提升。工程上的本质就是“算过的标签和正文不要扔,留着下次直接用”。

Python 演示

python46 行
"""迷你自注意力:演示 QKV 矩阵计算与缩放点积"""import numpy as np  def softmax(x, axis=-1):    # 数值稳定的 softmax:先减最大值再算指数    e = np.exp(x - x.max(axis=axis, keepdims=True))    return e / e.sum(axis=axis, keepdims=True)  def linear_transform(X, W):    # 线性变换:输入矩阵乘权重矩阵,得到 Q/K/V    return X @ W  def scaled_dot_product_attention(Q, K, V):    # 缩放点积注意力:打分、缩放、归一化、加权求和    d_k = Q.shape[-1]    scores = Q @ K.T    scaled = scores / np.sqrt(d_k)    weights = softmax(scaled)    out = weights @ V    return out, weights  def main():    np.random.seed(42)    n, d = 4, 8  # 4 个 token,每个 8 维    X = np.random.randn(n, d)    W_Q = np.random.randn(d, d)    W_K = np.random.randn(d, d)    W_V = np.random.randn(d, d)     Q = linear_transform(X, W_Q)    K = linear_transform(X, W_K)    V = linear_transform(X, W_V)    print("Q shape:", Q.shape, "K shape:", K.shape, "V shape:", V.shape)     out, attn = scaled_dot_product_attention(Q, K, V)    print("attention weights:\n", np.round(attn, 3))    print("每行权重之和:", np.round(attn.sum(axis=-1), 3))    print("output shape:", out.shape)  if __name__ == "__main__":    main()
目的:用纯 NumPy 实现一个迷你自注意力层,完整走一遍“线性变换得到 QKV → 点积打分 → 除以√d_k → softmax → 加权求和”的流程。
  1. X @ W矩阵乘法实现线性变换,X 的每一行都乘同一个权重矩阵,得到 Q/K/V 中的一员。
  2. scores = Q @ K.TQ 和 K 的转置相乘,得到 n×n 的原始相关度分数矩阵。
  3. scaled = scores / np.sqrt(d_k)除以缩放的维度平方根,防止分数随维度增大而虚高。
  4. softmax(scaled)对每一行做指数归一化,得到和为 1 的注意力权重。
  5. weights @ V用归一化权重对 V 做加权求和,得到最终输出。
  6. attn.sum(axis=-1)每行权重之和应该全为 1,用来验证 softmax 的正确性。

常见误区

误区“Q、K、V 不就是输入的三个副本吗?直接用 X 乘三份不就行了,为什么要单独学习权重?”

正解Q、K、V 是输入 X 分别经过三个不同的线性变换得到的三个“视角”。就像任务单、标签、正文虽然都源于同一份原始报告,但它们是三种不同用途的加工产物。直接用 X 当 Q/K/V,会让“提问者”和“回答者”复用同一套表征,角色混淆,注意力打分就失去了意义。可学习的 W_Q、W_K、W_V 让模型自己决定这三个视角各自该关注什么。

为何常见:因为注意力公式里 Q、K、V 的符号出现太频繁,初学者容易以为它们是输入的直接别名,忽略了隐藏在公式前的三个矩阵乘法。

误区“除以 √d_k 不就是个缩放吗?调大一点调小一点应该无所谓,反正 softmax 都能归一化。”

正解√d_k 不是拍脑袋定的正则项,而是有明确数学动机的——它把点积的方差从 d_k 拉回 1,保证 softmax 不会进入饱和区。如果不缩放(或缩错),大维度的分数会非常分散,softmax 输出趋向 one-hot,梯度趋近于零,模型训练会停滞或震荡。它是整个注意力机制数值稳定性的基石,不是可有可无的旋钮。

为何常见:softmax 的输入输出看起来都是“比例”,容易让人以为中间的任何缩放都会被归一化“吸收”,忽略了指数函数的敏感性和梯度问题。

误区“多头注意力就是训练好几个注意力模型,然后把它们的结果平均一下,提高稳定性。”

正解多头不是多个独立模型,而是同一个模型内部把特征空间切成 h 份,每个头只在低维子空间里计算;输出也不是平均,而是按特征维度拼接后乘输出投影 W^O 融合。平均会丢失每个头学到的独特信息,拼接+投影则保留每个头的独立贡献再让模型决定如何组合。这更像专家团各自写子报告、总编汇总,而不是把大家的结论简单求均值。

为何常见:看到“并行计算 h 个注意力”自然联想到集成学习里的多模型平均,但从矩阵形状看,每个头只是整体计算图的一个分支,并非独立的模型实例。

误区“注意力权重高的词,一定是模型认为最重要的词,直接用它做关键词提取准没错。”

正解注意力权重衡量的是“在当前上下文里,这个词对另一个词的加权贡献”,并不等价于全局重要性。一个权重高的词可能只是句法必需品(如介词“的”),而真正承载语义的名词可能权重反而低。此外,多头注意力里不同头关注不同侧面,单个头的权重分布不能代表模型整体意图。做关键词提取或摘要时,需要聚合多层多头的注意力分布,并结合任务场景看,不能直接拿单层热力图下结论。

为何常见:热力图直观展示权重,人眼天然把“深色”理解为“重要”,但注意力是一种相对关系度量,不是绝对重要性打分器。

面试题

Q1. 在 Self-Attention 中,K 的全称和含义是?

单选题 · easy

  • A.Key,内容的标签← 正确答案
  • B.Value,正文的内容
  • C.Query,查询的需求
  • D.Weight,可学的参数

答案:A。K 是 Key,即“内容标签”,它和 Query 做点积来匹配相关度;Value 是实际被加权的内容,Query 是查询需求。Weight 是线性变换里的矩阵,不是 QKV 之一。类比档案室的标签,K 决定“这份档案能不能回答你的问题”。

Q2. Q、K、V 矩阵是通过什么方式得到的?

单选题 · easy

  • A.输入X分别乘三个权重← 正确答案
  • B.输入X做三次复制粘贴
  • C.输入X经过三个激活函数
  • D.输入X直接拆分三部分

答案:A。Q=XW_Q、K=XW_K、V=XW_V,是输入分别与三个可学习权重矩阵做线性变换。复制粘贴得到的是完全相同的结果,无法区分角色;拆分则不引入新参数,模型表达能力受限。只有线性变换才能让 Q/K/V 各司其职。

Q3. softmax 在注意力机制中的主要作用是什么?

单选题 · easy

  • A.把分数归一成概率← 正确答案
  • B.把向量维度变低
  • C.把负分数变成正值
  • D.把矩阵转置成行

答案:A。softmax 把原始点积分数转换成和为 1 的正权重,也就是“优先级百分比”。把负分数变正只是它的副作用,不是目的;降低维度和转置都不是 softmax 的功能。类比档案室里把打分换算成引用占比。

Q4. 缩放点积注意力中,QKᵀ 得到一个 n×n 矩阵,它表示什么?

单选题 · mid

  • A.每对 token 的相关程度← 正确答案
  • B.每个 token 的模长大小
  • C.输入矩阵的协方差
  • D.输出矩阵的投影方向

答案:A。QKᵀ 的第 i 行第 j 列是 q_i 与 k_j 的点积,数值越大代表两个 token 越相关,这是注意力的“打分表”。协方差是统计概念,模长是单个向量的属性,都与“两两相关度打分”无关。

Q5. 如果 d_model=512,h=8,每个注意力头的维度 d_h 是多少?

单选题 · mid

  • A.头维度为 64← 正确答案
  • B.头维度为 32
  • C.头维度为 128
  • D.头维度为 512

答案:A。d_h = d_model / h = 512 / 8 = 64。多头注意力把总维度均分给每个头,让每个头在低维子空间并行计算。这是 Transformer 原文的标准配置,也是面试中常见的快速计算题。

Q6. 多头注意力最后如何组合各个头的输出?

单选题 · mid

  • A.拼接后经输出投影融合← 正确答案
  • B.简单相加再求平均值
  • C.只保留得分最高的头
  • D.按训练轮数动态加权

答案:A。各头输出先按特征维度拼接(Concat),再乘输出投影矩阵 W^O 完成融合。平均值会稀释每个头的独特信息;只保留最高分或动态加权都不是 Transformer 的实现方式。类比专家团子报告由总编汇总而非简单折中。

Q7. 对于 n 个 token、维度 d 的输入,QKᵀ 的结果矩阵形状是?

单选题 · mid

  • A.形状为 n 乘 n← 正确答案
  • B.形状为 d 乘 d
  • C.形状为 n 乘 d
  • D.形状为 d 乘 n

答案:A。Q 是 n×d,Kᵀ 是 d×n,两者相乘得到 n×n。这个矩阵的第 i 行是“第 i 个 token 对所有 token 的注意力分数”。维度 d 在点积时被约掉,所以结果只和 token 数量有关。

Q8. 为什么点积分数要除以 √d_k 而不是直接除以 d_k?

单选题 · hard

  • A.为标准差也就是方差开方← 正确答案
  • B.为了让矩阵维度变少
  • C.为了降低计算复杂度
  • D.为了让 softmax 失效

答案:A。点积方差为 d_k,标准差为 √d_k,除以标准差才能把方差拉回 1。除以 d_k 会把方差压到 1/d_k,过度压缩同样损害表达能力。缩放与维度和计算量无关,目的是防止 softmax 饱和、稳定梯度。

Q9. 注意力权重可视化可以帮助调试哪些问题?

多选题 · mid

  • A.检查模型是否在关注 padding← 正确答案
  • B.观察不同头关注的语法语义← 正确答案
  • C.定位梯度消失的具体层
  • D.直接求出损失函数的值

答案:AB。热力图能直观显示注意力是否落在无意义的 padding token 上(A),也能看出每个头学到的模式(B)。梯度消失需要通过反向传播的梯度统计来定位,损失函数值靠前向计算,两者都无法从权重矩阵直接读出。

Q10. 推理时使用 KV Cache 能带来哪些收益?

多选题 · hard

  • A.避免重复计算历史K/V← 正确答案
  • B.显著降低增量计算量← 正确答案
  • C.提高注意力权重精度
  • D.让 softmax 结果稳定

答案:AB。KV Cache 把历史 token 的 K、V 存起来,新 token 只需计算自身的 Q 并复用缓存,省掉了对历史的重复矩阵运算(A、B)。权重精度和 softmax 稳定性由浮点精度与缩放因子决定,与是否使用缓存无关。