1. 注意力公式详解:Attention(Q,K,V)

Transformer 中使用的注意力机制是 缩放点积注意力 (Scaled Dot-Product Attention)。它的公式是:

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

步骤分解与作用:

步骤

公式部分

作用

结果

相似度匹配

QK^T

计算 Q 与所有 K 之间的相似度(点积)。

这决定了每个查询(Q)对序列中所有键(K)的关注程度。

注意力分数(Logits)

缩放

\frac{\dots}{\sqrt{d_k}}

将分数除以 K 向量维度 dk​ 的平方根。

作用是防止 Q 和 K 的点积过大,使 Softmax 函数的输入落在稳定梯度区间,避免梯度消失。

缩放后的注意力分数

归一化

softmax(…)

将分数转换为概率分布,确保所有注意力权重之和为 1。

这些权重指示了模型应该“听取”每个 V 向量的多少信息。

注意力权重(Attention Weights)

加权求和

(…)V

用注意力权重对所有 V 向量进行加权求和

权重高的 V 向量信息被更多地保留到输出中。

最终的注意力输出(上下文向量)

2. Q,K,V 向量如何获得?

Q(Query)、K(Key)、V(Value)向量都是从同一输入 X(即上一个 Transformer 层的输出或初始嵌入)通过线性变换(即全连接层)获得的。

对于每一个注意力头(head):

  1. 输入:上层输出的特征矩阵 X(维度:[序列长度×模型维度])。

  2. 线性投影:模型学习了三个独立的权重矩阵 W_Q​,W_K​,W_V

*Q = \mathbf{X}W_Q

*K = \mathbf{X}W_K

*V = \mathbf{X}W_V

  1. 结果:Q,K,V 都是新的矩阵(维度:[序列长度×头维度])。这三个矩阵被用于上面的注意力计算公式。

关键点:这三个权重矩阵 W_Q​,W_K​,W_V​ 是可学习的参数,它们在训练过程中不断优化,从而教会模型如何为不同的任务“查询”信息 (Q),以及如何“索引”和“提供”信息 (K 和 V)。

3. 自回归生成中T_2T_1T_2的注意力计算

我们以一个简单的两步生成过程为例,展示在 Transformer 解码器中(如 ChatGPT),因果掩码和 KV Cache 是如何工作的。

假设输入序列是S = [T_1, T_2, \dots], 模型已经生成了T_1, 现在正在生成T_2

场景:模型生成 T_2

在生成 T_2​ 这一步,模型的输入(到注意力层)是 T_1​ 和 T_2的嵌入。我们将它们简记为 X=[x_1,x_2]

1. 计算 Q,K,V

模型计算 T_1​ 和 T_2​ 的 Q,K,V 向量:

  • Q=[Q_1,Q_2]

  • K=[K_1,K_2]

  • V=[V_1,V_2]

2. 计算注意力分数 QK^T (应用因果掩码)

计算 Q 矩阵与 K 矩阵的转置的点积:

QK^T = \begin{pmatrix} Q_1 \\ Q_2 \end{pmatrix} \begin{pmatrix} K_1^T & K_2^T \end{pmatrix} = \begin{pmatrix} Q_1 K_1^T & Q_1 K_2^T \\ Q_2 K_1^T & Q_2 K_2^T \end{pmatrix}

这得到了一个 2×2 的分数矩阵:

Score

Attention to K1​

Attention to K2​

Query Q_1

Q_1 K_1^T (对 T1​ 的自注意力)

Q_1K_2^T

Query Q_2

Q_2K_1^T (对 T1​ 的注意力)

Q_2K_2^T (对 T2​ 的自注意力)

应用因果掩码 (Causal Mask)

因果掩码会屏蔽未来的信息Q_1 是第一个 token, 它不能看到K_2 (即未来的T_2)。 因此, 我们强制将Q_1K_2 的分数设为-\infty:

\text{Masked Scores} = \frac{1}{\sqrt{d_k}} \begin{pmatrix} Q_1 K_1^T & -\infty \\ Q_2 K_1^T & Q_2 K_2^T \end{pmatrix}

3. Softmax 归一化

应用 Softmax 后,所有 -\infty 的项都会变成 0:

\text{Weights} = \text{softmax}(\text{Masked Scores}) = \begin{pmatrix} W_{1,1} & \mathbf{0} \\ W_{2,1} & W_{2,2} \end{pmatrix}

*W_{1,1}T_1 对自己的注意力权重。

*W_{2,1}T_2T_1 的注意力权重。

*W_{2,2}T_2T_2的自注意力权重。

4. 加权求和得到输出

计算 Weights⋅V 得到最终输出 Z=[Z_1,Z_2]

Z = \begin{pmatrix} W_{1,1}V_1 + \mathbf{0} \cdot V_2 \\ W_{2,1}V_1 + W_{2,2}V_2 \end{pmatrix}

最终,T_2 的输出Z_2 就是对T_1T_2 的V 向量进行加权求和的结果。

结合 KV Cache 的优化(推理时)

在实际推理时,为了避免重复计算 T_1​ 的 K_1V_1,模型会使用 KV Cache

  1. 第一步 (T_1):计算 K_1,V_1,并将其存入缓存。

  2. 第二步 (T_2)

    • 模型只计算新 token T_2​ 的 Q_2​,K_2,V_2​。

    • 它从 KV Cache 中取出 K_cache=[K_1]] 和 V_cache=[V_1]

    • 完整的 K 矩阵用于注意力计算是 K=[K_1,K_2]

    • 完整的 V 矩阵用于加权求和是 V=[V_1,V_2]

    • Q 矩阵只需要 Q_2(因为 Z_1 已经算完,无需再次关注)。

模型只需要计算 Q_2​ 对[K_1,K_2] 的注意力,避免了重新计算K_1, V_1Z_1 的浪费。

因此,T_2T_1T_2的注意力是通过Q_2向量与缓存中的K_1 和新计算的K_2进行相似度匹配, 然后用得到的权重对缓存中的V_1 和新计算的V_2进行加权求和而获得的。

Logo

更多推荐