首页 / 资讯中心 / 文章详情

Transformer架构解析:自注意力机制与位置编码原理详解

Transformer架构解析:自注意力机制与位置编码原理详解 ★ FEATURED ARTICLE
简介面向自然语言处理学习者与研究者这份资源是 NIPS 2017 经典论文《Attention is All You Need》的中文翻译文档聚焦自注意力机制与 Transformer 架构适合希望绕过英文原文、快速把握序列转导模型核心思想的读者。压缩包内共 1 个 docx 文件约 856KB完整呈现论文摘要、引言、背景、模型架构及各子层说明并保留缩放点积注意力、多头注意力等关键公式与实验数据。译文覆盖 WMT 2014 英德、英法翻译任务中 28.4 与 41.0 BLEU 的结果对比以及编码器-解码器堆栈、残差连接与层归一化等实现细节便于对照原文精读、整理笔记或作为组会分享材料。目前已有 1189 人学习适合作为入门 Transformer 与自注意力机制的第一手中文参考资料。1. 到底什么是 Transformer一个不用“排队”的翻译工厂如果你最近在看 AI 相关的资料大概率会被一个词反复砸中Transformer。它听起来像个变形金刚实际上是一篇论文提出的网络架构名字这篇论文的标题就叫《Attention Is All You Need》。很多人第一次听到“自注意力”“多头注意力”这些词就懵了觉得这是不是又一套玄学。其实你可以先记住一句话Transformer 是一种完全靠“注意力”来理解句子、不再靠“一个字一个字往后读”的模型架构。打个比方传统的循环神经网络读句子像老式流水线必须从第一个词开始读完第一个才能读第二个工人只能排队干活而 Transformer 像把整句话摊在一张大桌子上每个词都能同时看到其他所有词自己判断该重点看谁。这个“同时看”的本事就是 self-attention自注意力。它带来的直接好处是训练可以大规模并行速度更快长距离的依赖关系也更容易学到。搞懂它你再看今天各种语言模型、翻译工具、文本生成就不会一头雾水。2. 为什么非要换掉循环网络顺序计算这道坎2.1 循环网络的老毛病必须一步一步来在 Transformer 出现之前处理语言这类序列数据的主流做法是循环神经网络尤其是 LSTM 和门控循环单元。它们的思路很直观把句子当成一条时间线读第 t 个词的时候要依赖第 t-1 个词算出来的隐藏状态。这就像你读一本悬疑小说必须按页码顺序读不能跳着看因为后面的情节依赖前面的线索。问题也出在这里。这种“按顺序算”的机制天然排斥并行化。训练时一个批次里的句子长度参差不齐内存又有限你没法把很多长句子同时塞进去算。序列越长这个瓶颈越明显。论文里说得很直白这种固有的顺序性质排除了训练示例中的并行化在长序列上变得至关重要。虽然研究者用因子分解技巧、条件计算等方法提升过效率但顺序计算这个根本限制还在。2.2 卷积网络也不完美距离一远就费劲另一条路是用卷积神经网络做序列转导比如 ByteNet、ConvS2S 这些模型。卷积的好处是能并行所有位置一起算。但它有个代价两个位置离得越远要把它们关联起来需要的操作层数就越多。ConvS2S 是线性增长ByteNet 是对数增长。通俗地说句子开头的主语和结尾的动词隔了二十个词卷积网络得叠很多层才能让它们“碰上面”远距离依赖学起来就吃力。论文里给了一张对比表把自注意力、循环层、卷积层放在一起比。自注意力每层的计算复杂度是 O(n²·d)顺序操作数是 O(1)任意两个位置之间的最大路径长度也是 O(1)。循环层顺序操作数是 O(n)路径长度 O(n)卷积层路径长度是 O(logk(n))。这组数字翻译成人话就是自注意力让任意两个词之间的“沟通路径”最短一步到位而循环和卷积都得绕路。2.3 自注意力的核心让每个词自己决定看谁那自注意力到底怎么工作论文里的定义是把查询和一组键值对映射到输出查询、键、值、输出都是向量。输出是值的加权和权重由查询和对应键的兼容性算出来。听着抽象举个例子翻译“动物没有过马路因为它太累了”这句话模型在处理“它”的时候需要判断“它”指动物还是马路。自注意力让“它”这个位置发出一个查询去和句子里每个词的键做匹配发现“动物”的匹配度更高于是给“动物”的值更大的权重。这样“它”的表示里就融入了“动物”的信息。具体计算用的是缩放点积注意力查询矩阵 Q 和键矩阵 K 做点积除以 √dk 防止数值过大再经过 softmax 得到权重最后乘上值矩阵 V。论文里还提出多头注意力用 h8 组不同的线性投影并行做注意力每组关注不同的子空间。这就像八个专家同时读同一句话有人盯语法有人盯语义最后把意见汇总。单头注意力容易把不同层面的信息平均掉多头则保留了多样性。提示缩放点积里的 √dk 不是随便加的。dk 太大时点积结果会很大softmax 会被推到梯度极小的区域训练容易卡住除以 √dk 就是把这个数值拉回正常范围。3. Transformer 的内部构造编码器、解码器和位置编码3.1 编码器和解码器六层堆叠的分工Transformer 整体还是编码器-解码器结构。编码器负责把输入序列映射成连续表示解码器根据这个表示一个元素一个元素地生成输出。论文里编码器和解码器各由 N6 个相同的层堆叠而成。编码器每层有两个子层第一个是多头自注意力第二个是逐位置的全连接前馈网络。每个子层周围都有残差连接后面接层归一化输出维度统一是 dmodel512。解码器多了一个子层用来对编码器的输出做多头注意力这叫编码器-解码器注意力。另外解码器的自注意力子层做了掩蔽防止某个位置关注到它后面的位置。这个掩蔽很关键因为生成是自回归的预测第 i 个词时只能看已经生成的词不能偷看答案。掩蔽的做法是把非法连接对应的 softmax 输入设成负无穷softmax 之后这些位置的权重就变成零。3.2 前馈网络和嵌入层看起来简单但有讲究每个层里还有一个前馈网络对每个位置单独且相同地应用。它包含两个线性变换中间夹一个 ReLU 激活公式是 FFN(x)max(0, xW1b1)W2b2。输入输出维度是 512内层维度是 2048。论文里说这等价于核大小为 1 的两个卷积。虽然不同位置用的是同一套变换但不同层之间的参数是独立的。嵌入层负责把输入标记和输出标记转成 512 维向量。论文里有个细节两个嵌入层和 softmax 前的线性变换共享同一个权重矩阵嵌入层的权重还要乘以 √dmodel。共享权重是为了减少参数、让输入输出空间对齐乘以 √dmodel 则是为了在数值上和位置编码的量级匹配。3.3 位置编码没有顺序信息就补进去Transformer 没有循环也没有卷积天生不知道词的先后顺序。所以论文在输入嵌入上加了位置编码。位置编码和嵌入维度相同可以直接相加。论文用的是不同频率的正弦和余弦函数偶数维用 sin奇数维用 cos波长从 2π 到 10000·2π 形成几何级数。为什么选正弦函数而不是直接学一个位置嵌入论文的解释是对于任何固定偏移 kPE(posk) 可以表示成 PE(pos) 的线性函数模型更容易学到相对位置关系。而且正弦版本可能让模型外推到比训练时更长的序列。论文也试过学习式位置嵌入结果几乎一样最后选了正弦版。import numpy as np def positional_encoding(max_len, d_model): # 初始化位置编码矩阵行是位置列是维度 pe np.zeros((max_len, d_model)) position np.arange(0, max_len)[:, np.newaxis] # 形状 (max_len, 1) div_term np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model)) pe[:, 0::2] np.sin(position * div_term) # 偶数维用 sin pe[:, 1::2] np.cos(position * div_term) # 奇数维用 cos return pe # 参数说明max_len 是最大序列长度d_model 是嵌入维度论文里是 512 # 输出 pe 的形状是 (max_len, d_model)可以直接和词嵌入相加这段代码把论文里的公式落成了可运行的实现。div_term 控制不同维度的波长位置越靠后的维度波长越长。实际使用时位置编码不参与训练是固定算出来的和词嵌入相加后一起送进编码器。4. 常见误区与易混概念别把注意力当成万能钥匙4.1 自注意力不等于普通的注意力机制很多人把自注意力和注意力机制混为一谈。注意力机制早就有了比如 Bahdanau 注意力用在编码器-解码器之间让解码器在生成每个词时关注输入序列的不同部分。但那种注意力是“跨序列”的查询来自解码器键和值来自编码器。自注意力是“同序列”的查询、键、值都来自同一个地方。论文强调 Transformer 是第一个完全依靠自注意力来计算输入和输出表示的转导模型不靠序列对齐的循环或卷积。这个区别很关键普通注意力是辅助模块自注意力是主干。4.2 多头注意力不是简单地把头加起来初学者容易以为多头注意力就是把八个头的输出直接拼起来完事。实际上每个头有自己独立的线性投影矩阵把查询、键、值投影到低维子空间各自做注意力最后把结果拼接再经过一次线性投影。论文里 h8每个头的 dkdvdmodel/h64。因为每个头维度降低总计算成本和全维单头注意力差不多。多头的作用是让模型同时关注不同位置的不同表示子空间单头容易把这些信息平均掉。4.3 位置编码不是可有可无的装饰有人觉得位置编码只是锦上添花去掉也能跑。实际上没有位置编码Transformer 对词序完全不敏感“狗咬人”和“人咬狗”在它眼里是一样的。论文用正弦函数是为了让模型学到相对位置并且可能外推到更长序列。虽然后来也有学习式位置嵌入取得差不多效果但位置信息本身是必需的不是可选项。4.4 BLEU 分数高不等于翻译完美论文里报的 28.4 BLEU英德和 41.0 BLEU英法是机器翻译的自动评估指标衡量生成译文和参考译文的 n-gram 重叠程度。BLEU 高说明整体质量好但它不理解语义也不代表每个句子都翻对了。论文自己也说这些超参数是在开发集上实验后选的。看论文结果时要明白BLEU 是统计指标不是人工评测的替代品。4.5 训练成本低是相对而言论文说基础模型在 8 个 P100 上训练 12 小时大模型训练 3.5 天相比之前的最好结果训练成本只是一小部分。但这是相对当时的最先进模型说的不是绝对意义上的“便宜”。Transformer 的优势在于可并行性能把 GPU 吃满而不是说随便一台机器就能训。理解这一点才不会对“训练成本低”产生不切实际的期待。5. 什么时候该用 Transformer 的思路什么时候别硬套5.1 适合的场景长依赖、可并行、数据量够Transformer 最擅长的场景是序列到序列的任务尤其是句子较长、依赖关系跨度大的情况。机器翻译是论文的主战场但它的思路后来被扩展到文本摘要、问答、语言建模等任务。判断要不要用可以看三个信号一是任务里存在长距离依赖比如文档级翻译、长文本理解二是训练数据量足够大因为 Transformer 参数多数据少容易过拟合三是有并行计算资源能发挥它训练快的优势。论文里还提到一个细节当序列长度 n 小于表示维度 d 时自注意力层比循环层更快。机器翻译里常用的词块表示、字节对编码句子表示维度通常大于序列长度所以自注意力有优势。但如果你的任务序列特别长、维度又低这个优势可能不明显。5.2 不适合的场景超长序列、小数据、强顺序约束自注意力的计算复杂度是 O(n²·d)序列长度翻倍计算量翻四倍。处理超长文档、高分辨率图像、长音频时直接套全局自注意力会很吃力。论文自己也提到可以把自注意力限制在大小为 r 的邻域内把最大路径长度增加到 O(n/r)这是后来很多高效注意力变体的起点。所以遇到超长输入别硬上全局注意力得考虑局部化或稀疏化。另外数据量很小的任务要谨慎。Transformer 没有循环网络那种归纳偏置它靠大量数据自己学出顺序和结构。数据少的时候循环网络或卷积网络可能更稳。论文里做了消融实验发现 dropout 对防止过拟合非常有帮助基础模型用 Pdrop0.1大模型英法任务用 0.1 而不是 0.3。这些细节说明Transformer 的效果很依赖正则化和数据规模。5.3 一个具体判断例子假设你要做一个中英术语翻译工具句子平均长度 30 个词训练语料有几十万句对手头有几张 GPU。这种情况 Transformer 是合适的选择序列不算超长数据量够并行训练能缩短周期。但如果你要做的是实时逐字输入的法条匹配输入可能长达几千字而且要求低延迟那就得掂量全局自注意力的开销考虑滑动窗口或分层结构。我自己的习惯是每次遇到一个新序列任务先问三个问题序列多长、数据多少、有没有并行资源。三个答案都偏向“中等长度、数据充足、有 GPU”才优先考虑 Transformer 架构只要有一个明显不满足就先回到循环网络或卷积方案做基线再决定要不要换。这套判断不是绝对的但能避免一上来就套最热架构然后翻车的尴尬。注意论文里的超参数N6、dmodel512、h8、dff2048、warmup_steps4000是针对当时机器翻译任务调出来的不是放之四海皆准的默认值。换任务时这些数要重新实验别直接照搬。这份中文翻译版本把论文的模型架构、训练细节、消融实验和结果对比都保留了下来适合想快速读懂原论文又不想被英文长句卡住的人。如果你正在补 NLP 的基础或者想搞清楚 self-attention 到底怎么算、多头注意力为什么有效、位置编码为什么用正弦函数这份资料能让你少走不少弯路。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站