手写 Multi-Head Attention。
未标记
考查重点:多头张量形状与掩码计算。Q/K/V投影后拆头,用QKᵀ/√dₖ加需要的mask并做softmax,再乘V、拼头和输出投影;核对形状与全掩码处理
本题目录
参考答案
核心回答
MHA先将输入分别投影为Q、K、V,拆成多个头;每个头计算softmax(QKᵀ/√d_k)V,再拼接各头并通过输出投影。下面用PyTorch实现batch-first自注意力,包含布尔注意力掩码和key padding掩码;为突出机制,省略dropout、KV缓存及残差/归一化。
PyTorch实现
输入x形状为[B,T,D],D必须能被头数H整除。这里两类掩码都约定True表示禁止关注:attn_mask为[T,T],key_padding_mask为[B,T]。每个query至少保留一个可见key,全遮蔽行明确报错。
import math
import torch
from torch import nn
class MultiHeadSelfAttention(nn.Module):
def __init__(self, d_model: int, num_heads: int):
super().__init__()
if d_model <= 0 or num_heads <= 0 or d_model % num_heads:
raise ValueError("d_model必须为正且能被正num_heads整除")
self.d_model = d_model
self.num_heads = num_heads
self.head_dim = d_model // num_heads
self.qkv = nn.Linear(d_model, 3 * d_model)
self.out = nn.Linear(d_model, d_model)
def forward(self, x, attn_mask=None, key_padding_mask=None):
if x.ndim != 3 or x.shape[-1] != self.d_model or x.shape[1] == 0:
raise ValueError("x应为非空序列[B,T,D]")
batch, length, _ = x.shape
q, k, v = self.qkv(x).chunk(3, dim=-1)
def split(t):
return t.reshape(batch, length, self.num_heads,
self.head_dim).transpose(1, 2)
q, k, v = split(q), split(k), split(v)
scores = q @ k.transpose(-2, -1) / math.sqrt(self.head_dim)
blocked = torch.zeros((batch, 1, length, length),
dtype=torch.bool, device=x.device)
if attn_mask is not None:
if attn_mask.dtype != torch.bool or attn_mask.shape != (length, length):
raise ValueError("attn_mask须为布尔[T,T]")
blocked = blocked | attn_mask.to(x.device)[None, None]
if key_padding_mask is not None:
if (key_padding_mask.dtype != torch.bool or
key_padding_mask.shape != (batch, length)):
raise ValueError("key_padding_mask须为布尔[B,T]")
blocked = blocked | key_padding_mask.to(x.device)[:, None, None, :]
if blocked.all(dim=-1).any():
raise ValueError("每个query至少需要一个可见key")
weights = scores.masked_fill(blocked, float("-inf")).softmax(dim=-1)
heads = weights @ v
merged = heads.transpose(1, 2).contiguous().reshape(batch, length, self.d_model)
return self.out(merged), weights
维度与容易写错的位置
投影后Q/K/V各为[B,T,D],分头变成[B,H,T,D/H],分数和权重为[B,H,T,T]。softmax沿最后的key维做;加权V后回到[B,H,T,D/H],再还原[B,T,D],最后仍需输出投影W_O。
例如B=2、T=5、D=12、H=3,每头维度4,缩放除以2,分数形状是[2,3,5,5]。拼头时先交换回T和H的次序,再整理内存,不能直接把原[B,H,T,d]按[B,T,D]解释。
因果掩码把主对角线上方设为True,禁止读取未来。key padding掩码屏蔽的是被关注的key列,不会自动把padding query的输出清零;训练时还需相应损失掩码。不同PyTorch API对布尔掩码的约定可能不同,不能机械复用。
复杂度与扩展
对长度T、隐藏维度D,线性投影约O(BTD²),注意力约O(BT²D);显式权重占O(BHT²)空间。交叉注意力改为从一组输入产生Q、另一组输入产生K/V,并允许query与key长度不同。生产中通常使用已验证的融合实现;这段代码用于展示机制,不代表最快内核。
对应教程
- 1-1-大模型认知与工程概览:先理解Q/K/V和多头的作用,再跟踪代码中的维度变化。
参考资料
- 国内:wdndev:Attention与Transformer:借鉴投影、分头、注意力与拼接的流程,组织正文中 MHA 的形状转换和实现。
- 国内:WeThinkIn:模型架构与工作原理:依据各头 Q/K/V 与合并后的输出投影,说明正文中 W_O 仍不可省略的计算步骤。
- 国内:Datawhale:第三章 大语言模型基础:参考多头注意力和掩码机制,说明正文中因果掩码与 padding key 列屏蔽的作用。
- 国外:Vaswani等 / Google:Attention Is All You Need:依据原始 MHA 定义与头维度缩放,说明正文中的每头大小、缩放因子和输出矩阵。
- 国外:PyTorch:MultiheadAttention:依据 PyTorch 模块的维度与掩码契约,说明正文实现采用 True 为禁止关注时不能机械复用其他 API 掩码的原因。
相关面经
6 篇字节跳动
大模型实习算法岗手撕MHA
百度
多模态大模型手撕:MHA
小鹏、卓驭、百度、Momenta、华为、美团、零跑汽车、经纬恒润、长安汽车、智驾新程、三一重工
其次是Attention和Transformer。Attention is All you need。伟大无需多言,经典的要能手撕,尤其是MHA,如果你用了不同的att变种,关键改进点要会手撕,大部分考察都是变量的计算过程和维度变化,少部分考察要用torch来写,个人感觉做到大部分差不多。
腾讯
大模型算法岗手撕:手写多头注意力(Multi-Head Attention)
百度
端到端决策规划控制算法工程师展开剩余 1 篇面经
阿里巴巴
Agent 开发工程师手撕 MHA
收录题集
AI 工程编码
大模型手写代码题
训练、数据与模型优化:从数据清洗到 LoRA
编程实战面试题
编码题专题汇编
展开其余 2 条原题
Transformer、Attention、MHA、手撕、NumPy、Mask、Self-Attention、Token Mixing、contiguous、Positional Encoding|L4
其余 9 条问法
- 手撕Multi-Head Attention contiguousO的作用。
- 实现多头自注意力(Multi-Head Attention)机制的核心代码。;另一场次补充:手撕两道,第一道是自注意力机制,我直接写了mha,然后就不用写第二道了。
- 手写Multi-Head Attention(带Mask);另一场次补充:multi-head attention具体怎么实现?;另一场次补充:手撕多头注意力。但是这部分不会考很难,也不用太担心。;另一场次补充:请实现Multi-Head Attention。
- Pytorch实现MHA和打印螺旋矩阵 2选1
- 手撕selfattention(用矩阵乘法)。;另一场次补充:手撕multi-head attention。;另一场次补充:手撕multi-head attention;另一场次补充:手撕代码:self-attention;另一场次补充:手撕MHAtokenmixing;另一场次补充:Attention算子的实现。;另一场次补充:手撕多头注意力机制(MHA)。
- 手撕:用numpy,写MHA
- 手撕MHA(带mask);另一场次补充:手撕多头自注意力机制。;另一场次补充:代码:实现多头自注意力;另一场次补充:手撕题,例如手写MHA
- 手撕位置编码和MHA
- 手撕:多头注意力机制;另一场次补充:实现多头注意力机制;另一场次补充:手撕MHA和场景题;另一场次补充:实现多头自注意力。;另一场次补充:手撕自注意力机制;另一场次补充:实现多头自注意力;另一场次补充:手撕多头注意力。;另一场次补充:手撕:MHA。;另一场次补充:手撕MHA代码;另一场次补充:手撕多头注意力;另一场次补充:手撕是mha。;另一场次补充:手撕自注意力。;另一场次补充:手撕MHA。;另一场次补充:手撕MHA



