阅读笔记|Attention is all you need(中英对照)

发布于:2025-09-01 ⋅ 阅读:(21) ⋅ 点赞:(0)

Attention Is All You Need

31st Conference on Neural Information Processing Systems (NIPS 2017), Long Beach, CA, USA.

Abstract

The dominant sequence transduction models are based on complex recurrent or convolutional neural networks that include an encoder and a decoder. The best performing models also connect the encoder and decoder through an attention mechanism. We propose a new simple network architecture, the Transformer, based solely on attention mechanisms, dispensing with recurrence and convolutions entirely. Experiments on two machine translation tasks show these models to be superior in quality while being more parallelizable and requiring significantly less time to train. Our model achieves 28.4 BLEU on the WMT 2014 English-to-German translation task, improving over the existing best results, including ensembles, by over 2 BLEU. On the WMT 2014 English-to-French translation task, our model establishes a new single-model state-of-the-art BLEU score of 41.8 after training for 3.5 days on eight GPUs, a small fraction of the training costs of the best models from the literature. We show that the Transformer generalizes well to other tasks by applying it successfully to English constituency parsing both with large and limited training data.

目前主流的序列转换模型基于复杂的循环神经网络或卷积神经网络,采用编码器-解码器架构。性能最佳的模型还通过注意力机制连接编码器和解码器。我们提出了一种新型简单网络架构——Transformer,它完全基于注意力机制,彻底摒弃了循环和卷积结构。在两个机器翻译任务上的实验表明,该模型在翻译质量上表现更优,同时具有更好的并行性且训练时间显著减少。我们的模型在WMT 2014英德翻译任务中取得了28.4的BLEU分数,相比包括集成模型在内的现有最佳结果提升超过2个BLEU值。在WMT 2014英法翻译任务中,我们的模型在8块GPU上训练3.5天后建立了41.8的BLEU评分新纪录,其训练成本仅为文献中最佳模型所需成本的一小部分。通过成功应用于英语成分句法分析任务(无论训练数据量大小),我们证明Transformer架构能够良好地泛化至其他任务。

1 Introduction

Recurrent neural networks, long short-term memory [13] and gated recurrent [7] neural networks in particular, have been firmly established as state of the art approaches in sequence modeling and transduction problems such as language modeling and machine translation [35, 2, 5]. Numerous efforts have since continued to push the boundaries of recurrent language models and encoder-decoder architectures [38, 24, 15].

循环神经网络,尤其是长短期记忆网络(LSTM)[13]与门控循环单元(GRU)[7],已被公认为序列建模和转换任务(如语言建模与机器翻译)中的最先进方法[35, 2, 5]。此后大量研究持续推动着循环语言模型与编码器-解码器架构的性能边界[38, 24, 15]。

循环神经网络 (Recurrent Neural Network - RNN)

RNN的核心是循环连接,它让网络能够保留"记忆"。在处理序列的每一个时间步(如一个词)时,网络不仅接收当前的输入,还接收来自上一个时间步的隐藏状态。这使得网络能够利用之前的信息来影响当前的输出。

工作原理

  • 在时间步 t,输入 x_t 和上一个隐藏状态 h_{t-1} 被组合起来,通过一个激活函数(如tanh)生成新的隐藏状态 h_t
  • 这个新的隐藏状态 h_t 被用于两个方面:1) 生成当前输出 y_t(如果需要);2) 传递给下一个时间步 t+1

主要缺陷梯度消失/爆炸问题。当处理长序列时,网络很难学习到早期时间步的信息对后期时间步的影响(例如,段首的词对段尾的词的影响),因为梯度在反向传播时会指数级地减小或增大。这导致RNN难以捕获长期依赖关系


长短期记忆网络 (Long Short-Term Memory - LSTM)

LSTM由Sepp Hochreiter和Jürgen Schmidhuber于1997年提出,是专门为了解决RNN的长期依赖问题而设计的。

核心思想:LSTM引入了一个名为"细胞状态(Cell State)“的"传送带”,它贯穿整个时间步,只在少量线性交互下传递信息,从而使得梯度能够流动更长的距离而不易消失。同时,它通过三个"门(Gates)"结构来精细调控信息流。

三个门控机制

  1. 遗忘门(Forget Gate):决定从细胞状态中丢弃哪些信息。它查看当前输入和上一个隐藏状态,输出一个0到1之间的数(0表示"完全丢弃",1表示"完全保留")给细胞状态
  2. 输入门(Input Gate):决定将哪些新信息存入细胞状态。它由一个sigmoid层决定更新哪些值,和一个tanh层生成新的候选值
  3. 输出门(Output Gate):基于当前的细胞状态,决定下一个隐藏状态的值是什么。隐藏状态通常用于输出

优势:门控机制让LSTM能够有选择地记住或忘记信息,使其在捕获长期依赖关系方面远远优于普通RNN,成为2018年之前处理序列任务的主流架构


门控循环单元 (Gated Recurrent Unit - GRU)

GRU是LSTM的一个变体,由Kyunghyun Cho等人于2014年提出。它简化了LSTM的结构,效果相当,但计算效率更高。

核心思想:GRU将LSTM中的细胞状态和隐藏状态合并,只有一个隐藏状态。同时,它将遗忘门和输入门合并成一个单一的"更新门(Update Gate)"

两个门控机制

  1. 更新门(Update Gate):决定有多少上一时刻的信息保留到当前时刻(融合了LSTM的遗忘和输入门的功能)
  2. 重置门(Reset Gate):决定有多少上一时刻的信息被忽略,用于计算新的候选隐藏状态

优势:参数比LSTM少,训练速度更快,但在许多任务上能达到与LSTM相当的性能

Recurrent models typically factor computation along the symbol positions of the input and output sequences. Aligning the positions to steps in computation time, they generate a sequence of hidden states hth_tht, as a function of the previous hidden state ht−1h_{t-1}ht1 and the input for position ttt. This inherently sequential nature precludes parallelization within training examples, which becomes critical at longer sequence lengths, as memory constraints limit batching across examples. Recent work has achieved significant improvements in computational efficiency through factorization tricks [21] and conditional computation [32], while also improving model performance in case of the latter. The fundamental constraint of sequential computation, however, remains.

循环模型通常沿着输入和输出序列的符号位置进行因子化计算。通过将计算时间步与序列位置对齐,这些模型会基于前一个隐藏状态 ht−1h_{t-1}ht1 和当前位置 ttt 的输入,生成一系列隐藏状态 hth_tht这种固有的顺序特性阻碍了训练样本内的并行化处理——当序列长度较大时,这一问题变得尤为关键,因为内存限制会制约跨样本的批处理能力。 近期研究通过因子分解技巧[21]和条件计算[32]显著提升了计算效率,后者还同时改善了模型性能。然而,顺序计算的根本约束依然存在。

Attention mechanisms have become an integral part of compelling sequence modeling and transduction models in various tasks, allowing modeling of dependencies without regard to their distance in the input or output sequences [2, 19]. In all but a few cases [27], however, such attention mechanisms are used in conjunction with a recurrent network.

注意力机制已成为多种任务中序列建模与转换模型不可或缺的组成部分,它能够对依赖关系进行建模而无须考虑其在输入或输出序列中的距离[2, 19]。然而除少数特例外[27],这类注意力机制通常需与循环网络结合使用。

In this work we propose the Transformer, a model architecture eschewing recurrence and instead relying entirely on an attention mechanism to draw global dependencies between input and output. The Transformer allows for significantly more parallelization and can reach a new state of the art in translation quality after being trained for as little as twelve hours on eight P100 GPUs.

在本研究中,我们提出Transformer模型架构,该架构摒弃循环结构,完全依靠注意力机制来捕捉输入与输出之间的全局依赖关系。 Transformer实现了更高程度的并行化处理,仅需在8块P100 GPU上训练12小时即可达到机器翻译质量的新标杆。

2 Background

The goal of reducing sequential computation also forms the foundation of the Extended Neural GPU [16], ByteNet [18] and ConvS2S [9], all of which use convolutional neural networks as basic building block, computing hidden representations in parallel for all input and output positions. In these models, the number of operations required to relate signals from two arbitrary input or output positions grows in the distance between positions, linearly for ConvS2S and logarithmically for ByteNet. This makes it more difficult to learn dependencies between distant positions [12]. In the Transformer this is reduced to a constant number of operations, albeit at the cost of reduced effective resolution due to averaging attention-weighted positions, an effect we counteract with Multi-Head Attention as described in section 3.2.

减少序列计算量的目标同样构成了扩展神经GPU[16]、ByteNet[18]与ConvS2S[9]的研究基础——这些模型均采用卷积神经网络作为基本构建模块,并行计算所有输入及输出位置的隐藏表征。在这些模型中,关联两个任意输入或输出位置信号所需的计算操作次数会随位置间距增长:ConvS2S呈线性增长,ByteNet呈对数增长。该特性导致模型难以学习远距离位置之间的依赖关系[12]。而Transformer将此计算量降至常数级别,尽管这是以降低有效分辨率为代价(源于对注意力加权位置的平均化处理),我们通过第3.2节所述的多头注意力机制来抵消该效应。

Self-attention, sometimes called intra-attention is an attention mechanism relating different positions of a single sequence in order to compute a representation of the sequence. Self-attention has been used successfully in a variety of tasks including reading comprehension, abstractive summarization, textual entailment and learning task-independent sentence representations [4, 27, 28, 22].

自注意力(有时称为内部注意力)是一种注意力机制,它通过关联单个序列中不同位置的关系来计算该序列的表征。自注意力机制已成功应用于多种任务,包括阅读理解、抽象摘要、文本蕴含以及学习与任务无关的句子表征[4, 27, 28, 22]。

End-to-end memory networks are based on a recurrent attention mechanism instead of sequence-aligned recurrence and have been shown to perform well on simple-language question answering and language modeling tasks [34].

端到端记忆网络基于循环注意力机制而非序列对齐的循环结构,已被证明在简单语言问答与语言建模任务中表现优异[34]。

To the best of our knowledge, however, the Transformer is the first transduction model relying entirely on self-attention to compute representations of its input and output without using sequence-aligned RNNs or convolution. In the following sections, we will describe the Transformer, motivate self-attention and discuss its advantages over models such as [17, 18] and [9].

据我们所知,Transformer是首个完全依靠自注意力机制计算输入输出表征的转换模型,无需使用序列对齐的循环神经网络或卷积结构。 在后续章节中,我们将详细阐述Transformer架构,阐释自注意力的原理,并讨论其相较于[17,18]及[9]等模型的优势。

RNN/LSTM/GRU 与 Transformer 的对比

Transformer由Google在2017年的论文《Attention Is All You Need》中提出,它完全摒弃了循环结构,依赖自注意力机制(Self-Attention Mechanism),带来了革命性的变化。

核心区别

特性 RNN / LSTM / GRU Transformer
核心结构 循环结构。按时间步顺序处理序列,具有隐式的时序关系 自注意力机制 + 前馈网络并行处理序列中的所有元素,通过位置编码提供显式的位置信息
处理方式 串行计算。必须等 t-1 步算完才能算 t 步,无法并行,训练慢 并行计算。所有词元同时被处理,极大提高了训练效率
长程依赖 困难。尽管LSTM/GRU缓解了问题,但跨越极长序列(如1000步以上)依然有挑战。信息需要一步步传递,容易稀释 强大。自注意力机制允许任何两个位置直接连接,无论距离多远,模型都能直接计算其相关性。路径长度是常数级(O(1))
解释性 较差。隐藏状态像一个黑盒,难以知道模型到底"记住"了什么 较强。注意力权重矩阵可以被可视化,清晰地展示出在做决策时,模型关注了输入序列的哪些部分(例如,翻译某个词时关注了原句的哪些词)
计算复杂度 每时间步复杂度为 O(1),整个序列为 O(n) 自注意力的复杂度是 O(n²),其中n是序列长度。这意味着处理非常长的序列(如长文档、高分辨率图像)时计算开销巨大
典型应用 在Transformer出现前,是几乎所有序列任务的SOTA,如机器翻译、文本生成、语音识别 当今的绝对主流。BERT、GPT、T5等所有大型语言模型的基础架构。统治了NLP领域,并扩展到CV(ViT)、多模态等领域

总结与比喻

  • RNN/LSTM/GRU:像一个逐字阅读的人。他必须从头读到尾,并且依靠自己的记忆力来理解整个句子。如果句子太长,他可能会忘记开头的内容
  • Transformer:像一个拥有"神之视角"的读者。他可以把整个文章铺在桌上,一眼看完全文,并立即用彩线画出所有相互关联的词语(注意力机制),从而理解上下文。他读得更快(并行),但对大脑(算力)的要求更高,尤其是文章非常长的时候

总而言之,Transformer凭借其并行化能力和强大的长程依赖建模能力,取代了RNN家族成为自然语言处理等领域的新基石。然而,RNN/LSTM/GRU在计算资源有限、序列较长或需要严格逐步推理的场景中仍然有其价值。

3 Model Architecture

Most competitive neural sequence transduction models have an encoder-decoder structure [5, 2, 35]. Here, the encoder maps an input sequence of symbol representations (x1,...,xn)(x_1, ..., x_n)(x1,...,xn) to a sequence of continuous representations z=(z1,...,zn)\mathbf{z} = (z_1, ..., z_n)z=(z1,...,zn). Given z\mathbf{z}z, the decoder then generates an output sequence (y1,...,ym)(y_1, ..., y_m)(y1,...,ym) of symbols one element at a time. At each step the model is auto-regressive [10], consuming the previously generated symbols as additional input when generating the next.

目前最具竞争力的神经序列转换模型均采用编码器-解码器结构[5,2,35]。其中,编码器将符号表征的输入序列(x1,...,xn)(x_1, ..., x_n)(x1,...,xn)映射为连续表征序列z=(z1,...,zn)\mathbf{z} = (z_1, ..., z_n)z=(z1,...,zn)在给定z\mathbf{z}z的条件下,解码器逐元素生成符号输出序列(y1,...,ym)(y_1, ..., y_m)(y1,...,ym)。该模型在每个时间步均采用自回归方式[10],在生成下一个符号时会将先前已生成的符号作为附加输入。

自回归(Autoregressive, AR)

自回归(Autoregressive, AR) 是一种处理序列数据的经典方法,其核心思想非常直观:用序列中过去的值来预测未来值。 在生成任务中(如文本生成、语音合成、图像生成),自回归方式具有非常明确的运作模式:

  1. 前提假设:序列中的下一个元素(如下一个词元token)的概率分布,依赖于所有之前已生成的元素。
  2. 生成过程
    • 给定一个起始输入(如"请写一首诗关于:春天")。
    • 模型根据当前输入,计算出第一个词的概率分布(P(词1 | 起始输入)),并从中采样(或选择概率最高的词),例如"春"。
    • 然后将已生成的内容(“起始输入 + ‘春’”)作为新的输入,喂给模型,让它预测下一个词(P(词2 | 起始输入, "春")),得到"天"。
    • 重复这个过程:P(词n | 起始输入, "春", "天", ..., 词n-1),直到模型生成一个表示结束的特殊符号。

这个过程可以概括为一个公式:
P(序列) = P(词1) * P(词2 | 词1) * P(词3 | 词1, 词2) * ... * P(词T | 词1, 词2, ..., 词T-1)

简而言之:一步一步地生成,每次生成时都依赖于之前生成的所有内容。

核心特点

特点 说明
串行生成 生成过程是一步一步、顺序进行的。必须先生成第 t 个元素,才能基于它生成第 t+1 个元素。无法并行生成整个序列。
因果掩码 在训练时,为了模拟这种"只能看前面,不能看后面"的特性,模型会使用因果掩码(Causal Mask)。这确保了在计算第 t 个位置的注意力时,它只能关注到 1t 的位置,无法看到 t+1 及之后未来的信息。
exposure bias 一种已知的缺陷。模型在训练时,每一步的输入都是真实的前一个词(Teacher Forcing)。而在推理/生成时,每一步的输入是自己上一步生成的(可能包含错误的)词。这种训练和推理阶段输入分布的不一致,可能导致错误累积和扩散。

The Transformer follows this overall architecture using stacked self-attention and point-wise, fully connected layers for both the encoder and decoder, shown in the left and right halves of Figure 1, respectively.

Transformer遵循这一总体架构,在编码器和解码器中均采用堆叠式自注意力机制与逐点全连接层(分别如图1左半部与右半部所示)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.1 Encoder and Decoder Stacks

Encoder: The encoder is composed of a stack of N = 6 identical layers. Each layer has two sub-layers. The first is a multi-head self-attention mechanism, and the second is a simple, position-wise fully connected feed-forward network. We employ a residual connection [11] around each of the two sub-layers, followed by layer normalization [1]. That is, the output of each sub-layer is LayerNorm(x+Sublayer(x))\text{LayerNorm}(x + \text{Sublayer}(x))LayerNorm(x+Sublayer(x)), where Sublayer(x)\text{Sublayer}(x)Sublayer(x) is the function implemented by the sub-layer itself. To facilitate these residual connections, all sub-layers in the model, as well as the embedding layers, produce outputs of dimension dmodel=512d_{\text{model}} = 512dmodel=512 .

编码器: 编码器由N=6个相同层堆叠而成。每层包含两个子层:第一层是多头自注意力机制,第二层是简单的位置全连接前馈网络。我们在每个子层周围采用残差连接[11],并随后进行层归一化[1]。即每个子层的输出为 LayerNorm(x+Sublayer(x))\text{LayerNorm}(x + \text{Sublayer}(x))LayerNorm(x+Sublayer(x)) ,其中 Sublayer(x)\text{Sublayer}(x)Sublayer(x) 代表该子层自身实现的函数。为支持残差连接,模型中所有子层及嵌入层的输出维度均保持为 dmodel=512d_{\text{model}} = 512dmodel=512

Decoder: The decoder is also composed of a stack of N = 6 identical layers. In addition to the two sub-layers in each encoder layer, the decoder inserts a third sub-layer, which performs multi-head attention over the output of the encoder stack. Similar to the encoder, we employ residual connections around each of the sub-layers, followed by layer normalization. We also modify the self-attention sub-layer in the decoder stack to prevent positions from attending to subsequent positions. This masking, combined with fact that the output embeddings are offset by one position, ensures that the predictions for position iii can depend only on the known outputs at positions less than iii.

