核心公式

Attention(Q,K,V)=softmax(QKTdk)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

来源

自注意力模型的运作方式 我们要通过考虑一整串输入的向量来得到输出,每个 bb 都是考虑了所有 aa 之后产生的。以 b1b^1 为例,我们来介绍这个过程。

自注意力的目的是考虑整个序列,但是又不希望把整个序列的所有信息包在一个窗口里,所以有一个特别的机制,用 α\alpha 来判断每个向量与 a1a^1 的关联程度 计算向量关联程度的方法

两个向量点积的结果在某种程度上可以反映两个向量的相似度。如图(a)方式,把输入的两个向量分别乘上两个不同的矩阵 WqW^qWkW^k,得到两个向量 qqkk,再把 qqkk 做点积,把他们做逐元素的相乘,求和后就得到了 α\alpha。这是计算 α\alpha 的一种方法,也是目前最常用的一种方法,另一种计算方式见图(b)

将各个向量的关联性计算出之后(一般自己与自己也会计算关联性), 除以 dk\sqrt{d_k}(防止 QKTQK^T 数值过大 softmax 梯度消失),对所有的关联性做一个 softmax 操作,即 α1,i=eα1,i/jeα1,j\alpha\prime_{1,i} = e^{\alpha_{1,i}} / \sum_{j} e^{\alpha_{1,j}} , 得到 aa\prime

添加 softmax

接下来我们要根据 α\alpha',去抽取出序列里面重要的信息。把向量 a1a^1a4a^4 乘上 WvW^v 得到新的向量 v1v^1v4v^4,乘上对应的注意力分数 α\alpha',求和,即 b1=ia1,ivib^1=\sum_ia'_{1,i}v^i, 就得到了对应的 b 根据 α′抽取序列中重要的信息
将上述过程向量化后,即得到了 Self-Attention 的核心公式 从矩阵乘法的角度来理解注意力

位置编码

需要考虑位置信息时,就要用到位置编码。位置编码为每一个位置设定一个位置向量,用 eie^i 表示,上标 ii 代表位置,不同的位置就有不同的向量 位置编码

进阶版本

多头自注意力(multi-head self-attention)

相关有很多种不同的形式,所以也许可以有多个 qq,不同的 qq 负责不同种类的相关性 多头自注意力的计算过程

截断自注意力(truncated self-attention) 可以处理向量序列长度过大的问题。截断自注意力

各式各样的 self-attention

假设输入序列长度为 N,由于 QK 之间的 dot-product 计算,self-attention 的计算复杂度为 O(N2)O(N^2),当 N 足够大,比如做图像问题时,一张 256×256256 \times 256 的图片,如果把每一个像素都当成一个像素点,N 就变成了 2562256^2,这也是 self-attention 的痛点。因此,提高 self-attention 的效率从而大幅度提高整个网络的效率是需要解决的一个问题。

image-20260223195426580

我们在做文本翻译的时候,有时候在翻译当前的 token 时不需要整个 sequence 的输入,只需知道 token 两边的数据即可进行翻译,也就是做局部的 attention(local attention),这与 CNN 很相似

local attention

沿这个思路,当考虑的 token 从左右邻居变为左右间隔时,就变成了 stride attention image-20260223200305867

还有一种 global attention 的方式,就是选择 sequence 中的某些 token 作为 special token,或在 sequence 中增加 special token,让 special token 与序列产生全局的关系,非 special token 的 token 之间没有 attention

image-20260223201016481

那么,哪一种 attention 的效果最好呢?我们可以把这几种 attention 融合使用,比如 longformerbig bird 等模型 image-20260223201148345

ReformerRouting Transformer 提出了一种 clustering 的方案,即先对 query 和 key 进行 cluster,只有属于同一类的 query 和 key 计算 attention image-20260223201934346

上面的方法都是人为设定哪些地方需要算 attention,哪些地方不需要,但这并不一定代表着最好效果。我们当然可以用 learn 的方式来获得哪些 attention 需要计算(Sinkhorn Sorting Network):训练一个网络,输入是 input sequence,输出是相同长度的 weight sequence,将所有 weight sequence 拼接起来,再经过转换,就可以得到一个哪些地方需要算 attention,哪些地方不需要算 attention 的矩阵。有一个细节是:某些不同的 sequence 可能经过 NN 输出同一个 weight sequence,这样可以大大减小计算量。image-20260223211343069

上述我们所讲的都是 N×NN\times N 的 Matrix,但是实际来说,这样的 Matrix 通常来说并不是满秩的,也就是说我们可以对原始的 N×NN\times N 矩阵降维,去掉一些 column,得到一个比较小的 Matrix。具体来说,从 N 个 key 中选出 K 个具有代表性的 key,然后和 query 做 dot-product(此处不选具有代表性的 query 是因为 query 和 output 是相对的,去掉 query 会损失信息)。选出具有代表性的 key 的方法有两种:第一种是直接对 key 做卷积(Compressed Attention),第二种是对 key 做一个 transform(Linformer)

image-20260223222655453

值得一提的是,QKV的矩阵运算时,不同的矩阵运算顺序对于计算复杂度也有很大影响image-20260223224136626