前言在自然语言处理Natural Language ProcessingNLP领域Transformer已经成为目前最重要的深度学习模型之一。从BERT、GPT到如今的大语言模型LLM几乎都建立在Transformer架构之上。Transformer能够取得如此优异的性能其中最核心的原因就是提出了一种全新的信息交互方式——Attention注意力机制。在传统神经网络中每个单词通常只依赖于固定范围内的上下文而注意力机制允许每个单词动态关注句子中的所有其他单词并根据相关性分配不同的权重从而学习更加丰富的上下文语义。本文将结合PyTorch源码对Transformer中的**Scaled Dot-Product Attention缩放点积注意力**进行逐行分析从数学公式、张量维度变化、代码实现到运行示例帮助读者彻底理解Attention机制。第一章 Attention到底解决了什么问题1.1 RNN存在的问题在Transformer出现之前文本建模主要依赖循环神经网络RNN及其改进模型LSTM、GRU。RNN按照时间顺序依次处理单词今天 → 天气 → 很 → 好第一个单词的信息需要逐步传递到最后一个单词。例如今天 ↓ 天气 ↓ 很 ↓ 好这种结构存在两个主要缺陷① 长距离依赖问题前面的信息经过多次传递后容易衰减导致模型难以捕获远距离词之间的关系。② 无法并行计算必须按照顺序处理每个单词训练效率较低。1.2 Transformer提出新的思路Transformer不再采用逐词递归处理而是让句子中的每个单词都能够直接与所有其他单词建立联系。例如今天 天气 很 好Transformer允许今天 → 天气 今天 → 很 今天 → 好 天气 → 今天 天气 → 很 天气 → 好 ……即任意两个词之间都可以直接交互信息。这种思想就是Attention。1.3 什么是AttentionAttention的本质可以理解为让模型自动学习当前单词应该关注哪些单词以及关注多少。例如小明 去了 北京 因为 他 喜欢 那里当模型处理他时真正需要关注的是小明而不是去了 喜欢Attention就能够自动学习这种对应关系。第二章 Query、Key、Value到底是什么Attention最难理解的地方就是三个矩阵Query Key Value很多初学者都会疑惑为什么一个Attention要设计三个矩阵实际上它们分别承担不同职责。Query查询Query表示当前单词希望寻找哪些信息。例如苹果Query可以理解成我要寻找与自己最相关的信息。Key键Key表示每个单词向外提供的信息标签。例如香蕉对应一个Key。苹果也对应一个Key。Query会逐个与所有Key进行匹配。Value值Value表示真正需要融合的信息。最后Attention输出的不是Key而是Value所以Query负责提问 Key负责匹配 Value负责提供内容第三章 Self-Attention为什么QKV代码query key value position_x很多人第一次看到都会问为什么三个变量完全一样这是因为当前实现的是Self Attention即同一句话内部计算注意力。例如我 爱 深度 学习所有单词既作为查询者又作为被查询者。因此Q 来自输入 K 来自输入 V 来自输入虽然输入相同但真正Transformer里面还会经过QXWQ KXWK VXWV三个不同的线性层。这里只是为了教学方便没有加入线性变换。第四章 Attention数学公式详解Transformer论文给出的公式[Attention(Q,K,V)Softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V]整个公式可以拆成四步。第一步计算相关性。QKᵀ第二步缩放。÷√dk第三步Softmax。得到权重第四步加权求和。Weight×Value代码正好对应四个步骤。第五章 attention()源码逐行解析这里开始每一行代码都可以配合截图进行讲解。第一步 获取特征维度d_k query.size(-1)假设query.shape [2,4,512]分别表示batch_size 2 seq_len4 embedding512这里size(-1)表示最后一个维度。所以d_k512为什么需要这个数字因为后面需要√512≈22.6用于缩放Attention Score。为什么一定要缩放假设512维向量。两个随机向量点积Q·K可能达到300如果直接Softmax(300)结果0.99999999 0.00000001 0梯度几乎消失。所以论文提出除以√512即可缓解梯度问题。第六章 为什么要计算QKᵀ代码scores torch.matmul(query,key.transpose(-2,-1))很多同学不知道为什么不是QK而是QKᵀ原因就在于矩阵乘法维度。假设Q 4×512K4×512两个矩阵4×512 × 4×512无法相乘。必须4×512 × 512×4因此需要transpose()得到4×4这里每一个元素都是两个单词之间 点积相似度例如我 喜欢 吃 苹果 我 喜欢 吃 苹果形成4×4 Attention Matrix第七章 为什么Mask可以屏蔽未来信息代码scores.masked_fill(mask0,-1e9)很多人疑惑为什么-1e9就能屏蔽答案就在Softmax。Softmaxexp(x)如果x-1000000000那么e^-1000000000≈0最终权重≈0因此模型永远不会看到未来Token。例如Decoder今天 天气 很 好预测天气只能看到今天 天气不能看到很 好否则模型训练就是作弊。第八章 Softmax为什么能够表示注意力Attention Score例如[2 5 8]Softmax以后↓ [0.02 0.12 0.86]表示第三个词最重要。权重最大。所有权重加起来1因此Attention实际上就是概率分布。第九章 为什么最后要乘Value很多人误以为Attention输出就是Softmax实际上真正输出Softmax×Value例如权重 0.1 0.2 0.7ValueA B C最终0.1A 0.2B 0.7C得到新的向量。因此每个单词都融合了其它单词的信息。第十章 张量维度变化全过程重点这是学习 Attention 最重要的一部分。假设batch_size 2seq_len 4d_model 512那么整个计算过程中张量形状变化如下计算步骤运算输出形状说明输入Query、Key、Value[2,4,512]两个样本每句4个词每词512维转置K.transpose(-2,-1)[2,512,4]为矩阵乘法准备点积Q × Kᵀ[2,4,4]每个词与所有词计算相似度缩放/√512[2,4,4]防止Softmax梯度饱和Maskmasked_fill()[2,4,4]屏蔽非法位置Softmaxsoftmax()[2,4,4]得到注意力权重Dropoutdropout()[2,4,4]训练阶段随机失活加权求和Attention × Value[2,4,512]得到最终上下文表示需要特别注意的是只有中间的注意力权重矩阵维度变成了[batch_size, seq_len, seq_len]最终输出又恢复到了[batch_size, seq_len, d_model]。这意味着注意力机制不会改变每个词向量的维数而是改变其包含的信息使其融合了整个序列的上下文。第十一章 use_attention()函数完整执行流程use_attention()是整个实验的测试函数它模拟了 Transformer 中一次完整的自注意力计算流程。其执行顺序可以概括为Embedding │ ▼ Position Encoding │ ▼ Q K V │ ▼ Q × Kᵀ │ ▼ ÷ √dk │ ▼ Mask可选 │ ▼ Softmax │ ▼ Attention Weight │ ▼ Weight × Value │ ▼ 输出新的特征表示其中第一次调用attention(query, key, value)时没有使用 Mask因此属于标准的 Encoder 自注意力第二次构造了一个全零 Mask仅用于观察masked_fill()对注意力分数的影响并不代表实际 Transformer 的 Mask 用法。真实应用中通常使用Padding Mask或Look-Ahead Mask下三角 Mask。第十二章 本代码与Transformer源码的对应关系这段代码实际上是 Transformer 中Scaled Dot-Product Attention的教学版实现与论文和 PyTorch 官方实现的主要区别如下教学代码Transformer 实际实现Q K V输入相同但会分别经过三个线性层得到 Q、K、V单头注意力多头注意力Multi-Head Attention无残差连接Attention 后增加残差连接Residual无 LayerNorm每层后使用 Layer Normalization无前馈网络后续接 Position-wise Feed Forward Network演示用全零 Mask实际使用 Padding Mask 或 Look-Ahead Mask因此这段代码虽然只有几十行却完整体现了 Transformer 注意力计算的核心思想是学习 Multi-Head Attention 和完整 Transformer 的基础。第十三章 总结与学习建议缩放点积注意力Scaled Dot-Product Attention是 Transformer 的核心计算单元其本质是通过计算 Query 与 Key 的相似度为每个词动态分配注意力权重再利用这些权重对 Value 进行加权求和从而生成融合全局上下文信息的新表示。整个过程遵循“计算相似度 → 缩放 → 掩码 → Softmax → 加权求和”五个关键步骤对应论文中的公式[\text{Attention}(Q,K,V)\text{Softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V]建议学习顺序遵循以下路径熟悉矩阵乘法与张量维度变化能够手工推导QKᵀ和Attention×Value的维度。深入理解 Softmax 的概率归一化作用以及为什么需要使用√d_k对点积进行缩放。掌握 Padding Mask 和 Look-Ahead Mask 的设计目的及实现方式。在理解单头注意力Single-Head Attention的基础上进一步学习多头注意力Multi-Head Attention、残差连接Residual Connection、层归一化Layer Normalization和前馈神经网络Feed Forward Network最终掌握完整的 Transformer 编码器与解码器结构。对于初学者而言这段代码是理解 Transformer 的最佳切入点当能够独立解释每一行代码的功能、每一步的数学意义以及每个张量的维度变化时也就真正掌握了 Transformer 注意力机制的核心原理。
Transformer核心算法详解——Scaled Dot-Product Attention(缩放点积注意力)源码解析
前言在自然语言处理Natural Language ProcessingNLP领域Transformer已经成为目前最重要的深度学习模型之一。从BERT、GPT到如今的大语言模型LLM几乎都建立在Transformer架构之上。Transformer能够取得如此优异的性能其中最核心的原因就是提出了一种全新的信息交互方式——Attention注意力机制。在传统神经网络中每个单词通常只依赖于固定范围内的上下文而注意力机制允许每个单词动态关注句子中的所有其他单词并根据相关性分配不同的权重从而学习更加丰富的上下文语义。本文将结合PyTorch源码对Transformer中的**Scaled Dot-Product Attention缩放点积注意力**进行逐行分析从数学公式、张量维度变化、代码实现到运行示例帮助读者彻底理解Attention机制。第一章 Attention到底解决了什么问题1.1 RNN存在的问题在Transformer出现之前文本建模主要依赖循环神经网络RNN及其改进模型LSTM、GRU。RNN按照时间顺序依次处理单词今天 → 天气 → 很 → 好第一个单词的信息需要逐步传递到最后一个单词。例如今天 ↓ 天气 ↓ 很 ↓ 好这种结构存在两个主要缺陷① 长距离依赖问题前面的信息经过多次传递后容易衰减导致模型难以捕获远距离词之间的关系。② 无法并行计算必须按照顺序处理每个单词训练效率较低。1.2 Transformer提出新的思路Transformer不再采用逐词递归处理而是让句子中的每个单词都能够直接与所有其他单词建立联系。例如今天 天气 很 好Transformer允许今天 → 天气 今天 → 很 今天 → 好 天气 → 今天 天气 → 很 天气 → 好 ……即任意两个词之间都可以直接交互信息。这种思想就是Attention。1.3 什么是AttentionAttention的本质可以理解为让模型自动学习当前单词应该关注哪些单词以及关注多少。例如小明 去了 北京 因为 他 喜欢 那里当模型处理他时真正需要关注的是小明而不是去了 喜欢Attention就能够自动学习这种对应关系。第二章 Query、Key、Value到底是什么Attention最难理解的地方就是三个矩阵Query Key Value很多初学者都会疑惑为什么一个Attention要设计三个矩阵实际上它们分别承担不同职责。Query查询Query表示当前单词希望寻找哪些信息。例如苹果Query可以理解成我要寻找与自己最相关的信息。Key键Key表示每个单词向外提供的信息标签。例如香蕉对应一个Key。苹果也对应一个Key。Query会逐个与所有Key进行匹配。Value值Value表示真正需要融合的信息。最后Attention输出的不是Key而是Value所以Query负责提问 Key负责匹配 Value负责提供内容第三章 Self-Attention为什么QKV代码query key value position_x很多人第一次看到都会问为什么三个变量完全一样这是因为当前实现的是Self Attention即同一句话内部计算注意力。例如我 爱 深度 学习所有单词既作为查询者又作为被查询者。因此Q 来自输入 K 来自输入 V 来自输入虽然输入相同但真正Transformer里面还会经过QXWQ KXWK VXWV三个不同的线性层。这里只是为了教学方便没有加入线性变换。第四章 Attention数学公式详解Transformer论文给出的公式[Attention(Q,K,V)Softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V]整个公式可以拆成四步。第一步计算相关性。QKᵀ第二步缩放。÷√dk第三步Softmax。得到权重第四步加权求和。Weight×Value代码正好对应四个步骤。第五章 attention()源码逐行解析这里开始每一行代码都可以配合截图进行讲解。第一步 获取特征维度d_k query.size(-1)假设query.shape [2,4,512]分别表示batch_size 2 seq_len4 embedding512这里size(-1)表示最后一个维度。所以d_k512为什么需要这个数字因为后面需要√512≈22.6用于缩放Attention Score。为什么一定要缩放假设512维向量。两个随机向量点积Q·K可能达到300如果直接Softmax(300)结果0.99999999 0.00000001 0梯度几乎消失。所以论文提出除以√512即可缓解梯度问题。第六章 为什么要计算QKᵀ代码scores torch.matmul(query,key.transpose(-2,-1))很多同学不知道为什么不是QK而是QKᵀ原因就在于矩阵乘法维度。假设Q 4×512K4×512两个矩阵4×512 × 4×512无法相乘。必须4×512 × 512×4因此需要transpose()得到4×4这里每一个元素都是两个单词之间 点积相似度例如我 喜欢 吃 苹果 我 喜欢 吃 苹果形成4×4 Attention Matrix第七章 为什么Mask可以屏蔽未来信息代码scores.masked_fill(mask0,-1e9)很多人疑惑为什么-1e9就能屏蔽答案就在Softmax。Softmaxexp(x)如果x-1000000000那么e^-1000000000≈0最终权重≈0因此模型永远不会看到未来Token。例如Decoder今天 天气 很 好预测天气只能看到今天 天气不能看到很 好否则模型训练就是作弊。第八章 Softmax为什么能够表示注意力Attention Score例如[2 5 8]Softmax以后↓ [0.02 0.12 0.86]表示第三个词最重要。权重最大。所有权重加起来1因此Attention实际上就是概率分布。第九章 为什么最后要乘Value很多人误以为Attention输出就是Softmax实际上真正输出Softmax×Value例如权重 0.1 0.2 0.7ValueA B C最终0.1A 0.2B 0.7C得到新的向量。因此每个单词都融合了其它单词的信息。第十章 张量维度变化全过程重点这是学习 Attention 最重要的一部分。假设batch_size 2seq_len 4d_model 512那么整个计算过程中张量形状变化如下计算步骤运算输出形状说明输入Query、Key、Value[2,4,512]两个样本每句4个词每词512维转置K.transpose(-2,-1)[2,512,4]为矩阵乘法准备点积Q × Kᵀ[2,4,4]每个词与所有词计算相似度缩放/√512[2,4,4]防止Softmax梯度饱和Maskmasked_fill()[2,4,4]屏蔽非法位置Softmaxsoftmax()[2,4,4]得到注意力权重Dropoutdropout()[2,4,4]训练阶段随机失活加权求和Attention × Value[2,4,512]得到最终上下文表示需要特别注意的是只有中间的注意力权重矩阵维度变成了[batch_size, seq_len, seq_len]最终输出又恢复到了[batch_size, seq_len, d_model]。这意味着注意力机制不会改变每个词向量的维数而是改变其包含的信息使其融合了整个序列的上下文。第十一章 use_attention()函数完整执行流程use_attention()是整个实验的测试函数它模拟了 Transformer 中一次完整的自注意力计算流程。其执行顺序可以概括为Embedding │ ▼ Position Encoding │ ▼ Q K V │ ▼ Q × Kᵀ │ ▼ ÷ √dk │ ▼ Mask可选 │ ▼ Softmax │ ▼ Attention Weight │ ▼ Weight × Value │ ▼ 输出新的特征表示其中第一次调用attention(query, key, value)时没有使用 Mask因此属于标准的 Encoder 自注意力第二次构造了一个全零 Mask仅用于观察masked_fill()对注意力分数的影响并不代表实际 Transformer 的 Mask 用法。真实应用中通常使用Padding Mask或Look-Ahead Mask下三角 Mask。第十二章 本代码与Transformer源码的对应关系这段代码实际上是 Transformer 中Scaled Dot-Product Attention的教学版实现与论文和 PyTorch 官方实现的主要区别如下教学代码Transformer 实际实现Q K V输入相同但会分别经过三个线性层得到 Q、K、V单头注意力多头注意力Multi-Head Attention无残差连接Attention 后增加残差连接Residual无 LayerNorm每层后使用 Layer Normalization无前馈网络后续接 Position-wise Feed Forward Network演示用全零 Mask实际使用 Padding Mask 或 Look-Ahead Mask因此这段代码虽然只有几十行却完整体现了 Transformer 注意力计算的核心思想是学习 Multi-Head Attention 和完整 Transformer 的基础。第十三章 总结与学习建议缩放点积注意力Scaled Dot-Product Attention是 Transformer 的核心计算单元其本质是通过计算 Query 与 Key 的相似度为每个词动态分配注意力权重再利用这些权重对 Value 进行加权求和从而生成融合全局上下文信息的新表示。整个过程遵循“计算相似度 → 缩放 → 掩码 → Softmax → 加权求和”五个关键步骤对应论文中的公式[\text{Attention}(Q,K,V)\text{Softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V]建议学习顺序遵循以下路径熟悉矩阵乘法与张量维度变化能够手工推导QKᵀ和Attention×Value的维度。深入理解 Softmax 的概率归一化作用以及为什么需要使用√d_k对点积进行缩放。掌握 Padding Mask 和 Look-Ahead Mask 的设计目的及实现方式。在理解单头注意力Single-Head Attention的基础上进一步学习多头注意力Multi-Head Attention、残差连接Residual Connection、层归一化Layer Normalization和前馈神经网络Feed Forward Network最终掌握完整的 Transformer 编码器与解码器结构。对于初学者而言这段代码是理解 Transformer 的最佳切入点当能够独立解释每一行代码的功能、每一步的数学意义以及每个张量的维度变化时也就真正掌握了 Transformer 注意力机制的核心原理。