解码器: 解码器同样由N=6个相同层堆叠而成。除包含编码器每层中的两个子层外,解码器额外插入第三子层,该层对编码器堆栈的输出执行多头注意力计算。与编码器类似,我们在每个子层周围采用残差连接并后续进行层归一化。同时,我们修改了解码器堆栈中的自注意力子层,以防止当前位置关注到后续位置。这种掩码机制结合输出嵌入向右偏移一位的特性,可确保对位置iii的预测仅依赖于小于iii的已知输出位置。

掩码机制 (Masking Mechanism)

两个处理阶段

Transformer处理信息的过程可清晰地划分为两个阶段:

  1. 特征投影阶段:线性变换,无信息混合
  2. 注意力聚合阶段:计算相关性并加权求和,发生信息混合

掩码机制作用于注意力聚合阶段之内,在计算完注意力分数之后、应用Softmax函数之前这一关键步骤中生效。

第一阶段:特征投影 (Feature Projection) - 无信息混合

目标:为每个单词生成查询、键和值向量

  • 输入结构
    X=[←词向量1→←词向量2→⋮⋮⋮←词向量n→]形状: [n,dmodel] X = \begin{bmatrix} \leftarrow & \text{词向量}_1 & \rightarrow \\ \leftarrow & \text{词向量}_2 & \rightarrow \\ \vdots & \vdots & \vdots \\ \leftarrow & \text{词向量}_n & \rightarrow \end{bmatrix} \quad \text{形状: } [n, d_{\text{model}}] X= 词向量1词向量2词向量n 形状[n,dmodel]

  • 变换操作
    Q=X⋅WQ// 投影到查询空间K=X⋅WK// 投影到键空间V=X⋅WV// 投影到值空间 \begin{aligned} Q &= X \cdot W_Q \quad &\text{// 投影到查询空间} \\ K &= X \cdot W_K \quad &\text{// 投影到键空间} \\ V &= X \cdot W_V \quad &\text{// 投影到值空间} \end{aligned} QKV=XWQ=XWK=XWV// 投影到查询空间// 投影到键空间// 投影到值空间

  • 核心特性

  • 并行独立:输出矩阵的每一行仅依赖于输入矩阵的对应行
  • 无混合:各个单词的向量不被交叉计算
  • 本质:对每个单词的表示进行特征变换或重映射

结论:在此阶段,序列中各个单词的信息完全独立处理,没有混合。

第二阶段:注意力聚合 (Attention Aggregation) - 发生信息混合

1. 计算相关性分数
Scores=Q⋅KT \text{Scores} = Q \cdot K^T Scores=QKT
此处发生信息混合:每个元素都是不同单词查询向量与键向量的点积。

2. 应用掩码 (Masking)
Masked Scores=Scores+M \text{Masked Scores} = \text{Scores} + M Masked Scores=Scores+M

  • MMM 是下三角掩码矩阵,未来位置为 −∞-\infty,当前及之前位置为 000
  • 目的:在信息混合发生后,强制丢弃来自未来位置的信息贡献

3. 生成加权表示
Weights=Softmax(Masked Scores)Z=Weights⋅V \begin{aligned} \text{Weights} &= \text{Softmax}(\text{Masked Scores}) \\ Z &= \text{Weights} \cdot V \end{aligned} WeightsZ=Softmax(Masked Scores)=WeightsV
此处发生最终的信息融合:每个单词的新表示是所有单词值向量的加权和。


具体示例:4词序列的掩码过程

1. 计算注意力分数(未掩码状态)
<s> 一只 <e>
<s> Score(1,1) Score(1,2) Score(1,3) Score(1,4)
一只 Score(2,1) Score(2,2) Score(2,3) Score(2,4)
Score(3,1) Score(3,2) Score(3,3) Score(3,4)
<e> Score(4,1) Score(4,2) Score(4,3) Score(4,4)
2. 创建并应用掩码矩阵
<s> 一只 <e>
<s> 0 -1e9 -1e9 -1e9
一只 0 0 -1e9 -1e9
0 0 0 -1e9
<e> 0 0 0 0

掩码后结果

<s> 一只 <e>
<s> Score(1,1) Score(1,2)-1e9 Score(1,3)-1e9 Score(1,4)-1e9
一只 Score(2,1) Score(2,2) Score(2,3)-1e9 Score(2,4)-1e9
Score(3,1) Score(3,2) Score(3,3) Score(3,4)-1e9
<e> Score(4,1) Score(4,2) Score(4,3) Score(4,4)
3. Softmax转换

Softmax转换结果

  • <s>: [ prob(1,1), 0, 0, 0 ]
  • 一只: [ prob(2,1), prob(2,2), 0, 0 ]
  • : [ prob(3,1), prob(3,2), prob(3,3), 0 ]
  • <e>: [ prob(4,1), prob(4,2), prob(4,3), prob(4,4) ]

"一只" 这个词对 "猫""<e>" 的注意力权重为 0。也就是当计算 "一只" 这个词的表示时,它只能从 "<s>""一只" 本身提取信息,完全无法从未来的 "猫""<e>" 中获取任何信息。这完美地模拟了推理阶段的场景:在预测下一个词时,模型只能依赖于已生成的词。

4. 加权求和

现在,我们来计算"一只"这个词的最终输出表示 Z[2]。计算公式是:

Z[2]=prob(2,1)∗V[1]⏟来自<s>+prob(2,2)∗V[2]⏟来自自身+0∗V[3]⏟来自猫+0∗V[4]⏟来自<e> Z[2] = \underbrace{prob(2,1)*V[1]}_{\text{来自}<s>} + \underbrace{prob(2,2)*V[2]}_{\text{来自自身}} + \underbrace{0*V[3]}_{\text{来自猫}} + \underbrace{0*V[4]}_{\text{来自<e>}} Z[2]=来自<s> prob(2,1)V[1]+来自自身 prob(2,2)V[2]+来自猫 0V[3]+来自<e> 0V[4]

数学等价于Z[2]=prob(2,1)∗V[1]+prob(2,2)∗V[2]Z[2] = prob(2,1)*V[1] + prob(2,2)*V[2]Z[2]=prob(2,1)V[1]+prob(2,2)V[2]

所以,Z[2] 在数学上完全由 V[1]V[2] 线性组合而成,V[3]V[4] 没有提供任何有效信息。


固定参数如何与可变输入一起工作?

模型参数(W_Q, W_K, W_V 等)在推理时是固定不变的,无论输入长度如何变化。

  • 它对输入序列的长度没有假设。只要 QK 的第二个维度(特征维度 d_model)相同,无论它们的第一个维度(序列长度)是1、2还是100,矩阵乘法都可以进行。
  • 输出序列的长度只由 Q 的长度决定,与 KV 的长度无关。

在推理时:

  • 第1步:输入 X = [<s>] (形状 [1, d_model]

  • 输入 X₁ 的形状是 [1, 512]

  • 参数 W_Q 的形状是 [512, 64] (假设 d_k=64

  • Q₁ = X₁ * W_Q -> 输出形状为 [1, 64]

  • 计算 Q, K, V,它们的形状都是 [1, d_model]

  • 计算注意力:Q * K^T 的形状是 [1, 1] -> 得到一个权重,然后与 V[1, d_model]) 加权求和,输出 Z 的形状是 [1, d_model]

  • 第2步:输入 X = [<s>, 一只] (形状 [2, d_model]

  • 输入 X₂ 的形状是 [2, 512]序列长度变了!

  • 参数 W_Q 的形状仍然是 [512, 64]参数没变!

  • Q₂ = X₂ * W_Q -> 输出形状为 [2, 64]

  • 计算 Q, K, V,它们的形状都是 [2, d_model]

  • 计算注意力:Q * K^T 的形状是 [2, 2] -> 得到一个注意力权重矩阵,然后与 V[2, d_model]) 加权求和,输出 Z 的形状是 [2, d_model]

模型参数(W_Q, W_K, W_V 等)在所有步骤中都是共享的,它们只处理特征维度 d_model,与序列长度无关。

3.2 Attention

An attention function can be described as mapping a query and a set of key-value pairs to an output, where the query, keys, values, and output are all vectors. The output is computed as a weighted sum of the values, where the weight assigned to each value is computed by a compatibility function of the query with the corresponding key.

注意力函数可描述为将查询(query)和一组键值对(key-value pairs)映射到输出的过程,其中查询、键、值及输出均为向量。输出通过值的加权和计算得出,而每个值对应的权重则由查询与相应键的兼容性函数计算生成。

3.2.1 Scaled Dot-Product Attention

We call our particular attention “Scaled Dot-Product Attention” (Figure 2). The input consists of queries and keys of dimension dkd_kdk, and values of dimension dvd_vdv. We compute the dot products of the query with all keys, divide each by dk\sqrt{d_k}dk , and apply a softmax function to obtain the weights on the values.

我们将这种特定注意力机制称为"缩放点积注意力"(图2)。其输入由维度为dkd_kdk的查询和键,以及维度为dvd_vdv的值组成。 首先计算查询与所有键的点积,将每个结果除以dk\sqrt{d_k}dk ,然后应用softmax函数获取值的权重分布。

Figure 2: (left) Scaled Dot-Product Attention. (right) Multi-Head Attention consists of several
attention layers running in parallel.

In practice, we compute the attention function on a set of queries simultaneously, packed together into a matrix QQQ. The keys and values are also packed together into matrices KKK and VVV. We compute the matrix of outputs as:
Attention(Q,K,V)=softmax(QKTdk)V \text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QKT)V

实际应用中,我们通常将查询集合同时处理并打包为矩阵QQQ,键与值也相应打包为矩阵KKKVVV。输出矩阵的计算公式为:
Attention(Q,K,V)=softmax(QKTdk)V \text{Attention}(Q, K, V) = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dk QKT)V

注意力机制实例:阅读理解任务

假设我们要用注意力机制让机器回答关于一段文本的问题。文本内容为:
“苹果公司于1976年由史蒂夫·乔布斯、史蒂夫·沃兹尼亚克和罗纳德·韦恩创立,总部位于加利福尼亚州的库比蒂诺。”

问题:“苹果公司的创始人是谁?”

注意力机制三要素
组件 角色 在本例中的对应物
查询 (Query) 想要获取的信息 问题的向量表示:“创始人是谁”
键 (Key) 被检索内容的标识 文本中每个词的向量表示:“苹果”,“公司”,“创立”,“乔布斯”…
值 (Value) 实际返回的内容 文本中每个词的实际信息(通常与Key相同)
注意力计算过程

步骤1:计算注意力分数(相似度)

# 计算问题与每个词的相似度(点积)
query = "创始人是谁"的向量表示
keys = ["苹果", "公司", "于", "1976", "年", "由", "史蒂夫", "·", "乔布斯", "、", ...]的向量表示

# 计算相似度得分(数值为假设)
scores = [
    dot_product(query, "苹果"),    # 得分低:0.1
    dot_product(query, "公司"),    # 得分低:0.2  
    dot_product(query, "于"),      # 得分低:0.05
    dot_product(query, "1976"),    # 得分中:0.3
    dot_product(query, "年"),      # 得分低:0.1
    dot_product(query, "由"),      # 得分高:0.7 ← "由"表示创始人引出
    dot_product(query, "史蒂夫"),  # 得分高:0.8 ← 人名
    dot_product(query, "·"),       # 得分低:0.1
    dot_product(query, "乔布斯"),  # 得分高:0.9 ← 人名
    dot_product(query, "、"),      # 得分中:0.4 ← 并列连接词
    dot_product(query, "沃兹尼亚克"), # 得分高:0.85 ← 人名
    ...]

步骤2:Softmax归一化为权重

# 应用Softmax得到注意力权重(概率分布)
weights = softmax(scores)[
    "苹果": 0.01,    # 几乎不关注
    "公司": 0.02,    # 几乎不关注
    "于": 0.008,     # 几乎不关注  
    "1976": 0.04,    # 轻微关注
    "年": 0.01,      # 几乎不关注
    "由": 0.12,      # 关注:引出创始人
    "史蒂夫": 0.15,   # 关注:人名
    "·": 0.01,       # 几乎不关注
    "乔布斯": 0.18,   # 高度关注:创始人之一
    "、": 0.06,      # 关注:表示并列
    "沃兹尼亚克": 0.17, # 高度关注:创始人之一
    "韦恩": 0.13,    # 关注:创始人之一
    ...]
# 所有权重之和为1

步骤3:加权求和得到输出

# 用权重对对应的值(Value)进行加权求和
output = (
    0.01 * "苹果" + 0.02 * "公司" + ... + 
    0.12 * "由" + 0.15 * "史蒂夫" + 0.18 * "乔布斯" + 
    0.06 * "、" + 0.17 * "沃兹尼亚克" + 0.13 * "韦恩" + ...
)

# 最终输出是一个融合向量,集中了"乔布斯"、"沃兹尼亚克"、"韦恩"等关键信息
可视化注意力权重
文本:苹果公司于1976年由史蒂夫·乔布斯、史蒂夫·沃兹尼亚克和罗纳德·韦恩创立

注意力分布:
苹果   公司   于   1976  年   由   史蒂夫   ·   乔布斯   、   沃兹尼亚克  和   韦恩   创立
0.01  0.02  0.008 0.04  0.01  0.12  0.15   0.01  0.18    0.06  0.17       0.05  0.13  0.02

可见模型高度关注:"乔布斯"(0.18), "沃兹尼亚克"(0.17), "韦恩"(0.13)
最终结果
  • 注意力输出:一个富含"乔布斯、沃兹尼亚克、韦恩"信息的融合向量
  • 预测答案:基于这个加权后的信息,模型可以生成答案:“史蒂夫·乔布斯、史蒂夫·沃兹尼亚克和罗纳德·韦恩”

The two most commonly used attention functions are additive attention [2], and dot-product (multiplicative) attention. Dot-product attention is identical to our algorithm, except for the scaling factor of 1dk\frac{1}{\sqrt{d_k}}dk 1. Additive attention computes the compatibility function using a feed-forward network with a single hidden layer. While the two are similar in theoretical complexity, dot-product attention is much faster and more space-efficient in practice, since it can be implemented using highly optimized matrix multiplication code.

最常用的两种注意力函数是加性注意力[2]和点积(乘法)注意力。点积注意力与本文算法的唯一区别在于缺少1dk\frac{1}{\sqrt{d_k}}dk 1的缩放因子。加性注意力通过使用含单隐藏层的前馈网络计算兼容性函数。虽然两种方法在理论复杂度上相似,但点积注意力在实际应用中速度更快且空间效率更高,因其可通过高度优化的矩阵乘法代码实现。

While for small values of dkd_kdk, the two mechanisms perform similarly, additive attention outperforms dot product attention without scaling for larger values of dkd_kdk [3]. We suspect that for large values of dkd_kdk, the dot products grow large in magnitude, pushing the softmax function into regions where it has extremely small gradients. To counteract this effect, we scale the dot products by 1dk\frac{1}{\sqrt{d_k}}dk 1.

dkd_kdk 值较小时,两种机制表现相似;但dkd_kdk 值较大的情况下,加性注意力性能优于未缩放的点积注意力[3]。我们推测,当 dkd_kdk 较大时,点积的幅值会增大,从而将 softmax 函数推入梯度极小的区域。为抵消这种效应,我们采用 1dk\frac{1}{\sqrt{d_k}}dk 1 对点积进行缩放。

两种注意力函数对比:加性注意力 vs. 点积注意力

1. 点积注意力 (Dot-Product Attention)

计算公式
Attention(Q,K,V)=softmax(QKTdk)V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dk QKT)V

特点

  • 计算方式:直接计算查询(Query)和键(Key)的点积相似度
  • 缩放因子1dk\frac{1}{\sqrt{d_k}}dk 1 用于防止维度较高时点积结果过大
  • 优势
    • 计算高效:可通过高度优化的矩阵乘法实现
    • 空间效率高:不需要额外参数
    • 实际速度快:适合大规模应用
2. 加性注意力 (Additive Attention)

计算公式
Attention(Q,K,V)=softmax(score(Q,K))V \text{Attention}(Q, K, V) = \text{softmax}\left(\text{score}(Q, K)\right)V Attention(Q,K,V)=softmax(score(Q,K))V
score(q,k)=vTtanh⁡(Wqq+Wkk) \text{score}(q, k) = v^T \tanh(W_q q + W_k k) score(q,k)=vTtanh(Wqq+Wkk)

特点

  • 计算方式:通过单隐藏层前馈网络计算兼容性分数
  • 参数:需要学习参数 WqW_qWq, WkW_kWk, vvv
  • 优势
    • 灵活性高:可学习更复杂的匹配模式
    • 表达能力强:适用于查询和键维度不同的情况
3.2.2 Multi-Head Attention

Instead of performing a single attention function with dmodeld_{\text{model}}dmodel-dimensional keys, values and queries, we found it beneficial to linearly project the queries, keys and values hhh times with different, learned linear projections to dkd_kdk, dkd_kdk and dvd_vdv dimensions, respectively. On each of these projected versions of queries, keys and values we then perform the attention function in parallel, yielding dvd_vdv-dimensional output values. These are concatenated and once again projected, resulting in the final values, as depicted in Figure 2.

我们发现,相较于使用dmodeld_{\text{model}}dmodel 维度的键、值和查询执行单一注意力函数,采用以下方式更为有效:使用不同的可学习线性投影矩阵,将查询、键和值分别线性投影hhh次至dkd_kdkdkd_kdkdvd_vdv维度。随后在每个投影版本的查询、键和值上并行执行注意力函数,生成dvd_vdv维输出值。这些输出被拼接后再次投影,最终得到输出结果(如图2所示)

Multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions. With a single attention head, averaging inhibits this.
MultiHead(Q,K,V)=Concat(head1,...,headh)WOwhere headi=Attention(QWiQ,KWiK,VWiV) \begin{aligned} \text{MultiHead}(Q, K, V) &= \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O \\ \text{where head}_i &= \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) \end{aligned} MultiHead(Q,K,V)where headi=Concat(head1,...,headh)WO=Attention(QWiQ,KWiK,VWiV)

