图解 Transformer-中文讲解版 目录1、从高处俯瞰整个模型2、把张量画进流程图3、编码器里的数据流4、自注意力高层直觉5、自注意力向量级细节6、自注意力的矩阵实现7、多头注意力8、位置编码让模型感知顺序9、残差连接与层归一化10、解码器一侧11、最后的 Linear 与 Softmax 层12、训练过程回顾13、损失函数14、延伸阅读开篇在上一篇关于 Attention 的文章里我们看到注意力机制如何帮助神经机器翻译模型获得突破。本文要拆解的Transformer则把注意力机制推到了前台——它完全抛弃了 RNN仅靠注意力就完成序列建模因此天然适合并行计算训练速度大幅提升在特定任务上还超过了当时的 Google NMT。Google Cloud 也推荐把它作为 TPU 的参考模型。Transformer 来自论文 Attention is All You Need官方 TensorFlow 实现见 Tensor2TensorHarvard NLP 组提供了 PyTorch 注释版。下面我们逐步拆开它的内部结构。1. 从高处俯瞰整个模型先把 Transformer 当成一个黑盒以机器翻译为例喂它一句法语它吐出一句英语。把外壳掀开里面其实分成两部分一组编码器Encoders和一组解码器Decoders两者通过中间通道相连。编码端是若干层编码器堆叠而成原论文堆了 6 层数字 6 没有特别含义可以换解码端同样堆相同数量的解码器。每个编码器的结构都一样但权重不共享内部由两个子层组成自注意力层Self-Attention编码某个词时让模型同时去看输入句中其他词从中捕捉依赖关系。前馈神经网络Feed-Forward对每个位置独立施加同一份前馈网络。解码器除了拥有这两层在它们中间还多了一层编码器-解码器注意力Encoder-Decoder Attention作用类似 seq2seq 模型里的 attention让解码器去关注输入序列中相关的位置。2. 把张量画进流程图下面我们看数据本身是怎样在这些组件之间流动的。和大多数 NLP 任务一样第一步是把每个词通过词嵌入变成向量。每个词被嵌入为长度 512 的向量图中用方框表示。词嵌入只在最底层编码器输入端做一次。所有编码器对外的契约其实是一致的接收一组长度为 512 的向量列表。最底层接收的是词向量而上面每一层接收的是它正下方那一层的输出。这个列表的长度是个超参数通常取训练集中最长句子的长度。嵌入完成后每个词向量都会先后经过编码器的两个子层**关键性质**每个位置的词在编码器内部走自己独立的一条路径。自注意力子层里这些路径之间存在依赖每个位置都要看别的位置但到了前馈子层各位置之间彼此独立因此可以完全并行计算。这是 Transformer 训练比 RNN 快得多的根本原因之一。3. 编码器里的数据流下面用更短的句子做例子看看一个编码器内部到底发生了什么。每个位置的词向量都先穿过自注意力再穿过前馈网络每个位置独立通过同一份前馈网络。4. 自注意力高层直觉自注意力这个词第一次听可能很玄乎作者本人也是读了Attention is All You Need论文才第一次接触。下面用一个例子建立直觉。假设我们要翻译这句话“The animal didn’t cross the street because it was too tired”句中的it指代什么是street还是animal人一眼就看出来是animal但让算法自己判断并不容易。当模型处理it这个词时自注意力机制能帮它把it和animal在表示上关联起来。模型每处理一个位置自注意力都会让它环顾输入序列中的其他位置从中找出对当前位置有帮助的信息。如果你熟悉 RNN可以这样类比RNN 用隐状态把已经处理过的词的信息传给当前词而 Transformer 通过自注意力把序列中所有相关词的理解一次性烤进当前词的表示里。当第 5 层最顶层编码器处理 “it” 时注意力机制把一部分焦点放在 “The Animal” 上并将其表示融入到 “it” 的编码中。感兴趣可以去 Tensor2Tensor 提供的 Notebook 加载 Transformer 模型并交互式查看注意力可视化。5. 自注意力向量级细节先用向量讲清楚自注意力怎么算再扩展到矩阵实现。第一步构造 Query / Key / Value 三个向量对每个输入向量词嵌入分别乘上三个训练得到的权重矩阵W^Q、W^K、W^V得到对应的Query 向量 q、Key 向量 k、Value 向量 v。注意这三个新向量的维度比词嵌入要小——论文中嵌入是 512 维q/k/v 是 64 维。这并不是必须的而是为了让多头注意力的总计算量大致保持不变。把 x1 乘上 W^Q 矩阵就得到对应的 q1Query 向量。每个词都得到一组 query/key/value 投影。**怎么直观理解 query / key / value**它们是三种角色。可以想象在做信息检索query 是当前词发出的查询每个 key 像是其他词挂在外面的标签把 query 和各个 key 做点积就得到匹配分数分数越高意味着对应那个词的 value实际内容应该被更多地拿回来。继续往下看具体计算就更清楚了。第二步计算分数假设我们正在为第一个词Thinking计算自注意力。我们要给输入句中每个词打一个分数决定编码Thinking时该有多关注其他位置。分数 当前词的 query 向量与被打分词的 key 向量的点积。处理位置 1 时score₁ q1 · k1score₂ q1 · k2依此类推。第三、四步缩放 Softmax把每个分数除以√d_k √64 8key 向量维度的平方根目的是让梯度更稳定。然后再过一层 Softmax把所有分数归一化成正数且加起来等于 1。这个 softmax 分数就是在当前位置上每个词应该被表达多少。当前位置自己的分数通常最高但有时把注意力分给一些相关的其他词更有用。第五、六步加权求和得到输出第五步把每个 value 向量乘上对应的 softmax 分数。直觉是——保留我们想关注词的内容乘以接近 1 的数淡化无关词乘以例如 0.001 这样很小的数。第六步把这些加权后的 value 向量求和得到当前位置这里是第一个词的自注意力输出向量 z1。这就完成了一个位置上的自注意力计算。这个输出向量接下来会被送进前馈网络。但实际工程实现里我们不会逐位置算而是一口气用矩阵把所有位置一起算了下面就是矩阵版本。6. 自注意力的矩阵实现第一步算出 Q、K、V 三个矩阵把所有词的嵌入按行拼成矩阵 X然后分别乘上训练好的W^Q、W^K、W^V得到Q、K、V三个矩阵。X 矩阵每行是一个词。注意嵌入维度512图中 4 格和 q/k/v 维度64图中 3 格的差别。最后一步一个公式搞定因为我们直接用矩阵第二到第六步可以浓缩成一个公式矩阵形式的自注意力计算公式Z softmax( Q·Kᵀ / √d_k ) · V7. 多头注意力Multi-Head Attention论文进一步对自注意力做了改进引入了多头机制。它带来两个好处扩展模型关注不同位置的能力。前面的例子中z1 虽然包含了一点其他词的信息但很可能被自己这个词主导。多头让模型有更多机会去关注不同的位置比如句子 “The animal didn’t cross the street because it was too tired” 中知道it指代谁就很关键。提供多个表示子空间。一组 Q/K/V 权重矩阵是一个头论文里用了8 个头所以每个编码器/解码器都有 8 套 Q/K/V 权重。每套都随机初始化训练完后会把输入投影到 8 个不同的表示子空间里。多头注意力为每个头维护一组独立的 Q/K/V 权重矩阵把 X 分别投影出多组 Q/K/V。把前面那一套自注意力流程跑 8 遍每遍用不同的权重就会得到 8 个不同的输出矩阵 Z但下游的前馈层只接受单个矩阵怎么办做法是把 8 个 Z 在维度上拼接起来再乘上一个额外的权重矩阵W^O把它压回到合适的维度。多头自注意力大体就这些步骤矩阵确实很多。把所有步骤画在一张图里复盘一下讲完了多头机制再回到it的例子看不同的注意力头各自在关注什么编码 “it” 时一个头主要关注 “the animal”而另一个头主要关注 “tired”——某种意义上模型对 “it” 的表示同时融入了 “animal” 和 “tired” 的信息。但如果把所有 8 个头一起画出来可视化就会变得很难解读8. 位置编码让模型感知顺序到目前为止我们描述的模型还差一个东西它对词的先后顺序毫无感知。RNN 天然按顺序处理所以位置信息隐含在递归过程中但 Transformer 是并行处理所有位置的必须显式地告诉它谁在前、谁在后。解决方法是——给每个输入嵌入向量再加上一个位置编码向量Positional Encoding。这些向量遵循一种特定的模式模型在训练后就能据此推断每个词的位置或词与词之间的距离。直觉是把这些位置信息加进嵌入后再投影成 Q/K/V 做点积时向量之间就能体现有意义的距离。为了让模型感知词序我们额外加上位置编码向量——它的取值遵循特定的数学模式。假设嵌入维度只有 4真实的位置编码可能长这样嵌入维度为 4 时位置编码的真实例子。那位置编码的模式长什么样下图中每一行就是一个位置上对应的位置编码向量——第 1 行加给序列中第 1 个词第 2 行加给第 2 个词依此类推。每行有 512 个值每个值都在 -1 到 1 之间颜色编码后能看出明显的图案。20 个词行× 512 维列的真实位置编码。可以看到从中间一分两半左半边由 sine 函数生成右半边由 cosine 函数生成再拼接起来构成完整的位置编码向量。具体公式见原论文 3.5 节参考实现可看 Tensor2Tensor 仓库里的get_timing_signal_1d()。这并不是唯一的位置编码方法但它有一个好处——能外推到训练时未见过的更长序列。**2020 年 7 月勘误作者补充**上面这张图展示的是 Tensor2Tensor 实现里的位置编码方式左右拼接 sin/cos。论文里的写法略有不同是把 sin 和 cos 两路信号交错排列而不是直接拼接。下图展示了论文版本的样子生成代码在此9. 残差连接与层归一化编码器内部还有一个细节值得说每个子层自注意力 / 前馈网络外面都包了一层残差连接residual connection并在残差相加后再做一次层归一化Layer Normalization。如果把自注意力的向量流和层归一化操作画出来看起来是这样解码器的子层也是同样套路。如果想象一个由 2 层编码器 2 层解码器组成的精简版 Transformer整体结构大致是这样10. 解码器一侧编码端的概念都讲清楚了解码器的组件其实和编码器几乎一样——下面看它们如何协同工作。编码器先处理整个输入序列最顶层编码器输出会被转换成两个矩阵K和V作为编码端记忆提供给每一层解码器中的encoder-decoder attention子层使用。借助这两个矩阵解码器在生成时能持续关注输入序列里的相关位置编码阶段结束后进入解码阶段每一步解码器会输出目标序列里的一个词这里就是英文翻译里的下一个词。之后这个过程不断重复直到生成一个特殊的句末标记 表示翻译结束。每一步的输出会作为下一时间步最底层解码器的输入。和编码器一侧一样对解码器输入也要做嵌入并加上位置编码以指示词的位置。解码器在生成第 t 个位置时只能看到自己已经生成的位置 1…t-1不能看未来。实现方式是在 Softmax 之前把未来位置对应的分数设成-infsoftmax 之后这些位置的权重就趋近于 0。Encoder-Decoder Attention结构和多头自注意力完全一样区别在于——它的 Query 来自下一层即解码器自身的输出而 Key、Value 来自编码器栈最顶层的输出。这就是解码器看输入的通道。11. 最后的 Linear 与 Softmax 层解码器栈输出的还是一组浮点向量怎么把它变成一个真实的词这就是最后的 Linear 层 Softmax 层负责做的事情。Linear 层是一个简单的全连接网络把解码器输出的向量投影成一个非常长的向量称为logits 向量。假设我们的模型从训练集中学到了 10,000 个不同的英文单词“输出词表”那 logits 向量就有 10,000 个元素每个元素对应一个词的得分。Softmax 层把这些得分变成概率全部为正且加起来等于 1概率最大的那个位置对应的词就是这一时间步的输出。从下往上看解码器栈输出向量 → 通过 Linear 投影到 logits 向量 → Softmax 转成概率 → 取最大概率对应的词。12. 训练过程回顾前向传播推理讲完了再回头看一眼训练是怎么进行的。未训练的模型走的就是同样一套前向流程只不过我们手上有带标注的训练数据可以拿模型的输出和正确答案做对比再用反向传播把权重朝正确方向调整。为了画图简单假设我们的输出词表只有 6 个词a、am、i、thanks、student、句末符。词表是在训练之前的预处理阶段就确定好的。定义好词表后可以用一个长度等于词表大小的向量来表示每个词也就是one-hot 编码。例如表示词am玩具词表的 one-hot 编码示例。13. 损失函数假设这是训练的第一步我们用一个最简单的样本把法语merci翻译成英语thanks。我们希望模型输出的概率分布在thanks这一格上概率最高。但因为模型权重都是随机初始化的目前它给出的分布几乎是任意的初始权重随机未训练模型给出的分布是任意的我们把它和期望的分布做差异度量再用反向传播去调整所有权重让输出逐步贴近期望。怎么衡量两个概率分布的差异最直接的就是相减更严谨的指标是交叉熵cross-entropy和 KL 散度。真实场景里我们当然不会只翻译一个词。比如输入je suis étudiant期望输出i am a student。这意味着我们希望模型连续输出 5 个概率分布满足每个分布是长度为词表大小的向量玩具例子里是 6真实场景往往是 30,000 或 50,000第 1 个分布在i上概率最高第 2 个分布在am上概率最高……依此类推第 5 个分布在 句末符上概率最高。训练样本对应的目标概率分布——我们就是让模型去逼近这组分布。充分训练之后我们希望模型能输出像下图那样的分布训练完成后模型应当能输出我们期望的翻译。注意每个位置上其它词也会分到一点点概率——这是 softmax 的一个有用性质对训练过程很有帮助。当然如果这句话本来就在训练集里泛化能力还要靠交叉验证来真正考察。解码策略贪婪 vs Beam Search由于模型一次输出一个词最简单的做法是每一步直接选概率最大的那个词丢掉其他。这就是贪婪解码greedy decoding。更聪明一点的做法是Beam Search——每一步保留概率最高的若干个候选比如 2 个记beam_size 2在第 1 步保留I和a两个候选第 2 步则分别假设第 1 个词是I跑一次模型再假设是a跑一次比较哪条路径整体误差更小就把好的那条留下不断重复。beam_size每一步保留的候选数和最终返回的翻译数量都是可调超参数。最后选择AI大模型就是选择未来最近两年大家都可以看到AI的发展有多快时代在瞬息万变我们又为何不给自己多一个选择多一个出路多一个可能呢与其在传统行业里停滞不前不如尝试一下新兴行业而AI大模型恰恰是这两年的大风口人才需求急为紧迫人工智能时代最缺的是什么就是能动手解决问题还会动脑创新的技术牛人智泊AI为了让学员毕业后快速成为抢手的AI人才直接把课程升级到了V6.0版本‌。这个课程就像搭积木一样既有机器学习、深度学习这些基本功教学又教大家玩转大模型开发、处理图片语音等多种数据的新潮技能把AI技术从基础到前沿全部都包圆了课堂上不光教理论还带着学员做了十多个真实项目。学员要亲自上手搞数据清洗、模型调优这些硬核操作把课本知识变成真本事‌课程还教大家怎么和AI搭档一起工作就像程序员带着智能助手写代码、优化方案效率直接翻倍‌这么练出来的学员确实吃香83%的应届生都进了大厂搞研发平均工资比同行高出四成多‌。智泊AI还特别注重培养人无我有的能力比如需求分析、创新设计这些AI暂时替代不了的核心竞争力让学员在AI时代站稳脚跟‌。课程优势一人才库优秀学员参与真实商业项目实训课程优势二与大厂深入合作共建大模型课程课程优势三海外高校学历提升课程优势四热门岗位全覆盖匹配企业岗位需求如果说你是以下人群中的其中一类都可以来智泊AI学习人工智能找到高薪工作一次小小的“投资”换来的是终身受益·应届毕业生‌无工作经验但想要系统学习AI大模型技术期待通过实战项目掌握核心技术。·零基础转型‌非技术背景但关注AI应用场景计划通过低代码工具实现“AI行业”跨界‌。·业务赋能 ‌突破瓶颈传统开发者Java/前端等学习Transformer架构与LangChain框架向AI全栈工程师转型‌。智泊AI始终秉持着“让每个人平等享受到优质教育资源”的育人理念‌通过动态追踪大模型开发、数据标注伦理等前沿技术趋势‌构建起前沿课程智能实训精准就业的高效培养体系。重磅消息人工智能V6.0升级两大班型AI大模型全栈班、AI大模型算法班为学生提供更多选择。由于文章篇幅有限在这里我就不一一向大家展示了学习AI大模型是一项系统工程需要时间和持续的努力。但随着技术的发展和在线资源的丰富零基础的小白也有很好的机会逐步学习和掌握。【最新最全版】AI大模型全套学习籽料可无偿送LLM面试题AI大模型学习路线大模型PDF书籍640套AI大模型报告等等从入门到进阶再到精通超全面存下吧获取方式有需要的小伙伴可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】来智泊AI高起点就业培养企业刚需人才扫码咨询 抢免费试学⬇⬇⬇AI大模型学习之路道阻且长但只要你坚持下去就一定会有收获。