考虑两个 n 维的特征 (列向量)a,b∈Rn ,他们之间的相似度是一个很有用的指标,可以用于注意力机制(计算 权重/注意力分数 并以内积的形式对上下文中的特征进行加权求和(行向量与矩阵相乘所得矩阵的每一个行向量都是矩阵的行向量组的线性组合),其中的注意力分数就是 向量相似度)等。
Cosine Similarity 余弦相似度#
其点积(内积)aTb=∥a∥2∥b∥2cosθ=∑i=1naibi
很自然地,几何上,两个向量的夹角越小,其余弦值越大,内积也越大。
使用模长(L2范数)把点积归一化到[−1,1],也就是直接利用向量夹角的余弦值cos⟨a,b⟩=∥a∥∥b∥aTb来衡量向量的相似度,就称为余弦相似度
Scaled Dot-Product 缩放点积#
向量的点积本身,已经在长度和方向两个层面衡量了两个向量的相似度。
特殊地,余弦相似度cos⟨a,b⟩=∥a∥∥b∥aTb=(∥a∥aT)(∥b∥b) 把两个向量都投影到了高维单位超球面上再进行点积,虽然起到了归一化的效果,但损失了模长这一信息的表达能力。
某种意义上,向量的模长/范数可以理解为向量的绝对重要性。尽管有的任务中我们希望所有特征都是平等的,于是我们通过会初始化和归一化使得每一个特征的模长的期望都为1,此时使用余弦相似度非常合理且自然。
但在语言建模这种任务上,我们会希望模型能调节某些token的绝对重要性(直觉上,语言上下文中的某些部分(比如用户指令、句子中的关键词)也会比别的词具有更大的重要性),于是我们不是直接拿两个token的 Token Embedding向量直接做相似度计算,而是分别用可学习的WQ,WK,WV∈Rdmodel(以单头注意力为例)做一次线性变换,这提供了模型调节单个token在上下文中的绝对重要性的能力。
若此时仍旧使用余弦相似度就掩盖了模长信息、QKV投影对模长的调节。
后话:
23年LLaMA-3之后,QK Norm逐渐成为了大模型的常用组件(Qwen3系列、GLM系列、Deepseek的latent norm等),这一组件认为dkQKT是无界的,而softmax只关注值之间的相对差,稍大的差距(>10)即会造成过饱和,导致数值波动太大,影响训练稳定性。
QK norm通过在Q,K投影之后进行归一化(L2 Norm或RMS Norm等)来解决这个问题。显然,做L2 Norm之后直接就退化回了余弦相似度。做RMS Norm则稍好,因为RMS Norm中有 ϵ 和可学习的 g 缩放因子。不过,即使是RMS Norm,也导致此时的计算数学上基本等价于带缩放向量的余弦相似度。
我们倾向于将这个事情理解为Trade-off,毕竟,在超大模型上,与训练稳定性相比,微小的性能损失是可接受的。
那为啥不直接把点积改成余弦相似度,而是先norm再点积呢?原因在易于实现&工程效率
于是,我们转而直接对两个向量做点积,由于向量中各元素在初始化/归一化之后服从 N(0,1),故点积的值服从N(0,dmodel),于是用dmodel1进行缩放,将方差恢复为1
这就是所谓的缩放点积
Attention 注意力#
缩放点积计算了两个向量的相似度,注意力机制则希望利用这种相似度来计算权重,把其他向量的信息加权融合到这个向量的特征中去,这样,我们就在每一个向量中建模了上下文信息。
具体来说,我们直接使用矩阵乘法来实现批量的向量点积:
(QKT)i,j=k=1∑nqi,k⋅kj,k=qi⋅kj
QKT矩阵的i,j元即为hi和hj (h表示hidden state)的点积,于是dmodelQKT的第i行表示了hi对所有h的相似度。
如何利用这个相似度来把h的上下文信息融合到hi中去呢?自然地想到直接进行线性组合:
hi′=∑j=1nwjhj
于是用一个矩阵WAttn∈RN×N来乘我们的hidden state矩阵就好了,当然,实践中我们会给hidden state先做一次线性变换,得到V=hWV,再计算新的h′=WAttnV。
如何从dmodelQKT得到WAttn呢?不能直接让WAttn就等于dmodelQKT吗?
首先后者肯定是不行的,最显然的一个原因和之前做缩放的原因相同:行向量元素的和服从N(0,N) V的每个元素服从N(0,1),乘起来后矩阵中每个元素服从N(0,N),梯度爆炸;其次,缺乏非线性
我们需要:WAttn=Row-wiseNormalization(dmodelQKT)
用什么函数来做这个行归一化呢?直接除以N不行吗?现在我们知道,LLM中最常用的这个“激活”函数是:Row-wiseNormalization(x)≡Softmax(x)=∑j=1Nejxeix
非得用Softmax不可吗?并不是这样,Softmax函数有各种各样的缺点,包括数值稳定性、N2的计算时间复杂度,输出均值总为1以及由此带来的Attention Sink问题等等等等,很多模型也进行了探索和尝试,有的改造由此导出了所谓的Linear-attention,等等;
不过,在实践中,由于Flash-attention这样的技术把Softmax这个函数优化地非常快,且Softmax的有的特性(初始化时行方差为N2e−1远小于One-Hot时的方差N1,即初始化时注意力极度涣散;放大了元素的相对差,重要的token可以占据压倒性的优势等等)非常地好,在实践中的性能优势非常大,主流大模型不会直接把Softmax直接换掉,而是利用其他方式来修复Softmax的缺陷,例如Qwen的Gated Attention通过门控机制解决Attention Sink的问题。
最终我们得到:
Attention(h)=Softmax(dmodelQKT)V
其中:
Q=hWQ,K=hWK,V=hWV
这就是所谓的自注意力机制
如果把产生Q的h换成和产生K,V的h不一样的序列得到的向量,就是所谓的交叉注意力。