Where the projections are parameter matrices WiQ∈Rdmodel×dkW_i^Q \in \mathbb{R}^{d_{\text{model}} \times d_k}WiQRdmodel×dk, WiK∈Rdmodel×dkW_i^K \in \mathbb{R}^{d_{\text{model}} \times d_k}WiKRdmodel×dk, WiV∈Rdmodel×dvW_i^V \in \mathbb{R}^{d_{\text{model}} \times d_v}WiVRdmodel×dv and WO∈Rhdv×dmodelW^O \in \mathbb{R}^{h d_v \times d_{\text{model}}}WORhdv×dmodel.

多头注意力使模型能够共同关注不同位置中来自不同表征子空间的信息。若使用单注意力头,平均化操作会抑制这种能力。
MultiHead(Q,K,V)=Concat(head1,...,headh)WOwhere headi=Attention(QWiQ,KWiK,VWiV) \begin{aligned} \text{MultiHead}(Q, K, V) &= \text{Concat}(\text{head}_1, ..., \text{head}_h)W^O \\ \text{where head}_i &= \text{Attention}(QW_i^Q, KW_i^K, VW_i^V) \end{aligned} MultiHead(Q,K,V)where headi=Concat(head1,...,headh)WO=Attention(QWiQ,KWiK,VWiV)
其中投影矩阵为参数矩阵:WiQ∈Rdmodel×dkW_i^Q \in \mathbb{R}^{d_{\text{model}} \times d_k}WiQRdmodel×dkWiK∈Rdmodel×dkW_i^K \in {R}^{d_{\text{model}} \times d_k}WiKRdmodel×dkWiV∈Rdmodel×dvW_i^V \in \mathbb{R}^{d_{\text{model}} \times d_v}WiVRdmodel×dv 以及 WO∈Rhdv×dmodelW^O \in \mathbb{R}^{h d_v \times d_{\text{model}}}WORhdv×dmodel

In this work we employ h=8h = 8h=8 parallel attention layers, or heads. For each of these we use dk=dv=dmodel/h=64d_k = d_v = d_{\text{model}}/h = 64dk=dv=dmodel/h=64.Due to the reduced dimension of each head, the total computational cost is similar to that of single-head attention with full dimensionality.

本研究中我们采用h=8h=8h=8个并行注意力层(即头)。对每个头设置dk=dv=dmodel/h=64d_k = d_v = d_{\text{model}}/h = 64dk=dv=dmodel/h=64由于每个头的维度降低,总计算成本与全维度的单头注意力相近。

投影机制对比:传统注意力 vs. 多头注意力

