第7章 Multi-Head Attention
本章目标:
理解为什么需要多个 Head,每个 Head 学到了什么,以及完整的 Tensor Shape 推导。
7.1 为什么不是一个 Head?
假设句子:
text
The bank can guarantee deposits will eventually cover future tuition costs.
bank 这个词有两个含义:
- 银行(金融机构)
- 河岸
一个 Head 可能只关注到 deposits(存款),认为 bank 是银行。
但如果有多个 Head,不同的 Head 可以关注不同的方面:
- Head 1:关注语法关系(
bank是主语) - Head 2:关注语义关系(
bank和deposits相关) - Head 3:关注指代关系(
it指向谁)
#mermaid-svg-gaOxmAZ1voWJTTIl{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gaOxmAZ1voWJTTIl .error-icon{fill:#552222;}#mermaid-svg-gaOxmAZ1voWJTTIl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gaOxmAZ1voWJTTIl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gaOxmAZ1voWJTTIl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gaOxmAZ1voWJTTIl .marker.cross{stroke:#333333;}#mermaid-svg-gaOxmAZ1voWJTTIl svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gaOxmAZ1voWJTTIl p{margin:0;}#mermaid-svg-gaOxmAZ1voWJTTIl .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gaOxmAZ1voWJTTIl .cluster-label text{fill:#333;}#mermaid-svg-gaOxmAZ1voWJTTIl .cluster-label span{color:#333;}#mermaid-svg-gaOxmAZ1voWJTTIl .cluster-label span p{background-color:transparent;}#mermaid-svg-gaOxmAZ1voWJTTIl .label text,#mermaid-svg-gaOxmAZ1voWJTTIl span{fill:#333;color:#333;}#mermaid-svg-gaOxmAZ1voWJTTIl .node rect,#mermaid-svg-gaOxmAZ1voWJTTIl .node circle,#mermaid-svg-gaOxmAZ1voWJTTIl .node ellipse,#mermaid-svg-gaOxmAZ1voWJTTIl .node polygon,#mermaid-svg-gaOxmAZ1voWJTTIl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gaOxmAZ1voWJTTIl .rough-node .label text,#mermaid-svg-gaOxmAZ1voWJTTIl .node .label text,#mermaid-svg-gaOxmAZ1voWJTTIl .image-shape .label,#mermaid-svg-gaOxmAZ1voWJTTIl .icon-shape .label{text-anchor:middle;}#mermaid-svg-gaOxmAZ1voWJTTIl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gaOxmAZ1voWJTTIl .rough-node .label,#mermaid-svg-gaOxmAZ1voWJTTIl .node .label,#mermaid-svg-gaOxmAZ1voWJTTIl .image-shape .label,#mermaid-svg-gaOxmAZ1voWJTTIl .icon-shape .label{text-align:center;}#mermaid-svg-gaOxmAZ1voWJTTIl .node.clickable{cursor:pointer;}#mermaid-svg-gaOxmAZ1voWJTTIl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gaOxmAZ1voWJTTIl .arrowheadPath{fill:#333333;}#mermaid-svg-gaOxmAZ1voWJTTIl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gaOxmAZ1voWJTTIl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gaOxmAZ1voWJTTIl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gaOxmAZ1voWJTTIl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gaOxmAZ1voWJTTIl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gaOxmAZ1voWJTTIl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gaOxmAZ1voWJTTIl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gaOxmAZ1voWJTTIl .cluster text{fill:#333;}#mermaid-svg-gaOxmAZ1voWJTTIl .cluster span{color:#333;}#mermaid-svg-gaOxmAZ1voWJTTIl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gaOxmAZ1voWJTTIl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gaOxmAZ1voWJTTIl rect.text{fill:none;stroke-width:0;}#mermaid-svg-gaOxmAZ1voWJTTIl .icon-shape,#mermaid-svg-gaOxmAZ1voWJTTIl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gaOxmAZ1voWJTTIl .icon-shape p,#mermaid-svg-gaOxmAZ1voWJTTIl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gaOxmAZ1voWJTTIl .icon-shape .label rect,#mermaid-svg-gaOxmAZ1voWJTTIl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gaOxmAZ1voWJTTIl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gaOxmAZ1voWJTTIl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gaOxmAZ1voWJTTIl :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入 Token
Head 1
语法关系
Head 2
语义关系
Head 3
指代关系
Head 4
位置关系
Concat
Output Projection
输出
7.1.1 为什么不同 Head 会学到不同东西?
一个自然的疑问:代码里没有写 head1 = 金融专家,那模型怎么知道让不同 Head 学不同东西?
答案是:训练过程中自然分化(Emergent Specialization)。
训练刚开始时,所有 Head 都是随机初始化的,它们可能做着类似的事。但训练几百万步后:
- 假设 Head1 已经学会了"金融关系"(bank→loan)
- 如果 Head2 也学同样的关系,它对降低 Loss 没有帮助(信息冗余)
- 梯度会驱使 Head2 去寻找其他有价值的模式(比如语法关系)
最终,每个 Head 都会找到自己的"专业领域"------不是人为规定的,而是 Loss 驱动的。
7.1.2 为什么一个 512 维 Head 不如 8 个 64 维 Head?
直觉上,一个 512 维的 Head 参数量和 8 个 64 维的 Head 一样。为什么后者更好?
类比:一个全科医生 vs 八个专科医生。全科医生什么都要兼顾,结果什么都学不精;专科医生各自深耕一个方向,最后会诊时效果远好于一个人。
一个 512 维 Head 需要同时学习金融关系、语法关系、时间关系、指代关系......它倾向于学出一个"折中方案",每种关系都学得不够好。而 8 个 Head 可以各自专注一种模式,组合起来覆盖更丰富的语言现象。
7.1.3 ⚠️ 常见误解:Head 不是把 Embedding "切"成8份
很多人以为 Multi-Head 是这样的:
text
❌ 错误理解:
bank 的 512 维向量
→ 前64维给 Head1
→ 第65-128维给 Head2
→ ...
→ 最后64维给 Head8
这是错的。 如果这样切,每个 Head 只能看到原始信息的 1/8。
真正的做法是:每个 Head 都看到完整的 512 维输入,用自己独立的参数矩阵投影到 64 维。
text
✅ 正确理解:
bank 的 512 维向量
→ Head1 用 W₁[512,64] 投影 → 得到64维(混合了所有512维的信息)
→ Head2 用 W₂[512,64] 投影 → 得到64维(混合方式不同)
→ ...
→ Head8 用 W₈[512,64] 投影 → 得到64维
每个 Head 输出的 64 维中,每一个值都是原始 512 维的加权组合,不是截取的子集。这就是"投影(Projection)"的含义------降维但不丢信息。
📌 那源码里为什么看起来像"先算再切"? 为了GPU效率,代码把8个 Head 的参数拼成一个大矩阵
W_Q:[512,512],一次矩阵乘法得到[seq, 512],然后 reshape 成[seq, 8, 64]。数学上等价于8次独立投影,但计算更快。第7.4节的 Transpose 就是为此服务的。
7.2 Multi-Head Attention 的计算
7.2.1 每个 Head 独立计算
对于第 iii 个 Head:
headi=Attention(QWQi,KWKi,VWVi)\text{head}_i = \text{Attention}(Q W_Q^i, K W_K^i, V W_V^i)headi=Attention(QWQi,KWKi,VWVi)
其中:
- WQi∈Rdmodel×dkW_Q^i \in \mathbb{R}^{d_{model} \times d_k}WQi∈Rdmodel×dk
- WKi∈Rdmodel×dkW_K^i \in \mathbb{R}^{d_{model} \times d_k}WKi∈Rdmodel×dk
- WVi∈Rdmodel×dvW_V^i \in \mathbb{R}^{d_{model} \times d_v}WVi∈Rdmodel×dv
- dk=dv=dmodel/hd_k = d_v = d_{model} / hdk=dv=dmodel/h(h 是 Head 数量)
7.2.2 Concat 所有 Head
MultiHead(Q,K,V)=Concat(head1,...,headh)WO\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, ..., \text{head}_h) W_OMultiHead(Q,K,V)=Concat(head1,...,headh)WO
其中 WO∈Rh⋅dv×dmodelW_O \in \mathbb{R}^{h \cdot d_v \times d_{model}}WO∈Rh⋅dv×dmodel。
7.3 Tensor Shape 完整推导
以 d_model=512, num_heads=8, seq_len=5, batch=2 为例:
dk=dv=512/8=64d_k = d_v = 512 / 8 = 64dk=dv=512/8=64
#mermaid-svg-0EKEVTqfGj5Vg5vO{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0EKEVTqfGj5Vg5vO .error-icon{fill:#552222;}#mermaid-svg-0EKEVTqfGj5Vg5vO .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0EKEVTqfGj5Vg5vO .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .marker.cross{stroke:#333333;}#mermaid-svg-0EKEVTqfGj5Vg5vO svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0EKEVTqfGj5Vg5vO p{margin:0;}#mermaid-svg-0EKEVTqfGj5Vg5vO .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .cluster-label text{fill:#333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .cluster-label span{color:#333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .cluster-label span p{background-color:transparent;}#mermaid-svg-0EKEVTqfGj5Vg5vO .label text,#mermaid-svg-0EKEVTqfGj5Vg5vO span{fill:#333;color:#333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .node rect,#mermaid-svg-0EKEVTqfGj5Vg5vO .node circle,#mermaid-svg-0EKEVTqfGj5Vg5vO .node ellipse,#mermaid-svg-0EKEVTqfGj5Vg5vO .node polygon,#mermaid-svg-0EKEVTqfGj5Vg5vO .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0EKEVTqfGj5Vg5vO .rough-node .label text,#mermaid-svg-0EKEVTqfGj5Vg5vO .node .label text,#mermaid-svg-0EKEVTqfGj5Vg5vO .image-shape .label,#mermaid-svg-0EKEVTqfGj5Vg5vO .icon-shape .label{text-anchor:middle;}#mermaid-svg-0EKEVTqfGj5Vg5vO .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0EKEVTqfGj5Vg5vO .rough-node .label,#mermaid-svg-0EKEVTqfGj5Vg5vO .node .label,#mermaid-svg-0EKEVTqfGj5Vg5vO .image-shape .label,#mermaid-svg-0EKEVTqfGj5Vg5vO .icon-shape .label{text-align:center;}#mermaid-svg-0EKEVTqfGj5Vg5vO .node.clickable{cursor:pointer;}#mermaid-svg-0EKEVTqfGj5Vg5vO .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .arrowheadPath{fill:#333333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0EKEVTqfGj5Vg5vO .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0EKEVTqfGj5Vg5vO .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0EKEVTqfGj5Vg5vO .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0EKEVTqfGj5Vg5vO .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0EKEVTqfGj5Vg5vO .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0EKEVTqfGj5Vg5vO .cluster text{fill:#333;}#mermaid-svg-0EKEVTqfGj5Vg5vO .cluster span{color:#333;}#mermaid-svg-0EKEVTqfGj5Vg5vO div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0EKEVTqfGj5Vg5vO .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0EKEVTqfGj5Vg5vO rect.text{fill:none;stroke-width:0;}#mermaid-svg-0EKEVTqfGj5Vg5vO .icon-shape,#mermaid-svg-0EKEVTqfGj5Vg5vO .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0EKEVTqfGj5Vg5vO .icon-shape p,#mermaid-svg-0EKEVTqfGj5Vg5vO .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0EKEVTqfGj5Vg5vO .icon-shape .label rect,#mermaid-svg-0EKEVTqfGj5Vg5vO .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0EKEVTqfGj5Vg5vO .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0EKEVTqfGj5Vg5vO .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0EKEVTqfGj5Vg5vO :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入 X
2, 5, 512
线性变换 W_Q, W_K, W_V
各 512, 512
Q, K, V
各 2, 5, 512
Reshape: 分成8个Head
2, 5, 8, 64
Transpose
2, 8, 5, 64
每个Head独立计算Attention
2, 8, 5, 64
Transpose back
2, 5, 8, 64
Reshape: 合并Head
2, 5, 512
Output Projection W_O
512, 512
输出
2, 5, 512
7.4 为什么要 Transpose?
在实现中,我们把 Head 维度放到 batch 维度旁边,这样可以并行计算所有 Head:
text
[batch, seq, num_heads, d_k]
→ Transpose →
[batch, num_heads, seq, d_k]
这样,[batch * num_heads, seq, d_k] 可以作为一个大 batch 并行计算 Attention。
7.5 Output Projection 的作用
Concat 之后,维度是 [batch, seq, num_heads * d_v] = [batch, seq, d_model]。
Output Projection WOW_OWO 是一个可训练的 权重矩阵(和 WQW_QWQ、WKW_KWK、WVW_VWV 一样,通过反向传播学习),Shape 为 dmodel,dmodeld_{model}, d_{model}dmodel,dmodel(例如 512,512512, 512512,512)。它的作用是:
让不同 Head 的信息融合,而不是简单拼接。
注意:WOW_OWO 是 Multi-Head Attention 中的第四个 可训练矩阵,容易被忽略。完整的参数列表是:WQW_QWQ、WKW_KWK、WVW_VWV(各 Head 共同组成 dmodel,dmodeld_{model}, d_{model}dmodel,dmodel)加上这个 WO:dmodel,dmodelW_O: d_{model}, d_{model}WO:dmodel,dmodel。
为什么不能只 Concat 就结束?
Concat 只是把各个 Head 的结果排在一起:
text
Concat后的某个Token向量:
[Head1的64维 | Head2的64维 | ... | Head8的64维]
此时 Head1 的信息和 Head2 的信息还是互相隔离的------第 1~64 维只包含 Head1 的信息,第 65~128 维只包含 Head2 的信息,彼此之间没有任何交互。
例如 Head1 发现了"bank → loan(金融关系)",Head2 发现了"approved 是动作"。但"银行批准了 贷款"这个更完整的语义,需要把两个 Head 的发现组合起来才能得到。
如果直接输出 Concat 的结果,后续的 FFN 看到的只是"排在一起的独立信息",而不是"融合后的综合理解"。
WOW_OWO 如何实现跨 Head 融合?
WOW_OWO 的 Shape 是 512,512512, 512512,512(即 dmodel,dmodeld_{model}, d_{model}dmodel,dmodel)。它的每一个输出维度,都是所有 512 维(跨越所有 Head)的加权组合:
yi=wi1h1+wi2h2+⋯+wi,512h512y_i = w_{i1}h_1 + w_{i2}h_2 + \cdots + w_{i,512}h_{512}yi=wi1h1+wi2h2+⋯+wi,512h512
其中 h1,h2,...,h512h_1, h_2, \ldots, h_{512}h1,h2,...,h512 是 Concat 后的 512 维向量的各个分量(h1∼h64h_1 \sim h_{64}h1∼h64 来自 Head 1,h65∼h128h_{65} \sim h_{128}h65∼h128 来自 Head 2,依此类推),wijw_{ij}wij 是 WOW_OWO 矩阵第 iii 行第 jjj 列的权重。
关键在于:输出的每一个维度都同时使用了所有 Head 的信息。这就是"融合"。
用 4 维向量的具体例子理解
为了让这个过程完全透明,我们用一个简化例子:假设 dmodel=4d_{model}=4dmodel=4,2 个 Head,每个 Head 的输出是 2 维。
Step 1:各 Head 独立计算
假设对于 bank 这个 Token:
text
Head1 输出(关注金融关系):[5.0, 6.0]
Head2 输出(关注时间关系):[3.4, 4.3]
Step 2:Concat
text
Concat 后:[5.0, 6.0, 3.4, 4.3]
───────── ─────────
Head1 Head2
此时 Head1 和 Head2 的信息还是隔离的。
Step 3:乘以 WOW_OWO
WO=0.20.10.50.30.40.30.10.20.10.60.20.40.30.20.40.5W_O = \begin{bmatrix} 0.2 & 0.1 & 0.5 & 0.3 \\ 0.4 & 0.3 & 0.1 & 0.2 \\ 0.1 & 0.6 & 0.2 & 0.4 \\ 0.3 & 0.2 & 0.4 & 0.5 \end{bmatrix}WO= 0.20.40.10.30.10.30.60.20.50.10.20.40.30.20.40.5
计算输出第一维:
y1=0.2×5.0⏟Head1+0.1×6.0⏟Head1+0.5×3.4⏟Head2+0.3×4.3⏟Head2y_1 = 0.2 \times \underbrace{5.0}{Head1} + 0.1 \times \underbrace{6.0}{Head1} + 0.5 \times \underbrace{3.4}{Head2} + 0.3 \times \underbrace{4.3}{Head2}y1=0.2×Head1 5.0+0.1×Head1 6.0+0.5×Head2 3.4+0.3×Head2 4.3
y1=1.0+0.6+1.7+1.29=4.59y_1 = 1.0 + 0.6 + 1.7 + 1.29 = 4.59y1=1.0+0.6+1.7+1.29=4.59
注意:y1y_1y1 这一个数字同时融合了 Head1 的金融信息和 Head2 的时间信息。
同理,y2,y3,y4y_2, y_3, y_4y2,y3,y4 的每一个值也都融合了所有 Head 的信息------只是各自的融合权重不同(由 WOW_OWO 的不同行决定)。
text
Concat: [5.0, 6.0, 3.4, 4.3] ← Head 之间互相隔离
│
× W_O: [4, 4]
│
▼
输出: [4.59, ?, ?, ?] ← 每个维度都融合了所有 Head
本质 :Concat 后的向量中,前两维"只有金融信息",后两维"只有时间信息"。经过 WOW_OWO 之后,每一维都变成了"金融 + 时间"的加权混合。WOW_OWO 的权重通过训练学习到最佳的融合比例。
💡 类比 :8 个专科医生各自看完病人后,还需要一次会诊 (WOW_OWO)才能形成最终诊断。如果只是把 8 份报告装订在一起(Concat),没有人综合分析,那就不是真正的"融合"。WOW_OWO 就是那个阅读所有报告、综合出最终结论的主治医师。
7.6 不同 Head 学到了什么?
研究表明,不同的 Head 确实学到了不同的语言特征:
| Head 类型 | 关注内容 | 例子 |
|---|---|---|
| 语法 Head | 主谓宾关系 | cat → sat |
| 指代 Head | 代词指向 | it → animal |
| 位置 Head | 相邻词关系 | 关注前后几个词 |
| 语义 Head | 语义相关词 | bank → deposits |
7.7 TensorFlow 实现
python
import tensorflow as tf
class MultiHeadAttention(tf.keras.layers.Layer):
def __init__(self, d_model, num_heads):
super().__init__()
assert d_model % num_heads == 0
self.num_heads = num_heads
self.d_k = d_model // num_heads
self.W_Q = tf.keras.layers.Dense(d_model)
self.W_K = tf.keras.layers.Dense(d_model)
self.W_V = tf.keras.layers.Dense(d_model)
self.W_O = tf.keras.layers.Dense(d_model)
def split_heads(self, x, batch_size):
# x: [batch, seq, d_model]
# → [batch, seq, num_heads, d_k]
# → [batch, num_heads, seq, d_k]
x = tf.reshape(x, (batch_size, -1, self.num_heads, self.d_k))
return tf.transpose(x, perm=[0, 2, 1, 3])
def call(self, x, mask=None):
batch_size = tf.shape(x)[0]
Q = self.split_heads(self.W_Q(x), batch_size) # [batch, heads, seq, d_k]
K = self.split_heads(self.W_K(x), batch_size)
V = self.split_heads(self.W_V(x), batch_size)
# Scaled Dot-Product Attention
d_k = tf.cast(self.d_k, tf.float32)
scores = tf.matmul(Q, K, transpose_b=True) / tf.math.sqrt(d_k)
if mask is not None:
scores += (mask * -1e9)
weights = tf.nn.softmax(scores, axis=-1) # [batch, heads, seq, seq]
context = tf.matmul(weights, V) # [batch, heads, seq, d_k]
# 合并 Heads
context = tf.transpose(context, perm=[0, 2, 1, 3]) # [batch, seq, heads, d_k]
context = tf.reshape(context, (batch_size, -1, self.num_heads * self.d_k)) # [batch, seq, d_model]
output = self.W_O(context) # [batch, seq, d_model]
return output
# 测试
mha = MultiHeadAttention(d_model=512, num_heads=8)
x = tf.random.normal([2, 5, 512])
output = mha(x)
print(output.shape) # (2, 5, 512)
7.8 参数量分析
| 参数 | Shape | 参数量 |
|---|---|---|
| W_Q | d_model, d_model | d_model² |
| W_K | d_model, d_model | d_model² |
| W_V | d_model, d_model | d_model² |
| W_O | d_model, d_model | d_model² |
| 总计 | 4 × d_model² |
对于 d_model=512:4 × 512² = 1,048,576 ≈ 100万参数。
7.9 GQA(Grouped Query Attention)
现代 LLM(Llama 2、Qwen)使用 GQA 来减少 KV Cache 的内存占用:
#mermaid-svg-8UnmuphmzHJIZoHW{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8UnmuphmzHJIZoHW .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8UnmuphmzHJIZoHW .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8UnmuphmzHJIZoHW .error-icon{fill:#552222;}#mermaid-svg-8UnmuphmzHJIZoHW .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8UnmuphmzHJIZoHW .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8UnmuphmzHJIZoHW .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8UnmuphmzHJIZoHW .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8UnmuphmzHJIZoHW .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8UnmuphmzHJIZoHW .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8UnmuphmzHJIZoHW .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8UnmuphmzHJIZoHW .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8UnmuphmzHJIZoHW .marker.cross{stroke:#333333;}#mermaid-svg-8UnmuphmzHJIZoHW svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8UnmuphmzHJIZoHW p{margin:0;}#mermaid-svg-8UnmuphmzHJIZoHW .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8UnmuphmzHJIZoHW .cluster-label text{fill:#333;}#mermaid-svg-8UnmuphmzHJIZoHW .cluster-label span{color:#333;}#mermaid-svg-8UnmuphmzHJIZoHW .cluster-label span p{background-color:transparent;}#mermaid-svg-8UnmuphmzHJIZoHW .label text,#mermaid-svg-8UnmuphmzHJIZoHW span{fill:#333;color:#333;}#mermaid-svg-8UnmuphmzHJIZoHW .node rect,#mermaid-svg-8UnmuphmzHJIZoHW .node circle,#mermaid-svg-8UnmuphmzHJIZoHW .node ellipse,#mermaid-svg-8UnmuphmzHJIZoHW .node polygon,#mermaid-svg-8UnmuphmzHJIZoHW .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8UnmuphmzHJIZoHW .rough-node .label text,#mermaid-svg-8UnmuphmzHJIZoHW .node .label text,#mermaid-svg-8UnmuphmzHJIZoHW .image-shape .label,#mermaid-svg-8UnmuphmzHJIZoHW .icon-shape .label{text-anchor:middle;}#mermaid-svg-8UnmuphmzHJIZoHW .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8UnmuphmzHJIZoHW .rough-node .label,#mermaid-svg-8UnmuphmzHJIZoHW .node .label,#mermaid-svg-8UnmuphmzHJIZoHW .image-shape .label,#mermaid-svg-8UnmuphmzHJIZoHW .icon-shape .label{text-align:center;}#mermaid-svg-8UnmuphmzHJIZoHW .node.clickable{cursor:pointer;}#mermaid-svg-8UnmuphmzHJIZoHW .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8UnmuphmzHJIZoHW .arrowheadPath{fill:#333333;}#mermaid-svg-8UnmuphmzHJIZoHW .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8UnmuphmzHJIZoHW .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8UnmuphmzHJIZoHW .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8UnmuphmzHJIZoHW .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8UnmuphmzHJIZoHW .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8UnmuphmzHJIZoHW .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8UnmuphmzHJIZoHW .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8UnmuphmzHJIZoHW .cluster text{fill:#333;}#mermaid-svg-8UnmuphmzHJIZoHW .cluster span{color:#333;}#mermaid-svg-8UnmuphmzHJIZoHW div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8UnmuphmzHJIZoHW .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8UnmuphmzHJIZoHW rect.text{fill:none;stroke-width:0;}#mermaid-svg-8UnmuphmzHJIZoHW .icon-shape,#mermaid-svg-8UnmuphmzHJIZoHW .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8UnmuphmzHJIZoHW .icon-shape p,#mermaid-svg-8UnmuphmzHJIZoHW .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8UnmuphmzHJIZoHW .icon-shape .label rect,#mermaid-svg-8UnmuphmzHJIZoHW .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8UnmuphmzHJIZoHW .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8UnmuphmzHJIZoHW .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8UnmuphmzHJIZoHW :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} MQA 多查询注意力
Q: 8 heads
K: 1 head
V: 1 head
GQA 分组查询注意力
Q: 8 heads
K: 2 groups
V: 2 groups
MHA 标准多头注意力
Q: 8 heads
K: 8 heads
V: 8 heads
| 方案 | Q heads | K/V heads | KV Cache | 质量 |
|---|---|---|---|---|
| MHA | h | h | 大 | 最好 |
| GQA | h | g (g<h) | 中 | 接近MHA |
| MQA | h | 1 | 最小 | 略差 |
本章总结
#mermaid-svg-IrCw3KYDPWMfEuNo{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IrCw3KYDPWMfEuNo .error-icon{fill:#552222;}#mermaid-svg-IrCw3KYDPWMfEuNo .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IrCw3KYDPWMfEuNo .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IrCw3KYDPWMfEuNo .marker.cross{stroke:#333333;}#mermaid-svg-IrCw3KYDPWMfEuNo svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IrCw3KYDPWMfEuNo p{margin:0;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge{stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .section--1 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section--1 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section--1 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section--1 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section--1 text{fill:#ffffff;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth--1{stroke-width:17;}#mermaid-svg-IrCw3KYDPWMfEuNo .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-0 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-0 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-0 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-0 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-0 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-0{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-0{stroke-width:14;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-1 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-1 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-1 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-1 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-1 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-1{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-1{stroke-width:11;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 text{fill:#ffffff;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-2{stroke-width:8;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-3 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-3 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-3 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-3 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-3 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-3{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-3{stroke-width:5;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-4 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-4 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-4 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-4 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-4 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-4{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-4{stroke-width:2;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-5 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-5 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-5 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-5 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-5 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-5{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-5{stroke-width:-1;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-6 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-6 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-6 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-6 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-6 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-6{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-6{stroke-width:-4;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-7 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-7 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-7 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-7 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-7 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-7{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-7{stroke-width:-7;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-8 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-8 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-8 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-8 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-8 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-8{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-8{stroke-width:-10;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-9 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-9 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-9 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-9 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-9 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-9{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-9{stroke-width:-13;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-10 rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-10 path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-10 circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-10 polygon,#mermaid-svg-IrCw3KYDPWMfEuNo .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-10 text{fill:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .node-icon-10{font-size:40px;color:black;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .edge-depth-10{stroke-width:-16;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled circle,#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:lightgray;}#mermaid-svg-IrCw3KYDPWMfEuNo .disabled text{fill:#efefef;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-root rect,#mermaid-svg-IrCw3KYDPWMfEuNo .section-root path,#mermaid-svg-IrCw3KYDPWMfEuNo .section-root circle,#mermaid-svg-IrCw3KYDPWMfEuNo .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-IrCw3KYDPWMfEuNo .section-root text{fill:#ffffff;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-root span{color:#ffffff;}#mermaid-svg-IrCw3KYDPWMfEuNo .section-2 span{color:#ffffff;}#mermaid-svg-IrCw3KYDPWMfEuNo .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-IrCw3KYDPWMfEuNo .edge{fill:none;}#mermaid-svg-IrCw3KYDPWMfEuNo .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-IrCw3KYDPWMfEuNo :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Multi-Head Attention
多个Head
每个Head独立计算Attention
学习不同的语言特征
Concat
拼接所有Head的输出
维度: num_heads × d_k = d_model
Output Projection
融合不同Head的信息
W_O矩阵
Shape变化
输入: batch,seq,d_model
输出: batch,seq,d_model
本章常见误区
| 误区 | 正确理解 |
|---|---|
| ❌ Multi-Head 是把 Embedding 切成 8 份 | ✅ 每个 Head 都看完整输入,用独立参数投影到低维 |
| ❌ 第一个 Head 负责金融,第二个负责语法(人为指定) | ✅ 没有人指定,是训练中自然分化出来的 |
| ❌ Concat 后直接输出就行 | ✅ 还需要 WOW_OWO 融合不同 Head 的信息 |
| ❌ Head 越多越好 | ✅ Head 太多时每个 Head 维度太小(如4维),表达能力反而下降 |
| ❌ 多个 Head 的计算量是单 Head 的 8 倍 | ✅ 总参数量几乎一样(8个 512,64 ≈ 1个 512,512),且可并行 |
本章思考题
- 为什么 d_k = d_model / num_heads,而不是 d_k = d_model?
- 如果所有 Head 的权重矩阵都初始化为相同的值,会发生什么?
- GQA 为什么能减少 KV Cache?(提示:推理时需要缓存什么?)
- 增加 Head 数量一定会提升性能吗?为什么?
下一章预告
下一章我们讲 Feed Forward Network。
为什么每个 Block 都有 FFN?为什么维度要扩大四倍?GELU 和 ReLU 有什么区别?