恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Transformer零基础详解:从自注意力到手算理解架构

  • 首页
  • 资讯中心
  • /
  • Transformer零基础详解:从自注意力到手算理解架构

相关资讯

Flutter迁移OpenHarmony实战:日记本功能完整实现 2026/10/18 8:31:42
PHP微信支付V3完整实战:解决401签名失败与验签问题 2026/10/18 8:31:42
C语言数据结构与算法:程序员的底层交通规划图 2026/10/18 8:31:42

最新资讯

AI自主供应链攻击警示:GPT-6 Astra模拟红队测试的安全启示
多模型协作驱动前端样式生成:基于CF Inference的自然语言CSS工具实践
用Claude Code从零开发全栈宠物管理App:AI辅助编程实战与避坑指南
代码中rea缩写含义解析:React、Read、Real还是内部代号?
Java Swing游戏开发实战:大鱼吃小鱼教学骨架解析
Brave浏览器源码编译实战:从环境搭建到定制拦截规则

今日推荐

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本周热门

基于GMM的语音识别系统原理与MATLAB实现详解
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

本月精选

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)

Transformer零基础详解:从自注意力到手算理解架构

发布时间:2026/10/18 8:36:43
Transformer零基础详解:从自注意力到手算理解架构 第一次翻开《Attention Is All You Need》这篇论文的时候我只撑了不到十分钟就合上了。满屏的公式、矩阵维度和看起来很随意的“缩放点积注意力”对一个当时只写过几天基础模型代码的人来说完全是天书。但后来我用了整整三个周末把它从背景到公式再到多头的每一行都啃了一遍最关键的是自己动手把里面那个极其简单的计算流程手算过一次之后整个架构突然就“通”了。 这篇论文提出了 Transformer 架构核心观点用标题就能概括只需要注意力。它把过去处理序列任务离不开的循环结构RNN和卷积结构CNN全部丢掉只靠一种叫自注意力的机制就在翻译、生成和后续几乎所有自然语言处理任务上做出了碾压级的效果。如果你也是零基础希望真正理解 Transformer 而不是背概念那这篇文章就是按我当时理解的路径来写的先搞清楚它解决了什么问题再手算一次注意力最后把 Encoder、Decoder 和那些最容易想错的细节全部拆开。1. 先说清楚Attention 到底解决了什么老问题要理解一个模型为什么牛不能只看它有什么花样要先看它站在什么位置上替换掉了什么。1.1 在 Transformer 之前序列模型是怎么工作的在 2017 年之前主流处理序列任务的方法是循环神经网络RNN以及它的进阶版本 LSTM 和 GRU。拿机器翻译举例输入是一句英文输出是一句中文。RNN 的做法是一个词一个词地“读”每读到一个词就更新一次隐藏状态这个状态就像人脑里暂时记下的“读到这里为止的信息压缩包”。这个设计的核心问题是第 t 个词的信息要传到第 tk 个词必须老老实实经过 k 次状态更新。句子越长路径越长信息损耗越严重梯度也容易在长距离反向传播中消失。所以大家说 RNN 不适合长距离依赖就是这个原因。LSTM 用门控机制缓解了这个问题但它并没有从根本上改变“必须逐级传递”这件事。另一个让研究者头疼的问题是 RNN 无法并行。因为计算第 t 步的隐藏状态依赖第 t-1 步的输出这天然是一个串行过程。在 GPU 时代等于你有一百个工人却只能让他们排成一队逐个干活效率上非常吃亏。1.2 注意力机制从“按顺序搬砖”变成“全场直接打分”注意力机制本身不是 Transformer 发明的。早在早几年的机器翻译工作中研究者就会在 seq2seq 模型上额外加一个注意力模块解码器在生成某个词时不再只看最后那个压缩状态而是回头去扫一遍源语言所有位置的隐藏状态按“相关度”挑重点信息看。Transformer 的激进之处在于连 RNN 都不用了。它直接把注意力从辅助模块提升为主干结构让任意两个词之间都能一步直达地计算相互关系。这意味着句子里的第 1 个词和第 100 个词只要内容足够相关就能产生一个很大的注意力权重彻底绕开“逐级传递”的长路径问题同时所有位置的相互打分可以在一个矩阵乘法里全部算完GPU 终于能真正并行地干活。理解这一个点非常重要因为它解释了一个经常被问的问题为什么论文敢叫“Attention Is All You Need”潜台词是过去我们认为序列建模必须依赖某个按顺序传递信息的骨架RNN现在用一句话来总结 Transformer 的核心发现——不需要骨架两两直接建联就够了。后面的 Multi-Head、位置编码、残差结构本质上都是在解决“只用注意力”之后新暴露出来的工程问题。2. 自注意力的完整计算从 Q/K/V 到加权求和如果你打开论文最核心的公式只有一行[ Attention(Q,K,V)softmax(\frac{QK^T}{\sqrt{d_k}})V ]别害怕我不会让你直接跳上去看这个公式而是把它拆成计算步骤每一步配一个极简的示例。2.1 词向量从哪里来Q/K/V 又是怎么生成的一切开始于词向量。假设我们有三句话里的三个词“猫”、“趴”、“垫子”。每个词要先转换成一个固定长度的向量。在真实模型里这个向量可能是 512 维的这里我们为了演示方便假设每个词是一个 3 维向量猫 - [0.5, 1.0, 0.2] 趴 - [1.0, 0.5, 0.3] 垫子 - [0.3, 1.0, 0.8]每个词向量有 3 个数字代表它初始的语义特征。这一步可以通过随机初始化的 embedding 表也可以直接用预训练好的词向量。接下来是 Q、K、V 三胞胎的诞生。每个词向量会分别乘上三个可学习的权重矩阵 Wq、Wk、Wv得到三个新向量q x Wq k x Wk v x WvQ 是 Query可以理解为“我想查什么”K 是 Key可以理解为“我身上有什么标签”V 是 Value可以理解为“我真正能提供的内容”。为了简化我先假设三个权重矩阵都是单位矩阵这样 q、k、v 就等于原来的词向量。现实中它们经过训练会是不同的矩阵这并不影响你理解后续的计算流程。2.2 打分、缩放与 Softmax一次微型手算注意力最关键的一步是让每个词去和句子里所有词“互相打分”。假设我们正在处理“猫”这个词它就是当前的中心词。我们拿着“猫”的 Query去和句子里每个词的 Key 做点积得分(猫, 猫) [0.5, 1.0, 0.2] · [0.5, 1.0, 0.2] 1.29 得分(猫, 趴) [0.5, 1.0, 0.2] · [1.0, 0.5, 0.3] 1.06 得分(猫, 垫子) [0.5, 1.0, 0.2] · [0.3, 1.0, 0.8] 1.31点积越大说明这两个词在当前语义空间里越“相关”。但直接拿这个分数去加权还有问题当向量维度很高比如 512 维时点积的数值会变得非常大导致后续 softmax 进入梯度极小的饱和区。所以论文里加了一个缩放因子[ score \frac{q \cdot k}{\sqrt{d_k}} ]其中 (d_k) 是 Key 向量的维度。在我们例子里是 3所以每个分数除以 (\sqrt{3} \approx 1.732)。这一步的意义我会在后面专开一节细讲现在你先记住除以根号维度是为了控制分数的量级。然后对这三个分数做 softmax让它们的总和变成 1同时保持相对大小。计算过程大致是这样exp(1.29/1.732) ≈ 2.101 exp(1.06/1.732) ≈ 1.850 exp(1.31/1.732) ≈ 2.128 总和 ≈ 6.079 softmax 后 对“猫” ≈ 2.101 / 6.079 ≈ 0.346 对“趴” ≈ 1.850 / 6.079 ≈ 0.304 对“垫子” ≈ 2.128 / 6.079 ≈ 0.350这三个数就是注意力权重表示“在理解‘猫’这个词时我应该分别花多少注意力在‘猫’、‘趴’、‘垫子’上”。你注意到没有即使只是用简化向量算出来的结果“猫”和“垫子”的关联分数已经很高了实际训练好的模型也会自己学会这种关联。2.3 加权求和为什么能聚合全局信息拿到注意力权重后最后一步是把每个词的 Value 加权求和得到“猫”这个位置的新向量新“猫”向量 0.346 * v(猫) 0.304 * v(趴) 0.350 * v(垫子)因为 V 正好等于原始向量这算出来就是个融合了三个词信息的向量。如果是真实模型V 经过了可学习的线性变换这个加权结果就代表“在结合了全句信息之后‘猫’在这里应该有什么样的特征表达”。把这套流程对句子里的每个词都执行一遍你就得到了一整层自注意力的输出。整个过程乘法和加法全是矩阵运算一次前向传播就能完成所有位置的计算这正是 Transformer 能高效并行的基础。3. 把单头变成多头Multi-Head 与位置编码的意义前面我们算的是“单头注意力”。论文真正用的是多头注意力Multi-Head Attention还要加上位置编码、残差连接和层归一化否则模型根本训不起来。3.1 多头注意力在学什么单头注意力的问题在于它只能从一种关系维度去看词与词的关联。但自然语言里的关系是多元的两个词可能在语法上是主谓关系在语义上是同义关系在位置上存在修饰关系。一个打分函数学不过来这么多维度的相关性。多头注意力的做法非常简单粗暴准备多组 (W_q, W_k, W_v)每组独立地做一次完整注意力计算得到多组新向量然后把它们拼起来再乘一个线性变换到目标维度。论文里用的是 8 个头也就是 8 组权重。用生活化的类比单头注意力是一个人在评估词与词的相关度他可能只擅长根据“词性”来判断多头则像叫了 8 个专家有人看语义有人看句法有人看位置最后开会把意见汇总。每个头只观察到原来 512 维向量中的一个小切片在论文中每头是 64 维但它们从不同的子空间去捕捉信息合起来表达能力就上来了。实际实现时为了效率不是把 8 组矩阵各自循环一遍而是把 8 个头的 (W_q, W_k, W_v) 堆叠在一起通过一个巨大的矩阵乘法一次性算出所有注意力结果再拆分、分别做 softmax 和加权最后拼接。这也是很多读者看源码时最容易懵的地方——你如果只盯着代码看会觉得它和公式完全对不上但把矩阵维度列出来就清楚了。3.2 位置编码给模型补上“顺序”这根弦自注意力有一个致命问题它本质上把句子当成一个集合set来处理。在上面那个三词例子里你把“猫”、“趴”、“垫子”的顺序打乱成“垫子”、“猫”、“趴”每一对词之间的点积分数完全不变注意力权重不变输出也不变。这对语言来说是无法接受的“猫咬人”和“人咬猫”完全是两个意思。循环网络天然知道词序因为它是按顺序读取的。Transformer 放弃了这层结构就必须主动把位置信息“灌”进输入。论文用的是正弦和余弦函数编码公式是这样[ PE_{(pos, 2i)} \sin(pos / 10000^{2i/d_{model}}) ] [ PE_{(pos, 2i1)} \cos(pos / 10000^{2i/d_{model}}) ]其中 (pos) 表示词在句子中的位置(i) 表示向量维度下标(d_{model}) 是向量总维度。这些位置向量直接加到词向量上模型就知道“哪些词在第几个位置”了。选用三角函数而不是简单的整数位置背后有两个实在的理由一是位置编码的值有界稳定二是三角函数的相对位置关系可以通过线性变换表示模型更容易学到“某个词距离当前词 5 个位置”这类相对信息对捕捉句法结构很有帮助。后续不少模型用可学习的位置编码也能工作但论文的三角函数方案不需要训练参数且能应对比训练集更长的序列在当年是更优雅的选择。3.3 残差连接与层归一化让 Transformer 能训练得更稳注意力输出并不是直接进入下一层而是先和输入做残差相加再做层归一化Layer Normalization。这个设计在论文里看似一笔带过实际是模型能稳定堆叠到 6 层、12 层甚至更深的关键。原因在于只要注意力输出接近零残差结构就退化为 (x) 本身。这意味着每一层在最坏情况下不会比上一层的表达能力更差梯度也可以更顺畅地回传。层归一化则控制每个位置特征向量的均值和方差让网络各个层的数据分布不过度发散训练时学习率可以设置得更大胆收敛也更稳定。很多零基础的读者看到架构图里有“Add Norm”这一小条以为只是个无关紧要的细节然后自己复现时发现模型怎么训都不收敛或者一两层还行、一加深就爆炸才意识到这个残差机制的分量。4. 从公式到架构Encoder、Decoder 与训练/推理的差异理解了单层注意力你已经有能力看懂论文的框架图了。Transformer 主体是左边 6 层 Encoder、右边 6 层 Decoder中间用 Cross-Attention 衔接。4.1 编码器每层到底做了几步编码器中每一层只有两个核心子层多头自注意力和逐位置前馈网络FFN。每个子层外面都包着残差连接和层归一化。自注意力子层我们已经讲清楚了输入是一句完整句子的全部词向量输出是每个词融合了全句信息后的新向量。前馈子层是一个对每个位置独立施加的两层全连接网络FFN(x) max(0, x W1 b1) W2 b2中间层的维度论文里设为 2048比 512 的模型维度大 4 倍先升维再降维引入非线性变换。它不加任何跨位置的交互就是逐位置地对特征做加工相当于一个强大的特征提取器。实际操作中因为所有位置共享同一套参数它也可以被看成一个 1×1 卷积在逐位置操作。为什么编码器不用掩码因为编码器处理源语言句子时每个词都允许看到全句其他词的信息这是合理的读一个英文句子我们当然可以前后结合着理解每一个词。4.2 解码器里的掩码自注意力解码器的结构更复杂一些。它的第一个子层也是自注意力但这个自注意力是带掩码的在预测第 t 个词的时候它只能看到第 1 到第 t 个词的注意力信息看不到 t 后面的任何词。对应到矩阵里就是把形状为 (n \times n) 的注意力矩阵右上角未来的位置全部替换成负无穷大这样 softmax 之后的权重就会变成 0。这个设计的直觉很简单训练时我们有标准答案可以一次把整个目标句子的所有位置并行处理但如果某个位置的注意力能看到后面未来的词模型就会“作弊”——还没预测的词提前出现在视野里等于泄露了答案。解码器的第二个子层是交叉注意力Cross-Attention这是 Encoder 和 Decoder 最重要的连接点。它同样有三件套 Q、K、V但来源完全不同Q 来自解码器上一个子层的输出K 和 V 来自编码器最后一层的输出。用通俗的说法是解码器在生成一个词之前先拿着自己的当前状态去“查询”输入句子的所有位置决定该重点参考源语言的哪些词。第三个子层和编码器一样是 FFN。4.3 训练时并行、推理时逐词的原因这是一个很容易想不通的点既然你说 Transformer 可以并行为什么生成翻译结果的时候还是一个词一个词往外蹦关键要把“训练”和“推理”分开。训练阶段我们拥有完整的标准翻译结果。假设目标句是“I love you”模型在训练时不是先预测 I再拿 I 去预测 love而是整个句子的所有位置同时进到解码器里通过掩码自注意力保证位置 1 只看位置 1位置 2 只看位置 1 和 2以此类推。这种“直接把正确答案喂进去让模型并行预测所有单词”的做法叫教师强制Teacher Forcing。因为掩码挡住了未来信息训练输出是并行的GPU 可以一次算完。推理阶段没有标准答案。你第一步只能给解码器输入一个起始标记让它生成“I”拿到“I”之后再把“起始标记 I”作为输入生成“love”接着输入“起始标记 I love”生成“you”。每一步都在越来越长的上下文上重新计算这就是所谓的自回归生成。所以 Transformer 在训练时并行在推理时依然是串行的。这也是为什么大语言模型生成文本速度不快跟你聊天时感觉要等一等。论文中还有一个细节解码器输入端的位置也要加上位置编码。因为目标句子也是词序列掩码自注意力同样没有顺序感必须显式告诉它每个目标词处于第几个位置。如果你在实现时忘记给解码器输入加位置信息模型基本不会有像样的生成效果。5. 零基础最容易想错的四个细节这个部分是当年我反复琢磨了很久、也在社区里看到无数新人问过的问题。逐个给你讲透。5.1 为什么缩放因子是根号 d_k当 (Q) 和 (K) 的每个维度都近似服从均值为 0、方差为 1 的独立分布时它们的点积 (q \cdot k \sum_{i1}^{d_k} q_i k_i) 的期望是 0方差是 (d_k)。也就是说向量维度越高点积分数的绝对数值本身就越大。Softmax 函数对输入的数值非常敏感如果两个候选值一个是 20另一个是 18指数运算后相差约 8.4 倍softmax 结果会极度偏向 20几乎变成 one-hot 分布。在反向传播时one-hot 区域的梯度非常小模型很难学习。除以 (\sqrt{d_k}) 后点积的方差被拉回 1 附近softmax 的输入分布更平滑梯度也就更健康训练稳定得多。这也是为什么没必要引入其它更复杂的归一化方式——理论上用更高的 sqrt 也行但论文给出的这个设计既简单又可解释被后续所有 Transformer 模型沿用至今。5.2 Masked 注意力在实践中是怎么实现的很多第一次读源码的人会困惑代码里怎么没看到“把未来位置替换成负无穷”的步骤因为实现的时候一般是用一个上三角矩阵把未来位置设为一个很大的负数比如 -1e9再加到注意力分数上然后再做 softmax。要注意的是不能直接把这些位置设成 0因为 softmax 里 (e^0 1)根本起不到屏蔽作用。必须用一个足够大的负值让指数运算后趋近于 0。还要小心数值精度问题负值要足够大但不能大到溢出-1e9 在常用浮点精度下足够安全。在实际模型代码里你还会看到通过 key_padding_mask 把 padding 位置也一并屏蔽的写法原理同源。5.3 Self-Attention 的复杂度问题自注意力的计算过程里有一处 (QK^T)形状是 ((n, d_k) \times (d_k, n))结果是一个 (n \times n) 的注意力矩阵。这里的 (n) 是序列长度所以自注意力时间复杂度是 (O(n^2))空间复杂度也是 (O(n^2))。序列短的时候没问题一旦序列变长比如处理整本书、长文档或高分辨率图像(n^2) 的增长会非常快。这也是后续各种高效注意力变体稀疏注意力、线性注意力等出现的原因。理解这一点你才能明白为什么很多新模型需要加“长度外推”技巧以及为什么输入 token 数会直接影响模型显存占用。5.4 “并行”到底是什么意思很多人把 Transformer 的并行理解成“读完整句话后立刻得到完整输出句”这是不对的。Transformer 的并行体现在两个地方第一编码器处理源文本时所有词互相打分的注意力计算是一次矩阵乘法完成的不像 RNN 必须循环执行 (n) 次子步骤。第二解码器在训练时可以通过掩码一次处理目标句的所有位置把所有位置的预测损失一起算出来。但推理生成依旧是逐词的。更准确地说并行是发生在“给定完整上下文同时计算多个位置的新特征表示”这个层面而“生成新内容”这个动作因为是自回归的不可避免是串行的。把这两个层面分开你对 Transformer 的理解就已经超过绝大多数初学者了。6. 我的学习建议零基础到能复现的路径很多读者问我论文这么难公式这么多到底应该怎么读才能真的学会而不是看完就忘。下面是我自己实际用过的路径每一步都踩过坑。6.1 从一行行算完注意力开始别急着看论文的实验部分也别急着读源码。先用最简单的方法找一个只有三到四个词的句子手算一次注意力的完整过程。你可以完全复制本文第 2 节那个例子把每个矩阵的维度写出来把每一步的输出形状标出来。当你亲手在纸上写出 (Q, K, V)再写出 (QK^T) 的形状是 (n, n) 的时候那个吓人的公式就已经被你降伏了。我自己的经验是第一次手算会花大概两三个小时但算完之后后面再学多头、掩码、Cross-Attention每新增一个概念都只是在这棵已经立起来的树干上加枝叶。6.2 用最小化实现验证理解在你觉得自己懂了公式之后写一个最简版的自注意力。这个实现不需要任何训练只要把前向传播跑通就行。比如我用 PyTorch 写过这样一个最小版本import torch import torch.nn.functional as F def simple_attention(x, maskNone): # 假设 x: [batch, seq_len, d_model] # 为了演示这里直接用同一个线性层生成 q/k/v d_k x.shape[-1] q x k x v x scores torch.matmul(q, k.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k, dtypetorch.float32)) if mask is not None: scores scores.masked_fill(mask 0, float(-inf)) weights F.softmax(scores, dim-1) out torch.matmul(weights, v) return out, weights这段代码和论文公式严格对照核心就 5 行。跑通之后把mask参数传入一个第 3 节那种上三角掩码观察输出怎样变化你对掩码的理解就是实际经验而不是抽象概念了。然后再做两件事加多头把一个头的逻辑复制 8 份加位置编码按论文公式构造一个矩阵加到输入上。当你能写出一个只有几十行却能处理真实句子的小型 Transformer 编码器时你已经能看懂大部分论文实现。6.3 读论文的正确姿势我自己读论文的顺序和你分享下先读 Abstract 和 Introduction 中关于 RNN/CNN 困境的段落然后直接跳到第 3 章看模型架构尤其只盯着模型结构图和公式 (1) 到 (5) 看。实验部分先跳过等有真实任务要跑通了再回来看。论文里的机器翻译评测指标对理解核心机制来说并不关键。遇到不懂的名词比如“决策级融合”“残差连接的作用”之类建议先查消息来源可靠的教程再回来看论文原句。论文的价值在于精确和权威但它的行文默认你已经有相当的背景知识宁可先用博客把背景补齐再打开论文效率会高很多。6.4 接下来还能往哪走当你把 Transformer 本身搞懂后你会发现几乎所有现代大模型都是它的变体只保留 Encoder 的模型擅长理解与分类只保留 Decoder 的模型擅长生成Encoder-Decoder 结构擅长翻译和摘要。自注意力这个思想还延伸到了图像、音频、多模态领域几乎随处可见它的影子。这时候如果还想深入一步有几个方向值得折腾把多头注意力的各个头的权重可视化出来观察它们是否学到了不同的语法或语义关系实现一个简单的复制任务或翻译小玩具训练几次看看 loss 是否下降给模型加不同长度、不同语言的数据体验位置编码对长度的敏感性。这些实践都会让理论进一步变得血肉丰满。我在学习这篇论文时最大的教训是别害怕公式也别以为看懂公式就完事了。真正的理解来自亲手算一遍、亲手写一次、亲手跑一个任务。Transformer 的每一块设计都有非常直白的动机——从并行、长程依赖、到防作弊掩码没有一个是为了炫技而存在。你把注意力计算那套“打分—加权求和”的流程印在脑子里后面遇见的各种模型本质上都是在问同一个问题哪些信息该被多看一眼这个答案你自己就能找出来。最后分享一个我至今沿用的操作习惯拿到任何类似架构的论文先不看正文里天花乱坠的任务表格而是把所有矩阵的维度变化列成一张表顺便问自己“这一步为什么没有掩码那一步为什么需要掩码”。这几层问题读完论文基本就被你吃到七成了。然后丢下论文用 50 行代码跑通一个最小实现——这时候你才真正站在“理解”的门槛上。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号