1. 传统注意力机制(无多头)
  • 投影情况有投影,但只有一套参数
  • 过程描述:这里我们假设XQ=XK=XVX_Q = X_K = X_VXQ=XK=XV,是自注意力 (Self-Attention)机制,Q, K, V都来自同一个输入序列
  1. 输入矩阵 XXX(例如,n个词的词向量,形状为 [n, d_model])。。
  2. 使用一套投影矩阵 WQW^QWQ, WKW^KWK, WVW^VWVXXX 线性变换为 Q, K, V。
    • Q=X⋅WQ(WQ shape: [dmodel,dk])Q = X \cdot W^Q \quad (W^Q \text{ shape: } [d_{\text{model}}, d_k])Q=XWQ(WQ shape: [dmodel,dk])
    • K=X⋅WK(WK shape: [dmodel,dk])K = X \cdot W^K \quad (W^K \text{ shape: } [d_{\text{model}}, d_k])K=XWK(WK shape: [dmodel,dk])
    • V=X⋅WV(WV shape: [dmodel,dv])V = X \cdot W^V \quad (W^V \text{ shape: } [d_{\text{model}}, d_v])V=XWV(WV shape: [dmodel,dv])
  3. 通常为了简化,设 dk=dv=dmodeld_k = d_v = d_{\text{model}}dk=dv=dmodel
  • 计算过程
    Attention(X)=Softmax(QKTdk)V=Softmax((XWQ)(XWK)Tdk)(XWV) \text{Attention}(X) = \text{Softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V = \text{Softmax}\left(\frac{(XW^Q)(XW^K)^T}{\sqrt{d_k}}\right)(XW^V) Attention(X)=Softmax(dk QKT)V=Softmax(dk (XWQ)(XWK)T)(XWV)
  • 输出:一个形状为 [n, d_model] 的矩阵。所有注意力模式被混合压缩在一个dmodeld_{\text{model}}dmodel维的表征里
2. 多头注意力机制 (Multi-Head Attention)
  • 投影情况有投影,且有h套不同的参数
  • 过程描述:这里我们假设XQ=XK=XVX_Q = X_K = X_VXQ=XK=XV,是自注意力 (Self-Attention)机制,Q, K, V都来自同一个输入序列
  1. 输入同样是矩阵 XXX(形状 [n, d_model])。
  2. 使用 h套 不同的投影矩阵 WiQW_i^QWiQ, WiKW_i^KWiK, WiVW_i^VWiV (i=1,...,hi=1,...,hi=1,...,h) 将 XXX 并行地投影到 h 个不同的子空间。
    headi=Attention(XWiQ,XWiK,XWiV)=Softmax((XWiQ)(XWiK)Tdk)(XWiV) head_i = \text{Attention}(XW_i^Q, XW_i^K, XW_i^V) = \text{Softmax}\left(\frac{(XW_i^Q)(XW_i^K)^T}{\sqrt{d_k}}\right)(XW_i^V) headi=Attention(XWiQ,XWiK,XWiV)=Softmax(dk (XWiQ)(XWiK)T)(XWiV)
  3. 每个头的投影维度减小了,通常 dk=dv=dmodel/hd_k = d_v = d_{\text{model}} / hdk=dv=dmodel/h。每个 headihead_iheadi 的形状是 [n, d_model/h]
  4. 将 h 个头的输出 拼接 (Concat) 起来:Concat(head1,...,headh)Concat(head_1, ..., head_h)Concat(head1,...,headh)(形状 [n, d_model])。
  5. 最后再乘以一个输出投影矩阵 WOW^OWO(形状 [d_model, d_model])来整合信息,并允许模型学习如何融合不同头的特征。
  • 计算过程
    MultiHead(Q,K,V)=Concat(head1,…,headh)WOwhere headi=Attention(XWiQ,XWiK,XWiV) \begin{aligned} \text{MultiHead}(Q, K, V) &= \text{Concat}(head_1, \ldots, head_h) W^O \\ \text{where } head_i &= \text{Attention}(XW_i^Q, XW_i^K, XW_i^V) \end{aligned} MultiHead(Q,K,V)where headi=Concat(head1,,headh)WO=Attention(XWiQ,XWiK,XWiV)
  • 输出:一个形状为 [n, d_model] 的矩阵。这个输出是 h 种不同注意力模式的加权组合
3. 关键对比
特性 传统注意力 多头注意力
投影参数 1套 (WQ,WK,WV)(W^Q, W^K, W^V)(WQ,WK,WV) hhh(WiQ,WiK,WiV)(W_i^Q, W_i^K, W_i^V)(WiQ,WiK,WiV)
表征空间 单一子空间 hhh个不同子空间
关注模式 只能学习一种关注模式 可学习多种关注模式
参数数量 3×dmodel23 \times d_{\text{model}}^23×dmodel2 3×h×dk23 \times h \times d_k^23×h×dk2
计算复杂度 O(n2dmodel)O(n^2 d_{\text{model}})O(n2dmodel) O(n2dmodel)O(n^2 d_{\text{model}})O(n2dmodel)(相当)
4. 维度设计数学

为保持总计算量不变,设置:
dk=dv=dmodelh d_k = d_v = \frac{d_{\text{model}}}{h} dk=dv=hdmodel

参数总量对比

  • 传统:3dmodel23d_{\text{model}}^23dmodel2
  • 多头:3h×(dmodelh)2=3dmodel2h3h \times (\frac{d_{\text{model}}}{h})^2 = \frac{3d_{\text{model}}^2}{h}3h×(hdmodel)2=h3dmodel2

实际上,多头注意力通过降低每头的维度来控制参数量。

5. 为什么需要多套投影?

物理意义:不同的投影矩阵将输入映射到不同的表征子空间

  • 头1:可能学习语法关系投影
  • 头2:可能学习语义关系投影
  • 头3:可能学习位置关系投影
  • 头h:可能学习特定任务投影
6. 实际效果示例

在机器翻译任务中,不同头可能关注:

  • 2个头关注语法对齐
  • 3个头捕捉语义对应
  • 1个头处理罕见词翻译
  • 2个头处理长距离依赖

创新本质
多头注意力的核心创新不在于"是否投影",而在于"如何投影"——通过多组不同的投影矩阵,让模型能够从多个角度理解和处理输入信息,从而显著提升模型的表达能力和性能。

3.2.3 Applications of Attention in our Model

The Transformer uses multi-head attention in three different ways:

  • In “encoder-decoder attention” layers,the queries come from the previous decoder layer, and the memory keys and values come from the output of the encoder. This allows every position in the decoder to attend over all positions in the input sequence. This mimics the typical encoder-decoder attention mechanisms in sequence-to-sequence models such as [38, 2, 9].
  • The encoder contains self-attention layers. In a self-attention layer all of the keys, values and queries come from the same place, in this case, the output of the previous layer in the encoder. Each position in the encoder can attend to all positions in the previous layer of the encoder.
  • Similarly, self-attention layers in the decoder allow each position in the decoder to attend to all positions in the decoder up to and including that position.We need to prevent leftward information flow in the decoder to preserve the auto-regressive property. We implement this inside of scaled dot-product attention by masking out (setting to −∞-\infty) all values in the input of the softmax which correspond to illegal connections. See Figure 2.

Transformer在以下三个场景中应用多头注意力机制:

  1. 编码器-解码器注意力层:查询来自解码器上一层,记忆键值对来自编码器输出。该机制使解码器中每个位置都能关注输入序列的所有位置,模拟了[38,2,9]等序列到序列模型中典型的编码器-解码器注意力机制。
  2. 编码器自注意力层:所有键、值和查询均来自同一源——即编码器上一层的输出。编码器中每个位置可关注编码器前一层的所有位置。
  3. 解码器自注意力层:解码器中每个位置可关注该位置之前(含)的所有解码器位置为保持自回归特性,需阻止解码器中的向左信息流。我们通过掩码技术实现这一点:在缩放点积注意力中,将softmax输入内所有非法连接对应的值掩码为−∞-\infty(详见图2)。

注意力机制的两种核心场景

1. 自注意力 (Self-Attention) - Q, K, V 同源
  • 功能:让序列内部的元素相互建立关系。
  • 来源:Q, K, V 都来自同一个输入序列X
  • Q = X * W_Q
  • K = X * W_K
  • V = X * W_V
  • 应用:Transformer的编码器解码器的掩码自注意力层
2. 编码器-解码器注意力 (Cross-Attention) - Q, K, V 异源
  • 功能:让一个序列(解码器)查询另一个序列(编码器)的信息。
  • 来源
  • Q (Query):来自解码器的当前状态。“我想生成下一个词了,我该关注什么?”
  • K, V (Key, Value):来自编码器的最终输出。“这是我能提供的所有源信息。”
  • Q = Decoder_Output * W_Q
  • K = Encoder_Output * W_K
  • V = Encoder_Output * W_V
  • 应用:Transformer解码器的第二层注意力(就在掩码自注意力层之后)。

例子1:情感分析(编码器自注意力层)

  • 任务: 情感分析(判断句子情感是正面还是负面)
  • 输入句子: "Good movie" (正面)
  • 简化设定:
  • 词汇表: {"good": [1, 0], "movie": [0, 1]} (2维向量)
  • 忽略位置编码、偏置项、LayerNorm等细节。
  • 使用单头注意力,注意力维度 d_k = d_v = 2
  • 假设我们已有一个简单的权重矩阵(为了计算,我们直接定义它们)。
第0步:输入嵌入 (Input Embedding)

我们将单词转换为向量:

  • X_good = [1, 0]
  • X_movie = [0, 1]

我们的输入序列矩阵 X 就是这两个向堆叠:
X = [ [1, 0], # Good [0, 1] ] # Movie

第1步:一次编码

第1层:自注意力层 (Self-Attention Layer)
假设这一层的权重矩阵为:

  • W_Q = [ [1, 0], [0, 1] ] (单位矩阵,简单起见)
  • W_K = [ [1, 0], [0, 1] ]
  • W_V = [ [1, 1], [0, 1] ] (稍微复杂一点,为了产生变化)

1. 计算Q, K, V

Q = X * W_Q = X * I = X = [ [1, 0], [0, 1] ]
K = X * W_K = X * I = X = [ [1, 0], [0, 1] ]
V = X * W_V = [ [1, 0] * [1,1;0,1] = [1, 1], [0, 1] * [1,1;0,1] = [0, 1] ] = [ [1, 1], [0, 1] ]

2. 计算注意力分数 (Score) 和权重 (Weights)
Scores = Q * K^T = [ [1,0], [0,1] ] * [ [1,0], [0,1] ]^T = [ [1*1+0*0, 1*0+0*1], [0*1+1*0, 0*0+1*1] ] = [ [1, 0], [0, 1] ]
Weights = softmax(Scores) = softmax([ [1, 0], [0, 1] ]) = [ [e^1/(e^1+e^0), e^0/(e^1+e^0)], [e^0/(e^0+e^1), e^1/(e^0+e^1)] ] ≈ [ [0.73, 0.27], [0.27, 0.73] ]

3. 计算注意力输出 (Z)
Z = Weights * V = [ [0.73, 0.27], [0.27, 0.73] ] * [ [1, 1], [0, 1] ]
Z_good = 0.73 * [1,1] + 0.27 * [0,1] = [0.73, 0.73] + [0, 0.27] = [0.73, 1.00]
Z_movie = 0.27 * [1,1] + 0.73 * [0,1] = [0.27, 0.27] + [0, 0.73] = [0.27, 1.00]
Z = [ [0.73, 1.00], [0.27, 1.00] ]

发生了什么?

  • Z_good 是73%的自身向量 + 27%的movie向量。它现在不再只是[1,0],而是包含了movie信息的[0.73, 1.00]
  • Z_movie 是27%的good向量 + 73%的自身向量。它变成了[0.27, 1.00],包含了good的信息。
  • 输出Z就是新的、包含上下文信息的词表示。它进入了下一层。

第2层:全连接层 (FFN Layer)

假设FFN是一个简单的网络:FFN(x) = max(0, x * W1 + b1) * W2 + b2
为了超级简化,我们设:

  • W1 = [ [1, 0], [0, 1] ], b1 = 0
  • W2 = [ [2, 0], [0, 2] ], b2 = 0 (一个放大操作)
  • 激活函数使用 ReLU。

1. 对每个位置进行处理(以Z_good为例)
FFN_input = Z_good = [0.73, 1.00]
Hidden = ReLU( [0.73, 1.00] * [1,0;0,1] + 0 ) = ReLU([0.73, 1.00]) = [0.73, 1.00] (ReLU对正数无影响)
FFN_output = [0.73, 1.00] * [2,0;0,2] + 0 = [1.46, 2.00]

2. 对Z_movie进行同样操作
FFN_input = Z_movie = [0.27, 1.00]
FFN_output = [0.27, 1.00] * [2,0;0,2] = [0.54, 2.00]

这一层的最终输出:
Output_Layer1 = [ [1.46, 2.00], [0.54, 2.00] ]

发生了什么?
FFN对注意力输出的特征进行了非线性变换和放大,增强了模型的表达能力。这个输出将成为第二层注意力层的输入

第2步:二次编码

现在,第二层注意力层的输入不再是原始的X,而是上一层的输出Output_Layer1

假设第二层的权重矩阵是新的(模型学习的),我们设为:

  • W_Q2 = [ [0, 1], [1, 0] ] (一个旋转矩阵)
  • W_K2 = [ [0, 1], [1, 0] ]
  • W_V2 = [ [1, 0], [0, 1] ] (单位矩阵)

1. 计算新的Q, K, V
X2 = Output_Layer1 = [ [1.46, 2.00], [0.54, 2.00] ]
Q2 = X2 * W_Q2 = [ [1.46, 2.00] * [0,1;1,0] = [2.00, 1.46], [0.54, 2.00] * [0,1;1,0] = [2.00, 0.54] ]
K2 = X2 * W_K2 = [ [2.00, 1.46], [2.00, 0.54] ] (同上)
V2 = X2 * W_V2 = X2 = [ [1.46, 2.00], [0.54, 2.00] ] (因为V权重是单位矩阵)

2. 计算新的注意力和输出
Scores2 = Q2 * K2^T = [ [2.00, 1.46], [2.00, 0.54] ] * [ [2.00, 2.00], [1.46, 0.54] ] (…计算略…)
Weights2 = softmax(Scores2)
Z2 = Weights2 * V2

核心思想:
第二层注意力是在第一层已经加工过的特征[1.46, 2.00][0.54, 2.00])之上,再次进行“查询-键-值”操作。它能发现更复杂、更抽象的关系,因为它的“原材料”已经更好、信息更丰富。


例子2:机器翻译 (编码器-解码器注意力层)

任务:将英文“A cat”翻译成德语“Eine Katze”。
我们聚焦于解码器生成第二个词“Katze”时的编码器-解码器注意力层

假设简化编码器已经处理完输入:

  • Encoder_Output_A = [0.9, 0.1] (编码器对"A"的深层表示)
  • Encoder_Output_cat = [0.2, 0.8] (编码器对"cat"的深层表示)
  • Encoder_Output = [ [0.9, 0.1], [0.2, 0.8] ]

假设解码器已生成第一个词“Eine”并得到其状态:

  • Decoder_State_Eine = [0.4, 0.6] (解码器对"Eine"的深层表示)

现在,解码器要基于Decoder_State_EineEncoder_Output来生成下一个词“Katze”。

第1步:计算当前层的 Q, K, V(异源!)

  1. 计算 Q (来自解码器)
  • Q = Decoder_State_Eine * W_Q
  • 假设 W_Q = [[1, 0], [0, 1]] (单位矩阵)
  • Q = [0.4, 0.6] * I = [0.4, 0.6]
  • Q的含义:代表解码器当前的“疑问”或“状态”,即“我已经生成了‘Eine’,接下来该是什么?”
  1. 计算 K, V (来自编码器)
  • K = Encoder_Output * W_K
  • V = Encoder_Output * W_V
  • 假设 W_K = [[1, 0], [0, 1]], W_V = [[1, 0], [0, 1]]
  • K = [ [0.9, 0.1], [0.2, 0.8] ] (Key:编码器信息的“标签”)
  • V = [ [0.9, 0.1], [0.2, 0.8] ] (Value:编码器信息的“内容”)

第2步:计算注意力(解码器查询编码器)

  1. 计算注意力分数:衡量解码器当前状态(Q)与编码器每个位置(K)的相关性。
  • Scores = Q * K^T = [0.4, 0.6] * [ [0.9, 0.2], [0.1, 0.8] ] = [0.4*0.9+0.6*0.1, 0.4*0.2+0.6*0.8] = [0.36+0.06, 0.08+0.48] = [0.42, 0.56]
  • 分数显示,当前状态与编码器的第二个词“cat”(0.56) 比第一个词“A”(0.42) 更相关。
  1. 计算注意力权重
  • Weights = softmax([0.42, 0.56]) ≈ [0.45, 0.55]
  • 权重确认了这一点:模型应该55% 地关注“cat”,45% 地关注“A”。
  1. 计算上下文向量
  • Context = Weights * V = 0.45 * [0.9, 0.1] + 0.55 * [0.2, 0.8] = [0.405, 0.045] + [0.11, 0.44] = [0.515, 0.485]
  • 这个上下文向量 [0.515, 0.485] 就是一个融合了源语言最重要信息的摘要。它回答了解码器的“疑问”。

第3步:使用上下文向量

  1. 组合信息: 解码器将自身的状态 (Decoder_State_Eine) 和上下文向量 (Context) 组合在一起(通常是拼接在一起或相加),形成一个全新的、信息更丰富的向量。
    Combined_Vector = Combine(Decoder_State_Eine, Context)

  2. 通过前馈神经网络(FFN): 这个组合后的向量会被送入一个前馈神经网络。这个FFN是一个强大的函数逼近器,它学会了如何将这种“组合意图”映射到一个更高级的、准备用于预测的表示。
    FFN_Output = FFN(Combined_Vector)

  3. 通过输出投影和Softmax: FFN的输出被送入一个最终的线性投影层(一个矩阵乘法),将其投影到一个维度为整个目标语言词汇表大小的向量上。
    Logits = FFN_Output * W_vocabW_vocab的形状是 [d_model, vocab_size]
    这个得到的向量 Logits 的每个元素,对应着词汇表中每个词的一个“分数”。
    词表可以人为训练;或在调模型时使用Hugging Face transformers的 AutoTokenizer之类的库加载模型的分词器,自动导入tokenizer.json/vocab.txt/……训练好的词表文件

    • 分词 (Tokenization): 模型使用它那个固定的、预先训练好的词汇表,将您的输入文本切割成它能认识的“符号”(Tokens)。例如:您输入:“Explain attention.”

    • 分词过程: “Explain” -> [“Expl”, “##ain”]; “attention” -> [“attent”, “##ion”]; “.” -> [“.”]
      您的句子被转换成了一个符号ID序列:[10994, 2378, 4740, 1012](这些数字是词汇表中每个符号对应的唯一ID)。

    • 模型处理: 模型接收这个ID序列,通过其内部的神经网络(包括我们讨论的所有注意力和FFN层)进行处理。

    • 生成输出: 在输出端,模型计算的是下一个符号的概率分布,这个分布覆盖的是它整个预定义词汇表(比如10万个符号)。模型选择概率最高的那个符号ID(例如,ID 4632 对应着 “Sure”)。
      然后,它将这个新生成的符号加回到输入中,继续预测下一个符号,如此循环,直到生成一个完整的回复。

    • 解码: 最终,将生成的符号ID序列 [4632, 1234, …] 通过同一个词汇表反向查找,转换回人类可读的文本:“Sure, I’d be happy to explain…”。

  4. 概率分布:Logits通过Softmax函数,将这些分数转换为概率分布。词汇表中每个词都有一个概率,所有词的概率之和为1。
    Probabilities = Softmax(Logits)

  5. 选择输出词: 模型选择概率最高的那个词作为输出。在我们的例子中,“Katze”的概率最高,因此被选中。
    Output_Word = "Katze"


例子3:解码器自注意力层

训练阶段 (Teacher Forcing)

在训练时,我们采用一种叫做 “教师强制” 的策略。这个过程是这样的:

  1. 输入:编码器接收源句子,例如英文 "A cat"
  2. 编码:编码器将其处理成一个包含所有信息的上下文向量(可以看作是一组向量)。
  3. 解码器输入:解码器不会自己生成输入。我们会直接把完整的目标句子(例如中文 "<开始> 一只 猫 <结束>")输入给解码器。
  4. 解码器任务:解码器的任务不是“生成”句子,而是学习预测下一个词
  • 第一步:给定 "<开始>",预测下一个词应该是 "一只"
  • 第二步:给定 "<开始> 一只",预测下一个词应该是 "猫"
  • 第三步:给定 "<开始> 一只 猫",预测下一个词应该是 "<结束>"

为什么这么做?
因为这使得训练过程是并行的且稳定的。模型在每一步都有正确的上文作为指导,可以快速、高效地学习到“给定上文,下一个词是什么”的映射关系。

所以,在训练时:

  • 编码器使用英文词表
  • 解码器使用中文词表
  • 逻辑上是两个词表,所以需要两个嵌入层。但如果中英文词表合并了,也可以共享权重。
推理/预测阶段

在推理时(比如用训练好的模型做翻译),我们没有正确答案(目标句子)可以输入了。

  1. 输入:编码器接收源句子 "A cat"
  2. 编码:编码器生成上下文向量。
  3. 开始解码
  • 第一步:解码器输入一个起始符 "<开始>",输出一个概率分布,我们选择概率最高的词,比如 "一只"
  1. 循环解码
  • 第二步:解码器将自己上一步的输出 "一只" 作为输入,再结合编码器的信息,预测下一个词,得到 "猫"
  • 第三步:解码器再将 "猫" 作为输入,预测下一个词,得到 "<结束>"
  • 生成结束。

所以,在推理时:
解码器的输入不再是完整的目标句子,而是它自己刚刚生成的结果。这是一个自回归的过程,像循环神经网络一样一步一步地进行。

3.3 Position-wise Feed-Forward Networks

In addition to attention sub-layers, each of the layers in our encoder and decoder contains a fully connected feed-forward network, which is applied to each position separately and identically. This consists of two linear transformations with a ReLU activation in between.
FFN(x)=max⁡(0,xW1+b1)W2+b2 \text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2 FFN(x)=max(0,xW1+b1)W2+b2

除注意力子层外,编码器与解码器的每个层都包含一个全连接前馈网络,该网络以相同方式独立处理每个位置。 其结构由两个线性变换及中间的ReLU激活函数组成:
FFN(x)=max⁡(0,xW1+b1)W2+b2 \text{FFN}(x) = \max(0, xW_1 + b_1)W_2 + b_2 FFN(x)=max(0,xW1+b1)W2+b2

ReLU: 线性整流函数
“参数共享” 强调的是对Z的每一行独立进行 xW1 + b1 操作。即无论哪一行,使用的 W1 和 W2 都是同一套。

  • “Good”(位置1)的计算用的是 W1 和 W2。
  • “Movie”(位置2)的计算用的也是 W1 和 W2。

这就是 “所有位置共享同一组FFN参数” 的含义。同一个参数矩阵 W1 分别与不同的输入数据 x1 和 x2 相乘。

While the linear transformations are the same across different positions, they use different parameters from layer to layer. Another way of describing this is as two convolutions with kernel size 1. The dimensionality of input and output is dmodel=512d_{\text{model}} = 512dmodel=512, and the inner-layer has dimensionality dff=2048d_{ff} = 2048dff=2048.

尽管线性变换在不同位置间保持一致,但不同层使用不同的参数。这也可理解为两个核大小为1的卷积操作。输入输出维度为dmodel=512d_{\text{model}} = 512dmodel=512,内层维度为dff=2048d_{ff} = 2048dff=2048

  • 编码器第1层的FFN参数、第2层的FFN参数…第6层的FFN参数,每一层都是不同的,都是独立学习和更新的。
  • 维度:512 -> 2048(Feed-Forward network 的中间维度。) -> 512

3.4 Embeddings and Softmax

Similarly to other sequence transduction models, we use learned embeddings to convert the input tokens and output tokens to vectors of dimension dmodeld_{\text{model}}dmodel. We also use the usual learned linear transformation and softmax function to convert the decoder output to predicted next-token probabilities. In our model, we share the same weight matrix between the two embedding layers and the pre-softmax linear transformation, similar to [30]. In the embedding layers, we multiply those weights by dmodel\sqrt{d_{\text{model}}}dmodel .

与其他序列转换模型类似,我们使用可学习嵌入 将输入标记和输出标记转换为维度 dmodeld_{\text{model}}dmodel 的向量。 同时采用常规的可学习线性变换和softmax函数,将解码器输出转换为预测的下一个标记概率。本模型中,我们参照[30]的方法,在两个嵌入层与softmax前置线性变换之间共享权重矩阵。在嵌入层中,我们将这些权重乘以dmodel\sqrt{d_{\text{model}}}dmodel

为什么是可学习的?它是如何学习的?

在Transformer以及几乎所有的现代深度学习模型中,嵌入(Embedding)是可学习的。这正是它们强大能力的核心来源之一。
“可学习”是嵌入层与传统的独热编码(One-hot Encoding)等固定编码方式最根本的区别。

嵌入层本质上是一个巨大的参数矩阵,而这个矩阵中的每一个值都是模型需要学习的参数。

1. 初始化

  • 在训练开始前,这个嵌入矩阵中的值通常被随机初始化为一些很小的随机数(比如从均值为0、标准差为0.02的正态分布中采样)。
  • 此时,每个词的向量表示是随机的、没有意义的。

2. 学习过程
模型开始在有标签的数据上进行训练(例如,做翻译任务:输入“猫”,期望输出“cat”)。

  • 前向传播:模型使用当前的嵌入矩阵将词转换为向量,并进行一系列计算,最终得到一个预测结果。
  • 计算损失:计算预测结果与真实结果之间的损失(Loss)
  • 反向传播:模型会计算损失函数对网络中每一个参数的梯度,这其中就包括嵌入矩阵中的每一个值
  • 参数更新:优化器(如Adam)根据这些梯度来更新嵌入矩阵的值,使得模型在下一次做出更好预测的可能性增加。

3. 结果

  • 通过成千上万次这样的更新,嵌入矩阵中的值不再随机。
  • 语义或语法上相似的词(如“猫”和“狗”),由于在训练数据中出现的上下文环境相似,它们在反向传播过程中接收到的梯度更新信号也相似,因此它们的向量在空间中的位置会逐渐彼此靠近。
  • 最终,这个嵌入矩阵从一堆随机数,变成了一张精准的“词义地图”。模型自己学会了如何将抽象符号映射到数学空间,并在这个空间中保留词语之间的语义关系。

我们平时说的“BERT直接编码”,指的是我们在使用它时,不需要再为特定任务重新训练它(即冻结参数,不更新),它的所有参数(包括词嵌入矩阵)都已经在预训练阶段学习完毕并固定下来了。而不是说它没有经历过训练过程,它的一切能力都来源于那个昂贵且复杂的预训练过程。


为什么有两个嵌入层?

最主要的原因是:编码器和解码器的词汇表可能是完全不同的

  • 英文词汇表包含的是 ["a", "cat", "the", "dog", ...]
  • 中文词汇表包含的是 ["一", "只", "猫", "狗", ...]

因此,逻辑上必须有两个独立的嵌入层来处理两个不同的词汇表。
让我们以机器翻译(英译中)为例:

  1. 编码器的嵌入层 (Encoder Embedding):

    • 输入源语言序列(Source Sequence),例如英文句子:"A cat"
    • 任务:将"A""cat"这些英文单词转换为向量。
    • 功能:为编码器提供源语言的词向量表示,让其能够理解输入的句子。
  2. 解码器的嵌入层 (Decoder Embedding):

    • 输入目标语言序列(Target Sequence),例如正在生成的中文翻译:"一只 猫"
    • 任务:将"一只""猫"这些中文单词转换为向量。
    • 功能:为解码器提供目标语言的词向量表示,让其知道目前已经生成了哪些词,并基于此预测下一个词。

一个重要技巧:共享权重

虽然逻辑上是两个层,但在很多实现中,如果源语言和目标语言的词汇表是相同的(或者在重叠的部分),工程师会让这两个嵌入层共享同一个权重矩阵

  • 任务类型:在语言模型任务中,输入和输出是同一个语言(比如用上文预测下一个词),词汇表完全一致。这时共享权重是天经地义的。
  • 词汇表重叠:即使在翻译任务中,如果词汇表被构建成一个包含源语言和目标语言所有词汇的联合大词汇表,那么也可以共享。例如,一个大型多语言模型可能就使用一个巨大的共享词汇表。

共享权重有什么好处?

  1. 大幅减少参数量:模型只需要学习一套词向量,而不是两套。
  2. 提升性能:对于在两种语言中写法、含义都相似的词(例如:"cat"和“猫”、"network"和“网络”),模型会学到让它们的向量表示也非常接近。这为模型学习对齐两种语言提供了强大的 inductive bias(归纳偏差)。

在嵌入层中乘以 dmodel\sqrt{d_{\text{model}}}dmodel

在嵌入层中乘以 dmodel\sqrt{d_{\text{model}}}dmodel 是一个精心设计的初始化策略,其主要目的是为了补偿嵌入向量初始范数过小的问题,从而稳定训练初期并加速收敛

  • 嵌入层的初始化:在训练开始时,嵌入矩阵中的权重通常是从一个均值为0、标准差很小的正态分布中随机采样得到的(例如,N(0, 0.02))。这意味着每个初始的嵌入向量(vinitialv_{\text{initial}}vinitial)的值都很小,接近0。
  • 向量的范数:一个向量的L2范数(Euclidean norm)可以粗略地衡量它的"长度"或"幅度"。由于初始值很小,这些初始嵌入向量的范数也非常小。
  • 问题所在:在Transformer的架构中,嵌入向量的"长度"需要与后续的位置编码(Positional Encoding) 以及注意力机制中的点积操作相匹配。如果嵌入向量太"短",而位置编码是固定尺度的,那么在它们相加之后,位置信息可能会主导词义信息,干扰模型最初的学习。

为了纠正这个问题,论文选择将学习到的嵌入向量放大 dmodel\sqrt{d_{\text{model}}}dmodel 倍。

数学原理

  • 一个由 ddd 个均值为0、方差为 σ2\sigma^2σ2 的随机变量组成的向量,其期望的L2范数大约是 σd\sigma \sqrt{d}σd
  • 假设嵌入权重初始化的标准差是1(或者一个常数),那么初始嵌入向量的期望范数就与 dmodel\sqrt{d_{\text{model}}}dmodel 成正比。
  • 因此,将嵌入向量乘以 dmodel\sqrt{d_{\text{model}}}dmodel ,可以将其期望范数放大到大约与 dmodeld_{\text{model}}dmodel 成正比,从而使其幅度调整到一个更合理的范围。

更直观的理解

  • 可以把这个操作看作是一种反向的"归一化"。常见的操作是对向量进行归一化使其变为单位向量(长度为1)。而这里的问题是向量太短了,所以需要把它"拉长"到一个预期的尺度上。
  • dmodel\sqrt{d_{\text{model}}}dmodel 是一个经验性的选择,它恰好能很好地将向量尺度调整到与模型其他部分(如位置编码、注意力计算)相匹配的程度。

3.5 Positional Encoding

Since our model contains no recurrence and no convolution, in order for the model to make use of the order of the sequence, we must inject some information about the relative or absolute position of the tokens in the sequence. To this end, we add “positional encodings” to the input embeddings at the bottoms of the encoder and decoder stacks.The positional encodings have the same dimension dmodeld_{\text{model}}dmodel as the embeddings, so that the two can be summed. There are many choices of positional encodings, learned and fixed [9].

由于我们的模型不包含循环与卷积结构,为使模型能够利用序列的顺序信息,我们必须注入关于序列中标记相对或绝对位置的信息。 为此,我们在编码器和解码器堆栈底部的输入嵌入中添加"位置编码"。位置编码与嵌入具有相同的维度dmodeld_{\text{model}}dmodel,因此二者可直接相加。位置编码存在多种选择方案,包括可学习的和固定的方式[9]。

In this work, we use sine and cosine functions of different frequencies:
PE(pos,2i)=sin⁡(pos/100002i/dmodel)PE(pos,2i+1)=cos⁡(pos/100002i/dmodel) \begin{aligned} PE_{(pos, 2i)} &= \sin(pos / 10000^{2i/d_{\text{model}}}) \\ PE_{(pos, 2i+1)} &= \cos(pos / 10000^{2i/d_{\text{model}}}) \end{aligned} PE(pos,2i)PE(pos,2i+1)=sin(pos/100002i/dmodel)=cos(pos/100002i/dmodel)
where pospospos is the position and iii is the dimension. That is, each dimension of the positional encoding corresponds to a sinusoid. The wavelengths form a geometric progression from 2π2\pi2π to 10000⋅2π10000 \cdot 2\pi100002π. We chose this function because we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset kkk, PEpos+kPE_{pos+k}PEpos+k can be represented as a linear function of PEposPE_{pos}PEpos.

本研究中,我们使用不同频率的正弦与余弦函数:
PE(pos,2i)=sin⁡(pos/100002i/dmodel)PE(pos,2i+1)=cos⁡(pos/100002i/dmodel) \begin{aligned} PE_{(pos, 2i)} &= \sin(pos / 10000^{2i/d_{\text{model}}}) \\ PE_{(pos, 2i+1)} &= \cos(pos / 10000^{2i/d_{\text{model}}}) \end{aligned} PE(pos,2i)PE(pos,2i+1)=sin(pos/100002i/dmodel)=cos(pos/100002i/dmodel)
其中pospospos表示位置,iii表示维度。即位置编码的每个维度对应一个正弦曲线。其波长构成从2π2\pi2π10000⋅2π10000 \cdot 2\pi100002π的几何级数。选择该函数的原因是我们假设:模型能借此轻松学习通过相对位置进行注意力计算,因为对于任意固定偏移量kkkPEpos+kPE_{pos+k}PEpos+k可表示为PEposPE_{pos}PEpos的线性函数。

We also experimented with using learned positional embeddings [9] instead, and found that the two versions produced nearly identical results (see Table 3 row (E)). We chose the sinusoidal version because it may allow the model to extrapolate to sequence lengths longer than the ones encountered during training.

我们还尝试使用可学习的位置嵌入[9]进行对比实验,发现两种方案产生的结果几乎相同(参见表3第(E)行)。最终选择正弦编码方案,是因为它能使模型外推至比训练时更长的序列长度。

为什么分母是10000?

这个10000是一个超参数,它的具体值没有严格的数学推导,但它的选择是为了实现一个特定的目的:控制不同维度上的正弦波长

我们来看看位置编码的公式:

PE(pos,2i)=sin⁡(pos/100002i/dmodel)PE_{(pos, 2i)} = \sin(pos / 10000^{2i/d_{\text{model}}})PE(pos,2i)=sin(pos/100002i/dmodel)
PE(pos,2i+1)=cos⁡(pos/100002i/dmodel)PE_{(pos, 2i+1)} = \cos(pos / 10000^{2i/d_{\text{model}}})PE(pos,2i+1)=cos(pos/100002i/dmodel)

分母中的 100002i/dmodel10000^{2i/d_{\text{model}}}100002i/dmodel 实际上是控制波长的部分。当 iii 从0到 dmodel/2−1d_{\text{model}}/2 - 1dmodel/21 变化时,这个值会从 100000=110000^0 = 1100000=1 变化到 100001=1000010000^1 = 10000100001=10000。这意味着:

  • 对于较低的维度 (iii 较小),波长较短,频率较高。这些维度能捕捉到序列中位置的精细变化
  • 对于较高的维度 (iii 较大),波长较长,频率较低。这些维度能捕捉到序列中位置的宏观变化

选择10000这个值,是为了让波长覆盖一个很大的范围,从 2π2\pi2π10000⋅2π10000 \cdot 2\pi100002π。这确保了在不同的位置维度上,模型都能得到足够丰富的位置信息,无论是近距离的相对位置还是远距离的相对位置。


为什么PE(pos+k)是PE(pos)的线性函数?

这是正弦位置编码的核心优势,也是它能够让模型轻松学习相对位置的关键原因。

利用三角函数的和差公式:

sin⁡(A+B)=sin⁡(A)cos⁡(B)+cos⁡(A)sin⁡(B)\sin(A+B) = \sin(A)\cos(B) + \cos(A)\sin(B) sin(A+B)=sin(A)cos(B)+cos(A)sin(B)
cos⁡(A+B)=cos⁡(A)cos⁡(B)−sin⁡(A)sin⁡(B) \cos(A+B) = \cos(A)\cos(B) - \sin(A)\sin(B) cos(A+B)=cos(A)cos(B)sin(A)sin(B)

我们可以把 PE(pos+k,i)PE_{(pos+k, i)}PE(pos+k,i) 展开。
A=pos/100002i/dmodelA = pos / 10000^{2i/d_{\text{model}}}A=pos/100002i/dmodelB=k/100002i/dmodelB = k / 10000^{2i/d_{\text{model}}}B=k/100002i/dmodel

对于偶数维度 2i2i2i
PE(pos+k,2i)=sin⁡((pos+k)/100002i/dmodel)=sin⁡(A+B)=sin⁡(A)cos⁡(B)+cos⁡(A)sin⁡(B)=sin⁡(A)cos⁡(k/100002i/dmodel)+cos⁡(A)sin⁡(k/100002i/dmodel)PE_{(pos+k, 2i)} = \sin((pos+k) / 10000^{2i/d_{\text{model}}}) = \sin(A+B) = \sin(A)\cos(B) + \cos(A)\sin(B) = \sin(A)\cos(k / 10000^{2i/d_{\text{model}}}) + \cos(A)\sin(k / 10000^{2i/d_{\text{model}}})PE(pos+k,2i)=sin((pos+k)/100002i/dmodel)=sin(A+B)=sin(A)cos(B)+cos(A)sin(B)=sin(A)cos(k/100002i/dmodel)+cos(A)sin(k/100002i/dmodel)

对于奇数维度 2i+12i+12i+1
PE(pos+k,2i+1)=cos⁡((pos+k)/100002i/dmodel)=cos⁡(A+B)=cos⁡(A)cos⁡(B)−sin⁡(A)sin⁡(B)=cos⁡(A)cos⁡(k/100002i/dmodel)−sin⁡(A)sin⁡(k/100002i/dmodel)PE_{(pos+k, 2i+1)} = \cos((pos+k) / 10000^{2i/d_{\text{model}}}) = \cos(A+B) = \cos(A)\cos(B) - \sin(A)\sin(B) = \cos(A)\cos(k / 10000^{2i/d_{\text{model}}}) - \sin(A)\sin(k / 10000^{2i/d_{\text{model}}})PE(pos+k,2i+1)=cos((pos+k)/100002i/dmodel)=cos(A+B)=cos(A)cos(B)sin(A)sin(B)=cos(A)cos(k/100002i/dmodel)sin(A)sin(k/100002i/dmodel)

你会发现:

  • sin⁡(A)=PE(pos,2i)\sin(A) = PE_{(pos, 2i)}sin(A)=PE(pos,2i)
  • cos⁡(A)=PE(pos,2i+1)\cos(A) = PE_{(pos, 2i+1)}cos(A)=PE(pos,2i+1)

B=k/100002i/dmodelB = k / 10000^{2i/d_{\text{model}}}B=k/100002i/dmodel 是一个与位置 pospospos 无关的常数,它只取决于偏移量 kkk维度 iii。因此,sin⁡(B)\sin(B)sin(B)cos⁡(B)\cos(B)cos(B) 也是常数。

所以,我们可以得到:
PE(pos+k,2i)=PE(pos,2i)⋅常数1+PE(pos,2i+1)⋅常数2PE_{(pos+k, 2i)} = PE_{(pos, 2i)} \cdot \text{常数1} + PE_{(pos, 2i+1)} \cdot \text{常数2}PE(pos+k,2i)=PE(pos,2i)常数1+PE(pos,2i+1)常数2
PE(pos+k,2i+1)=PE(pos,2i+1)⋅常数3−PE(pos,2i)⋅常数4PE_{(pos+k, 2i+1)} = PE_{(pos, 2i+1)} \cdot \text{常数3} - PE_{(pos, 2i)} \cdot \text{常数4}PE(pos+k,2i+1)=PE(pos,2i+1)常数3PE(pos,2i)常数4

这表明,位置 pos+kpos+kpos+k 的编码可以由位置 pospospos 的编码通过一个线性变换(矩阵乘法)得到。

这种线性关系让Transformer中的自注意力机制能够更方便地学习到相对位置信息。因为对于任何两个相距 kkk 的词,它们位置编码之间的关系是固定的线性关系,而模型可以学习到一个权重矩阵来捕捉这种关系。这比直接学习每个位置的绝对编码要高效得多,并且正如原文所说,它还让模型能够泛化到训练时没有见过的更长序列


为什么根据奇偶分成了正弦余弦?

PEpos + k 编码依赖于 pos 的正弦值 余弦值。如果只用正弦函数,那么 pos余弦信息从哪里来呢?模型将不得不通过学习某种复杂的非线性函数来间接获取这个余弦值,这会增加学习的难度。

通过将位置编码的相邻维度(例如,偶数维 2i 和奇数维 2i+1)分别设计成正弦和余弦,就提供了一个完整的配对

  • 偶数维 2i 对应正弦sin⁡(ωi⋅pos)\sin(\omega_i \cdot pos)sin(ωipos)
  • 奇数维 2i+1 对应余弦cos⁡(ωi⋅pos)\cos(\omega_i \cdot pos)cos(ωipos)

其中,ωi=1/100002i/dmodel\omega_i = 1 / 10000^{2i/d_{\text{model}}}ωi=1/100002i/dmodel

这样,对于任何一个位置 pos,其位置编码向量中都包含了完整的正弦和余弦信息。当模型需要计算 pos + k 的编码时,它可以直接利用 pos 的编码向量中的正弦和余弦值,通过简单的线性变换(矩阵乘法),就能计算出 pos + k 的编码。


示例:位置编码(Positional Encoding)

假设场景:

  • 模型维度 (d_model): 4 (为了简化演示,原论文为512)
  • 序列位置 (pos): 我们计算位置0和位置1的编码
第1步:理解公式

公式为:
PE(pos,2i)=sin⁡(pos100002i/dmodel)PE(pos,2i+1)=cos⁡(pos100002i/dmodel) \begin{aligned} PE_{(pos, 2i)} &= \sin\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) \\ PE_{(pos, 2i+1)} &= \cos\left(\frac{pos}{10000^{2i/d_{\text{model}}}}\right) \end{aligned} PE(pos,2i)PE(pos,2i+1)=sin(100002i/dmodelpos)=cos(100002i/dmodelpos)

因为 d_model = 4,所以维度索引 i 的取值范围是 [0, 1] (因为 2i/d_model 中的 i 从0到 d_model/2 - 1)。

第2步:计算位置0的编码 (PE₀)

计算每个维度 i 的值:

对于 i = 0:

  • 计算第0维和第1维
  • PE(0,0)=sin⁡(0100000/4)=sin⁡(0100000)=sin⁡(0)=0.0PE_{(0,0)} = \sin\left(\frac{0}{10000^{0/4}}\right) = \sin\left(\frac{0}{10000^0}\right) = \sin(0) = 0.0PE(0,0)=sin(100000/40)=sin(1000000)=sin(0)=0.0
  • PE(0,1)=cos⁡(0100000/4)=cos⁡(0100000)=cos⁡(0)=1.0PE_{(0,1)} = \cos\left(\frac{0}{10000^{0/4}}\right) = \cos\left(\frac{0}{10000^0}\right) = \cos(0) = 1.0PE(0,1)=cos(100000/40)=cos(1000000)=cos(0)=1.0

对于 i = 1:

  • 计算第2维和第3维
  • PE(0,2)=sin⁡(0100002/4)=sin⁡(0100000.5)=sin⁡(0)=0.0PE_{(0,2)} = \sin\left(\frac{0}{10000^{2/4}}\right) = \sin\left(\frac{0}{10000^{0.5}}\right) = \sin(0) = 0.0PE(0,2)=sin(100002/40)=sin(100000.50)=sin(0)=0.0
  • PE(0,3)=cos⁡(0100002/4)=cos⁡(0100000.5)=cos⁡(0)=1.0PE_{(0,3)} = \cos\left(\frac{0}{10000^{2/4}}\right) = \cos\left(\frac{0}{10000^{0.5}}\right) = \cos(0) = 1.0PE(0,3)=cos(100002/40)=cos(100000.50)=cos(0)=1.0

所以位置0的编码为: [0.0, 1.0, 0.0, 1.0]

第3步:计算位置1的编码 (PE₁)

对于 i = 0:

  • PE(1,0)=sin⁡(1100000/4)=sin⁡(11)=sin⁡(1)≈0.84PE_{(1,0)} = \sin\left(\frac{1}{10000^{0/4}}\right) = \sin\left(\frac{1}{1}\right) = \sin(1) \approx 0.84PE(1,0)=sin(100000/41)=sin(11)=sin(1)0.84
  • PE(1,1)=cos⁡(1100000/4)=cos⁡(11)=cos⁡(1)≈0.54PE_{(1,1)} = \cos\left(\frac{1}{10000^{0/4}}\right) = \cos\left(\frac{1}{1}\right) = \cos(1) \approx 0.54PE(1,1)=cos(100000/41)=cos(11)=cos(1)0.54

对于 i = 1:

  • PE(1,2)=sin⁡(1100002/4)=sin⁡(1100000.5)=sin⁡(1100)≈sin⁡(0.01)≈0.01PE_{(1,2)} = \sin\left(\frac{1}{10000^{2/4}}\right) = \sin\left(\frac{1}{10000^{0.5}}\right) = \sin\left(\frac{1}{100}\right) \approx \sin(0.01) \approx 0.01PE(1,2)=sin(100002/41)=sin(100000.51)=sin(1001)sin(0.01)0.01
  • PE(1,3)=cos⁡(1100002/4)=cos⁡(1100000.5)=cos⁡(1100)≈cos⁡(0.01)≈1.00PE_{(1,3)} = \cos\left(\frac{1}{10000^{2/4}}\right) = \cos\left(\frac{1}{10000^{0.5}}\right) = \cos\left(\frac{1}{100}\right) \approx \cos(0.01) \approx 1.00PE(1,3)=cos(100002/41)=cos(100000.51)=cos(1001)cos(0.01)1.00

所以位置1的编码为: [0.84, 0.54, 0.01, 1.00]

第4步:与词嵌入相加

假设词嵌入为:

  • E_good = [1, 0, 0, 0] (在位置0)
  • E_movie = [0, 1, 0, 0] (在位置1)

最终输入模型的特征为

  • 位置0: [1, 0, 0, 0] + [0.0, 1.0, 0.0, 1.0] = [1.0, 1.0, 0.0, 1.0]
  • 位置1: [0, 1, 0, 0] + [0.84, 0.54, 0.01, 1.00] = [0.84, 1.54, 0.01, 1.00]

4 Why Self-Attention

In this section we compare various aspects of self-attention layers to the recurrent and convolutional layers commonly used for mapping one variable-length sequence of symbol representations (x1,...,xn)(x_1, ..., x_n)(x1,...,xn) to another sequence of equal length (z1,...,zn)(z_1, ..., z_n)(z1,...,zn), with xi,zi∈Rdx_i, z_i \in \mathbb{R}^dxi,ziRd, such as a hidden layer in a typical sequence transduction encoder or decoder. Motivating our use of self-attention we consider three desiderata.

本节我们将自注意力层与常用的循环层和卷积层进行多维度比较,这些层通常用于将符号表征的变长序列(x1,...,xn)(x_1, ..., x_n)(x1,...,xn)映射为等长序列(z1,...,zn)(z_1, ..., z_n)(z1,...,zn)(其中xi,zi∈Rdx_i, z_i \in \mathbb{R}^dxi,ziRd),例如典型序列转换编码器或解码器中的隐藏层。基于以下三个核心需求,我们阐述采用自注意力的动机。

  • 变长序列 (x1,...,xn)(x_1, ..., x_n)(x1,...,xn): 这表示输入序列的长度 nnn 是可变的。比如,一个句子可能包含5个单词,而另一个句子可能包含20个单词。对于自然语言处理任务,模型必须能够处理不同长度的句子,而不是被限制在一个固定的长度上。
  • 等长序列 (z1,...,zn)(z_1, ..., z_n)(z1,...,zn): 这表示输出序列的长度与输入序列的长度相等。在Transformer编码器的一个自注意力层中,输入是长度为 nnn 的序列,输出同样是长度为 nnn 的序列。每个输入向量 xix_ixi 经过处理后,都会生成一个对应的输出向量 ziz_izi

One is the total computational complexity per layer. Another is the amount of computation that can be parallelized, as measured by the minimum number of sequential operations required.

其一是每层的总计算复杂度。其二是可并行化计算量,该指标通过所需顺序操作的最小数量来度量。

The third is the path length between long-range dependencies in the network. Learning long-range dependencies is a key challenge in many sequence transduction tasks.One key factor affecting the ability to learn such dependencies is the length of the paths forward and backward signals have to traverse in the network. The shorter these paths between any combination of positions in the input and output sequences, the easier it is to learn long-range dependencies [12]. Hence we also compare the maximum path length between any two input and output positions in networks composed of the different layer types.

其三是网络中长程依赖之间的路径长度。 学习长程依赖是许多序列转换任务的核心挑战。影响这种依赖学习能力的关键因素,是前向与后向信号在网络中需要 traversed 的路径长度。 输入输出序列中任意位置组合间的路径越短,就越容易学习长程依赖[12]。因此我们还需要比较不同层类型组成的网络中,任意两个输入输出位置间的最大路径长度。

“前向与后向信号在网络中需要 traversed 的路径长度”指的是在计算一个输出(或进行反向传播)时,信息需要在网络中“旅行”多远,经过多少层或多少步,才能到达目的地。
1. 前向信号(Forward Signal)

前向信号是从输入到输出的计算过程。想象一个句子:“我喜欢看那部关于机器人的电影,它非常引人入胜。”

如果模型需要理解“引人入胜”这个词是用来描述“电影”的,那么信息就需要从“电影”这个位置传递到“引人入胜”这个位置。

  • 在传统的循环神经网络(RNN)中:信息必须一步一步地传递。电影的信息要经过多个时间步,才能在计算 引人入胜 的特征时被利用。这就像是一个接力赛,信息必须经过多个中间节点才能到达终点。这个路径的长度取决于两个词之间的距离(时间步数)。

  • 在Transformer的自注意力机制中电影引人入胜 之间的信息传递是一步到位的。自注意力机制允许网络直接计算两个词之间的注意力分数,无论它们在序列中相隔多远。这个路径的长度始终是1(在一个自注意力层内)。

2. 后向信号(Backward Signal)

后向信号是反向传播的过程,用于计算梯度并更新模型的权重。梯度的传递路径长度与前向传播的路径长度密切相关。

  • 在传统的RNN中:梯度也需要一步一步地反向传递。当梯度从“引人入胜”反向传播到“电影”时,它必须经过每个时间步的连接。如果路径很长,梯度可能会在传递过程中逐渐消失或爆炸(梯度消失/梯度爆炸问题),这会使模型难以有效地学习长距离依赖。

  • 在Transformer中:由于自注意力机制是直接连接所有位置的,梯度也可以一步到位地反向传播。这大大缩短了梯度路径的长度,从而减轻了梯度消失/爆炸的问题,使得模型能够更有效地学习长距离依赖。

As noted in Table 1, a self-attention layer connects all positions with a constant number of sequentially executed operations, whereas a recurrent layer requires O(n)O(n)O(n) sequential operations. In terms of computational complexity, self-attention layers are faster than recurrent layers when the sequence length nnn is smaller than the representation dimensionality ddd, which is most often the case with sentence representations used by state-of-the-art models in machine translations, such as word-piece and byte-pair representations. To improve computational performance for tasks involving very long sequences, self-attention could be restricted to considering only a neighborhood of size rrr in the input sequence centered around the respective output position. This would increase the maximum path length to O(n/r)O(n/r)O(n/r). We plan to investigate this approach further in future work.

如表1所示,自注意力层以恒定数量的顺序操作连接所有位置,而循环层需要O(n)O(n)O(n)次顺序操作。就计算复杂度而言,当序列长度nnn小于表征维度ddd时(这种情形在机器翻译最先进模型使用的句子表征中极为常见,例如词片表征和字节对表征),自注意力层比循环层更快。 为提升超长序列任务的计算性能,可将自注意力限制仅考虑输入序列中以各输出位置为中心、大小为rrr的邻域。这将使最大路径长度增至O(n/r)O(n/r)O(n/r)。我们计划在未來工作中进一步研究该方法。

顺序操作次数

为什么自注意力层是恒定数量的操作?

自注意力机制通过一步操作,同时计算序列中所有位置之间的注意力。

想象一个包含 nnn 个词的句子。为了计算第一个词的输出特征,自注意力层需要将它与所有 nnn 个词(包括它自己)进行比较,计算它们的注意力分数,然后加权求和。这个过程对于序列中的每一个词都是同时进行的。

虽然在计算注意力分数时,涉及到矩阵乘法,其复杂度是 O(n2)O(n^2)O(n2),但这只是一步操作,因为现代硬件(如GPU)可以高效地并行处理矩阵运算。从逻辑上讲,所有位置之间的关系是在一个单一的、并行的操作中建立起来的。因此,从信息的传递路径来看,无论序列多长,任何两个位置之间的连接路径都是恒定的(通常视为一步)。

为什么循环层需要 O(n)O(n)O(n) 次顺序操作?

循环层(例如RNN)的机制是按时间步处理序列。

  • 它首先处理序列的第一个词。
  • 然后,它将第一个词的输出作为输入,与第二个词一起处理。
  • 接着,它将第二个词的输出作为输入,与第三个词一起处理,以此类推…

这个过程是无法并行化的。为了得到最后一个词的输出,信息必须依次流过序列中的每一个时间步。因此,一个长为 nnn 的序列,需要 nnn 次顺序操作才能将信息从序列的开始传递到结束。


自注意力层与RNN计算复杂度

n<dn < dn<d 时,自注意力层更快

这个结论是基于对单层计算复杂度的比较:

  • 自注意力层:计算复杂度为 O(n2⋅d)O(n^2 \cdot d)O(n2d)。这是因为你需要计算所有 nnn 个位置两两之间的注意力分数,这个操作是 O(n2)O(n^2)O(n2)。每个位置的向量维度是 ddd,所以总复杂度为 O(n2⋅d)O(n^2 \cdot d)O(n2d)

  • 循环层(RNN):计算复杂度为 O(n⋅d2)O(n \cdot d^2)O(nd2)。这是因为在每个时间步,你需要对一个 ddd 维的输入向量进行一个矩阵-向量乘法,这个操作的复杂度是 O(d2)O(d^2)O(d2)。因为有 nnn 个时间步,所以总复杂度为 O(n⋅d2)O(n \cdot d^2)O(nd2)

因此,当 n<dn < dn<d 时,n2⋅d<n⋅d2n^2 \cdot d < n \cdot d^2n2d<nd2,这意味着自注意力层的计算量更小,处理速度更快。

论文中提到,在当时最先进的机器翻译模型中,词片(word-piece)字节对(byte-pair) 等子词(sub-word)表征非常常见。这些表征方法将一个长词分解成多个更小的单元,因此句子中的词元数量 nnn 往往会比模型维度 ddd 要小。

A single convolutional layer with kernel width k<nk < nk<n does not connect all pairs of input and output positions. Doing so requires a stack of O(n/k)O(n/k)O(n/k) convolutional layers in the case of contiguous kernels, or O(log⁡k(n))O(\log_k(n))O(logk(n)) in the case of dilated convolutions [18], increasing the length of the longest paths between any two positions in the network. Convolutional layers are generally more expensive than recurrent layers, by a factor of kkk. Separable convolutions [6], however, decrease the complexity considerably, to O(k⋅n⋅d+n⋅d2)O(k \cdot n \cdot d + n \cdot d^2)O(knd+nd2). Even with k=nk = nk=n, however, the complexity of a separable convolution is equal to the combination of a self-attention layer and a point-wise feed-forward layer, the approach we take in our model.

卷积核宽度k<nk < nk<n的单一卷积层无法连接所有输入输出位置对。若使用连续卷积核,需要堆叠O(n/k)O(n/k)O(n/k)个卷积层;若使用空洞卷积[18],则需要O(log⁡k(n))O(\log_k(n))O(logk(n))层,这都会增加网络中任意两点间的最长路径长度。卷积层的计算成本通常比循环层高kkk倍。然而可分离卷积[6]能将复杂度显著降至O(k⋅n⋅d+n⋅d2)O(k \cdot n \cdot d + n \cdot d^2)O(knd+nd2)。但即使k=nk=nk=n,可分离卷积的复杂度仍等同于自注意力层加逐点前馈层的组合——这正是我们模型中采用的方法。

卷积层如何捕捉长程依赖?

首先,你需要理解卷积层是如何处理序列的。一个标准的一维卷积层(就像处理文本时那样)有一个固定宽度的卷积核(kernel),这个核在序列上滑动,每次只处理一小段邻近的输入。

  • 单一卷积层:如果卷积核的宽度是 kkk,那么一个单一的卷积层只能让一个输出位置捕捉到它周围长度为 kkk 的信息。它无法直接连接到很远的位置。

一个卷积核的感受野就是它一次能“看到”的输入区域。

  • 连续卷积核:为了让信息从序列的一端传递到另一端,你需要堆叠多层卷积。每一层都将上一层的输出作为输入,逐步扩大感受野。如果核宽为 kkk,要覆盖一个长度为 nnn 的序列,你需要堆叠大约 n/kn/kn/k 层。这就像是在搭建一座由小石块组成的桥梁,需要很多块才能跨越长河。

例:感受野与层数的关系

我们可以用一个公式来精确计算感受野的大小。对于一个步长为 sss、核宽为 kkk 的一维卷积层,第 LLL 层的感受野大小 RFLRF_LRFL 可以通过以下公式递归计算:

RFL=RFL−1+(k−1)⋅∏i=1L−1siRF_L = RF_{L-1} + (k - 1) \cdot \prod_{i=1}^{L-1} s_iRFL=RFL1+(k1)i=1L1si

这看起来有点复杂,让我们用一个更直观的例子来解释:

假设:

  • 序列长度 n=10n=10n=10

  • 核宽 k=3k=3k=3

  • 步长 s=1s=1s=1

  • 第1层:感受野大小为 3。

  • 第2层:一个输出神经元会“看”到上一层3个神经元的输出。而这3个神经元中的每个又“看”到上一层(即原始输入)的3个神经元。它们的感受野会有重叠。

  • 第2层的感受野大小为 3+(3−1)=53 + (3-1) = 53+(31)=5

  • 第3层的感受野大小为 5+(3−1)=75 + (3-1) = 75+(31)=7

  • 第4层的感受野大小为 7+(3−1)=97 + (3-1) = 97+(31)=9

  • 第5层的感受野大小为 9+(3−1)=119 + (3-1) = 119+(31)=11

  • 结论:需要堆叠5层才能让输出能“看到”整个长度为10的序列。

现在,让我们考虑步长的影响:

如果我们将步长 sss 也纳入考量,那么感受野的增长会更快。

  • 假设:n=10n=10n=10k=3k=3k=3步长 s=2s=2s=2

  • 第1层:感受野大小为 3。

  • 第2层:一个输出神经元会“看”到上一层3个神经元的输出,而这些神经元在原始输入上是隔着一个步长的。因此,第2层的感受野大小是 3+(3−1)⋅2=73 + (3-1) \cdot 2 = 73+(31)2=7

  • 第3层:感受野大小是 7+(3−1)⋅2⋅2=157 + (3-1) \cdot 2 \cdot 2 = 157+(31)22=15


空洞卷积(Dilated Convolutions)

这是一种更高效的方法,它在卷积核的元素之间引入了“空洞”,从而在不增加参数和计算量的情况下,指数级地扩大感受野。用这种方法,你只需要堆叠 O(log⁡k(n))O(\log_k(n))O(logk(n)) 层就能连接所有位置。这就像是使用更长的木板来搭建桥梁,需要的层数大大减少。

场景:一维序列

假设我们有一个一维输入序列,长度为8,代表了8个词或像素点:

[1, 2, 3, 4, 5, 6, 7, 8]

我们有一个卷积核,宽度为3:[w₁, w₂, w₃]

  1. 标准卷积(空洞率 = 1)
  • 卷积核的感受野是3。
  • 卷积核会依次覆盖输入序列中的连续3个元素。
  • 输出序列的第一个元素,是通过 [1, 2, 3][w₁, w₂, w₃] 计算得出的。
  • 输出序列的第二个元素,是通过 [2, 3, 4][w₁, w₂, w₃] 计算得出的。
  • 结论:要让一个输出元素能“看到”整个序列(长度为8),我们必须堆叠多层卷积。每一层的感受野都只会比上一层多 k−1=2k-1=2k1=2 个元素。
  1. 空洞卷积(空洞率 = 2)
  • 卷积核的参数依然是3个:[w₁, w₂, w₃]
  • 但现在,卷积核的元素之间会有一个“空洞”。
  • 卷积核的感受野不再是3,而是5。它会跳过中间的元素来提取信息。
  • 输出序列的第一个元素,是通过 [1, _, 3, _, 5][w₁, w₂, w₃] 计算得出的。
  • 计算过程如下:
    • 输出 = 1 * w₁ + 3 * w₂ + 5 * w₃
    • 尽管只有3个参数,它却覆盖了输入序列中5个元素。
  • 接着,卷积核会向右滑动,计算下一个输出。
    • 下一个输出 = 2 * w₁ + 4 * w₂ + 6 * w₃
  • 结论:通过将空洞率从1变为2,我们没有增加任何计算量和参数,但却将卷积核的感受野从3扩大到了5。这意味着,在处理长序列时,空洞卷积可以用更少的层数就捕捉到长距离依赖,因为它的感受野扩展得更快。
  1. 空洞卷积(空洞率 = 4)
  • 如果我们将空洞率设置为4,感受野会进一步扩大。
  • 输出序列的第一个元素,是通过 [1, _, _, _, 5, _, _, _, 9]
  • 如果序列长度是9,它就可以通过 [1, 5, 9][w₁, w₂, w₃] 来计算。
  • 感受野将是 1+(3−1)⋅4=91 + (3-1) \cdot 4 = 91+(31)4=9

这个例子很好地展示了空洞卷积的核心思想:**用更稀疏的连接,换取更大的感受野。**这使得模型能够高效地处理长距离信息,而不必通过传统的堆叠方式来增加网络深度。

但无论是哪种方法,为了捕捉整个序列的依赖,卷积层都需要通过多层堆叠的方式。这就意味着信息在网络中的最大路径长度会增加,而路径越长,学习长程依赖就越困难,特别是当序列非常长时。


RNN与CNN计算成本的对比

我们假设:

  • 序列长度为 nnn
  • 输入和输出的维度都为 ddd
  • 卷积核的宽度为 kkk

循环层(RNN)的计算成本

循环层(如基本的RNN)在每个时间步都执行一个矩阵向量乘法。它将前一个时间步的隐藏状态和当前时间步的输入相结合,来计算一个新的隐藏状态。

  • 这个矩阵的维度是 d×dd \times dd×d
  • 向量的维度是 d×1d \times 1d×1
  • 一个矩阵向量乘法的计算复杂度是 O(d2)O(d^2)O(d2)

由于序列中有 nnn 个时间步,循环层总的计算复杂度就是 nnn 次这样的操作:

O(n⋅d2)O(n \cdot d^2)O(nd2)

卷积层(CNN)的计算成本

标准的一维卷积层在序列上滑动一个卷积核

  • 这个卷积核的维度是 k×d×dk \times d \times dk×d×d(或者说,它是一个 k×dk \times dk×d 的矩阵,用于对 ddd 维输入进行操作)。
  • 在每个滑动窗口,卷积核会与 kkk 个输入向量(每个向量维度为 ddd)进行计算。
  • 一次卷积操作的计算复杂度是 O(k⋅d2)O(k \cdot d^2)O(kd2)

由于有 nnn 个位置需要进行卷积(忽略边界效应),总的计算复杂度就是 nnn 次这样的操作:

O(n⋅k⋅d2)O(n \cdot k \cdot d^2)O(nkd2)


可分离卷积(Separable Convolutions)

这是一种将标准卷积分解为两个更小操作的方法,大大降低了计算成本。它的复杂度是 O(k⋅n⋅d+n⋅d2)O(k \cdot n \cdot d + n \cdot d^2)O(knd+nd2)

可分离卷积主要有两种类型:空间可分离卷积(Spatial Separable Convolution)和深度可分离卷积(Depthwise Separable Convolution)。

空间可分离卷积

这种类型主要用于图像处理,它将一个二维卷积核(例如,一个3x3的核)分解成两个一维卷积核(例如,一个3x1和一个1x3的核)。

工作原理:

  • 标准卷积:一个3x3的卷积核在图像上滑动,每个位置需要进行 3x3=9 次乘法运算。
  • 空间可分离卷积:首先用3x1的卷积核进行一次卷积,然后在得到的中间结果上,再用1x3的卷积核进行第二次卷积。

计算量比较:

  • 标准卷积:对于一个输入通道,每次操作需要 3×3=93 \times 3 = 93×3=9 次乘法。
  • 可分离卷积:第一次操作需要 3×1=33 \times 1 = 33×1=3 次乘法,第二次操作需要 1×3=31 \times 3 = 31×3=3 次乘法。总共是 3+3=63 + 3 = 63+3=6 次乘法。

通过分解,计算量从9次减少到了6次,大大提高了计算效率。但这种方法的一个主要限制是,只有当卷积核的矩阵可以被分解(即它的秩为1)时,这种操作才是等价的,这在实践中并不总是成立。

深度可分离卷积

这是在现代神经网络中最常见的一种可分离卷积,尤其在像MobileNet和Xception这样的轻量级网络架构中。它将标准卷积分解成两个独立的步骤:深度卷积逐点卷积

假设我们的任务是:

  • 输入图像:一个 7×77 \times 77×7 像素,有3个通道(RGB)的图像。
  • 卷积核:一个 3×33 \times 33×3 的卷积核,我们想要得到16个输出通道。

标准卷积的操作是:

  1. 我们有16个 3×3×33 \times 3 \times 33×3×3(高、宽、输入通道)的卷积核。
  2. 每个卷积核在输入图像上滑动,并与所有3个输入通道进行同时卷积,生成一个 5×55 \times 55×5 的输出特征图。
  3. 因为我们有16个这样的核,最终得到16个输出通道,也就是一个 5×5×165 \times 5 \times 165×5×16 的输出。

计算量:

  • 每个卷积核的参数数量:3×3×3=273 \times 3 \times 3 = 273×3×3=27
  • 卷积核总数:16个
  • 每次滑动的乘法和加法操作数:3×3×3=273 \times 3 \times 3 = 273×3×3=27
  • 滑动次数(输出特征图尺寸):5×5=255 \times 5 = 255×5=25
  • 总计算量27×25×16=10,80027 \times 25 \times 16 = 10,80027×25×16=10,800

参数数量:

  • 总参数数量27×16=43227 \times 16 = 43227×16=432

深度可分离卷积的操作是:

第1步:深度卷积 (Depthwise Convolution)

  1. 我们对每个输入通道单独进行卷积。
  2. 我们有3个 3×3×13 \times 3 \times 13×3×1 的卷积核。
  3. 第一个卷积核只在输入图像的第一个通道(红色)上滑动。
  4. 第二个卷积核只在第二个通道(绿色)上滑动。
  5. 第三个卷积核只在第三个通道(蓝色)上滑动。
  6. 这个操作会生成一个 5×5×35 \times 5 \times 35×5×3 的中间输出。

计算量:

  • 每个卷积核的参数数量:3×3×1=93 \times 3 \times 1 = 93×3×1=9
  • 卷积核总数:3个
  • 每次滑动的操作数:3×3=93 \times 3 = 93×3=9
  • 滑动次数:5×5=255 \times 5 = 255×5=25
  • 总计算量9×25×3=6759 \times 25 \times 3 = 6759×25×3=675

参数数量:

  • 总参数数量9×3=279 \times 3 = 279×3=27

第2步:逐点卷积 (Pointwise Convolution)

  1. 我们使用1x1的卷积核来组合所有输入通道(这里的输入是上一步的输出,有3个通道)。
  2. 我们想要16个输出通道,所以需要16个 1×1×31 \times 1 \times 31×1×3 的卷积核。
  3. 每个1x1卷积核在中间输出上滑动(实际上就是对每个位置的3个通道进行加权求和),生成一个 5×5×15 \times 5 \times 15×5×1 的输出特征图。
  4. 因为我们有16个这样的核,最终得到一个 5×5×165 \times 5 \times 165×5×16 的输出。

计算量:

  • 每个卷积核的参数数量:1×1×3=31 \times 1 \times 3 = 31×1×3=3
  • 卷积核总数:16个
  • 每次滑动的操作数:1×1×3=31 \times 1 \times 3 = 31×1×3=3
  • 滑动次数:5×5=255 \times 5 = 255×5=25
  • 总计算量3×25×16=12003 \times 25 \times 16 = 12003×25×16=1200

参数数量:

  • 总参数数量3×16=483 \times 16 = 483×16=48

As side benefit, self-attention could yield more interpretable models. We inspect attention distributions from our models and present and discuss examples in the appendix. Not only do individual attention heads clearly learn to perform different tasks, many appear to exhibit behavior related to the syntactic and semantic structure of the sentences.

作为额外优势,自注意力机制可产生更具可解释性的模型。 我们在附录中检查并展示了模型的注意力分布示例及其分析。各个注意力头不仅明显学会了执行不同任务,许多注意力头还表现出与句法语义结构相关的行为特征。

Table 1: Maximum path lengths, per-layer complexity and minimum number of sequential operations for different layer types.  is the sequence length,  is the representation dimension,  is the kernel size of convolutions and  the size of the neighborhood in restricted self-attention.

表1:不同层类型的最大路径长度、单层复杂度及最小顺序操作数。其中,nnn 表示序列长度,ddd 表示表征维度,kkk 表示卷积核大小,rrr 表示受限自注意力机制中邻域的范围大小。

核心概念解释

1. 最大路径长度 (Maximum Path Length)

  • 含义:指信息在神经网络中从输入节点传递到输出节点所需要经过的最长边数(或操作步骤数)。
  • 为什么重要:路径越长,信息(如梯度或特征)在传递过程中就越容易消失或爆炸(例如梯度消失问题),模型学习远距离依赖关系就越困难。
  • 对比
  • 自注意力 (Self-Attention):任意两个位置(无论多远)之间的路径长度都是 1(在一个层内直接连接)。堆叠 LLL 层后,最大路径长度仅为 LLL
  • 循环神经网络 (RNN):信息必须按顺序一步步传递。第一个词元和最后一个词元之间的路径长度是 nnn(序列长度)。
  • 卷积神经网络 (CNN):需要一个输出神经元通过多层堆叠来扩大其感受野,从而“看到”远处的输入。最大路径长度与层数 LLL线性关系(例如,使用空洞卷积时约为 O(log⁡k(n))O(\log_k(n))O(logk(n)))。
  • 结论:自注意力机制在捕捉长程依赖(Long-range Dependencies)方面具有理论上的优势,因为它提供了最短的可能路径。

2. 每层复杂度 (Per-layer Complexity)

  • 含义:计算单个网络层(例如一个自注意力层、一个卷积层或一个循环层)所需进行的浮点运算次数 (FLOPs) 的渐近上限,通常用大O符号表示。
  • 为什么重要:它衡量了模型的计算效率,决定了训练和推理的速度,尤其是在处理长序列时。
  • 对比(假设序列长度为 nnn,表示维度为 ddd):
  • 自注意力层 (Self-Attention Layer)O(n2⋅d)O(n^2 \cdot d)O(n2d)
    • 原因:需要计算一个 n×nn \times nn×n 的注意力分数矩阵(O(n2)O(n^2)O(n2)),其中每个元素的计算涉及 ddd 维向量(O(d)O(d)O(d))。后续的加权求和等操作也是类似复杂度。
  • 循环层 (Recurrent Layer)O(n⋅d2)O(n \cdot d^2)O(nd2)
    • 原因:对 nnn 个时间步中的每一个,都需要执行一个矩阵-向量乘法(O(d2)O(d^2)O(d2))。
  • 卷积层 (Convolutional Layer)O(k⋅n⋅d2)O(k \cdot n \cdot d^2)O(knd2)
    • 原因:卷积核宽度为 kkk,在 nnn 个位置上滑动,每次操作涉及 kkkddd 维向量与一个 d×dd \times dd×d 的权重矩阵相乘(O(k⋅d2)O(k \cdot d^2)O(kd2))。
  • 结论:当序列长度 nnn 远小于模型维度 ddd 时(在词元丰富的表征中很常见),自注意力层的复杂度 O(n2⋅d)O(n^2 \cdot d)O(n2d) 可能优于循环层的 O(n⋅d2)O(n \cdot d^2)O(nd2)。但当 nnn 非常大时(如长文档、高分辨率图像),自注意力的 n2n^2n2 项会成为计算瓶颈。

3. 最小顺序操作数 (Minimum Number of Sequential Operations)

  • 含义:完成计算所必须的、无法并行执行的操作步骤的最小数量。它衡量了模型的并行度
  • 为什么重要:顺序操作越少,模型在GPU/TPU等并行硬件上的计算速度潜力就越大。
  • 对比
  • 自注意力层 (Self-Attention Layer)O(1)O(1)O(1)
    • 原因:所有词元对的注意力分数计算和加权求和可以完全并行化。理论上,整个层的计算可以看作一个巨大的矩阵运算,在硬件上一步完成。
  • 循环层 (Recurrent Layer)O(n)O(n)O(n)
    • 原因:其计算本质上是顺序的。必须首先计算时间步 ttt 的状态,然后才能计算时间步 t+1t+1t+1 的状态。这 nnn 个步骤无法并行执行。
  • 卷积层 (Convolutional Layer)O(1)O(1)O(1)
    • 原因:卷积核在不同位置的滑动计算是相互独立的,可以完全并行化。
  • 结论:自注意力层和卷积层具有很高的并行性,而循环层是固有的顺序结构,并行化程度低,因此训练和推理速度通常更慢。

这三个概念从不同角度衡量了神经网络架构的特性:

  • 最大路径长度 -> 模型捕捉长期依赖的能力
  • 每层复杂度 -> 模型的计算效率
  • 最小顺序操作数 -> 模型的并行计算潜力

5 Training

This section describes the training regime for our models.

本节阐述了我们模型的训练方案。

5.1 Training Data and Batching

We trained on the standard WMT 2014 English-German dataset consisting of about 4.5 million sentence pairs. Sentences were encoded using byte-pair encoding [3], which has a shared source-target vocabulary of about 37000 tokens. For English-French, we used the significantly larger WMT 2014 English-French dataset consisting of 36M sentences and split tokens into a 32000 word-piece vocabulary [38]. Sentence pairs were batched together by approximate sequence length. Each training batch contained a set of sentence pairs containing approximately 25000 source tokens and 25000 target tokens.

我们在标准的WMT 2014英德数据集上进行了训练,该数据集包含约450万个句子对。句子采用字节对编码(BPE)[3]进行处理,源语言和目标语言共享一个约37000个词元的词汇表。对于英法翻译任务,我们使用了规模更大的WMT 2014英法数据集,包含3600万个句子,并采用32000个词片(word-piece) 词汇表进行分词处理[38]。句子对根据近似序列长度进行批量组合,每个训练批次包含一组句子对,其中源语言和目标语言各约25000个词元。

字节对编码(Byte-Pair Encoding, BPE)

在机器翻译等NLP任务中,我们需要将文本拆分成模型能处理的单元(即词元-tokens)。传统方法有两种,各有严重缺陷:

  • 词级(Word-level)分词:将每个词作为一个独立的单元。
  • 问题:词汇表会变得极其庞大(想象所有单词的不同形式),且无法处理训练集中未出现过的生僻词新词(如“区块链”、“新冠”),这些词都会被标记为<UNK>,导致信息丢失。
  • 字符级(Character-level)分词:将每个字符作为一个单元。
  • 问题:序列长度变得非常长(一个句子可能变成几百个字符的序列),大大增加了模型的计算和建模难度,模型难以学习有意义的语义单元。

BPE通过折中方案完美解决了以上问题:它可以将一个词拆分成更常见的、可重用的“子词”片段。例如,“unconsciously”可能被拆成"un", "conscious", "ly"。这样,“consciously”就可以共享"conscious""ly"这两个片段。


WordPiece

是一种与 BPE (Byte-Pair Encoding) 非常相似的子词分词 (Subword Tokenization) 算法。它由谷歌的研究者提出,并先后成为 BERTDistilBERTMPNet 等众多顶尖NLP模型的核心分词器。

WordPiece 与 BPE 的核心区别:
它们的主要区别在于决定“合并哪一对符号”的准则 (merging criterion)

特性 BPE (Byte-Pair Encoding) WordPiece
合并准则 频率 (Frequency)
直接选择出现次数最多的相邻符号对进行合并。
概率 (Probability)/互信息
选择能最大程度地增加语言模型似然度的符号对进行合并。
数学表达 max(freq(pair))
(最大化频率)
max(frac(freq(a, b)}{freq(a) * freq(b)})
(最大化互信息)
简单理解:选择那些共现频率远高于其独立出现频率的预期值的符号对。这意味着两个符号“在一起”的可能性非常强,不应该被拆开。
合并策略 贪婪地合并最高频对。 贪婪地合并能最大提升语言模型概率的对。
别名 符号对编码 最大互信息编码
代表性模型 GPT 系列Transformer (原论文) BERTDistilBERT
分词符号 通常不加特殊符号 在词首添加 ## 以示区分(如:"playing" -> ["play", "##ing"]

一个简单的例子来说明区别:

假设在语料库中:

  • 字符 "u" 出现了 100 次
  • 字符 "n" 出现了 150 次
  • 序列 "u n" 作为相邻对出现了 90 次

BPE 会认为 "u n" 的出现频率(90次)非常高,很可能会优先合并它们形成 "un"

WordPiece 会计算一个得分:score("u", "n") = freq(u,n) / (freq(u) * freq(n)) = 90 / (100 * 150) = 0.006
同时,它也会计算其他对的得分。假设另一个对 ("h", "e") 的得分是 0.009,那么 WordPiece 就会优先合并 "h""e",因为它们的共现更具“显著性”或“意外性”,表明它们更应该作为一个整体存在。

控制每个批次的计算量恒定

核心原因:最大化并行计算效率,减少冗余计算

现代深度学习模型(如Transformer)通常在GPU上进行训练,而GPU的核心优势是大规模并行计算。训练时,一个批次(batch)内的所有样本会同时被处理。

1. 序列长度不一

  • 一个翻译数据集中的句子长度各不相同,有的很短(e.g., 5个词),有的很长(e.g., 50个词)。
  • 如果随机组成批次,为了能同时处理一个批次内的所有样本,软件框架(如PyTorch/TensorFlow)必须将该批次内所有样本的序列长度都填充(Padding)到与本批次中最长样本相同的长度

2.论文中提到的另一个关键点是:“每个训练批次包含…… approximately 25000 source tokens and 25000 target tokens”。这样做的好处是:

  1. 稳定的内存使用:GPU的内存是有限的。通过固定每个批次的总词元数(tokens) 而不是固定的句子数(sentences),可以确保每个批次的计算量和内存占用大致相同,避免了因为偶尔遇到一个超长句子的批次而导致的内存溢出(Out Of Memory, OOM)错误。
  2. 稳定的学习信号:虽然每个批次的句子数量可能不同(一个包含长句的批次可能只有几十个句子,而一个包含短句的批次可能有上百个句子),但模型在每个批次中看到的总信息量(词元数)是近似恒定的。这有助于训练过程更加稳定。

5.2 Hardware and Schedule

硬件与训练周期

We trained our models on one machine with 8 NVIDIA P100 GPUs. For our base models using the hyperparameters described throughout the paper, each training step took about 0.4 seconds. We trained the base models for a total of 100,000 steps or 12 hours. For our big models,(described on the bottom line of table), step time was 1.0 seconds. The big models were trained for 300,000 steps (3.5 days).

我们在配备8块NVIDIA P100 GPU的单一机器上完成模型训练。使用本文所述的超参数配置,基础模型的每个训练步骤耗时约0.4秒,总训练时长为10万步骤(约12小时)。对于大规模模型(参数见表格末行),单步训练时间增至1.0秒,总训练量为30万步骤(约3.5天)。

5.3 Optimizer

We used the Adam optimizer [20] with β1=0.9\beta_1 = 0.9β1=0.9, β2=0.98\beta_2 = 0.98β2=0.98 and ϵ=10−9\epsilon = 10^{-9}ϵ=109. We varied the learning rate over the course of training, according to the formula:
lrate=dmodel−0.5⋅min⁡(step_num−0.5,step_num⋅warmup_steps−1.5) lrate = d_{\text{model}}^{-0.5} \cdot \min(step\_num^{-0.5}, step\_num \cdot warmup\_steps^{-1.5}) lrate=dmodel0.5min(step_num0.5,step_numwarmup_steps1.5)
This corresponds to increasing the learning rate linearly for the first warmup_stepswarmup\_stepswarmup_steps training steps, and decreasing it thereafter proportionally to the inverse square root of the step number. We used warmup_steps=4000warmup\_steps = 4000warmup_steps=4000.

我们采用Adam优化器[20],参数设置为β1=0.9\beta_1 = 0.9β1=0.9β2=0.98\beta_2 = 0.98β2=0.98ϵ=10−9\epsilon = 10^{-9}ϵ=109。学习率在训练过程中根据以下公式动态调整:
学习率=d模型−0.5⋅min⁡(训练步数−0.5,训练步数⋅预热步数−1.5) 学习率 = d_{\text{模型}}^{-0.5} \cdot \min(训练步数^{-0.5}, 训练步数 \cdot 预热步数^{-1.5}) 学习率=d模型0.5min(训练步0.5,训练步数预热步1.5)
该调整策略意味着在前warmup_stepswarmup\_stepswarmup_steps个训练步骤中线性增加学习率,之后随训练步数的平方根倒数比例下降。我们设置预热步数warmup_steps=4000warmup\_steps = 4000warmup_steps=4000

Adam 的核心思想

Adam 的本质是结合了两种优化算法的思想,并进行了偏差校正,使其在训练初期也更加稳定。:

  1. 动量(Momentum):不仅仅使用当前的梯度,还会积累历史的梯度方向,形成一个“速度”。这有助于加速收敛并在困难的优化地形(如沟壑或局部最优点)中保持正确的方向。
  2. RMSProp:根据历史梯度的大小(平方)来调整每个参数的学习率。对于频繁更新、梯度大的参数,降低其学习率;对于不常更新、梯度小的参数,增大其学习率。这使得学习过程更加稳定。

以下是 Adam 原始论文 (Adam: A Method for Stochastic Optimization) 中提出的算法。我们假设有:

  • f(θ)f(\theta)f(θ):带有参数 θ\thetaθ 的目标函数(损失函数)。
  • gt=∇θft(θt−1)g_t = \nabla_\theta f_t(\theta_{t-1})gt=θft(θt1):在时间步 ttt 下,对参数 θ\thetaθ 计算的梯度。

初始化:

  • 设置初始参数 θ0\theta_0θ0
  • 设置一阶矩向量(动量)m0←0m_0 \leftarrow 0m00
  • 设置二阶矩向量(未中心化的方差)v0←0v_0 \leftarrow 0v00
  • 设置时间步 t←0t \leftarrow 0t0
  • 选择算法的超参数:
  • β1\beta_1β1 (建议默认 0.9)
  • β2\beta_2β2 (建议默认 0.999)
  • ϵ\epsilonϵ (建议默认 10−810^{-8}108)
  • α\alphaα (建议默认 0.001) <- 这是基础学习率

循环(直到收敛):
t←t+1t \leftarrow t + 1tt+1
gt←∇θft(θt−1)g_t \leftarrow \nabla_\theta f_t(\theta_{t-1})gtθft(θt1)
(计算当前梯度)
mt←β1⋅mt−1+(1−β1)⋅gtm_t \leftarrow \beta_1 \cdot m_{t-1} + (1 - \beta_1) \cdot g_tmtβ1mt1+(1β1)gt
(更新一阶矩估计,动量)
vt←β2⋅vt−1+(1−β2)⋅gt2v_t \leftarrow \beta_2 \cdot v_{t-1} + (1 - \beta_2) \cdot g_t^2vtβ2vt1+(1β2)gt2
(更新二阶矩估计,平方梯度)
m^t←mt/(1−β1t)\hat{m}_t \leftarrow m_t / (1 - \beta_1^t)m^tmt/(1β1t)
(对一阶矩进行偏差校正)
v^t←vt/(1−β2t)\hat{v}_t \leftarrow v_t / (1 - \beta_2^t)v^tvt/(1β2t)
(对二阶矩进行偏差校正)
θt←θt−1−α⋅m^tv^t+ϵ\theta_t \leftarrow \theta_{t-1} - \alpha \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}θtθt1αv^t +ϵm^t
(更新参数)

