云计算百科
云计算领域专业知识百科平台

图解Transformer与PyTorch实现

前言:推开那扇通往“上帝视角”的门

🌪️ 一场静悄悄的革命

把时针拨回 2017 年。

那时候的 AI 还在费劲地像小学生一样,一个字一个字地读课文(RNN/LSTM 时代)。它读到句子末尾时,往往已经忘了开头讲了什么。

就在那一年,Google 的几位工程师丢出了一篇论文——《Attention Is All You Need》。

这篇论文就像一块巨石砸进了平静的湖面,激起的涟漪最终演变成了今天的海啸:BERT、GPT-3、ChatGPT、Sora…… 这些震撼世界的模型,剥开外衣后,里面躺着的都是同一个架构——Transformer。

它是 AI 时代的蒸汽机,是通往通用人工智能(AGI)的入场券。

🤯 为什么要写这篇博客?

如果你尝试过去读原论文,或者搜过网上的教程,你可能经历过以下心态崩溃的瞬间:

  • 被数学劝退:看到满屏的

    softmax

    (

    Q

    K

    T

    d

    k

    )

    V

    \\text{softmax}(\\frac{QK^T}{\\sqrt{d_k}})V

    softmax(dk

    QKT)V 直接关网页。

  • 被图表劝退:看到那些箭头满天飞的架构图,眼睛学会了,脑子没学会。
  • 似懂非懂:“我知道它叫自注意力机制,但它到底在注意个啥?”
  • 这篇博客不打算这么干。

    我们不追求把每个数学推导都写得天衣无缝,我们追求的是直觉(Intuition)。 我会用搭乐高、查字典、开相亲大会、做阅读理解等各种生动的比喻,带你钻进 Transformer 的黑盒子里,看着数据是如何在里面流动的。

    我们将把这个复杂的巨兽拆解成一个个简单的零件,最后你会发现:原来所谓的“神级架构”,也不过就是精妙的工程学积木罢了。

    🗺️ 我们的探险路线图

    为了不让你在迷宫里晕头转向,这是我们接下来的旅程规划:

    #mermaid-svg-IXDGPm1GZoXtXwek{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-IXDGPm1GZoXtXwek .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-IXDGPm1GZoXtXwek .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-IXDGPm1GZoXtXwek .error-icon{fill:#552222;}#mermaid-svg-IXDGPm1GZoXtXwek .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-IXDGPm1GZoXtXwek .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-IXDGPm1GZoXtXwek .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-IXDGPm1GZoXtXwek .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-IXDGPm1GZoXtXwek .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-IXDGPm1GZoXtXwek .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-IXDGPm1GZoXtXwek .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-IXDGPm1GZoXtXwek .marker{fill:#333333;stroke:#333333;}#mermaid-svg-IXDGPm1GZoXtXwek .marker.cross{stroke:#333333;}#mermaid-svg-IXDGPm1GZoXtXwek svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-IXDGPm1GZoXtXwek p{margin:0;}#mermaid-svg-IXDGPm1GZoXtXwek .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-IXDGPm1GZoXtXwek .cluster-label text{fill:#333;}#mermaid-svg-IXDGPm1GZoXtXwek .cluster-label span{color:#333;}#mermaid-svg-IXDGPm1GZoXtXwek .cluster-label span p{background-color:transparent;}#mermaid-svg-IXDGPm1GZoXtXwek .label text,#mermaid-svg-IXDGPm1GZoXtXwek span{fill:#333;color:#333;}#mermaid-svg-IXDGPm1GZoXtXwek .node rect,#mermaid-svg-IXDGPm1GZoXtXwek .node circle,#mermaid-svg-IXDGPm1GZoXtXwek .node ellipse,#mermaid-svg-IXDGPm1GZoXtXwek .node polygon,#mermaid-svg-IXDGPm1GZoXtXwek .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-IXDGPm1GZoXtXwek .rough-node .label text,#mermaid-svg-IXDGPm1GZoXtXwek .node .label text,#mermaid-svg-IXDGPm1GZoXtXwek .image-shape .label,#mermaid-svg-IXDGPm1GZoXtXwek .icon-shape .label{text-anchor:middle;}#mermaid-svg-IXDGPm1GZoXtXwek .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-IXDGPm1GZoXtXwek .rough-node .label,#mermaid-svg-IXDGPm1GZoXtXwek .node .label,#mermaid-svg-IXDGPm1GZoXtXwek .image-shape .label,#mermaid-svg-IXDGPm1GZoXtXwek .icon-shape .label{text-align:center;}#mermaid-svg-IXDGPm1GZoXtXwek .node.clickable{cursor:pointer;}#mermaid-svg-IXDGPm1GZoXtXwek .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-IXDGPm1GZoXtXwek .arrowheadPath{fill:#333333;}#mermaid-svg-IXDGPm1GZoXtXwek .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-IXDGPm1GZoXtXwek .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-IXDGPm1GZoXtXwek .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IXDGPm1GZoXtXwek .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-IXDGPm1GZoXtXwek .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IXDGPm1GZoXtXwek .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-IXDGPm1GZoXtXwek .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-IXDGPm1GZoXtXwek .cluster text{fill:#333;}#mermaid-svg-IXDGPm1GZoXtXwek .cluster span{color:#333;}#mermaid-svg-IXDGPm1GZoXtXwek div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-IXDGPm1GZoXtXwek .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-IXDGPm1GZoXtXwek rect.text{fill:none;stroke-width:0;}#mermaid-svg-IXDGPm1GZoXtXwek .icon-shape,#mermaid-svg-IXDGPm1GZoXtXwek .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-IXDGPm1GZoXtXwek .icon-shape p,#mermaid-svg-IXDGPm1GZoXtXwek .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-IXDGPm1GZoXtXwek .icon-shape rect,#mermaid-svg-IXDGPm1GZoXtXwek .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-IXDGPm1GZoXtXwek .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-IXDGPm1GZoXtXwek .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-IXDGPm1GZoXtXwek :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    生成与输出

    核心组件拆解

    起点

    第1章: 为什么要抛弃RNN?

    第2章: 宏观俯瞰 Transformer

    第3章: Embedding & 位置编码

    第4-5章: 自注意力 & 多头机制

    第6-7章: 残差连接 & FFN

    第8章: 解码器的 Mask 秘密

    第9章: 输出与未来

    终点: 觉醒


    📚 目录:Transformer 拆解之旅

    • [第一章:告别“接力跑”——为什么要抛弃 RNN?]

      • 看旧时代的霸主是如何因“记性不好”和“腿脚太慢”被历史淘汰的。
    • [第二章:黑盒与乐高——宏观俯瞰 Transformer]

      • 不谈细节,先看骨架。认识 Encoder 和 Decoder 这对孪生兄弟。
    • [第三章:单词的 GPS——Embedding 与位置编码]

      • 机器不识字也不识数,怎么让它知道“我爱你”和“你爱我”的区别?
    • [第四章:灵魂核心——自注意力机制 (Self-Attention)]

      • 全篇最硬核!看 AI 如何通过“相亲大会”找出一句话里的隐藏关系。
    • [第五章:多头注意力 (Multi-Head Attention)——三个臭皮匠,顶个诸葛亮]

      • 为什么要搞 8 个脑袋?论“多维度思考”的重要性。
    • [第六章:连接与归一化——残差连接 (Residual) 与 LayerNorm]

      • 防止楼盖塌的工程学奇迹,给信息开通“VIP 直通车”。
    • [第七章:前馈神经网络 (Feed-Forward Networks)——记忆的精炼]

      • Attention 负责社交,FFN 负责思考。揭秘参数量最大的“记忆区”。
    • [第八章:解码器的独角戏——Masked Multi-Head Attention]

      • 考试不能作弊!看 Decoder 如何戴着“眼罩”预测未来。
    • [第九章:终章——输出与未来]

      • 从一堆数字变回人类语言。BERT 和 GPT 家族是如何分道扬镳的?
    • [附录 1:代码实战] (PyTorch 逐行手撕 Transformer)

    • [后记] (走出黑盒,看见星辰大海)


    第一章:告别“接力跑”——为什么要抛弃 RNN?

    在 2017 年那篇著名的论文《Attention Is All You Need》横空出世之前,自然语言处理(NLP)的世界是由 RNN(循环神经网络) 和它的升级版 LSTM(长短期记忆网络) 统治的。

    虽然它们在当时也是划时代的发明,但它们身上有一个致命的基因缺陷——时序依赖(Sequential Dependency)。

    1. 以前的 AI 是怎么“读书”的?

    想象一下,你让一个旧时代的 AI 翻译这句话:

    “The cat didn’t cross the street because it was too tired.” (这只猫没有过马路,因为它太累了。)

    RNN 处理这句话的方式,就像是一个只能看见眼前一个单词的阅读者,或者像是在玩**“传话游戏”**(接力跑)。

  • 它读入 The,大脑里生成一个记忆(隐藏状态

    h

    1

    h_1

    h1)。

  • 带着

    h

    1

    h_1

    h1 的记忆,它读入 cat,生成新的记忆

    h

    2

    h_2

    h2

  • 带着

    h

    2

    h_2

    h2 的记忆,它读入 didn't……

  • ……
  • 直到读到最后面的 it 时,它必须在无数次“记忆更新”后,依然能准确地从脑子里翻出 cat 的信息,从而知道这个 it 指的是猫,而不是马路。
  • ❌ 痛点一:距离产生的不是美,是遗忘

    在这个“接力跑”的过程中,随着句子越来越长,开头的信息就像传话游戏一样,越传越模糊。这就是著名的长距离依赖问题(Long-term Dependency Problem)。虽然 LSTM 通过“遗忘门”强行续命,但面对几百个词的长文,它依然会“老年痴呆”。

    ❌ 痛点二:显卡有劲儿使不上

    这是最让工程师抓狂的。因为第 100 个词的计算必须等第 99 个词算完。这意味着你买了最贵的 NVIDIA 显卡,有几千个计算核心,结果它们只能排队一个接一个地干活,无法并行。

    我们来看一张图,感受一下这种“憋屈”:

    #mermaid-svg-aVKJOF1sPUtKQxdL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-aVKJOF1sPUtKQxdL .error-icon{fill:#552222;}#mermaid-svg-aVKJOF1sPUtKQxdL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-aVKJOF1sPUtKQxdL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-aVKJOF1sPUtKQxdL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-aVKJOF1sPUtKQxdL .marker.cross{stroke:#333333;}#mermaid-svg-aVKJOF1sPUtKQxdL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-aVKJOF1sPUtKQxdL p{margin:0;}#mermaid-svg-aVKJOF1sPUtKQxdL .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-aVKJOF1sPUtKQxdL .cluster-label text{fill:#333;}#mermaid-svg-aVKJOF1sPUtKQxdL .cluster-label span{color:#333;}#mermaid-svg-aVKJOF1sPUtKQxdL .cluster-label span p{background-color:transparent;}#mermaid-svg-aVKJOF1sPUtKQxdL .label text,#mermaid-svg-aVKJOF1sPUtKQxdL span{fill:#333;color:#333;}#mermaid-svg-aVKJOF1sPUtKQxdL .node rect,#mermaid-svg-aVKJOF1sPUtKQxdL .node circle,#mermaid-svg-aVKJOF1sPUtKQxdL .node ellipse,#mermaid-svg-aVKJOF1sPUtKQxdL .node polygon,#mermaid-svg-aVKJOF1sPUtKQxdL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-aVKJOF1sPUtKQxdL .rough-node .label text,#mermaid-svg-aVKJOF1sPUtKQxdL .node .label text,#mermaid-svg-aVKJOF1sPUtKQxdL .image-shape .label,#mermaid-svg-aVKJOF1sPUtKQxdL .icon-shape .label{text-anchor:middle;}#mermaid-svg-aVKJOF1sPUtKQxdL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-aVKJOF1sPUtKQxdL .rough-node .label,#mermaid-svg-aVKJOF1sPUtKQxdL .node .label,#mermaid-svg-aVKJOF1sPUtKQxdL .image-shape .label,#mermaid-svg-aVKJOF1sPUtKQxdL .icon-shape .label{text-align:center;}#mermaid-svg-aVKJOF1sPUtKQxdL .node.clickable{cursor:pointer;}#mermaid-svg-aVKJOF1sPUtKQxdL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-aVKJOF1sPUtKQxdL .arrowheadPath{fill:#333333;}#mermaid-svg-aVKJOF1sPUtKQxdL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-aVKJOF1sPUtKQxdL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-aVKJOF1sPUtKQxdL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aVKJOF1sPUtKQxdL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-aVKJOF1sPUtKQxdL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aVKJOF1sPUtKQxdL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-aVKJOF1sPUtKQxdL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-aVKJOF1sPUtKQxdL .cluster text{fill:#333;}#mermaid-svg-aVKJOF1sPUtKQxdL .cluster span{color:#333;}#mermaid-svg-aVKJOF1sPUtKQxdL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-aVKJOF1sPUtKQxdL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-aVKJOF1sPUtKQxdL rect.text{fill:none;stroke-width:0;}#mermaid-svg-aVKJOF1sPUtKQxdL .icon-shape,#mermaid-svg-aVKJOF1sPUtKQxdL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-aVKJOF1sPUtKQxdL .icon-shape p,#mermaid-svg-aVKJOF1sPUtKQxdL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-aVKJOF1sPUtKQxdL .icon-shape rect,#mermaid-svg-aVKJOF1sPUtKQxdL .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-aVKJOF1sPUtKQxdL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-aVKJOF1sPUtKQxdL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-aVKJOF1sPUtKQxdL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    RNN 的接力跑模式 (串行)

    路途遥远,信息衰减

    Input: The

    h1

    h2

    Input: cat

    h3

    Input: …

    h99

    h100

    Input: it

    图解说明:注意那个从

    h

    1

    h_1

    h1

    h

    100

    h_{100}

    h100 的虚线。在 RNN 中,it 想要理解自己是指代 cat,需要跨越漫长的时间步,信号早已微弱不堪。


    2. Transformer 的“上帝视角”

    Transformer 的出现,就像是把这个逐字阅读的 AI,变成了一个过目不忘的速读天才。

    它抛弃了循环(Recurrence),它不再一个词一个词地读,而是一巴掌把整句话拍在桌子上,同时处理所有的词!

    • 没有时间先后:它不需要等 The 读完才读 cat。
    • 并行计算:显卡里的几千个核心终于可以同时开工了,速度起飞。
    • 无视距离:在 Transformer 眼里,第 1 个词和第 100 个词之间的距离是 0。它们之间可以直接“眉来眼去”(计算注意力),不需要中间商传话。

    这就好比大家在一个吵闹的鸡尾酒会上:

    • RNN 是一个人拿着麦克风挨个采访,问完这个才能问下一个。
    • Transformer 是所有人同时在房间里,谁想和谁说话都可以直接喊,大家都能瞬间听到彼此。

    我们来看 Transformer 是如何工作的:

    #mermaid-svg-rkejNaFNd8LBkDye{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rkejNaFNd8LBkDye .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rkejNaFNd8LBkDye .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rkejNaFNd8LBkDye .error-icon{fill:#552222;}#mermaid-svg-rkejNaFNd8LBkDye .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rkejNaFNd8LBkDye .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rkejNaFNd8LBkDye .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rkejNaFNd8LBkDye .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rkejNaFNd8LBkDye .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rkejNaFNd8LBkDye .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rkejNaFNd8LBkDye .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rkejNaFNd8LBkDye .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rkejNaFNd8LBkDye .marker.cross{stroke:#333333;}#mermaid-svg-rkejNaFNd8LBkDye svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rkejNaFNd8LBkDye p{margin:0;}#mermaid-svg-rkejNaFNd8LBkDye .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-rkejNaFNd8LBkDye .cluster-label text{fill:#333;}#mermaid-svg-rkejNaFNd8LBkDye .cluster-label span{color:#333;}#mermaid-svg-rkejNaFNd8LBkDye .cluster-label span p{background-color:transparent;}#mermaid-svg-rkejNaFNd8LBkDye .label text,#mermaid-svg-rkejNaFNd8LBkDye span{fill:#333;color:#333;}#mermaid-svg-rkejNaFNd8LBkDye .node rect,#mermaid-svg-rkejNaFNd8LBkDye .node circle,#mermaid-svg-rkejNaFNd8LBkDye .node ellipse,#mermaid-svg-rkejNaFNd8LBkDye .node polygon,#mermaid-svg-rkejNaFNd8LBkDye .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rkejNaFNd8LBkDye .rough-node .label text,#mermaid-svg-rkejNaFNd8LBkDye .node .label text,#mermaid-svg-rkejNaFNd8LBkDye .image-shape .label,#mermaid-svg-rkejNaFNd8LBkDye .icon-shape .label{text-anchor:middle;}#mermaid-svg-rkejNaFNd8LBkDye .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rkejNaFNd8LBkDye .rough-node .label,#mermaid-svg-rkejNaFNd8LBkDye .node .label,#mermaid-svg-rkejNaFNd8LBkDye .image-shape .label,#mermaid-svg-rkejNaFNd8LBkDye .icon-shape .label{text-align:center;}#mermaid-svg-rkejNaFNd8LBkDye .node.clickable{cursor:pointer;}#mermaid-svg-rkejNaFNd8LBkDye .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rkejNaFNd8LBkDye .arrowheadPath{fill:#333333;}#mermaid-svg-rkejNaFNd8LBkDye .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rkejNaFNd8LBkDye .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rkejNaFNd8LBkDye .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rkejNaFNd8LBkDye .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rkejNaFNd8LBkDye .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rkejNaFNd8LBkDye .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rkejNaFNd8LBkDye .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rkejNaFNd8LBkDye .cluster text{fill:#333;}#mermaid-svg-rkejNaFNd8LBkDye .cluster span{color:#333;}#mermaid-svg-rkejNaFNd8LBkDye div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rkejNaFNd8LBkDye .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rkejNaFNd8LBkDye rect.text{fill:none;stroke-width:0;}#mermaid-svg-rkejNaFNd8LBkDye .icon-shape,#mermaid-svg-rkejNaFNd8LBkDye .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rkejNaFNd8LBkDye .icon-shape p,#mermaid-svg-rkejNaFNd8LBkDye .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rkejNaFNd8LBkDye .icon-shape rect,#mermaid-svg-rkejNaFNd8LBkDye .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rkejNaFNd8LBkDye .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rkejNaFNd8LBkDye .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rkejNaFNd8LBkDye :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Transformer 的上帝视角

    所有词同时输入

    直接连接

    直接连接

    Input: The cat … it

    Transformer 核心处理区

    The

    it

    cat

    Output: 翻译结果

    图解说明:在 Transformer 中,cat 和 it 之间有一条直接的连线(通过 Self-Attention 机制,后面章节会细讲)。无论句子多长,它们永远是“邻居”。

    3. 本章小结:时代的转折点

    如果把 NLP 模型的进化史看作交通工具的演变:

    • RNN 是一列老式火车,车厢必须一节扣一节,第一节动了,最后一节才能跟着动。
    • Transformer 是一支星际舰队,所有飞船(单词)在太空中展开,彼此之间通过无线电瞬时联络,既能独立机动,又能整体协同。

    这一章你需要记住的核心概念:

  • 抛弃 RNN 是为了解决无法并行训练(慢)和长距离遗忘(笨)的问题。
  • Transformer 的必杀技是并行化和全局视野。

  • 这就引出了一个巨大的悬念:既然没有了先后顺序,Transformer 怎么知道“我爱你”和“你爱我”的区别呢?毕竟这两个句子的单词完全一样啊!这就是我们第二章和第三章要解决的问题。


    在第一章,我们已经把 RNN 扔进了历史的垃圾桶。现在,我们要把 Transformer 搬上解剖台。

    在深入那些复杂的矩阵乘法之前,我们先得退后一步,用宏观的视角看看它的整体骨架。如果你一上来就钻进“自注意力”的细节,很容易只见树木不见森林。


    第二章:黑盒与乐高——宏观俯瞰 Transformer

    很多技术博客上来就给你扔出一张密密麻麻的内部结构图,看着就头晕。我们不这么干。我们先假设 Transformer 就是一个完全密封的黑盒子。

    1. 最简单的视角:神奇的翻译机

    想象 Transformer 是一个放在桌子上的黑色方块。

    • 左边入口:塞进去一句中文:“我爱学习”。
    • 右边出口:吐出来一句英文:“I love study”。

    此时,我们不需要知道里面发生了什么,只需要知道它是一个Sequence-to-Sequence(序列到序列)的模型。

    #mermaid-svg-iQG7zzNYbwMPjLE9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-iQG7zzNYbwMPjLE9 .error-icon{fill:#552222;}#mermaid-svg-iQG7zzNYbwMPjLE9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-iQG7zzNYbwMPjLE9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .marker.cross{stroke:#333333;}#mermaid-svg-iQG7zzNYbwMPjLE9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-iQG7zzNYbwMPjLE9 p{margin:0;}#mermaid-svg-iQG7zzNYbwMPjLE9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .cluster-label text{fill:#333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .cluster-label span{color:#333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .cluster-label span p{background-color:transparent;}#mermaid-svg-iQG7zzNYbwMPjLE9 .label text,#mermaid-svg-iQG7zzNYbwMPjLE9 span{fill:#333;color:#333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .node rect,#mermaid-svg-iQG7zzNYbwMPjLE9 .node circle,#mermaid-svg-iQG7zzNYbwMPjLE9 .node ellipse,#mermaid-svg-iQG7zzNYbwMPjLE9 .node polygon,#mermaid-svg-iQG7zzNYbwMPjLE9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-iQG7zzNYbwMPjLE9 .rough-node .label text,#mermaid-svg-iQG7zzNYbwMPjLE9 .node .label text,#mermaid-svg-iQG7zzNYbwMPjLE9 .image-shape .label,#mermaid-svg-iQG7zzNYbwMPjLE9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-iQG7zzNYbwMPjLE9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-iQG7zzNYbwMPjLE9 .rough-node .label,#mermaid-svg-iQG7zzNYbwMPjLE9 .node .label,#mermaid-svg-iQG7zzNYbwMPjLE9 .image-shape .label,#mermaid-svg-iQG7zzNYbwMPjLE9 .icon-shape .label{text-align:center;}#mermaid-svg-iQG7zzNYbwMPjLE9 .node.clickable{cursor:pointer;}#mermaid-svg-iQG7zzNYbwMPjLE9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .arrowheadPath{fill:#333333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-iQG7zzNYbwMPjLE9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iQG7zzNYbwMPjLE9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-iQG7zzNYbwMPjLE9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iQG7zzNYbwMPjLE9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-iQG7zzNYbwMPjLE9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-iQG7zzNYbwMPjLE9 .cluster text{fill:#333;}#mermaid-svg-iQG7zzNYbwMPjLE9 .cluster span{color:#333;}#mermaid-svg-iQG7zzNYbwMPjLE9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-iQG7zzNYbwMPjLE9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-iQG7zzNYbwMPjLE9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-iQG7zzNYbwMPjLE9 .icon-shape,#mermaid-svg-iQG7zzNYbwMPjLE9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-iQG7zzNYbwMPjLE9 .icon-shape p,#mermaid-svg-iQG7zzNYbwMPjLE9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-iQG7zzNYbwMPjLE9 .icon-shape rect,#mermaid-svg-iQG7zzNYbwMPjLE9 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-iQG7zzNYbwMPjLE9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-iQG7zzNYbwMPjLE9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-iQG7zzNYbwMPjLE9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    输入: 我爱学习

    Transformer 黑盒

    输出: I love study

    2. 掀开盖子:左右互搏的“乐高塔”

    现在,我们把黑盒子的盖子掀开。你会发现里面并不是浑然一体的,而是分成了左右两大阵营,就像两座乐高积木塔。

    这就是大名鼎鼎的 Encoder-Decoder(编码器-解码器) 架构。

    • 左边的塔(Encoder 编码器):负责“输入”。它的工作是“理解”。它要把你那句中文嚼碎了、吃透了,转化成一团机器能看懂的“语义向量”。
    • 右边的塔(Decoder 解码器):负责“输出”。它的工作是“生成”。它拿着左边给它的“语义”,根据上文,一个字一个字地蹦出英文。
    🎓 生动比喻:老学究与畅销书作家

    为了彻底理解这两兄弟的关系,我们可以这样比喻:

    • Encoder(老学究):他博古通今,阅读理解能力满分。你给他一篇文章,他看完后不说话,而是默默地画出一张“思维导图”(Context Vector)。这张图里包含了文章里所有的知识点、逻辑关系和情感色彩。
    • Decoder(畅销书作家):他文笔极好,负责根据那张“思维导图”来写文章。但他有个习惯,写字必须一个一个写。他一边看着老学究给的导图(Cross Attention),一边看着自己刚刚写下的字(Masked Self-Attention),以此来决定下一个字写什么。

    注意:这两座塔不仅是分开的,而且是可以堆叠的。 在 Google 最初的论文中,Encoder 和 Decoder 各自堆了 6 层。为什么是 6 层?没啥特别原因,可能是 Google 工程师觉得 6 这个数字吉利(其实是实验出来的超参数)。这就好比老学究不是一个人,而是 6 个老学究组成的的专家组,一层层地传递信息,理解得越来越深。

    3. 宏观架构图解

    我们用 Mermaid 来画一下这个“乐高塔”结构。请注意中间那条横跨左右的连线,那就是**“老学究”把“思维导图”递给“作家”的关键时刻**。

    #mermaid-svg-vbvADCBfv6pIHHzF{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vbvADCBfv6pIHHzF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vbvADCBfv6pIHHzF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vbvADCBfv6pIHHzF .error-icon{fill:#552222;}#mermaid-svg-vbvADCBfv6pIHHzF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vbvADCBfv6pIHHzF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vbvADCBfv6pIHHzF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vbvADCBfv6pIHHzF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vbvADCBfv6pIHHzF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vbvADCBfv6pIHHzF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vbvADCBfv6pIHHzF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vbvADCBfv6pIHHzF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vbvADCBfv6pIHHzF .marker.cross{stroke:#333333;}#mermaid-svg-vbvADCBfv6pIHHzF svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vbvADCBfv6pIHHzF p{margin:0;}#mermaid-svg-vbvADCBfv6pIHHzF .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-vbvADCBfv6pIHHzF .cluster-label text{fill:#333;}#mermaid-svg-vbvADCBfv6pIHHzF .cluster-label span{color:#333;}#mermaid-svg-vbvADCBfv6pIHHzF .cluster-label span p{background-color:transparent;}#mermaid-svg-vbvADCBfv6pIHHzF .label text,#mermaid-svg-vbvADCBfv6pIHHzF span{fill:#333;color:#333;}#mermaid-svg-vbvADCBfv6pIHHzF .node rect,#mermaid-svg-vbvADCBfv6pIHHzF .node circle,#mermaid-svg-vbvADCBfv6pIHHzF .node ellipse,#mermaid-svg-vbvADCBfv6pIHHzF .node polygon,#mermaid-svg-vbvADCBfv6pIHHzF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vbvADCBfv6pIHHzF .rough-node .label text,#mermaid-svg-vbvADCBfv6pIHHzF .node .label text,#mermaid-svg-vbvADCBfv6pIHHzF .image-shape .label,#mermaid-svg-vbvADCBfv6pIHHzF .icon-shape .label{text-anchor:middle;}#mermaid-svg-vbvADCBfv6pIHHzF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vbvADCBfv6pIHHzF .rough-node .label,#mermaid-svg-vbvADCBfv6pIHHzF .node .label,#mermaid-svg-vbvADCBfv6pIHHzF .image-shape .label,#mermaid-svg-vbvADCBfv6pIHHzF .icon-shape .label{text-align:center;}#mermaid-svg-vbvADCBfv6pIHHzF .node.clickable{cursor:pointer;}#mermaid-svg-vbvADCBfv6pIHHzF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vbvADCBfv6pIHHzF .arrowheadPath{fill:#333333;}#mermaid-svg-vbvADCBfv6pIHHzF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vbvADCBfv6pIHHzF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vbvADCBfv6pIHHzF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vbvADCBfv6pIHHzF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vbvADCBfv6pIHHzF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vbvADCBfv6pIHHzF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vbvADCBfv6pIHHzF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vbvADCBfv6pIHHzF .cluster text{fill:#333;}#mermaid-svg-vbvADCBfv6pIHHzF .cluster span{color:#333;}#mermaid-svg-vbvADCBfv6pIHHzF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vbvADCBfv6pIHHzF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vbvADCBfv6pIHHzF rect.text{fill:none;stroke-width:0;}#mermaid-svg-vbvADCBfv6pIHHzF .icon-shape,#mermaid-svg-vbvADCBfv6pIHHzF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vbvADCBfv6pIHHzF .icon-shape p,#mermaid-svg-vbvADCBfv6pIHHzF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vbvADCBfv6pIHHzF .icon-shape rect,#mermaid-svg-vbvADCBfv6pIHHzF .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vbvADCBfv6pIHHzF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vbvADCBfv6pIHHzF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vbvADCBfv6pIHHzF :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Decoder Stack (解码器堆叠)

    Encoder Stack (编码器堆叠)

    传递语义记忆 (K, V)

    传递语义记忆 (K, V)

    传递语义记忆 (K, V)

    传递语义记忆 (K, V)

    输入: 我 爱 学 习

    Encoder Layer 1

    Encoder Layer 2

    Encoder Layer 6 (老学究的最终理解)

    输入: Start I love …

    Decoder Layer 1

    Decoder Layer 2

    Decoder Layer 6

    Linear + Softmax

    输出概率: study

    4. 这里的“坑”和“彩蛋”

    在继续深入之前,有两个概念你需要先有个印象,防止后面迷路:

  • 并行与串行的分裂:

    • Encoder 是完全并行的。它是一眼看完整个句子(我爱学习),这 4 个字同时进入模型处理。
    • Decoder 在推理(翻译)时,依然是串行的。它只能先生成 I,再生成 love,再生成 study。因为它不知道后面会写啥。
  • 家族分家(预告): 现在的 AI 届,原始的 Encoder-Decoder 结构其实用得变少了,大家开始分家产:

    • BERT 家族:只拿走了左边的 Encoder。因为它不需要说话,只需要“理解”语言(做填空题、阅读理解)。
    • GPT 家族:只拿走了右边的 Decoder。因为它不需要理解特定的输入文本,它只管在那儿“瞎编”下一句,一路生成下去。

  • 本章小结

    这一章我们不需要搞懂内部计算,只需要记住:

  • Transformer = Encoder(理解者) + Decoder(生成者)。
  • 它们是由多层网络堆叠而成的(像乐高积木)。
  • 信息流是从 Encoder 流向 Decoder。
  • 现在,我们要把镜头推进,走进 Encoder 的第一层。但在计算之前,机器面临一个巨大的问题:机器不认识汉字,也不认识英文,它只认识数字。

    而且,我们在第一章说过,Transformer 并行处理导致它没有“时间概念”。如果不做特殊处理,机器会认为“读书”和“书读”是一回事。


    在前两章我们吹了半天 Transformer 的“并行计算”有多牛,但这其实带来了一个巨大的副作用:它是个不折不扣的“路痴”。

    因为它是把所有词一口气吃进去的,所以在它眼里,“我打你”和“你打我”是一模一样的——不就是“我、你、打”这三个词的组合嘛!

    为了治好这个 Bug,我们需要给每个词装上身份证(Embedding)和GPS(位置编码)。


    第三章:单词的 GPS——Embedding 与位置编码

    1. 机器的字典:Embedding(词嵌入)

    首先,不管是 Transformer 还是以前的 RNN,机器其实根本不认识“Apple”这个词。在它看来,这只是一串 ASCII 码。

    我们需要把文字变成机器能计算的数字。但不能简单地把 Apple 变成 1,Banana 变成 2。因为 1 和 2 在数学上挨得很近,但苹果和香蕉在语义上可能差很远(或者很近)。

    我们使用的是 Embedding(词嵌入)。

    🎓 生动比喻:单词的“DNA 图谱”

    想象一下,我们把字典里的每一个词,都对应到一个长长的数字列表(向量)。这个列表通常有 512 维(或者 768、1024 维)。

    每一维数字都代表这个词的一种“潜在特征”。虽然机器不会明说,但我们可以这样脑补:

    • 第 1 维代表“是不是名词”
    • 第 2 维代表“是不是活物”
    • 第 3 维代表“王室程度”

    比如:

    • King (国王) -> [0.9, 0.9, 0.99, …] (名词,活人,极其王室)
    • Queen (女王) -> [0.9, 0.9, 0.99, …] (跟国王很像,只有代表性别的某一维不同)
    • Apple (苹果) -> [0.9, 0.1, 0.00, …] (名词,植物,跟王室没半毛钱关系)

    这就是 Embedding:把冰冷的单词,变成了有丰富语义内涵的数学向量。


    2. 治愈路痴:Positional Encoding(位置编码)

    Embedding 搞定后,真正的麻烦来了。

    RNN 是按顺序读的,读完第一个才能读第二个,所以它天然知道位置信息。但 Transformer 是并行的(还记得第一章鸡尾酒会的比喻吗?)。

    如果我们直接把 Embedding("我"),Embedding("爱"),Embedding("你") 扔进去,模型只知道这三个词出现了,完全不知道谁在谁前面。

    为了解决这个问题,聪明的工程师想了一招:给 Embedding 向量“加”点料。

    🎓 生动比喻:给座位编号

    想象一群人(单词)乱哄哄地挤进一个房间(Transformer)。 为了不乱套,我们在每个人进门时,强行给他的衣服上贴一个号码牌,或者发一个带有位置信息的 GPS 信号。

    • 对于第一个词“我”,我们给它加上

      P

      1

      P_1

      P1 的位置信号。

    • 对于第二个词“爱”,我们给它加上

      P

      2

      P_2

      P2 的位置信号。

    这样,即使大家混在一起,模型只要看一眼信号,就知道:“哦,虽然你们是一起进来的,但‘我’是排在第一号座位的。”

    ⚠️ 这里的核心骚操作:是相加(Add),不是拼接(Concat)

    初学者很容易觉得,位置信息应该像挂拖车一样跟在词向量后面(拼接)。但 Transformer 居然是直接把位置向量“加”到了词向量上面!

    I

    n

    p

    u

    t

    =

    E

    m

    b

    e

    d

    d

    i

    n

    g

    +

    P

    o

    s

    i

    t

    i

    o

    n

    a

    l

    E

    n

    c

    o

    d

    i

    n

    g

    Input = Embedding + PositionalEncoding

    Input=Embedding+PositionalEncoding

    这就像是:

    • 词义是红色颜料。
    • 位置是蓝色颜料。
    • Transformer 实际上把它们混成了紫色颜料输进去。

    这难道不会破坏原来的词义吗? 答案是:会有一点点干扰,但没关系。因为词向量的维度很高(512维),而位置编码的数值很独特。在高维空间里,模型能够学会把“词义”和“位置”重新分离开来。

    3. 正弦波的魔法:为什么用 Sin/Cos?

    Transformer 的位置编码并不是简单的 1, 2, 3, 4 这种整数。因为如果句子太长,数值会变得无限大,把词义完全盖过去。

    它使用的是正弦和余弦函数(Sin/Cos)。

    #mermaid-svg-TYRwknC3AY4yCjnV{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TYRwknC3AY4yCjnV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TYRwknC3AY4yCjnV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TYRwknC3AY4yCjnV .error-icon{fill:#552222;}#mermaid-svg-TYRwknC3AY4yCjnV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TYRwknC3AY4yCjnV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TYRwknC3AY4yCjnV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TYRwknC3AY4yCjnV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TYRwknC3AY4yCjnV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TYRwknC3AY4yCjnV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TYRwknC3AY4yCjnV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TYRwknC3AY4yCjnV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TYRwknC3AY4yCjnV .marker.cross{stroke:#333333;}#mermaid-svg-TYRwknC3AY4yCjnV svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TYRwknC3AY4yCjnV p{margin:0;}#mermaid-svg-TYRwknC3AY4yCjnV .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-TYRwknC3AY4yCjnV .cluster-label text{fill:#333;}#mermaid-svg-TYRwknC3AY4yCjnV .cluster-label span{color:#333;}#mermaid-svg-TYRwknC3AY4yCjnV .cluster-label span p{background-color:transparent;}#mermaid-svg-TYRwknC3AY4yCjnV .label text,#mermaid-svg-TYRwknC3AY4yCjnV span{fill:#333;color:#333;}#mermaid-svg-TYRwknC3AY4yCjnV .node rect,#mermaid-svg-TYRwknC3AY4yCjnV .node circle,#mermaid-svg-TYRwknC3AY4yCjnV .node ellipse,#mermaid-svg-TYRwknC3AY4yCjnV .node polygon,#mermaid-svg-TYRwknC3AY4yCjnV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TYRwknC3AY4yCjnV .rough-node .label text,#mermaid-svg-TYRwknC3AY4yCjnV .node .label text,#mermaid-svg-TYRwknC3AY4yCjnV .image-shape .label,#mermaid-svg-TYRwknC3AY4yCjnV .icon-shape .label{text-anchor:middle;}#mermaid-svg-TYRwknC3AY4yCjnV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TYRwknC3AY4yCjnV .rough-node .label,#mermaid-svg-TYRwknC3AY4yCjnV .node .label,#mermaid-svg-TYRwknC3AY4yCjnV .image-shape .label,#mermaid-svg-TYRwknC3AY4yCjnV .icon-shape .label{text-align:center;}#mermaid-svg-TYRwknC3AY4yCjnV .node.clickable{cursor:pointer;}#mermaid-svg-TYRwknC3AY4yCjnV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TYRwknC3AY4yCjnV .arrowheadPath{fill:#333333;}#mermaid-svg-TYRwknC3AY4yCjnV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TYRwknC3AY4yCjnV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TYRwknC3AY4yCjnV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TYRwknC3AY4yCjnV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TYRwknC3AY4yCjnV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TYRwknC3AY4yCjnV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TYRwknC3AY4yCjnV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TYRwknC3AY4yCjnV .cluster text{fill:#333;}#mermaid-svg-TYRwknC3AY4yCjnV .cluster span{color:#333;}#mermaid-svg-TYRwknC3AY4yCjnV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TYRwknC3AY4yCjnV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TYRwknC3AY4yCjnV rect.text{fill:none;stroke-width:0;}#mermaid-svg-TYRwknC3AY4yCjnV .icon-shape,#mermaid-svg-TYRwknC3AY4yCjnV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TYRwknC3AY4yCjnV .icon-shape p,#mermaid-svg-TYRwknC3AY4yCjnV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TYRwknC3AY4yCjnV .icon-shape rect,#mermaid-svg-TYRwknC3AY4yCjnV .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TYRwknC3AY4yCjnV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TYRwknC3AY4yCjnV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TYRwknC3AY4yCjnV :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    位置编码的波纹

    Sin/Cos

    Sin/Cos

    Sin/Cos

    位置 1

    波纹向量 1

    位置 2

    波纹向量 2

    位置 100

    波纹向量 100

    你可以把它理解为**“多重时钟”**:

    • 向量的第 1 维像秒针,走得快(频率高)。
    • 向量的第 2 维像分针,走得慢。
    • 向量的第 3 维像时针,走得更慢。

    每个位置(Time Step),都对应着这些指针的一个唯一组合。 这样,无论句子多长,位置编码的数值永远在 -1 到 1 之间震荡,既稳定又独特。

    4. 流程图解

    让我们用 Mermaid 把这两个步骤合二为一,看看数据进入 Transformer 内部的第一步到底长啥样。

    #mermaid-svg-to7xurLLWY4CfU44{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-to7xurLLWY4CfU44 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-to7xurLLWY4CfU44 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-to7xurLLWY4CfU44 .error-icon{fill:#552222;}#mermaid-svg-to7xurLLWY4CfU44 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-to7xurLLWY4CfU44 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-to7xurLLWY4CfU44 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-to7xurLLWY4CfU44 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-to7xurLLWY4CfU44 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-to7xurLLWY4CfU44 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-to7xurLLWY4CfU44 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-to7xurLLWY4CfU44 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-to7xurLLWY4CfU44 .marker.cross{stroke:#333333;}#mermaid-svg-to7xurLLWY4CfU44 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-to7xurLLWY4CfU44 p{margin:0;}#mermaid-svg-to7xurLLWY4CfU44 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-to7xurLLWY4CfU44 .cluster-label text{fill:#333;}#mermaid-svg-to7xurLLWY4CfU44 .cluster-label span{color:#333;}#mermaid-svg-to7xurLLWY4CfU44 .cluster-label span p{background-color:transparent;}#mermaid-svg-to7xurLLWY4CfU44 .label text,#mermaid-svg-to7xurLLWY4CfU44 span{fill:#333;color:#333;}#mermaid-svg-to7xurLLWY4CfU44 .node rect,#mermaid-svg-to7xurLLWY4CfU44 .node circle,#mermaid-svg-to7xurLLWY4CfU44 .node ellipse,#mermaid-svg-to7xurLLWY4CfU44 .node polygon,#mermaid-svg-to7xurLLWY4CfU44 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-to7xurLLWY4CfU44 .rough-node .label text,#mermaid-svg-to7xurLLWY4CfU44 .node .label text,#mermaid-svg-to7xurLLWY4CfU44 .image-shape .label,#mermaid-svg-to7xurLLWY4CfU44 .icon-shape .label{text-anchor:middle;}#mermaid-svg-to7xurLLWY4CfU44 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-to7xurLLWY4CfU44 .rough-node .label,#mermaid-svg-to7xurLLWY4CfU44 .node .label,#mermaid-svg-to7xurLLWY4CfU44 .image-shape .label,#mermaid-svg-to7xurLLWY4CfU44 .icon-shape .label{text-align:center;}#mermaid-svg-to7xurLLWY4CfU44 .node.clickable{cursor:pointer;}#mermaid-svg-to7xurLLWY4CfU44 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-to7xurLLWY4CfU44 .arrowheadPath{fill:#333333;}#mermaid-svg-to7xurLLWY4CfU44 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-to7xurLLWY4CfU44 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-to7xurLLWY4CfU44 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-to7xurLLWY4CfU44 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-to7xurLLWY4CfU44 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-to7xurLLWY4CfU44 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-to7xurLLWY4CfU44 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-to7xurLLWY4CfU44 .cluster text{fill:#333;}#mermaid-svg-to7xurLLWY4CfU44 .cluster span{color:#333;}#mermaid-svg-to7xurLLWY4CfU44 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-to7xurLLWY4CfU44 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-to7xurLLWY4CfU44 rect.text{fill:none;stroke-width:0;}#mermaid-svg-to7xurLLWY4CfU44 .icon-shape,#mermaid-svg-to7xurLLWY4CfU44 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-to7xurLLWY4CfU44 .icon-shape p,#mermaid-svg-to7xurLLWY4CfU44 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-to7xurLLWY4CfU44 .icon-shape rect,#mermaid-svg-to7xurLLWY4CfU44 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-to7xurLLWY4CfU44 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-to7xurLLWY4CfU44 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-to7xurLLWY4CfU44 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    输入处理流程

    原始文本: I love AI

    分词 (Tokenization)

    Token IDs: [24, 56, 99]

    Embedding 查表

    词向量 (Word Embeddings) [Batch, Seq_Len, 512]

    +

    位置编码生成 (Positional Encoding) (Sin/Cos Waves)

    最终输入向量 (带着位置信息的词向量)

    本章小结

  • Embedding 让机器理解了词义(国王和女王很像)。
  • Positional Encoding 让机器理解了顺序(由于并行计算丢失了顺序,需要人工补回来)。
  • 它们是通过数学相加的方式融合的。
  • 现在,数据已经准备好了!它既包含了“是什么意思”,也包含了“在什么位置”。


    如果说 Embedding 是给 Transformer 供血的血管,那 Self-Attention(自注意力机制) 就是它的心脏。这也是这篇论文标题《Attention Is All You Need》里那个价值千金的词。

    很多教程在这里会甩出一堆

    Q

    ×

    K

    T

    Q \\times K^T

    Q×KT 的公式把你劝退。别怕,我们还是用故事来讲。


    第四章:灵魂核心——自注意力机制 (Self-Attention)

    1. 到底什么是“自注意力”?

    我们在第一章说过,RNN 的毛病是“读到后面忘前面”。而 Self-Attention 的核心思想就是:在读每一个词的时候,都把整个句子的其他词再看一遍,看看谁跟自己最亲。

    还是那句经典的例子:

    “The animal didn’t cross the street because it was too tired.”

    当机器读到 “it” 这个词时,它的注意力应该放在哪里?

    • 它应该去关注 “street” 吗?不对,马路不会觉得累。
    • 它应该去关注 “animal” 吗?对!动物才会觉得累。

    Self-Attention 就像一盏聚光灯。当处理 “it” 时,它会把灯光最强烈地打在 “animal” 身上,把 “street” 放在阴影里。这样,“it” 就吸收了 “animal” 的含义。


    2. 核心铁三角:Q、K、V 的身世之谜

    为了实现这种“找关系”的能力,Transformer 把输入的每一个词向量(Vector),都分裂成了三个分身。

    这三个分身是通过分别乘以三个不同的权重矩阵(

    W

    Q

    ,

    W

    K

    ,

    W

    V

    W^Q, W^K, W^V

    WQ,WK,WV)变出来的。它们分别是:

  • Query (查询向量):这是**“我手中的牌”**。

    • 代表当前这个词去“寻找”其他词时的诉求。
    • 比如 “it” 的 Query 在喊:“谁是能让我‘觉得累’的名词?”
  • Key (键向量):这是**“你头上的标签”**。

    • 代表这个词被用来“匹配”时的特征。
    • 比如 “animal” 的 Key 写着:“我是名词,我是活物”。
  • Value (值向量):这是**“你的内涵”**。

    • 代表这个词真正的语义内容。
    • 如果匹配成功,就要把这个 Value 拿走,融合到 Query 身上。
  • 🎓 生动比喻:图书馆检索系统

    为了彻底搞懂 Q、K、V,我们可以把这看作一次图书馆查书的过程:

    • Query (

      Q

      Q

      Q):是你手里的借书条(上面写着:我要找关于“很多毛的活物”的书)。

    • Key (

      K

      K

      K):是书架上每一本书脊上的分类编号(比如:生物类-哺乳动物)。

    • Value (

      V

      V

      V):是书里面真正的内容。

    过程是这样的:

  • 你拿着借书条 (

    Q

    Q

    Q),去和每一本书的分类号 (

    K

    K

    K) 进行比对。

  • 如果不匹配,相似度就很低(比如那是本《微积分》)。
  • 如果匹配度很高(是本《动物百科》),你就把这本书的内容 (

    V

    V

    V) 取出来,读进脑子里。


  • 3. 计算四步走:从相亲到牵手

    机器内部是如何通过数学运算来模拟这个过程的呢?其实就是向量点积(Dot Product)。

    第一步:计算匹配度 (Score)

    拿当前词的

    Q

    Q

    Q,去乘以所有词的

    K

    K

    K

    S

    c

    o

    r

    e

    =

    Q

    K

    T

    Score = Q \\cdot K^T

    Score=QKT

    • 点积越大,代表两个向量越相似,也就是关系越紧密。
    • “it” 的

      Q

      Q

      Q 和 “animal” 的

      K

      K

      K 点积,得分 0.9(很高)。

    • “it” 的

      Q

      Q

      Q 和 “street” 的

      K

      K

      K 点积,得分 0.1(很低)。

    第二步:归一化与打分 (Softmax)

    为了让分数变成概率(加起来等于 1),我们需要过一个 Softmax 函数。 在此之前,为了防止分数太大导致梯度消失,通常会除以一个系数(

    d

    k

    \\sqrt{d_k}

    dk

    ,比如 8)。

    • 处理后:“animal” 的权重变成 88%,“street” 的权重变成 2%,其他的词分剩下的 10%。
    第三步:加权求和 (Weighted Sum)

    这是最后一步,也是最神奇的一步。 用刚才算出来的权重,去乘以所有词的

    V

    V

    V,然后加在一起。

    O

    u

    t

    p

    u

    t

    =

    0.88

    ×

    V

    a

    n

    i

    m

    a

    l

    +

    0.02

    ×

    V

    s

    t

    r

    e

    e

    t

    +

    .

    .

    .

    Output = 0.88 \\times V_{animal} + 0.02 \\times V_{street} + …

    Output=0.88×Vanimal+0.02×Vstreet+

    结果: 此时,“it” 这个词经过这一层处理后,它的向量里虽然还保留着 “it” 的影子,但大部分成分已经变成了 “animal” 的特征。它不再是一个单纯的代词,它“吸星大法”吸取了上下文的精华!


    4. 流程图解:QKV 的内部工厂

    这个过程是所有词同时进行的(矩阵运算)。让我们看下 Meramid 图解:

    #mermaid-svg-Ndar7XvFdmue8SMl{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ndar7XvFdmue8SMl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ndar7XvFdmue8SMl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ndar7XvFdmue8SMl .error-icon{fill:#552222;}#mermaid-svg-Ndar7XvFdmue8SMl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ndar7XvFdmue8SMl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ndar7XvFdmue8SMl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ndar7XvFdmue8SMl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ndar7XvFdmue8SMl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ndar7XvFdmue8SMl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ndar7XvFdmue8SMl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ndar7XvFdmue8SMl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ndar7XvFdmue8SMl .marker.cross{stroke:#333333;}#mermaid-svg-Ndar7XvFdmue8SMl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ndar7XvFdmue8SMl p{margin:0;}#mermaid-svg-Ndar7XvFdmue8SMl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ndar7XvFdmue8SMl .cluster-label text{fill:#333;}#mermaid-svg-Ndar7XvFdmue8SMl .cluster-label span{color:#333;}#mermaid-svg-Ndar7XvFdmue8SMl .cluster-label span p{background-color:transparent;}#mermaid-svg-Ndar7XvFdmue8SMl .label text,#mermaid-svg-Ndar7XvFdmue8SMl span{fill:#333;color:#333;}#mermaid-svg-Ndar7XvFdmue8SMl .node rect,#mermaid-svg-Ndar7XvFdmue8SMl .node circle,#mermaid-svg-Ndar7XvFdmue8SMl .node ellipse,#mermaid-svg-Ndar7XvFdmue8SMl .node polygon,#mermaid-svg-Ndar7XvFdmue8SMl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ndar7XvFdmue8SMl .rough-node .label text,#mermaid-svg-Ndar7XvFdmue8SMl .node .label text,#mermaid-svg-Ndar7XvFdmue8SMl .image-shape .label,#mermaid-svg-Ndar7XvFdmue8SMl .icon-shape .label{text-anchor:middle;}#mermaid-svg-Ndar7XvFdmue8SMl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Ndar7XvFdmue8SMl .rough-node .label,#mermaid-svg-Ndar7XvFdmue8SMl .node .label,#mermaid-svg-Ndar7XvFdmue8SMl .image-shape .label,#mermaid-svg-Ndar7XvFdmue8SMl .icon-shape .label{text-align:center;}#mermaid-svg-Ndar7XvFdmue8SMl .node.clickable{cursor:pointer;}#mermaid-svg-Ndar7XvFdmue8SMl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Ndar7XvFdmue8SMl .arrowheadPath{fill:#333333;}#mermaid-svg-Ndar7XvFdmue8SMl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ndar7XvFdmue8SMl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ndar7XvFdmue8SMl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ndar7XvFdmue8SMl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Ndar7XvFdmue8SMl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ndar7XvFdmue8SMl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Ndar7XvFdmue8SMl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ndar7XvFdmue8SMl .cluster text{fill:#333;}#mermaid-svg-Ndar7XvFdmue8SMl .cluster span{color:#333;}#mermaid-svg-Ndar7XvFdmue8SMl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ndar7XvFdmue8SMl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Ndar7XvFdmue8SMl rect.text{fill:none;stroke-width:0;}#mermaid-svg-Ndar7XvFdmue8SMl .icon-shape,#mermaid-svg-Ndar7XvFdmue8SMl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Ndar7XvFdmue8SMl .icon-shape p,#mermaid-svg-Ndar7XvFdmue8SMl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Ndar7XvFdmue8SMl .icon-shape rect,#mermaid-svg-Ndar7XvFdmue8SMl .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Ndar7XvFdmue8SMl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Ndar7XvFdmue8SMl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Ndar7XvFdmue8SMl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Self-Attention 内部处理机制

    分数 (Scores)

    注意力权重 (Weights)

    输入向量 X (Embedding + Pos)

    W_Q 矩阵

    Query (Q) 拿着借书条

    W_K 矩阵

    Key (K) 书分类号

    W_V 矩阵

    Value (V) 书的内容

    点积运算 (MatMul) Score = Q × K

    Softmax (归一化为概率 %)

    加权求和 (MatMul) Output = % × V

    最终输出 Z (吸收了上下文信息的向量)

    5. 为什么要除以

    d

    k

    \\sqrt{d_k}

    dk

    如果

    Q

    Q

    Q

    K

    K

    K 的维度很大,点积的结果会变得非常大。这就好比你在 Softmax 里输入了一个几千的数字,Softmax 就会变得极端——只认最大的那个,其他的全变成 0,导致梯度几乎消失,模型学不动了。除以一个数是为了把数值拉回“舒适区”。


    本章小结

  • Q、K、V 是同一个词的三个不同侧面。
  • Self-Attention 就是拿

    Q

    Q

    Q

    K

    K

    K,算出权重,然后加权汇总

    V

    V

    V

  • 通过这个机制,单词不再是孤岛,它们根据语义关系建立了深层的连接。
  • 但是!人看文章不能只用一种视角。有的要看语法,有的要看指代,有的要看情绪。 现在的 Attention 只有一组 QKV,这就像只有一只眼睛。


    如果 Transformer 只有这一个脑袋,它可能会比较“死板”。为了让它变成真正的六边形战士,Google 的工程师赋予了它“三头六臂”。


    第五章:多头注意力 (Multi-Head Attention)——三个臭皮匠,顶个诸葛亮

    1. 为什么要搞这么多脑袋?

    想象一下,你正在读这句影评:

    “The movie was long but good.”

    如果你只有一种思维方式(一个 Head),你可能只关注到了 movie 和 long 的关系(描述时长)。 但是,这句话里明显还有另一层更重要的逻辑:尽管 long(通常是贬义),但是 good(褒义),这里有一个转折关系。

    单头注意力的缺陷在于:它可能在同一时间,只能专注于一种类型的语义关联。如果它忙着看语法结构,可能就忽略了情感色彩。

    Multi-Head Attention(多头注意力) 的核心思想就是: 既然一个脑袋不够用,那我就搞 8 个!

    • Head 1:专门负责看语法结构(谁是主语,谁是宾语)。
    • Head 2:专门负责看指代关系(it 指的是谁)。
    • Head 3:专门负责看时态信息(是过去发生还是将来发生)。
    • Head 4:专门负责看情感色彩(是夸还是骂)。

    大家各司其职,最后把结果汇总起来,这就构成了一个对句子全方位、多角度的理解。


    2. 怎么“砍”成多头?(Split & Concat)

    你可能会担心:“搞 8 个头,计算量岂不是变成了原来的 8 倍?我的显卡还要不要了?”

    这就是 Transformer 设计精妙的地方。它并没有把计算量翻倍,而是把原来的向量“切”碎了。

    假设原本的词向量维度(

    d

    m

    o

    d

    e

    l

    d_{model}

    dmodel)是 512。 我们要搞 8 个头 (

    h

    =

    8

    h=8

    h=8)。

    Transformer 是这样做的:

  • 切分:它把 512 维的向量,切成了 8 份,每份只有 64 维 (

    d

    k

    =

    512

    /

    8

    =

    64

    d_k = 512 / 8 = 64

    dk=512/8=64)。

  • 并行:这 8 个“小脑袋”分别拿着自己那 64 维的数据,同时去进行

    Q

    ,

    K

    ,

    V

    Q, K, V

    Q,K,V 的自注意力计算。

  • 独立:注意!每个头都有自己独享的一组

    W

    Q

    ,

    W

    K

    ,

    W

    V

    W^Q, W^K, W^V

    WQ,WK,WV 权重矩阵。这意味着 Head 1 学到的东西,Head 2 根本不知道,互不干扰。

  • 拼接:等 8 个头都算完了,分别输出了 8 个 64 维的向量。我们就把它们首尾相连(Concat),重新拼回成一个 512 维的大向量。
  • 这就好比: 本来是一个大神(512维)在读一本书。 现在变成了 8 个普通人(64维),每个人只读一章。 虽然单人的能力弱了,但大家同时读,最后开会把读后感拼在一起,效率极高且视角丰富。


    3. 最后的融合:线性变换 (Linear)

    把 8 个头的输出拼起来之后,虽然维度变回了 512,但它们之间还是“生分”的(前面 64 位是 Head 1 的看法,后面 64 位是 Head 2 的看法…)。

    所以,最后必须加一个线性变换层(Linear Layer,

    W

    O

    W^O

    WO)。

    这个层的作用就像是会议主持人或者鸡尾酒调酒师。它把这一条拼接好的长向量混合一下,让不同头的信息进行交互和融合,最终生成一个统一的输出向量。


    4. 流程图解:多头工厂

    这一部分最适合用图来看。你会发现它像极了工厂里的分流—加工—汇流流水线。

    #mermaid-svg-8uJnM5X3JTCyX47j{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8uJnM5X3JTCyX47j .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8uJnM5X3JTCyX47j .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8uJnM5X3JTCyX47j .error-icon{fill:#552222;}#mermaid-svg-8uJnM5X3JTCyX47j .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8uJnM5X3JTCyX47j .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8uJnM5X3JTCyX47j .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8uJnM5X3JTCyX47j .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8uJnM5X3JTCyX47j .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8uJnM5X3JTCyX47j .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8uJnM5X3JTCyX47j .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8uJnM5X3JTCyX47j .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8uJnM5X3JTCyX47j .marker.cross{stroke:#333333;}#mermaid-svg-8uJnM5X3JTCyX47j svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8uJnM5X3JTCyX47j p{margin:0;}#mermaid-svg-8uJnM5X3JTCyX47j .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-8uJnM5X3JTCyX47j .cluster-label text{fill:#333;}#mermaid-svg-8uJnM5X3JTCyX47j .cluster-label span{color:#333;}#mermaid-svg-8uJnM5X3JTCyX47j .cluster-label span p{background-color:transparent;}#mermaid-svg-8uJnM5X3JTCyX47j .label text,#mermaid-svg-8uJnM5X3JTCyX47j span{fill:#333;color:#333;}#mermaid-svg-8uJnM5X3JTCyX47j .node rect,#mermaid-svg-8uJnM5X3JTCyX47j .node circle,#mermaid-svg-8uJnM5X3JTCyX47j .node ellipse,#mermaid-svg-8uJnM5X3JTCyX47j .node polygon,#mermaid-svg-8uJnM5X3JTCyX47j .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8uJnM5X3JTCyX47j .rough-node .label text,#mermaid-svg-8uJnM5X3JTCyX47j .node .label text,#mermaid-svg-8uJnM5X3JTCyX47j .image-shape .label,#mermaid-svg-8uJnM5X3JTCyX47j .icon-shape .label{text-anchor:middle;}#mermaid-svg-8uJnM5X3JTCyX47j .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8uJnM5X3JTCyX47j .rough-node .label,#mermaid-svg-8uJnM5X3JTCyX47j .node .label,#mermaid-svg-8uJnM5X3JTCyX47j .image-shape .label,#mermaid-svg-8uJnM5X3JTCyX47j .icon-shape .label{text-align:center;}#mermaid-svg-8uJnM5X3JTCyX47j .node.clickable{cursor:pointer;}#mermaid-svg-8uJnM5X3JTCyX47j .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8uJnM5X3JTCyX47j .arrowheadPath{fill:#333333;}#mermaid-svg-8uJnM5X3JTCyX47j .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8uJnM5X3JTCyX47j .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8uJnM5X3JTCyX47j .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8uJnM5X3JTCyX47j .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8uJnM5X3JTCyX47j .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8uJnM5X3JTCyX47j .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8uJnM5X3JTCyX47j .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8uJnM5X3JTCyX47j .cluster text{fill:#333;}#mermaid-svg-8uJnM5X3JTCyX47j .cluster span{color:#333;}#mermaid-svg-8uJnM5X3JTCyX47j div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8uJnM5X3JTCyX47j .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8uJnM5X3JTCyX47j rect.text{fill:none;stroke-width:0;}#mermaid-svg-8uJnM5X3JTCyX47j .icon-shape,#mermaid-svg-8uJnM5X3JTCyX47j .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8uJnM5X3JTCyX47j .icon-shape p,#mermaid-svg-8uJnM5X3JTCyX47j .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8uJnM5X3JTCyX47j .icon-shape rect,#mermaid-svg-8uJnM5X3JTCyX47j .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8uJnM5X3JTCyX47j .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8uJnM5X3JTCyX47j .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8uJnM5X3JTCyX47j :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Multi-Head Attention 机制

    并行处理 (8个平行宇宙)

    Q,K,V 计算

    Q,K,V 计算

    Q,K,V 计算

    Head 1 (关注语法) 64维

    输入向量 Z (512维)

    切分

    Head 2 (关注指代) 64维

    Head 8 (关注情感) 64维

    输出 1

    输出 2

    输出 8

    拼接 (Concat) 64 x 8 = 512维

    线性变换 (Linear/WO) 信息大融合

    最终输出 (Multi-Head Output)

    5. 这里的“彩蛋”

    虽然我们在图里说是“关注语法”、“关注情感”,但其实这是我们人类的事后诸葛亮。 在训练开始前,机器并不知道 Head 1 应该学什么。 这些功能是 AI 在训练过程中自己学会的。

    • 有时候你会发现 Head 3 和 Head 4 学重了,这被称为“多头冗余”,但为了保险起见,冗余一点也没关系。

    本章小结

  • Multi-Head 解决了单头注意力视角单一的问题。
  • 它通过降低维度来实现并行多路计算,计算总量并没有暴增。
  • 它包含了:切分 -> 独立Attention -> 拼接 -> 线性融合 四个步骤。
  • 到这里,Attention 部分的核心就讲完了!但是,如果你把现在的模型叠个 100 层,它可能会根本训练不起来,因为数据传着传着就“死”了(梯度消失/爆炸)。

    为了让这栋大楼能盖得更高更稳,我们需要引入两个建筑学神器:残差连接 (Residual Connection) 和 层归一化 (Layer Normalization)。


    如果把 Transformer 比作盖楼,前几章我们已经造好了最核心的砖块(Attention)。但是,只要稍微有些工程经验的人都知道:楼盖得太高,是会塌的。

    在深度学习里,这个“塌”表现为梯度消失(Gradient Vanishing)或者网络退化——越深的网络反而越笨。

    为了让 Transformer 能够毫无顾虑地叠上几十层甚至上百层,Google 工程师引入了两根“定海神针”:残差连接(Residual Connection) 和 层归一化(Layer Normalization)。

    这一章,我们看看这两个听起来很高大上、实际上却非常朴素的机制。


    第六章:连接与归一化——防止“楼倒塌”的工程学

    在 Transformer 的每一层(Layer)里,无论是 Attention 还是后面要讲的 FFN,都被包裹在一个固定的结构里:Add & Norm。

    1. 残差连接 (Residual Connection/Add):给信息留条退路

    还记得我们前几章讲的 Multi-Head Attention 吗?虽然它很厉害,但万一这一层“脑抽”了,把原本好的信息给算坏了怎么办?

    残差连接(源自 ResNet)的核心思想就是:不要只相信你的运算结果,还要保留原始的输入。

    O

    u

    t

    p

    u

    t

    =

    L

    a

    y

    e

    r

    (

    x

    )

    +

    x

    Output = Layer(x) + x

    Output=Layer(x)+x

    🎓 生动比喻:抄作业的艺术

    想象你在做数学题(这一层网络)。

    • x

      x

      x:是你上一次考试的成绩(或者参考答案)。

    • L

      a

      y

      e

      r

      (

      x

      )

      Layer(x)

      Layer(x):是你现在的计算过程。

    残差连接的意思是:你可以去计算新的结果,但最后交卷的时候,要把你算出来的东西加上原来的

    x

    x

    x

    这样设计有两个巨大的好处:

  • 保底机制:万一你这次算得一团糟(

    L

    a

    y

    e

    r

    (

    x

    )

    Layer(x)

    Layer(x) 接近 0 或乱码),只要加上

    x

    x

    x,至少结果不会比原来更差。这相当于给信息开了一条VIP 直通车,让它能无损通过。

  • 梯度高速公路:在反向传播(训练)时,梯度可以通过这条直连通路,畅通无阻地传回最开始的层,彻底解决了“梯度消失”这个千古难题。
  • 2. 层归一化 (Layer Normalization/Norm):让大家都在起跑线上

    神经网络最怕“大起大落”。 如果第一层的输出是 0.5,第二层变成了 500,第三层变成了 50000……这数值一爆炸,后面的数学公式就没法算了(激活函数会饱和)。

    我们需要把每一层的输出,都强行拉回到一个标准的范围(比如均值为 0,方差为 1)。

    在图像处理(CV)里,大家常用 Batch Norm(按批次归一化)。但在 NLP 里,因为句子长短不一,Batch Norm 很难用。所以 Transformer 用的是 Layer Norm。

    🎓 生动比喻:标准化考试分数

    想象班里有学霸和学渣。

    • 这次考试太难,大家平均分只有 30 分。
    • 下次考试太简单,大家平均分 90 分。

    如果不处理,这两次分数的含义完全不同。Layer Norm 做的事情就是: 不管卷子难易,我把你这一行的所有分数进行“缩放”。

    • 把平均分强行拉回 0。
    • 把分散程度强行拉回 1。

    这样,无论数据在里面怎么折腾,下一层网络接收到的,永远是分布稳定、清爽干净的数据。

    3. Add & Norm 的组合拳

    在 Transformer 的论文图里,你会看到每个模块周围都有一圈线。这就是 Add & Norm 的工作流程。

  • Input 兵分两路。
  • 一路去干活(做 Attention 计算)。
  • 一路在旁边躺平(保留原样)。
  • 干完活回来,把两路结果相加(Add)。
  • 最后把结果拿去标准化(Norm)。
  • 4. 流程图解:VIP 通道与安检门

    让我们用 Mermaid 看看这个结构是如何包裹 Attention 的。

    #mermaid-svg-v2LbDUFgISpGP2mm{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-v2LbDUFgISpGP2mm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-v2LbDUFgISpGP2mm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-v2LbDUFgISpGP2mm .error-icon{fill:#552222;}#mermaid-svg-v2LbDUFgISpGP2mm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-v2LbDUFgISpGP2mm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-v2LbDUFgISpGP2mm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-v2LbDUFgISpGP2mm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-v2LbDUFgISpGP2mm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-v2LbDUFgISpGP2mm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-v2LbDUFgISpGP2mm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-v2LbDUFgISpGP2mm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-v2LbDUFgISpGP2mm .marker.cross{stroke:#333333;}#mermaid-svg-v2LbDUFgISpGP2mm svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-v2LbDUFgISpGP2mm p{margin:0;}#mermaid-svg-v2LbDUFgISpGP2mm .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-v2LbDUFgISpGP2mm .cluster-label text{fill:#333;}#mermaid-svg-v2LbDUFgISpGP2mm .cluster-label span{color:#333;}#mermaid-svg-v2LbDUFgISpGP2mm .cluster-label span p{background-color:transparent;}#mermaid-svg-v2LbDUFgISpGP2mm .label text,#mermaid-svg-v2LbDUFgISpGP2mm span{fill:#333;color:#333;}#mermaid-svg-v2LbDUFgISpGP2mm .node rect,#mermaid-svg-v2LbDUFgISpGP2mm .node circle,#mermaid-svg-v2LbDUFgISpGP2mm .node ellipse,#mermaid-svg-v2LbDUFgISpGP2mm .node polygon,#mermaid-svg-v2LbDUFgISpGP2mm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-v2LbDUFgISpGP2mm .rough-node .label text,#mermaid-svg-v2LbDUFgISpGP2mm .node .label text,#mermaid-svg-v2LbDUFgISpGP2mm .image-shape .label,#mermaid-svg-v2LbDUFgISpGP2mm .icon-shape .label{text-anchor:middle;}#mermaid-svg-v2LbDUFgISpGP2mm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-v2LbDUFgISpGP2mm .rough-node .label,#mermaid-svg-v2LbDUFgISpGP2mm .node .label,#mermaid-svg-v2LbDUFgISpGP2mm .image-shape .label,#mermaid-svg-v2LbDUFgISpGP2mm .icon-shape .label{text-align:center;}#mermaid-svg-v2LbDUFgISpGP2mm .node.clickable{cursor:pointer;}#mermaid-svg-v2LbDUFgISpGP2mm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-v2LbDUFgISpGP2mm .arrowheadPath{fill:#333333;}#mermaid-svg-v2LbDUFgISpGP2mm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-v2LbDUFgISpGP2mm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-v2LbDUFgISpGP2mm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v2LbDUFgISpGP2mm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-v2LbDUFgISpGP2mm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v2LbDUFgISpGP2mm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-v2LbDUFgISpGP2mm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-v2LbDUFgISpGP2mm .cluster text{fill:#333;}#mermaid-svg-v2LbDUFgISpGP2mm .cluster span{color:#333;}#mermaid-svg-v2LbDUFgISpGP2mm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-v2LbDUFgISpGP2mm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-v2LbDUFgISpGP2mm rect.text{fill:none;stroke-width:0;}#mermaid-svg-v2LbDUFgISpGP2mm .icon-shape,#mermaid-svg-v2LbDUFgISpGP2mm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-v2LbDUFgISpGP2mm .icon-shape p,#mermaid-svg-v2LbDUFgISpGP2mm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-v2LbDUFgISpGP2mm .icon-shape rect,#mermaid-svg-v2LbDUFgISpGP2mm .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-v2LbDUFgISpGP2mm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-v2LbDUFgISpGP2mm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-v2LbDUFgISpGP2mm :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Add & Norm 模块详解

    努力干活区

    去计算 F(x)

    VIP 直通车 (原样保留 x)

    计算结果

    Multi-Head Attention (或者 FFN)

    输入向量 x

    分流点

    +

    Layer Norm (归一化处理)

    输出 = Norm(x + F(x))

    图解说明:注意那条虚线,它就是残差连接。它绕过了复杂的 Attention 计算,直接连到了加号上。这就是深层网络不退化的秘密武器。


    本章小结

  • 残差连接 (Add):给数据开后门,保证深层网络也能训练,防止学得越久越傻。
  • 层归一化 (Norm):把数据整理干净,防止数值爆炸或消失,让训练更稳定。
  • Add & Norm 是 Transformer 的“混凝土”,每一层都离不开它。
  • 现在,我们的输入经过了 Attention(提取特征),又经过了 Add & Norm(稳固结构)。

    接下来,数据将进入 Encoder 这一层的最后一个组件——前馈神经网络 (Feed-Forward Networks)。 如果说 Attention 是“观察”,那 FFN 就是“思考”和“消化”。


    这一章我们来讲讲 Transformer 里最容易被忽视,但参数量其实最大的部分。

    在前面的章节里,Attention 就像是一个社交达人,它忙着在不同的单词之间牵线搭桥,搞清楚“谁和谁是亲戚”。

    但光有社交是不够的。收集了一堆信息之后,每个单词都需要回到自己的工位上,冷静下来,把这些信息消化、吸收、内化成自己的东西。

    这就是 前馈神经网络 (Feed-Forward Networks, FFN) 的工作。


    第七章:前馈神经网络 (Feed-Forward Networks)——记忆的精炼

    1. 社交后的独处:Position-wise

    首先,我们要纠正一个概念。虽然它叫“神经网络”,但在 Transformer 的这一层里,它其实是非常孤僻的。

    • Attention 层:是全局的。它看遍了整个句子,把别人的信息拿过来。
    • FFN 层:是独立的(Position-wise)。它单独处理每一个词向量,不看周围的人。

    比喻时刻:

    • Attention 是开会讨论。大家交换意见,我听听你的想法,你听听我的想法。
    • FFN 是会后总结。每个人回到自己的脑子里(或者笔记本上),单独整理刚才听到的内容,提炼出重点。

    注意:虽然大家是各回各家单独处理,但大家用的“处理逻辑”(权重矩阵

    W

    W

    W)是一模一样的。这就像全班同学都用同一套模版写总结。

    2. 三明治结构:宽进窄出

    FFN 的内部结构非常简单,就像一个三明治,或者说是一个膨胀—收缩的过程。

    它由两个线性变换(Linear)夹着一个非线性激活函数(ReLU)组成。

  • 第一层 Linear(膨胀): 把输入的维度(比如 512)强行变大(通常变大 4 倍,变成 2048)。

    • 为什么要变大? 就像把一个折叠的纸团展开。在低维空间挤在一起分不清的特征,投射到高维空间后,更容易把它们分离开来。
  • 激活函数(ReLU): 这是注入“灵魂”的一步。如果没有它,两层 Linear 叠在一起其实还是等于一层 Linear。ReLU 负责把那些负能量(负数)砍掉,只保留正能量。

    • 公式:

      R

      e

      L

      U

      (

      x

      )

      =

      max

      (

      0

      ,

      x

      )

      ReLU(x) = \\max(0, x)

      ReLU(x)=max(0,x)

  • 第二层 Linear(收缩): 把 2048 维的向量再压缩回 512 维。

    • 为什么要变回来? 为了和下一层网络对接(还记得残差连接吗?维度必须一致才能相加)。
  • 🎓 生动比喻:做面团
    • 输入:一团刚揉好的面(包含了 Attention 收集的信息)。
    • 第一步(变宽):把面团用力擀开,铺满整个桌子。这样你能看清面粉里的每一个细节。
    • 第二步(ReLU):在面饼上撒点料,或者切掉边缘不整齐的部分。
    • 第三步(变窄):把面饼重新揉回一个小面团。

    此时,这个面团虽然外观没变(还是 512 维),但内部的筋道(特征)已经完全不同了。

    3. 数学公式(看一眼就行)

    F

    F

    N

    (

    x

    )

    =

    max

    (

    0

    ,

    x

    W

    1

    +

    b

    1

    )

    W

    2

    +

    b

    2

    FFN(x) = \\max(0, xW_1 + b_1)W_2 + b_2

    FFN(x)=max(0,xW1+b1)W2+b2

    • x

      x

      x:输入(512维)

    • W

      1

      W_1

      W1:把 512 变成 2048

    • W

      2

      W_2

      W2:把 2048 变成 512

    4. 流程图解:数据的“呼吸”运动

    让我们看看数据在这个环节是如何“吸气膨胀”再“呼气收缩”的。

    #mermaid-svg-OncFgLMfEeOkAQz1{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OncFgLMfEeOkAQz1 .error-icon{fill:#552222;}#mermaid-svg-OncFgLMfEeOkAQz1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OncFgLMfEeOkAQz1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OncFgLMfEeOkAQz1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OncFgLMfEeOkAQz1 .marker.cross{stroke:#333333;}#mermaid-svg-OncFgLMfEeOkAQz1 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OncFgLMfEeOkAQz1 p{margin:0;}#mermaid-svg-OncFgLMfEeOkAQz1 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-OncFgLMfEeOkAQz1 .cluster-label text{fill:#333;}#mermaid-svg-OncFgLMfEeOkAQz1 .cluster-label span{color:#333;}#mermaid-svg-OncFgLMfEeOkAQz1 .cluster-label span p{background-color:transparent;}#mermaid-svg-OncFgLMfEeOkAQz1 .label text,#mermaid-svg-OncFgLMfEeOkAQz1 span{fill:#333;color:#333;}#mermaid-svg-OncFgLMfEeOkAQz1 .node rect,#mermaid-svg-OncFgLMfEeOkAQz1 .node circle,#mermaid-svg-OncFgLMfEeOkAQz1 .node ellipse,#mermaid-svg-OncFgLMfEeOkAQz1 .node polygon,#mermaid-svg-OncFgLMfEeOkAQz1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OncFgLMfEeOkAQz1 .rough-node .label text,#mermaid-svg-OncFgLMfEeOkAQz1 .node .label text,#mermaid-svg-OncFgLMfEeOkAQz1 .image-shape .label,#mermaid-svg-OncFgLMfEeOkAQz1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-OncFgLMfEeOkAQz1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OncFgLMfEeOkAQz1 .rough-node .label,#mermaid-svg-OncFgLMfEeOkAQz1 .node .label,#mermaid-svg-OncFgLMfEeOkAQz1 .image-shape .label,#mermaid-svg-OncFgLMfEeOkAQz1 .icon-shape .label{text-align:center;}#mermaid-svg-OncFgLMfEeOkAQz1 .node.clickable{cursor:pointer;}#mermaid-svg-OncFgLMfEeOkAQz1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OncFgLMfEeOkAQz1 .arrowheadPath{fill:#333333;}#mermaid-svg-OncFgLMfEeOkAQz1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OncFgLMfEeOkAQz1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OncFgLMfEeOkAQz1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OncFgLMfEeOkAQz1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OncFgLMfEeOkAQz1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OncFgLMfEeOkAQz1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OncFgLMfEeOkAQz1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OncFgLMfEeOkAQz1 .cluster text{fill:#333;}#mermaid-svg-OncFgLMfEeOkAQz1 .cluster span{color:#333;}#mermaid-svg-OncFgLMfEeOkAQz1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OncFgLMfEeOkAQz1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OncFgLMfEeOkAQz1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-OncFgLMfEeOkAQz1 .icon-shape,#mermaid-svg-OncFgLMfEeOkAQz1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OncFgLMfEeOkAQz1 .icon-shape p,#mermaid-svg-OncFgLMfEeOkAQz1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OncFgLMfEeOkAQz1 .icon-shape rect,#mermaid-svg-OncFgLMfEeOkAQz1 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OncFgLMfEeOkAQz1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OncFgLMfEeOkAQz1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OncFgLMfEeOkAQz1 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    FFN 内部运作机理

    特征展开

    特征提炼完成

    输入向量 x (维度: 512)

    Linear Layer 1 (升维: 512 -> 2048)

    中间层向量 (维度: 2048)

    ReLU 激活函数 (过滤/非线性变换)

    激活后的向量 (维度: 2048)

    Linear Layer 2 (降维: 2048 -> 512)

    输出向量 (维度: 512)

    5. 一个有趣的发现

    你可能听说过 GPT 的参数量很大(比如 1750 亿参数)。其实,这其中有 2/3 的参数都集中在 FFN 里!

    • Attention 的参数只占很少一部分(

      W

      Q

      ,

      W

      K

      ,

      W

      V

      W^Q, W^K, W^V

      WQ,WK,WV 都不大)。

    • FFN 的那个“中间层”(2048 甚至更大)消耗了大量的矩阵空间。

    有研究认为,Attention 负责逻辑和关系,而 FFN 真的就像是“大脑的记忆区”,里面存储了大量的具体知识(比如“法国的首都是巴黎”这种事实,可能就存在 FFN 的权重里)。


    本章小结

  • FFN 紧跟在 Attention 后面,负责对每个位置的信息进行独立加工。
  • 它是一个 宽-窄-宽(或者说窄-宽-窄,取决于怎么看)的结构。
  • 它的作用是提炼特征,把 Attention 收集到的杂乱信息整合成清晰的语义。

  • 至此,Encoder(编码器)的所有秘密都被我们解开了!

    Input -> Embedding -> Pos -> [ Attention -> Add&Norm -> FFN -> Add&Norm ] x N -> Output

    现在,我们要跨过那道界线,进入右边的 Decoder(解码器)。 虽然 Decoder 看起来和 Encoder 很像,但它有一个非常“心机”的改动——它在考试时不能偷看答案。


    在 Encoder(左边的塔)里,我们要理解一句话,当然是一眼看完全文最好(上帝视角)。 但在 Decoder(右边的塔)里,任务变了。Decoder 的任务是生成。

    而在生成的时候,最忌讳的就是——剧透。


    第八章:解码器的独角戏——Masked Multi-Head Attention

    1. 为什么 Decoder 不能有“上帝视角”?

    想象你在参加英语考试,题目是中译英:

    中文:我爱学习 答案:I love study

    在训练的时候,我们是把正确答案 I love study 喂给 Decoder 的(这叫 Teacher Forcing)。

    但是,如果 Decoder 在预测 I 的时候,已经偷看到了后面的 love 和 study,那它还学个屁啊?它直接照抄不就行了? 这就好比老师让你填空,结果把答案写在了横线后面,你根本不用动脑子,直接抄就行。

    到了真正考试(推理/应用)的时候,是没有人给你看后面的词的。如果训练时习惯了作弊,考试时绝对抓瞎。

    所以,我们需要给 Decoder 戴上一副特制的眼镜: 当它读到第

    t

    t

    t 个词的时候,强行让它看不见

    t

    t

    t 之后的词。

    这就是 Mask (掩码)。


    2. Mask 的魔法:下三角矩阵

    具体怎么做呢?我们回想一下 Attention 的计算公式:

    S

    o

    f

    t

    m

    a

    x

    (

    Q

    K

    T

    )

    Softmax(Q \\cdot K^T)

    Softmax(QKT)

    Q

    K

    T

    Q \\cdot K^T

    QKT 算出来的是一个

    N

    ×

    N

    N \\times N

    N×N 的方阵,代表每个词对其他词的关注度。

    为了实施“防作弊”策略,我们在把这个矩阵扔进 Softmax 之前,要做个**“大手术”**:

    我们把矩阵的右上角全部涂黑(或者是贴上胶带)。 在数学上,就是把右上角的位置全部赋值为 负无穷大 (

    -\\infty

    )。

    🎓 生动比喻:阶梯教室的挡板

    想象 Decoder 是一个阶梯教室:

    • 坐在第 1 排的人(第 1 个词),只能看见他自己。
    • 坐在第 2 排的人(第 2 个词),能看见第 1 排和自己。
    • 坐在第 3 排的人,能看见 1、2 和自己。
    • 任何人都绝对看不见坐在他后面的人!

    这样,I 只能关注 I;love 只能关注 I 和 love。未来的词 study 对它们来说就是一片黑暗。

    ❌ 为什么是负无穷大?

    因为 Softmax 函数会将输入转化为概率。

    e

    0

    e^{-\\infty} \\approx 0

    e0。 这样一来,所有右上角的权重在经过 Softmax 后都会变成 0。这就在数学上彻底切断了“偷看未来”的可能性。


    3. 图解:被遮挡的视线

    看这个图之前,请记住:下三角是光明的,上三角是黑暗的。

    #mermaid-svg-AfOj2YVTeoMhLdG2{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AfOj2YVTeoMhLdG2 .error-icon{fill:#552222;}#mermaid-svg-AfOj2YVTeoMhLdG2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AfOj2YVTeoMhLdG2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .marker.cross{stroke:#333333;}#mermaid-svg-AfOj2YVTeoMhLdG2 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AfOj2YVTeoMhLdG2 p{margin:0;}#mermaid-svg-AfOj2YVTeoMhLdG2 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .cluster-label text{fill:#333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .cluster-label span{color:#333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .cluster-label span p{background-color:transparent;}#mermaid-svg-AfOj2YVTeoMhLdG2 .label text,#mermaid-svg-AfOj2YVTeoMhLdG2 span{fill:#333;color:#333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .node rect,#mermaid-svg-AfOj2YVTeoMhLdG2 .node circle,#mermaid-svg-AfOj2YVTeoMhLdG2 .node ellipse,#mermaid-svg-AfOj2YVTeoMhLdG2 .node polygon,#mermaid-svg-AfOj2YVTeoMhLdG2 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AfOj2YVTeoMhLdG2 .rough-node .label text,#mermaid-svg-AfOj2YVTeoMhLdG2 .node .label text,#mermaid-svg-AfOj2YVTeoMhLdG2 .image-shape .label,#mermaid-svg-AfOj2YVTeoMhLdG2 .icon-shape .label{text-anchor:middle;}#mermaid-svg-AfOj2YVTeoMhLdG2 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AfOj2YVTeoMhLdG2 .rough-node .label,#mermaid-svg-AfOj2YVTeoMhLdG2 .node .label,#mermaid-svg-AfOj2YVTeoMhLdG2 .image-shape .label,#mermaid-svg-AfOj2YVTeoMhLdG2 .icon-shape .label{text-align:center;}#mermaid-svg-AfOj2YVTeoMhLdG2 .node.clickable{cursor:pointer;}#mermaid-svg-AfOj2YVTeoMhLdG2 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .arrowheadPath{fill:#333333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AfOj2YVTeoMhLdG2 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AfOj2YVTeoMhLdG2 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AfOj2YVTeoMhLdG2 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AfOj2YVTeoMhLdG2 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AfOj2YVTeoMhLdG2 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AfOj2YVTeoMhLdG2 .cluster text{fill:#333;}#mermaid-svg-AfOj2YVTeoMhLdG2 .cluster span{color:#333;}#mermaid-svg-AfOj2YVTeoMhLdG2 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AfOj2YVTeoMhLdG2 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AfOj2YVTeoMhLdG2 rect.text{fill:none;stroke-width:0;}#mermaid-svg-AfOj2YVTeoMhLdG2 .icon-shape,#mermaid-svg-AfOj2YVTeoMhLdG2 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AfOj2YVTeoMhLdG2 .icon-shape p,#mermaid-svg-AfOj2YVTeoMhLdG2 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AfOj2YVTeoMhLdG2 .icon-shape rect,#mermaid-svg-AfOj2YVTeoMhLdG2 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AfOj2YVTeoMhLdG2 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AfOj2YVTeoMhLdG2 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AfOj2YVTeoMhLdG2 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Masked Attention 矩阵可视化

    √ 看得见

    X 被挡住 (-inf)

    X 被挡住 (-inf)

    √ 看得见

    √ 看得见

    X 被挡住 (-inf)

    √ 看得见

    √ 看得见

    √ 看得见

    Word 1 (I)

    Col 1 (I)

    Col 2 (love)

    Col 3 (study)

    Word 2 (love)

    Word 3 (study)

    4. Decoder 的第二层 Attention:跨界之恋 (Cross Attention)

    Decoder 比 Encoder 多了一个组件。 在搞完上面那个“防作弊 Self-Attention”之后,Decoder 还需要做一件最重要的事:看 Encoder 的脸色。

    这一层叫 Encoder-Decoder Attention(或者叫 Cross Attention)。

    这里的

    Q

    ,

    K

    ,

    V

    Q, K, V

    Q,K,V 来源发生了变化,这是全篇唯一的**“混血”**环节:

    • Query (

      Q

      Q

      Q):来自 Decoder 自己(刚算完的那个带着 Mask 的输出)。

      • 潜台词:“我想写下一个字了,请问老学究,根据我现在写的内容,原文里哪里最重要?”
    • Key (

      K

      K

      K) & Value (

      V

      V

      V):来自 Encoder 的输出(老学究画的那张思维导图)。

      • 潜台词:“原文的信息都在这儿了,你自己查吧。”
    🎓 生动比喻:作家查资料
  • Masked Self-Attention:作家看着自己刚写完的上半句话,整理思路(防止前后矛盾)。
  • Cross Attention:作家抬起头,看了一眼老学究给的“原文大纲”,从中提取灵感,决定下一个词写什么。

  • 5. Decoder 完整结构图

    Decoder 的每一层其实是 3 个子层 组成的(比 Encoder 多一层)。

    #mermaid-svg-Q8lmVcdngY3GLS2F{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Q8lmVcdngY3GLS2F .error-icon{fill:#552222;}#mermaid-svg-Q8lmVcdngY3GLS2F .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Q8lmVcdngY3GLS2F .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Q8lmVcdngY3GLS2F .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Q8lmVcdngY3GLS2F .marker.cross{stroke:#333333;}#mermaid-svg-Q8lmVcdngY3GLS2F svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Q8lmVcdngY3GLS2F p{margin:0;}#mermaid-svg-Q8lmVcdngY3GLS2F .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Q8lmVcdngY3GLS2F .cluster-label text{fill:#333;}#mermaid-svg-Q8lmVcdngY3GLS2F .cluster-label span{color:#333;}#mermaid-svg-Q8lmVcdngY3GLS2F .cluster-label span p{background-color:transparent;}#mermaid-svg-Q8lmVcdngY3GLS2F .label text,#mermaid-svg-Q8lmVcdngY3GLS2F span{fill:#333;color:#333;}#mermaid-svg-Q8lmVcdngY3GLS2F .node rect,#mermaid-svg-Q8lmVcdngY3GLS2F .node circle,#mermaid-svg-Q8lmVcdngY3GLS2F .node ellipse,#mermaid-svg-Q8lmVcdngY3GLS2F .node polygon,#mermaid-svg-Q8lmVcdngY3GLS2F .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Q8lmVcdngY3GLS2F .rough-node .label text,#mermaid-svg-Q8lmVcdngY3GLS2F .node .label text,#mermaid-svg-Q8lmVcdngY3GLS2F .image-shape .label,#mermaid-svg-Q8lmVcdngY3GLS2F .icon-shape .label{text-anchor:middle;}#mermaid-svg-Q8lmVcdngY3GLS2F .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Q8lmVcdngY3GLS2F .rough-node .label,#mermaid-svg-Q8lmVcdngY3GLS2F .node .label,#mermaid-svg-Q8lmVcdngY3GLS2F .image-shape .label,#mermaid-svg-Q8lmVcdngY3GLS2F .icon-shape .label{text-align:center;}#mermaid-svg-Q8lmVcdngY3GLS2F .node.clickable{cursor:pointer;}#mermaid-svg-Q8lmVcdngY3GLS2F .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Q8lmVcdngY3GLS2F .arrowheadPath{fill:#333333;}#mermaid-svg-Q8lmVcdngY3GLS2F .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Q8lmVcdngY3GLS2F .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Q8lmVcdngY3GLS2F .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q8lmVcdngY3GLS2F .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Q8lmVcdngY3GLS2F .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q8lmVcdngY3GLS2F .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Q8lmVcdngY3GLS2F .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Q8lmVcdngY3GLS2F .cluster text{fill:#333;}#mermaid-svg-Q8lmVcdngY3GLS2F .cluster span{color:#333;}#mermaid-svg-Q8lmVcdngY3GLS2F div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Q8lmVcdngY3GLS2F .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Q8lmVcdngY3GLS2F rect.text{fill:none;stroke-width:0;}#mermaid-svg-Q8lmVcdngY3GLS2F .icon-shape,#mermaid-svg-Q8lmVcdngY3GLS2F .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Q8lmVcdngY3GLS2F .icon-shape p,#mermaid-svg-Q8lmVcdngY3GLS2F .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Q8lmVcdngY3GLS2F .icon-shape rect,#mermaid-svg-Q8lmVcdngY3GLS2F .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Q8lmVcdngY3GLS2F .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Q8lmVcdngY3GLS2F .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Q8lmVcdngY3GLS2F :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Decoder Layer 内部构造

    提供 Q

    提供 K, V

    Decoder 输入 (Shifted Output)

    1. Masked Self-Attention (只能看前面,不能看后面)

    Add & Norm

    2. Encoder-Decoder Attention (Q来自下方, K/V来自Encoder)

    Encoder 的输出 (K, V)

    Add & Norm

    3. Feed-Forward Network (消化思考)

    Add & Norm

    输出到下一层


    本章小结

  • Decoder 是生成者:它必须按顺序预测,不能偷看未来。
  • Mask 机制:通过在 Attention 分数矩阵的上三角填充负无穷大,在数学上屏蔽了未来的信息。
  • Cross Attention:这是连接 Encoder 和 Decoder 的桥梁。Decoder 用自己的

    Q

    Q

    Q 去查 Encoder 的

    K

    K

    K

    V

    V

    V

  • 现在,Decoder 经过层层堆叠,终于输出了一个向量。 但这个向量只是一串数字,怎么把它变回我们人类能看懂的单词(比如 study)呢?


    第九章:终章——输出与未来

    1. 最后一公里:Linear & Softmax

    在 Decoder 的最顶层,输出的依然是一个 512 维(或 1024 维)的向量。 为了把它变成字,我们需要经过最后两个关卡。

    第一关:Linear Layer(巨大的单词投影仪)

    机器的词汇表(Vocabulary)通常很大,比如有 30,000 个单词。 Linear 层就是一个超级巨大的全连接网络。它的作用是把那个 512 维 的向量,瞬间投影放大到 30,000 维。

    • 逻辑:这个 30,000 维的向量里,每一个维度都对应字典里的一个词。
    • 结果:我们会得到 30,000 个数值(Logits)。数值越大,代表机器觉得下个词是这个词的可能性越高。
    第二关:Softmax(概率裁判)

    这 30,000 个数值有正有负,甚至还有无穷大,没法直接看。 Softmax 把它们转换成概率。

    • 所有概率加起来等于 1。
    • 比如:
      • apple: 0.001%
      • book: 0.002%
      • study: 95%

    最终,我们选概率最大的那个词(study),作为当前的输出。


    2. 流程图解:从数字到单词

    这是 Transformer 生产线上的最后一道工序:

    #mermaid-svg-a58D8EoJlrftNuXd{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-a58D8EoJlrftNuXd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-a58D8EoJlrftNuXd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-a58D8EoJlrftNuXd .error-icon{fill:#552222;}#mermaid-svg-a58D8EoJlrftNuXd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-a58D8EoJlrftNuXd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-a58D8EoJlrftNuXd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-a58D8EoJlrftNuXd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-a58D8EoJlrftNuXd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-a58D8EoJlrftNuXd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-a58D8EoJlrftNuXd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-a58D8EoJlrftNuXd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-a58D8EoJlrftNuXd .marker.cross{stroke:#333333;}#mermaid-svg-a58D8EoJlrftNuXd svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-a58D8EoJlrftNuXd p{margin:0;}#mermaid-svg-a58D8EoJlrftNuXd .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-a58D8EoJlrftNuXd .cluster-label text{fill:#333;}#mermaid-svg-a58D8EoJlrftNuXd .cluster-label span{color:#333;}#mermaid-svg-a58D8EoJlrftNuXd .cluster-label span p{background-color:transparent;}#mermaid-svg-a58D8EoJlrftNuXd .label text,#mermaid-svg-a58D8EoJlrftNuXd span{fill:#333;color:#333;}#mermaid-svg-a58D8EoJlrftNuXd .node rect,#mermaid-svg-a58D8EoJlrftNuXd .node circle,#mermaid-svg-a58D8EoJlrftNuXd .node ellipse,#mermaid-svg-a58D8EoJlrftNuXd .node polygon,#mermaid-svg-a58D8EoJlrftNuXd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-a58D8EoJlrftNuXd .rough-node .label text,#mermaid-svg-a58D8EoJlrftNuXd .node .label text,#mermaid-svg-a58D8EoJlrftNuXd .image-shape .label,#mermaid-svg-a58D8EoJlrftNuXd .icon-shape .label{text-anchor:middle;}#mermaid-svg-a58D8EoJlrftNuXd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-a58D8EoJlrftNuXd .rough-node .label,#mermaid-svg-a58D8EoJlrftNuXd .node .label,#mermaid-svg-a58D8EoJlrftNuXd .image-shape .label,#mermaid-svg-a58D8EoJlrftNuXd .icon-shape .label{text-align:center;}#mermaid-svg-a58D8EoJlrftNuXd .node.clickable{cursor:pointer;}#mermaid-svg-a58D8EoJlrftNuXd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-a58D8EoJlrftNuXd .arrowheadPath{fill:#333333;}#mermaid-svg-a58D8EoJlrftNuXd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-a58D8EoJlrftNuXd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-a58D8EoJlrftNuXd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-a58D8EoJlrftNuXd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-a58D8EoJlrftNuXd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-a58D8EoJlrftNuXd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-a58D8EoJlrftNuXd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-a58D8EoJlrftNuXd .cluster text{fill:#333;}#mermaid-svg-a58D8EoJlrftNuXd .cluster span{color:#333;}#mermaid-svg-a58D8EoJlrftNuXd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-a58D8EoJlrftNuXd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-a58D8EoJlrftNuXd rect.text{fill:none;stroke-width:0;}#mermaid-svg-a58D8EoJlrftNuXd .icon-shape,#mermaid-svg-a58D8EoJlrftNuXd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-a58D8EoJlrftNuXd .icon-shape p,#mermaid-svg-a58D8EoJlrftNuXd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-a58D8EoJlrftNuXd .icon-shape rect,#mermaid-svg-a58D8EoJlrftNuXd .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-a58D8EoJlrftNuXd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-a58D8EoJlrftNuXd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-a58D8EoJlrftNuXd :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Output Generation

    Decoder 最终输出向量 (512维)

    Linear Layer (全连接层: 512 -> 30,000)

    Logits (30,000 个维度的打分)

    Softmax (归一化为概率)

    概率分布 (Study: 0.9, Love: 0.05, …)

    Argmax 选最大的

    最终单词: 'study'


    3. 后日谈:Transformer 的家族分家

    Transformer 论文发表后,AI 界发生了天翻地覆的变化。但有趣的是,后来的大佬们很少直接用原版的 Transformer(Encoder-Decoder 架构),而是把这个架构拆开来用了。

    这就形成了现在大语言模型(LLM)界的两大门派:

    🔵 编码器派 (Encoder-only):BERT 家族
    • 代表人物:BERT, RoBERTa
    • 做法:只用了 Transformer 的 左半边 (Encoder)。
    • 特长:“懂你”。因为 Encoder 可以同时看到上下文,它是搞阅读理解、情感分析、文本分类的神。它不擅长说话,但擅长听懂人话。
    🟢 解码器派 (Decoder-only):GPT 家族
    • 代表人物:GPT-3, ChatGPT, Llama, Claude
    • 做法:只用了 Transformer 的 右半边 (Decoder)(当然,去掉了中间那个 Cross Attention,变成了纯粹的 Autoregressive)。
    • 特长:“忽悠”(哦不,是生成)。它就像一个话痨,你看不到未来,只能根据上文不停地蹦出下一个字。虽然它一开始不如 BERT 懂语法,但大家后来发现,只要大力出奇迹(堆数据、堆算力),Decoder 居然也能涌现出惊人的理解能力!

    冷知识:现在的 ChatGPT 其实本质上就是一个巨大的 Decoder。它一直在做我们在第八章讲的事情:预测下一个词。


    4. 结语:Attention Is All You Need

    回顾我们的旅程,从第一章抛弃 RNN,到中间的 Attention 矩阵运算,再到最后的概率输出。

    Transformer 的成功在于它做对了三件事:

  • 并行计算:解放了 GPU 的算力,让大规模训练成为可能。
  • 注意力机制:让机器学会了像人一样,从纷繁复杂的信息中抓住重点。
  • 通用性:它不仅能做 NLP,后来还去搞了计算机视觉(ViT),甚至蛋白质折叠(AlphaFold)。
  • 那个 2017 年 Google 团队想出来的“黑盒子”,如今已经变成了人工智能时代的蒸汽机。


    太棒了!有了理论基础,再看代码就像看说明书一样简单。

    为了保持风格一致,这份代码讲解依然不走“枯燥教科书”路线。我会把 PyTorch 代码 和之前的 生动比喻 对应起来,并且特别标注出**“形状变换”**(Tensor Shapes),因为做 NLP 最头疼的就是不知道矩阵变成啥样了。

    这是一份**《Transformer 核心组件·实战手术刀》。你可以把它作为博客的附录或者单独的技术实战篇**。


    附录:PyTorch 代码逐行拆解

    下面我们用 PyTorch 把 Transformer 最核心的零件拆下来给你看。 (注:为了代码清晰,省去了部分 Dropout 和初始化细节,专注核心逻辑。)

    0. 准备工作

    import torch
    import torch.nn as nn
    import math
    import torch.nn.functional as F

    # 假设我们有一个简单的配置
    d_model = 512 # 词向量维度 (Embedding Size)
    n_heads = 8 # 多头注意力的头数
    d_ff = 2048 # FFN 中间层维度 (4倍 d_model)


    1. 对应第三章:Embedding + 位置编码 (GPS)

    这是数据的入口。最关键的是 PositionalEncoding,它是不需要训练的(requires_grad=False),它只是一个固定的数学波纹。

    class PositionalEncoding(nn.Module):
    def __init__(self, d_model, max_len=5000):
    super(PositionalEncoding, self).__init__()

    # 1. 创建一个足够长的矩阵 (max_len x d_model)
    pe = torch.zeros(max_len, d_model)
    position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)

    # 2. 计算分母 div_term (那个 10000^(2i/d) 的倒数)
    # 这里的数学技巧是为了数值稳定性
    div_term = torch.exp(torch.arange(0, d_model, 2).float() * (math.log(10000.0) / d_model))

    # 3. 填充 Sin 和 Cos
    # 偶数位用 Sin,奇数位用 Cos
    pe[:, 0::2] = torch.sin(position * div_term)
    pe[:, 1::2] = torch.cos(position * div_term)

    # 4. 增加一个维度,变成 [1, max_len, d_model],方便后续直接和 batch 相加
    pe = pe.unsqueeze(0)

    # 5. 注册为 buffer (意味着它不是参数,不需要梯度更新,但在保存模型时会跟着走)
    self.register_buffer('pe', pe)

    def forward(self, x):
    # x 的形状: [Batch, Seq_Len, d_model]
    # 直接把位置编码加到 x 上 (切片切出当前序列长度)
    x = x + self.pe[:, :x.size(1)]
    return x

    👨‍💻 讲解: 这一步就是把**“蓝色颜料”(位置信息)倒进“红色颜料”**(词向量)里。 register_buffer 是 PyTorch 的一个小技巧,告诉模型:“这是个常量,别在这个变量上浪费梯度计算资源。”


    2. 对应第四、五章:多头注意力 (Multi-Head Attention)

    这是全篇最难写的部分。核心难点在于维度的变换。我们需要把 512 切成 8 个 64,算完后再拼回去。

    class MultiHeadAttention(nn.Module):
    def __init__(self, d_model, n_heads):
    super(MultiHeadAttention, self).__init__()
    self.d_model = d_model
    self.n_heads = n_heads
    self.head_dim = d_model // n_heads # 每个头的维度: 512 / 8 = 64

    assert self.head_dim * n_heads == d_model, "维度必须能被头数整除!"

    # 定义 W_q, W_k, W_v 矩阵
    # 这里有个骚操作:与其定义 8 个小矩阵,不如定义 1 个大矩阵,后面再切分
    self.w_q = nn.Linear(d_model, d_model)
    self.w_k = nn.Linear(d_model, d_model)
    self.w_v = nn.Linear(d_model, d_model)

    # 定义最后的融合层 W_o
    self.fc_out = nn.Linear(d_model, d_model)

    def forward(self, query, key, value, mask=None):
    batch_size = query.shape[0]

    # 1. 线性变换 (Linear Projection)
    # Q, K, V 形状: [Batch, Seq_Len, d_model]
    Q = self.w_q(query)
    K = self.w_k(key)
    V = self.w_v(value)

    # 2. 切分多头 (Split Heads)
    # 这一步把 d_model 拆成了 n_heads * head_dim
    # 变换后形状: [Batch, Seq_Len, n_heads, head_dim]
    Q = Q.view(batch_size, 1, self.n_heads, self.head_dim)
    K = K.view(batch_size, 1, self.n_heads, self.head_dim)
    V = V.view(batch_size, 1, self.n_heads, self.head_dim)

    # 3. 调整维度顺序 (Transpose)
    # 为了做矩阵乘法,我们需要把 seq_len 和 head_dim 放在最后两维
    # 变换后形状: [Batch, n_heads, Seq_Len, head_dim]
    Q = Q.permute(0, 2, 1, 3)
    K = K.permute(0, 2, 1, 3)
    V = V.permute(0, 2, 1, 3)

    # 4. 计算注意力分数 (Scaled Dot-Product Attention)
    # energy 形状: [Batch, n_heads, Seq_Len, Seq_Len]
    # 这里的 matmul 是针对最后两个维度的
    energy = torch.matmul(Q, K.transpose(2, 1)) / math.sqrt(self.head_dim)

    # 如果有 Mask (比如 Decoder 不能看后面,或者 Padding Mask)
    if mask is not None:
    # 把 mask 为 0 的地方填成负无穷 (-1e20)
    energy = energy.masked_fill(mask == 0, 1e20)

    # 5. Softmax 归一化
    attention = torch.softmax(energy, dim=1)

    # 6. 加权求和
    # x 形状: [Batch, n_heads, Seq_Len, head_dim]
    x = torch.matmul(attention, V)

    # 7. 拼接多头 (Concat)
    # 先变回 [Batch, Seq_Len, n_heads, head_dim]
    x = x.permute(0, 2, 1, 3).contiguous()
    # 再压扁成 [Batch, Seq_Len, d_model]
    x = x.view(batch_size, 1, self.d_model)

    # 8. 最后的线性混合
    x = self.fc_out(x)

    return x

    👨‍💻 讲解:

    • view 和 permute 是这里的灵魂。这就像是你在玩魔方,为了让同颜色的面转到一起,你需要先把魔方转几个角度。
    • contiguous() 是个 PyTorch 的内存管理细节,如果不加,在 view 的时候可能会报错(因为内存不连续了)。
    • masked_fill 就是那个“阶梯教室挡板”,把不需要看的地方强行设为负无穷。

    3. 对应第七章:前馈神经网络 (FFN)

    这是那个“宽进窄出”的三明治结构。简单粗暴,但参数量巨大。

    class FeedForward(nn.Module):
    def __init__(self, d_model, d_ff, dropout=0.1):
    super(FeedForward, self).__init__()
    # nn.Sequential 就像是一个把层串起来的容器
    self.net = nn.Sequential(
    # 第一层:膨胀 (512 -> 2048)
    nn.Linear(d_model, d_ff),
    # 激活函数:ReLU (过滤负能量)
    nn.ReLU(),
    # Dropout:防止过拟合
    nn.Dropout(dropout),
    # 第二层:收缩 (2048 -> 512)
    nn.Linear(d_ff, d_model)
    )

    def forward(self, x):
    return self.net(x)


    4. 对应第六章:Encoder Layer (组装乐高)

    把上面所有的零件,用 Add & Norm 封装起来,就成了 Encoder 的一层。

    class EncoderLayer(nn.Module):
    def __init__(self, d_model, n_heads, d_ff, dropout=0.1):
    super(EncoderLayer, self).__init__()

    # 两个主要的子层
    self.self_attn = MultiHeadAttention(d_model, n_heads)
    self.feed_forward = FeedForward(d_model, d_ff, dropout)

    # 两个归一化层 (Layer Norm)
    self.norm1 = nn.LayerNorm(d_model)
    self.norm2 = nn.LayerNorm(d_model)

    # Dropout
    self.dropout = nn.Dropout(dropout)

    def forward(self, x, mask):
    # — 子层 1: Self-Attention —
    # 1. 保留残差 (原始输入)
    residual = x

    # 2. 计算 Attention
    x = self.self_attn(x, x, x, mask)

    # 3. Dropout + Add + Norm
    # 注意:这里展示的是 Post-Norm (论文原版),现在的 LLM 多用 Pre-Norm
    x = self.norm1(residual + self.dropout(x))

    # — 子层 2: Feed Forward —
    # 1. 保留残差
    residual = x

    # 2. 计算 FFN
    x = self.feed_forward(x)

    # 3. Dropout + Add + Norm
    x = self.norm2(residual + self.dropout(x))

    return x

    👨‍💻 讲解: 这里的代码结构非常清晰地展示了 “Add & Norm”: x = norm(residual + sub_layer(x))。 这就是让 Transformer 能叠 100 层的秘诀。


    5. 拼装成 Transformer Encoder

    最后,我们用 nn.ModuleList 把 6 个(或 N 个)EncoderLayer 叠在一起。

    class TransformerEncoder(nn.Module):
    def __init__(self, d_model, n_layers, n_heads, d_ff, vocab_size, max_len):
    super(TransformerEncoder, self).__init__()

    # 词嵌入 + 位置编码
    self.embedding = nn.Embedding(vocab_size, d_model)
    self.pos_encoding = PositionalEncoding(d_model, max_len)

    # 堆叠 N 层 EncoderLayer
    self.layers = nn.ModuleList([
    EncoderLayer(d_model, n_heads, d_ff)
    for _ in range(n_layers)
    ])

    self.dropout = nn.Dropout(0.1)

    def forward(self, x, mask):
    # 1. 输入处理
    x = self.embedding(x)
    x = self.pos_encoding(x)
    x = self.dropout(x)

    # 2. 一层一层往下传
    for layer in self.layers:
    x = layer(x, mask)

    return x


    总结

    看完了代码,是不是觉得 Transformer 也没那么可怕? 它本质上就是一堆 Linear 层(矩阵乘法),加上形状变换(view/permute),最后套上归一化(LayerNorm)。

    虽然现在的 GPT-4 等模型在此基础上做了很多微小的修改(比如用 RMSNorm 替代 LayerNorm,用 SwiGLU 替代 ReLU,用 RoPE 替代 Sin/Cos),但骨架依然是你今天亲手拆解的这一副。

    现在,打开你的 IDE,试着把这些代码跑起来吧!


    后记:走出黑盒,看见星辰大海

    当你读到这行字的时候,恭喜你!你已经成功拆解了当今 AI 时代最硬核的引擎——Transformer。

    回过头看,你可能不敢相信,那个现在能写诗、能写代码、能陪你聊天的 ChatGPT,那个号称拥有“人类智慧”的庞然大物,其底层逻辑竟然就是我们刚刚聊完的这几样东西:

    • 几个矩阵乘法(让词与词之间发生化学反应)。
    • 几个残差连接(防止楼盖塌了)。
    • 一个 Softmax(把结果变成概率)。
    • 再加上无数的数据和算力。

    1. 并不神秘的“魔法”

    写这篇博客最大的初衷,就是想打破对 AI 的“迷信”。

    以前我们总觉得,要让机器学会语言,必须教它主谓宾、定状补,教它复杂的语法树。但 Transformer 告诉我们:No,你只需要让它自己去“看”(Attention),看足够多的书,它自己就能涌现出理解力。

    它没有任何一条硬性规则告诉它“it 指代 animal”,它只是通过亿万次的训练,算出这两个词在一起出现的概率最高。

    这是一种暴力美学,也是一种统计学的胜利。

    2. 为什么是 Transformer?

    你可能会问,未来会有模型取代 Transformer 吗? 答案是肯定的。比如最近很火的 Mamba (SSM) 架构就在挑战它的地位。

    但 Transformer 在 AI 历史上的地位就像是蒸汽机。 它之所以伟大,不仅是因为效果好,更是因为它即使粗暴地堆叠,也能并行地运转(记得第一章的抛弃 RNN 吗?)。正是这种架构上的突破,才让后来 GPT-4 这种万亿参数的“怪兽”成为可能。

    它开启了 “Scale is all you need”(规模即一切)的时代。

    3. 你的下一站

    看懂了原理图,只是万里长征第一步。如果你想真正掌握它,我给你三个建议:

  • 手撸代码:不要光看博客。去 GitHub 上找一份 PyTorch 实现 Transformer 的代码(比如哈佛大学NLP组著名的《The Annotated Transformer》)。当你亲手敲下 torch.matmul(q, k.transpose(-2, -1)) 的那一刻,你会有一种触电般的感觉。
  • 玩玩微调:去 Hugging Face 上下载一个 BERT 或 GPT-2,用你自己的数据(比如你的微信聊天记录)微调一下,看看它能不能学会你说话的语气。
  • 保持好奇:AI 领域一天一个样。今天我们学的是 Self-Attention,明天可能就是 Mamba,后天可能就是 Q-Star。架构会变,但**“如何把现实问题转化为数学向量”**的思维方式不会变。
  • 写在最后

    2017 年,8 位 Google 工程师发表《Attention Is All You Need》时,他们可能也没想到,这个本来用于翻译的积木块,会在几年后点燃通用人工智能(AGI)的火种。

    我们正处在一个新时代的黎明。现在,你已经懂得了这台“引擎”的图纸。 接下来,请带上这个工具,去创造你自己的东西吧。

    因为在 AI 的世界里,Attention is all you need,但 Curiosity(好奇心)才是你唯一的边界。


    全文完

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 图解Transformer与PyTorch实现
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!