Self-Attention可以从一组token表示开始解释。输入矩阵X的形状是序列长度L乘模型维度d_model,分别乘三组可学习矩阵得到Q、K、V。对某个位置而言,Q表示它要查询什么,K表示各位置可被匹配的特征,V是最终被加权汇总的内容。这些说法只是帮助理解,真正计算仍是线性投影和矩阵乘。
接着计算Q乘K转置,得到L乘L的相关分数。分数要除以根号d_k,其中d_k是每个头的key维度。若不缩放,维度增大时点积方差容易变大,softmax可能过早进入饱和区。然后加入mask。因果mask阻止当前位置看到未来token,padding mask排除补齐位置,二者的布尔语义和广播形状必须按具体框架确认。
对每个query所在的行做softmax后,得到对全部key的归一化权重,再与V相乘形成该位置的新表示。多头attention会把Q、K、V投影到多个较小子空间,各头独立完成这套计算,随后把结果拼接并通过输出线性层混合回模型维度。不同头可能学习不同关系,但不能预设每个头必然对应语法、实体或位置。
注意力权重也不能直接当成因果解释。它只能说明当前网络、当前输入和当前层里V被怎样加权;后续残差、MLP与其他层还会改变输出。两个模型可能有不同权重却给出相似预测,也可能改变某些权重但输出不按直觉变化。因此做可解释性分析时,还要结合干预、梯度或反事实实验。
复杂度方面,标准全局attention要形成所有token两两关系,主要计算随L平方增长,朴素实现还会显式存储L乘L分数。FlashAttention通过分块和在线softmax减少高带宽内存读写,数学上仍是精确全局attention,并没有把连接模式变稀疏。
KV Cache的边界也要说清。自回归decode每次只新增一个token,历史token的K和V不变,所以可以缓存,避免每步重新投影历史内容。但训练和prefill要同时处理整段输入,仍需计算整段QK关系。KV Cache降低的是解码中的重复计算,不会消除训练或prefill的二次attention。
若扩展到cross-attention,Q来自目标序列,K和V来自另一段memory,分数形状变为目标长度乘源长度。它和self-attention公式相似,但信息来源、mask和缓存策略不同。面试中先声明当前讲的是self-attention,能避免把两类连接混在一起。
全mask行需要特别处理,因为空集合上的softmax没有正常概率含义。生产实现应使用框架已验证的mask路径,并在因果、padding、混合精度和全mask样本上检查输出与梯度。
工程上我会先用小张量手算一行 attention,再和框架输出、mask 后概率和梯度对齐。全局 attention 还是稀疏 attention,要按上下文长度、延迟与显存做取舍;如果全 mask、混合精度或长序列出现 NaN,就应保留数值校验、告警与回退路径,不能只看最终 loss。