逐步拆解说明

  1. 计算梯度 (gtg_tgt)
  • 在随机优化中,我们通常使用一个迷你批次(mini-batch)的数据来计算当前梯度。
  1. 更新一阶矩 (mtm_tmt) - 动量
  • mtm_tmt 是梯度指数移动平均值(Exponential Moving Average)。它可以被看作是带有衰减的动量。
  • β1\beta_1β1 控制着历史动量信息的衰减率。β1=0.9\beta_1 = 0.9β1=0.9 意味着当前 mtm_tmt 90% 来自历史,10% 来自新梯度。
  • 它积累了梯度的方向,有助于加速收敛和减少振荡。
  1. 更新二阶矩 (vtv_tvt) - 自适应学习率
  • vtv_tvt梯度平方的指数移动平均值。它衡量了历史梯度的大小。
  • β2\beta_2β2 控制着历史平方梯度信息的衰减率。β2=0.999\beta_2 = 0.999β2=0.999 意味着衰减得更慢,使得 vtv_tvt 的变化更平滑。
  • 它的作用是感知每个参数的历史更新幅度。对于过去更新很大的参数,其 vtv_tvt 值大,从而在下一步会减小其学习率。
  1. 偏差校正 (m^t\hat{m}_tm^t, v^t\hat{v}_tv^t) - Adam 的关键创新
  • 在训练初期(ttt 很小的时候),mtm_tmtvtv_tvt 被初始化为 000,会导致它们向 000 偏置(尤其是在 β1\beta_1β1, β2\beta_2β2 接近 1 时)。
  • 偏差校正通过除以 (1−βt)(1 - \beta^t)(1βt) 来解决这个问题。当 ttt 很小时,校正因子也很小,能将 mtm_tmtvtv_tvt 放大到合理的量级。
  • 随着 ttt 增大,βt→0\beta^t \to 0βt0,校正因子 (1−βt)→1(1 - \beta^t) \to 1(1βt)1,偏差校正的作用逐渐减弱。这确保了训练初期的稳定性。
  1. 更新参数 (θt\theta_tθt)
  • 这是最终步骤。参数更新公式为:θnew=θold−α⋅m^tv^t+ϵ\theta_{new} = \theta_{old} - \alpha \cdot \frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}θnew=θoldαv^t +ϵm^t
  • α\alphaα基础学习率。这是你设置的最重要的超参数,决定了更新的总体步长。
  • m^tv^t+ϵ\frac{\hat{m}_t}{\sqrt{\hat{v}_t} + \epsilon}v^t +ϵm^t自适应学习率因子
    • m^t\hat{m}_tm^t 提供了符号和方向(像动量)。
    • v^t\sqrt{\hat{v}_t}v^t 提供了幅度缩放。对于梯度历史值大的参数,v^t\sqrt{\hat{v}_t}v^t 大,使得 m^tv^t\frac{\hat{m}_t}{\sqrt{\hat{v}_t}}v^t m^t 变小,从而减小其实际更新步长。反之亦然。
  • ϵ\epsilonϵ:一个极小的数(如 10−810^{-8}108),防止分母为零,保证数值稳定性。

因此,Transformer 论文中对 Adam 的配置 (β1=0.9,β2=0.98,ϵ=10−9\beta_1=0.9, \beta_2=0.98, \epsilon=10^{-9}β1=0.9,β2=0.98,ϵ=109) 是对原始 Adam 的一个微调

  • β2\beta_2β20.999 调整为 0.98,让优化器更关注最近的梯度平方,使得 vtv_tvt 更新更快,适应性更强。
  • ϵ\epsilonϵ10−810^{-8}108 调整为 10−910^{-9}109,略微降低了平滑项的影响。

学习率调度公式 (Learning Rate Schedule)

这是Transformer论文的一个关键创新点,称为带热启发的逆平方根衰减 (Inverse Square Root Learning Rate Schedule with Warmup)

公式:
lrate=dmodel−0.5⋅min⁡(step_num−0.5,step_num⋅warmup_steps−1.5) lrate = d_{\text{model}}^{-0.5} \cdot \min(step\_num^{-0.5}, step\_num \cdot warmup\_steps^{-1.5}) lrate=dmodel0.5min(step_num0.5,step_numwarmup_steps1.5)

这个公式由两部分组成:

缩放因子 (Scale Factor)dmodel−0.5d_{\text{model}}^{-0.5}dmodel0.5

  • 作用:根据模型维度(dmodeld_{\text{model}}dmodel)对学习率进行归一化。模型越大(维度越高),默认学习率就应该设置得越小,以防止初始更新步长过大。这确保了不同规模的模型有一个相对稳定的初始更新幅度。

动态调度部分min⁡(step_num−0.5,step_num⋅warmup_steps−1.5)\min(step\_num^{-0.5}, step\_num \cdot warmup\_steps^{-1.5})min(step_num0.5,step_numwarmup_steps1.5)

这是一个分段函数,以 warmup_steps 为界:

  1. 第一阶段:线性增长 (预热期 Warm-up Phase)

    • step_num<warmup_stepsstep\_num < warmup\_stepsstep_num<warmup_stepsstep_num−0.5step\_num^{-0.5}step_num0.5 的值很小,而 step_num⋅warmup_steps−1.5step\_num \cdot warmup\_steps^{-1.5}step_numwarmup_steps1.5 的值会随着步数增加而线性增长。此时 min() 函数会选择后者。
    • 为什么需要预热? 训练初期,模型的权重是随机初始化的。此时如果使用过大的学习率,梯度可能会非常不稳定,导致模型迅速收敛到一个不好的局部最优点甚至直接“训崩”。线性预热策略让学习率从一个很小的值(几乎是0)开始,在前4000步内线性增加到一个预设的峰值。这给了模型一个“热身”的机会,让参数稳定地进入一个合适的区域,为后续的大幅度优化打下坚实基础。
  2. 第二阶段:逆平方根衰减 (衰减期 Decay Phase)

    • step_num>warmup_stepsstep\_num > warmup\_stepsstep_num>warmup_stepsstep_num⋅warmup_steps−1.5step\_num \cdot warmup\_steps^{-1.5}step_numwarmup_steps1.5 会变成一个大于1且持续线性增长的值,而 step_num−0.5step\_num^{-0.5}step_num0.5 则会随着步数增加而下降。此时 min() 函数会选择前者。
    • 为什么用逆平方根衰减? 在训练中后期,模型逐渐收敛到损失曲面一个相对平坦的区域。此时需要逐渐减小学习率,以便进行更精细的微调,避免在最优点附近来回震荡。逆平方根衰减 (rate∝1/step_numrate \propto 1/\sqrt{step\_num}rate1/step_num ) 是一种非常平稳的衰减策略,它不像指数衰减那么剧烈,也不像线性衰减那么直接,能够在长时间内保持一个相对有活力的学习率,这对于Transformer这种大规模模型的长期训练非常有益。

参数值:warmup_steps=4000warmup\_steps = 4000warmup_steps=4000
这是一个超参数,决定了预热过程有多长。选择4000步意味着模型需要经过4000个训练步骤来完成学习率的线性增长阶段。这个值是根据模型和数据集的经验选择的。

这种组合策略被证明非常适合于训练像Transformer这样深度且参数众多的模型,它成为了后续许多基于Transformer的模型(如BERT、GPT等)的标准配置。它有效地平衡了训练速度、稳定性和最终的模型性能。

5.4 Regularization

We employ three types of regularization during training:

Residual Dropout We apply dropout [33] to the output of each sub-layer, before it is added to the sub-layer input and normalized. In addition, we apply dropout to the sums of the embeddings and the positional encodings in both the encoder and decoder stacks. For the base model, we use a rate of Pdrop=0.1P_{drop} = 0.1Pdrop=0.1.

Label Smoothing During training, we employed label smoothing of value ϵls=0.1\epsilon_{ls} = 0.1ϵls=0.1 [36]. This hurts perplexity, as the model learns to be more unsure, but improves accuracy and BLEU score.

我们在训练过程中采用三种正则化方法:
残差丢弃 在每个子层的输出与子层输入进行相加并归一化之前,对其施加丢弃法[33]。此外,在编码器和解码器堆栈中,对词嵌入与位置编码的求和结果也施加丢弃法。基础模型采用丢弃率Pdrop=0.1P_{drop} = 0.1Pdrop=0.1
标签平滑 训练过程中采用ϵls=0.1\epsilon_{ls} = 0.1ϵls=0.1的标签平滑技术[36]。这会略微提升困惑度(因为模型学会了保持不确定性),但能有效提升准确率和BLEU评分。

标签平滑(Label Smoothing)

是一种用于分类任务的正则化技术,其主要目的是防止模型在训练过程中变得“过于自信”(Over-confident),从而缓解过拟合,提升模型的泛化能力和校准度(Calibration)。

在标准的分类任务中,我们通常使用 “硬标签”(Hard Label)“one-hot”编码

  • 硬标签 (Hard Label):对于一个样本,其真实类别的概率为1,其他所有类别的概率都为0。
  • 例如:手写数字识别中,一张数字“7”的图片的标签是:[0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
  • 问题所在
  1. 过拟合风险:模型会无限逼近这个极端分布,赋予正确类别极高的概率(如0.999),这可能导致过拟合,特别是在训练数据有噪声或类别本身存在模糊性时。
  2. 泛化能力差:这种“非此即彼”的标签使得模型变得僵化,缺乏对类别间相似性的认识(例如数字“1”和“7”有一定相似度)。
  3. 校准误差:模型输出的概率无法真实反映其预测的置信度(一个输出概率为0.99的预测,其真实准确率可能只有80%)。

标签平滑通过“软化”标签来解决这些问题:

  • 软标签 (Soft Label):将真实类别的概率从1降低一点,并将“减掉的那部分概率”均匀地分配给所有其他类别。
  • 例如:应用 ϵls=0.1\epsilon_{ls} = 0.1ϵls=0.1 的标签平滑后,数字“7”的标签变为:[0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.91, 0.01, 0.01]

6 Results

6.1 Machine Translation

On the WMT 2014 English-to-German translation task, the big transformer model (Transformer (big) in Table 2) outperforms the best previously reported models (including ensembles) by more than 2.0 BLEU, establishing a new state-of-the-art BLEU score of 28.4. The configuration of this model is listed in the bottom line of Table 3. Training took 3.5 days on 8 P100 GPUs. Even our base model surpasses all previously published models and ensembles, at a fraction of the training cost of any of the competitive models.

在WMT 2014英德翻译任务中,大型Transformer模型(表2中的Transformer (big))以超过2.0 BLEU分的优势超越了之前最佳的报告模型(包括集成模型),建立了28.4的新State-of-the-art BLEU分数。该模型的配置参数列于表3最底部行,在8张P100 GPU上耗时3.5天完成训练。即使我们的基础模型也超越了所有以往发布的模型和集成系统,且训练成本仅为任何竞争模型的零头。

On the WMT 2014 English-to-French translation task, our big model achieves a BLEU score of 41.0, outperforming all of the previously published single models, at less than 1/4 the training cost of the previous state-of-the-art model. The Transformer (big) model trained for English-to-French used dropout rate Pdrop=0.1P_{drop} = 0.1Pdrop=0.1, instead of 0.3.

在WMT 2014英法翻译任务中,我们的大型模型获得了41.0的BLEU分数,优于所有以往发布的单模型,同时训练成本不到之前State-of-the-art模型的1/4。用于英法翻译的Transformer (big)模型使用Pdrop=0.1P_{drop} = 0.1Pdrop=0.1的丢弃率,而非0.3。

For the base models, we used a single model obtained by averaging the last 5 checkpoints, which were written at 10-minute intervals. For the big models, we averaged the last 20 checkpoints. We used beam search with a beam size of 4 and length penalty α=0.6\alpha = 0.6α=0.6 [38]. These hyperparameters were chosen after experimentation on the development set. We set the maximum output length during inference to input length + 50, but terminate early when possible [38].

对于基础模型,我们采用对最后5个检查点取平均的方法得到单一模型(检查点以10分钟为间隔保存)。对于大型模型,我们对最后20个检查点取平均。我们使用集束搜索(beam search),束宽为4,长度惩罚系数α=0.6\alpha = 0.6α=0.6[38]。这些超参数是在开发集上经过实验后确定的。在推理过程中,我们将最大输出长度设置为输入长度+50,但会尽可能提前终止[38]。

Table 2 summarizes our results and compares our translation quality and training costs to other model architectures from the literature. We estimate the number of floating point operations used to train a model by multiplying the training time, the number of GPUs used, and an estimate of the sustained single-precision floating-point capacity of each GPU1^11.

表2总结了我们的实验结果,并将本研究的翻译质量与训练成本与文献中的其他模型架构进行了对比。我们通过将训练时间、使用的GPU数量以及每块GPU的持续单精度浮点计算能力估值相乘,估算出了训练模型所需的浮点运算次数1^11

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表2:在英语到德语和英语到法语的newstest2014测试中,Transformer以更低的训练成本获得了优于以往State-of-the-art模型的BLEU分数。

6.2 Model Variations

To evaluate the importance of different components of the Transformer, we varied our base model in different ways, measuring the change in performance on English-to-German translation on the development set, newstest2013. We used beam search as described in the previous section, but no checkpoint averaging. We present these results in Table 3.

为评估Transformer不同组件的重要性,我们以多种方式改变基础模型配置,并测量其在英德翻译开发集newstest2013上的性能变化。我们使用上一节所述的集束搜索(beam search),但未采用检查点平均。结果呈现在表3中。

In Table 3 rows (A), we vary the number of attention heads and the attention key and value dimensions, keeping the amount of computation constant, as described in Section 3.2.2. While single-head attention is 0.9 BLEU worse than the best setting, quality also drops off with too many heads.

在表3的(A)行中,我们改变了注意力头数及键/值维度,同时如3.2.2节所述保持计算量不变。虽然单头注意力效果比最佳设置低0.9 BLEU,但头数过多也会导致质量下降。

In Table 3 rows (B), we observe that reducing the attention key size dkd_kdk hurts model quality. This suggests that determining compatibility is not easy and that a more sophisticated compatibility function than dot product may be beneficial. We further observe in rows © and (D) that, as expected, bigger models are better, and dropout is very helpful in avoiding over-fitting. In row (E) we replace our sinusoidal positional encoding with learned positional embeddings [9], and observe nearly identical results to the base model.

在表3的(B)行中,我们观察到减小注意力键尺寸dkd_kdk会降低模型质量。这表明兼容性判断并非易事,且相比点积更复杂的兼容性函数可能更有益。在©和(D)行中进一步观察到,更大规模的模型表现更好(符合预期),而dropout对防止过拟合非常有效。在(E)行中,我们将正弦位置编码替换为可学习的位置嵌入[9],结果与基础模型几乎无差异。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表3:Transformer架构的变体实验。未列出的参数值与基础模型保持一致。所有指标均在英德翻译开发集newstest2013上测得。列出的困惑度为基于字节对编码的子词粒度困惑度,不可与词粒度困惑度直接比较。

6.3 English Constituency Parsing

To evaluate if the Transformer can generalize to other tasks we performed experiments on English constituency parsing. This task presents specific challenges: the output is subject to strong structural constraints and is significantly longer than the input. Furthermore, RNN sequence-to-sequence models have not been able to attain state-of-the-art results in small-data regimes [37].

为评估Transformer是否能够泛化到其他任务,我们在英语成分句法分析任务上进行了实验。该任务面临特定挑战:输出需要遵循严格的结构化约束,且其长度显著超过输入。此外,循环神经网络序列到序列模型在少数据环境下始终无法取得领先性能[37]。

We trained a 4-layer transformer with dmodel=1024d_{\text{model}} = 1024dmodel=1024 on the Wall Street Journal (WSJ) portion of the Penn Treebank [25], about 40K training sentences. We also trained it in a semi-supervised setting, using the larger high-confidence and BerkleyParser corpora from [37] with approximately 17M sentences. We used a vocabulary of 16K tokens for the WSJ only setting and a vocabulary of 32K tokens for the semi-supervised setting.

我们在宾州树库[25]的《华尔街日报》(WSJ)语料上(约4万训练句子)训练了dmodel=1024d_{\text{model}} = 1024dmodel=1024的4层Transformer模型。同时采用[37]中的大规模高置信度语料和BerkleyParser语料(约1700万句子)进行了半监督训练。仅使用WSJ数据时采用16K词表,半监督设置下采用32K词表。

We performed only a small number of experiments to select the dropout, both attention and residual (section 5.4), learning rates and beam size on the Section 22 development set, all other parameters remained unchanged from the English-to-German base translation model. During inference, we increased the maximum output length to input length + 300. We used a beam size of 21 and α=0.3\alpha = 0.3α=0.3 for both WSJ only and the semi-supervised setting.

我们仅在22开发集上进行了少量实验来筛选dropout(包括注意力和残差连接dropout,见第5.4节)、学习率和集束大小,其余参数均保持英德翻译基础模型的配置。推理阶段将最大输出长度调整为输入长度+300。无论WSJ还是半监督设置均使用集束宽度21和α=0.3\alpha = 0.3α=0.3的参数。

Our results in Table 4 show that despite the lack of task-specific tuning our model performs surprisingly well, yielding better results than all previously reported models with the exception of the Recurrent Neural Network Grammar [8].

表4结果显示:尽管未进行任务特异性调优,我们的模型仍表现出色,除递归神经网络语法模型[8]外超越了所有已报道模型。

In contrast to RNN sequence-to-sequence models [37], the Transformer outperforms the BerkeleyParser even when training only on the WSJ training set of 40K sentences.

与RNN序列到序列模型[37]形成鲜明对比的是,Transformer仅使用4万句WSJ训练集时性能就已超越BerkeleyParser。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表4:Transformer在英语成分句法分析任务中展现出色泛化能力(结果基于WSJ第23节测试集)。

7 Conclusion

In this work, we presented the Transformer, the first sequence transduction model based entirely on attention, replacing the recurrent layers most commonly used in encoder-decoder architectures with multi-headed self-attention.

本研究中,我们提出了Transformer——首个完全基于注意力机制的序列转换模型,它使用多头自注意力机制取代了编码器-解码器架构中最常用的循环神经网络层。

For translation tasks, the Transformer can be trained significantly faster than architectures based on recurrent or convolutional layers. On both WMT 2014 English-to-German and WMT 2014 English-to-French translation tasks, we achieve a new state of the art. In the former task our best model outperforms even all previously reported ensembles.

在翻译任务中,Transformer的训练速度显著快于基于循环或卷积层的架构。在WMT 2014英德和WMT 2014英法翻译任务中,我们均实现了最新的最优性能。在英德翻译任务中,我们最佳模型的表现甚至超越了所有以往报道的集成模型。

We are excited about the future of attention-based models and plan to apply them to other tasks. We plan to extend the Transformer to problems involving input and output modalities other than text and to investigate local, restricted attention mechanisms to efficiently handle large inputs and outputs such as images, audio and video. Making generation less sequential is another research goals of ours.

我们对注意力基模型的未来充满期待,并计划将其应用于更多任务。我们计划将Transformer扩展到文本之外的其他输入输出模态,并研究局部受限注意力机制以高效处理图像、音频和视频等大规模输入输出数据。减少生成过程的序列依赖性是我们的另一个研究目标。

The code we used to train and evaluate our models is available at https://github.com/tensorflow/tensor2tensor
f 40K sentences.

与RNN序列到序列模型[37]形成鲜明对比的是,Transformer仅使用4万句WSJ训练集时性能就已超越BerkeleyParser。

[外链图片转存中…(img-b9i97c5D-1756619442205)]

表4:Transformer在英语成分句法分析任务中展现出色泛化能力(结果基于WSJ第23节测试集)。

7 Conclusion

In this work, we presented the Transformer, the first sequence transduction model based entirely on attention, replacing the recurrent layers most commonly used in encoder-decoder architectures with multi-headed self-attention.

本研究中,我们提出了Transformer——首个完全基于注意力机制的序列转换模型,它使用多头自注意力机制取代了编码器-解码器架构中最常用的循环神经网络层。

For translation tasks, the Transformer can be trained significantly faster than architectures based on recurrent or convolutional layers. On both WMT 2014 English-to-German and WMT 2014 English-to-French translation tasks, we achieve a new state of the art. In the former task our best model outperforms even all previously reported ensembles.

在翻译任务中,Transformer的训练速度显著快于基于循环或卷积层的架构。在WMT 2014英德和WMT 2014英法翻译任务中,我们均实现了最新的最优性能。在英德翻译任务中,我们最佳模型的表现甚至超越了所有以往报道的集成模型。

We are excited about the future of attention-based models and plan to apply them to other tasks. We plan to extend the Transformer to problems involving input and output modalities other than text and to investigate local, restricted attention mechanisms to efficiently handle large inputs and outputs such as images, audio and video. Making generation less sequential is another research goals of ours.

我们对注意力基模型的未来充满期待,并计划将其应用于更多任务。我们计划将Transformer扩展到文本之外的其他输入输出模态,并研究局部受限注意力机制以高效处理图像、音频和视频等大规模输入输出数据。减少生成过程的序列依赖性是我们的另一个研究目标。

The code we used to train and evaluate our models is available at https://github.com/tensorflow/tensor2tensor