第4章 Transformer Block

第4章 Transformer Block

本章目标:

理解一个完整的 Transformer Block 的结构,以及 Tensor 的 Shape 是如何在其中变化的。


4.1 一个 Block 的全貌

Transformer 是由多个相同的 Block 堆叠而成的。

原始论文(2017)使用的是 Post-Norm 结构,每个 Block 的结构如下:
#mermaid-svg-V7FvNgZSvg0vSoKX{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-V7FvNgZSvg0vSoKX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-V7FvNgZSvg0vSoKX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-V7FvNgZSvg0vSoKX .error-icon{fill:#552222;}#mermaid-svg-V7FvNgZSvg0vSoKX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-V7FvNgZSvg0vSoKX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-V7FvNgZSvg0vSoKX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-V7FvNgZSvg0vSoKX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-V7FvNgZSvg0vSoKX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-V7FvNgZSvg0vSoKX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-V7FvNgZSvg0vSoKX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-V7FvNgZSvg0vSoKX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-V7FvNgZSvg0vSoKX .marker.cross{stroke:#333333;}#mermaid-svg-V7FvNgZSvg0vSoKX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-V7FvNgZSvg0vSoKX p{margin:0;}#mermaid-svg-V7FvNgZSvg0vSoKX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-V7FvNgZSvg0vSoKX .cluster-label text{fill:#333;}#mermaid-svg-V7FvNgZSvg0vSoKX .cluster-label span{color:#333;}#mermaid-svg-V7FvNgZSvg0vSoKX .cluster-label span p{background-color:transparent;}#mermaid-svg-V7FvNgZSvg0vSoKX .label text,#mermaid-svg-V7FvNgZSvg0vSoKX span{fill:#333;color:#333;}#mermaid-svg-V7FvNgZSvg0vSoKX .node rect,#mermaid-svg-V7FvNgZSvg0vSoKX .node circle,#mermaid-svg-V7FvNgZSvg0vSoKX .node ellipse,#mermaid-svg-V7FvNgZSvg0vSoKX .node polygon,#mermaid-svg-V7FvNgZSvg0vSoKX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-V7FvNgZSvg0vSoKX .rough-node .label text,#mermaid-svg-V7FvNgZSvg0vSoKX .node .label text,#mermaid-svg-V7FvNgZSvg0vSoKX .image-shape .label,#mermaid-svg-V7FvNgZSvg0vSoKX .icon-shape .label{text-anchor:middle;}#mermaid-svg-V7FvNgZSvg0vSoKX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-V7FvNgZSvg0vSoKX .rough-node .label,#mermaid-svg-V7FvNgZSvg0vSoKX .node .label,#mermaid-svg-V7FvNgZSvg0vSoKX .image-shape .label,#mermaid-svg-V7FvNgZSvg0vSoKX .icon-shape .label{text-align:center;}#mermaid-svg-V7FvNgZSvg0vSoKX .node.clickable{cursor:pointer;}#mermaid-svg-V7FvNgZSvg0vSoKX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-V7FvNgZSvg0vSoKX .arrowheadPath{fill:#333333;}#mermaid-svg-V7FvNgZSvg0vSoKX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-V7FvNgZSvg0vSoKX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-V7FvNgZSvg0vSoKX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V7FvNgZSvg0vSoKX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-V7FvNgZSvg0vSoKX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V7FvNgZSvg0vSoKX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-V7FvNgZSvg0vSoKX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-V7FvNgZSvg0vSoKX .cluster text{fill:#333;}#mermaid-svg-V7FvNgZSvg0vSoKX .cluster span{color:#333;}#mermaid-svg-V7FvNgZSvg0vSoKX 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-V7FvNgZSvg0vSoKX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-V7FvNgZSvg0vSoKX rect.text{fill:none;stroke-width:0;}#mermaid-svg-V7FvNgZSvg0vSoKX .icon-shape,#mermaid-svg-V7FvNgZSvg0vSoKX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V7FvNgZSvg0vSoKX .icon-shape p,#mermaid-svg-V7FvNgZSvg0vSoKX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-V7FvNgZSvg0vSoKX .icon-shape .label rect,#mermaid-svg-V7FvNgZSvg0vSoKX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V7FvNgZSvg0vSoKX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-V7FvNgZSvg0vSoKX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-V7FvNgZSvg0vSoKX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入 x

batch, seq, d_model

Multi-Head Self-Attention
残差连接 +
LayerNorm
Feed Forward Network
残差连接 +
LayerNorm
输出

batch, seq, d_model

⚠️ 注意:上图是原始论文的 Post-Norm 结构。现代 LLM(GPT-2、Llama、Qwen)使用 Pre-Norm 结构,区别见 4.4 节。

注意:输入和输出的 Shape 完全相同

这是 Transformer 能堆叠多层的关键。


4.2 Block 的四个组件

组件 作用 章节
Multi-Head Self-Attention 让每个 Token 和所有 Token 交互 第6、7章
Residual(残差连接) 防止梯度消失,保留原始信息 第10章
LayerNorm 稳定训练,加速收敛 第9章
Feed Forward Network 对每个 Token 做非线性变换 第8章

4.3 为什么这样排列?

Block 的排列顺序是:

text 复制代码
Attention → Add & Norm → FFN → Add & Norm

这个顺序不是随意的:

  1. Attention 先:让 Token 先收集全局信息
  2. Add & Norm:稳定 Attention 的输出,防止梯度爆炸
  3. FFN 后:对每个 Token 的表示做进一步变换(引入非线性)
  4. Add & Norm:再次稳定

4.3.1 为什么要两次 Residual + 两次 LayerNorm?

很多人看到 Block 结构会疑惑:为什么不是只在最后做一次 Residual + LayerNorm?

答案在于:一个 Block 做了两件本质不同的事情,每件事完成后都需要独立"提交"结果。

阶段 做什么 类比 为什么需要独立的 Add & Norm
Attention 收集其他Token的信息 开会听取意见 意见可能有错,不能直接覆盖旧认知
FFN 对已有信息独立加工 回家自己思考 推理可能跑偏,不能直接覆盖会议结论

每个阶段的 Residual 含义

  • 第一次 Residual(Attention后):旧认知 + 从别人那里收集的新信息
  • 第二次 Residual(FFN后):收集后的认知 + 自己深入思考的结果

如果只在 Block 最后做一次 Residual:

text 复制代码
❌  H_new = H_old + Attention(H_old) + FFN(...)

那就意味着 FFN 的输入是 Attention 的"裸输出"(未经稳定化),数值可能不稳定,且 Attention 的错误会直接传给 FFN。

两次独立的 Add & Norm 确保:

  1. FFN 收到的是已经稳定化的中间结果
  2. 每个阶段的错误都被 Residual "缓冲"------即使那个阶段失败了,原始信息也不会丢失

4.4 Pre-Norm vs Post-Norm

原始论文使用 Post-Norm (LayerNorm 在残差相加之后):

text 复制代码
Post-Norm:  x → Attention(x) → x + Attention(x) → LayerNorm → ...

现代 LLM(GPT-2、Qwen、Llama)使用 Pre-Norm (LayerNorm 在子层之前):

text 复制代码
Pre-Norm:   x → LayerNorm(x) → Attention(LayerNorm(x)) → x + Attention(LayerNorm(x)) → ...

#mermaid-svg-g6HSgOlZLpenTuEn{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-g6HSgOlZLpenTuEn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-g6HSgOlZLpenTuEn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-g6HSgOlZLpenTuEn .error-icon{fill:#552222;}#mermaid-svg-g6HSgOlZLpenTuEn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-g6HSgOlZLpenTuEn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-g6HSgOlZLpenTuEn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-g6HSgOlZLpenTuEn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-g6HSgOlZLpenTuEn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-g6HSgOlZLpenTuEn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-g6HSgOlZLpenTuEn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-g6HSgOlZLpenTuEn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-g6HSgOlZLpenTuEn .marker.cross{stroke:#333333;}#mermaid-svg-g6HSgOlZLpenTuEn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-g6HSgOlZLpenTuEn p{margin:0;}#mermaid-svg-g6HSgOlZLpenTuEn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-g6HSgOlZLpenTuEn .cluster-label text{fill:#333;}#mermaid-svg-g6HSgOlZLpenTuEn .cluster-label span{color:#333;}#mermaid-svg-g6HSgOlZLpenTuEn .cluster-label span p{background-color:transparent;}#mermaid-svg-g6HSgOlZLpenTuEn .label text,#mermaid-svg-g6HSgOlZLpenTuEn span{fill:#333;color:#333;}#mermaid-svg-g6HSgOlZLpenTuEn .node rect,#mermaid-svg-g6HSgOlZLpenTuEn .node circle,#mermaid-svg-g6HSgOlZLpenTuEn .node ellipse,#mermaid-svg-g6HSgOlZLpenTuEn .node polygon,#mermaid-svg-g6HSgOlZLpenTuEn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-g6HSgOlZLpenTuEn .rough-node .label text,#mermaid-svg-g6HSgOlZLpenTuEn .node .label text,#mermaid-svg-g6HSgOlZLpenTuEn .image-shape .label,#mermaid-svg-g6HSgOlZLpenTuEn .icon-shape .label{text-anchor:middle;}#mermaid-svg-g6HSgOlZLpenTuEn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-g6HSgOlZLpenTuEn .rough-node .label,#mermaid-svg-g6HSgOlZLpenTuEn .node .label,#mermaid-svg-g6HSgOlZLpenTuEn .image-shape .label,#mermaid-svg-g6HSgOlZLpenTuEn .icon-shape .label{text-align:center;}#mermaid-svg-g6HSgOlZLpenTuEn .node.clickable{cursor:pointer;}#mermaid-svg-g6HSgOlZLpenTuEn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-g6HSgOlZLpenTuEn .arrowheadPath{fill:#333333;}#mermaid-svg-g6HSgOlZLpenTuEn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-g6HSgOlZLpenTuEn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-g6HSgOlZLpenTuEn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-g6HSgOlZLpenTuEn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-g6HSgOlZLpenTuEn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-g6HSgOlZLpenTuEn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-g6HSgOlZLpenTuEn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-g6HSgOlZLpenTuEn .cluster text{fill:#333;}#mermaid-svg-g6HSgOlZLpenTuEn .cluster span{color:#333;}#mermaid-svg-g6HSgOlZLpenTuEn 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-g6HSgOlZLpenTuEn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-g6HSgOlZLpenTuEn rect.text{fill:none;stroke-width:0;}#mermaid-svg-g6HSgOlZLpenTuEn .icon-shape,#mermaid-svg-g6HSgOlZLpenTuEn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-g6HSgOlZLpenTuEn .icon-shape p,#mermaid-svg-g6HSgOlZLpenTuEn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-g6HSgOlZLpenTuEn .icon-shape .label rect,#mermaid-svg-g6HSgOlZLpenTuEn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-g6HSgOlZLpenTuEn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-g6HSgOlZLpenTuEn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-g6HSgOlZLpenTuEn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Pre-Norm 现代LLM
x
LayerNorm
Attention
+
输出
Post-Norm 原始论文2017
x
Attention
+
LayerNorm
输出

关键区别:

  • Post-Norm:残差加完之后再归一化。梯度必须"穿过" LayerNorm 才能走捷径。
  • Pre-Norm :残差连接是"干净的" x + F(LayerNorm(x)),梯度可以无阻碍地直接回传。
方案 优点 缺点 使用模型
Post-Norm 原始论文,理论表达能力更优 训练不稳定,必须用 warmup BERT, 原始 Transformer
Pre-Norm 训练稳定,不需要精细的 warmup 理论上表达能力略弱 GPT-2, Llama, Qwen

📌 本书约定:4.1 节展示的是原始论文的 Post-Norm 结构(理解历史)。4.5 节及后续实战代码统一使用 Pre-Norm(对接现代实践)。
💡 Pre-Norm 的一个细节 :由于 Pre-Norm 把 LayerNorm 放在子层之前,最后一个 Block 的输出是未经 Norm 的残差。因此现代 LLM(GPT-2、Llama、Qwen)在所有 Block 结束后、送入 Linear Projection 之前,会额外加一个 LayerNorm(代码中通常叫 model.normln_f)。这确保最终 Hidden State 的数值范围稳定。


4.5 Tensor Shape 的完整流程(Pre-Norm)

batch=2, seq_len=5, d_model=512 为例,这是现代 LLM 使用的 Pre-Norm 结构
#mermaid-svg-SDa5vLyHkJM7qpJU{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-SDa5vLyHkJM7qpJU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-SDa5vLyHkJM7qpJU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-SDa5vLyHkJM7qpJU .error-icon{fill:#552222;}#mermaid-svg-SDa5vLyHkJM7qpJU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-SDa5vLyHkJM7qpJU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-SDa5vLyHkJM7qpJU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-SDa5vLyHkJM7qpJU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-SDa5vLyHkJM7qpJU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-SDa5vLyHkJM7qpJU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-SDa5vLyHkJM7qpJU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-SDa5vLyHkJM7qpJU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-SDa5vLyHkJM7qpJU .marker.cross{stroke:#333333;}#mermaid-svg-SDa5vLyHkJM7qpJU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-SDa5vLyHkJM7qpJU p{margin:0;}#mermaid-svg-SDa5vLyHkJM7qpJU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-SDa5vLyHkJM7qpJU .cluster-label text{fill:#333;}#mermaid-svg-SDa5vLyHkJM7qpJU .cluster-label span{color:#333;}#mermaid-svg-SDa5vLyHkJM7qpJU .cluster-label span p{background-color:transparent;}#mermaid-svg-SDa5vLyHkJM7qpJU .label text,#mermaid-svg-SDa5vLyHkJM7qpJU span{fill:#333;color:#333;}#mermaid-svg-SDa5vLyHkJM7qpJU .node rect,#mermaid-svg-SDa5vLyHkJM7qpJU .node circle,#mermaid-svg-SDa5vLyHkJM7qpJU .node ellipse,#mermaid-svg-SDa5vLyHkJM7qpJU .node polygon,#mermaid-svg-SDa5vLyHkJM7qpJU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-SDa5vLyHkJM7qpJU .rough-node .label text,#mermaid-svg-SDa5vLyHkJM7qpJU .node .label text,#mermaid-svg-SDa5vLyHkJM7qpJU .image-shape .label,#mermaid-svg-SDa5vLyHkJM7qpJU .icon-shape .label{text-anchor:middle;}#mermaid-svg-SDa5vLyHkJM7qpJU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-SDa5vLyHkJM7qpJU .rough-node .label,#mermaid-svg-SDa5vLyHkJM7qpJU .node .label,#mermaid-svg-SDa5vLyHkJM7qpJU .image-shape .label,#mermaid-svg-SDa5vLyHkJM7qpJU .icon-shape .label{text-align:center;}#mermaid-svg-SDa5vLyHkJM7qpJU .node.clickable{cursor:pointer;}#mermaid-svg-SDa5vLyHkJM7qpJU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-SDa5vLyHkJM7qpJU .arrowheadPath{fill:#333333;}#mermaid-svg-SDa5vLyHkJM7qpJU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-SDa5vLyHkJM7qpJU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-SDa5vLyHkJM7qpJU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SDa5vLyHkJM7qpJU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-SDa5vLyHkJM7qpJU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SDa5vLyHkJM7qpJU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-SDa5vLyHkJM7qpJU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-SDa5vLyHkJM7qpJU .cluster text{fill:#333;}#mermaid-svg-SDa5vLyHkJM7qpJU .cluster span{color:#333;}#mermaid-svg-SDa5vLyHkJM7qpJU 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-SDa5vLyHkJM7qpJU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-SDa5vLyHkJM7qpJU rect.text{fill:none;stroke-width:0;}#mermaid-svg-SDa5vLyHkJM7qpJU .icon-shape,#mermaid-svg-SDa5vLyHkJM7qpJU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-SDa5vLyHkJM7qpJU .icon-shape p,#mermaid-svg-SDa5vLyHkJM7qpJU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-SDa5vLyHkJM7qpJU .icon-shape .label rect,#mermaid-svg-SDa5vLyHkJM7qpJU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-SDa5vLyHkJM7qpJU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-SDa5vLyHkJM7qpJU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-SDa5vLyHkJM7qpJU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入

2, 5, 512

LayerNorm

2, 5, 512

Multi-Head Attention

2, 5, 512

残差 +

2, 5, 512

LayerNorm

2, 5, 512

FFN

内部扩展到 2, 5, 2048

再压缩回 2, 5, 512
残差 +

2, 5, 512

输出

2, 5, 512

关键点:整个 Block 的输入输出 Shape 都是 [batch, seq, d_model]


4.6 TensorFlow 实现

python 复制代码
import tensorflow as tf

class TransformerBlock(tf.keras.layers.Layer):
    def __init__(self, d_model, num_heads, dff, dropout_rate=0.1):
        super().__init__()
        self.attention = tf.keras.layers.MultiHeadAttention(
            num_heads=num_heads, key_dim=d_model // num_heads
        )
        self.ffn = tf.keras.Sequential([
            tf.keras.layers.Dense(dff, activation='relu'),
            tf.keras.layers.Dense(d_model)
        ])
        self.norm1 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
        self.norm2 = tf.keras.layers.LayerNormalization(epsilon=1e-6)
        self.dropout1 = tf.keras.layers.Dropout(dropout_rate)
        self.dropout2 = tf.keras.layers.Dropout(dropout_rate)

    def call(self, x, training=False, mask=None):
        # Pre-Norm + Self-Attention + 残差
        attn_output = self.attention(
            self.norm1(x), self.norm1(x), attention_mask=mask
        )
        attn_output = self.dropout1(attn_output, training=training)
        x = x + attn_output  # 残差

        # Pre-Norm + FFN + 残差
        ffn_output = self.ffn(self.norm2(x))
        ffn_output = self.dropout2(ffn_output, training=training)
        x = x + ffn_output  # 残差

        return x

# 测试
block = TransformerBlock(d_model=512, num_heads=8, dff=2048)
x = tf.random.normal([2, 5, 512])
output = block(x)
print(output.shape)  # (2, 5, 512)

4.7 多个 Block 堆叠

python 复制代码
class TransformerEncoder(tf.keras.layers.Layer):
    def __init__(self, num_layers, d_model, num_heads, dff):
        super().__init__()
        self.blocks = [
            TransformerBlock(d_model, num_heads, dff)
            for _ in range(num_layers)
        ]

    def call(self, x, training=False):
        for block in self.blocks:
            x = block(x, training=training)
        return x

encoder = TransformerEncoder(num_layers=6, d_model=512, num_heads=8, dff=2048)
x = tf.random.normal([2, 5, 512])
output = encoder(x)
print(output.shape)  # (2, 5, 512)

4.7.1 每层的参数是独立的

注意上面的代码:for _ in range(num_layers) 创建了 6 个独立的 Block。

这意味着:

text 复制代码
Layer 1:Wq₁, Wk₁, Wv₁, FFN₁  ← 一套独立参数
Layer 2:Wq₂, Wk₂, Wv₂, FFN₂  ← 另一套独立参数
Layer 3:Wq₃, Wk₃, Wv₃, FFN₃  ← 又一套独立参数
...

每一层的 WQW_QWQ、WKW_KWK、WVW_VWV 和 FFN 都是独立训练的,互不共享。

这解释了为什么不同层会学到不同层次的特征

层次 学到的内容 类比
浅层(Layer 1-3) 词法、局部搭配 认识每个字
中层(Layer 4-8) 语法、语义关系 理解句子结构
深层(Layer 9-12) 抽象语义、推理 理解言外之意

如果所有层共享同一套 WQW_QWQ、WKW_KWK、WVW_VWV,那每一层做的事情都一样------相当于同一层重复 6 次,表达能力大幅下降。

💡 这也是为什么 Transformer 越大(层数越多)越强:更多独立的层 = 更多层次的理解。GPT-3 有 96 层 = 96 套独立的 Attention + FFN 参数。


4.8 一层 Block 有多少参数?

以 d_model=512, num_heads=8, dff=2048 为例:

组件 参数 Shape 参数量
Multi-Head Attention W_Q 8个头拼成一个 512, 512 262,144
Multi-Head Attention W_K 同上 512, 512 262,144
Multi-Head Attention W_V 同上 512, 512 262,144
Output Projection W_O 512, 512 262,144
Attention 小计 1,048,576 ≈ 105万
LayerNorm 1 (γ, β) 512 + 512 1,024
FFN W_1 512, 2048 1,048,576
FFN W_2 2048, 512 1,048,576
FFN 小计 2,097,152 ≈ 210万
LayerNorm 2 (γ, β) 512 + 512 1,024
一层 Block 总计 ≈ 315万

整个 Transformer 的参数公式

总参数=vocab_size×dmodel⏟Embedding+M×(Attention+FFN+LayerNorm)⏟M层Block+dmodel×vocab_size⏟输出层LM Head\text{总参数} = \underbrace{\text{vocab\size} \times d{model}}{\text{Embedding}} + \underbrace{M \times (\text{Attention} + \text{FFN} + \text{LayerNorm})}{\text{M层Block}} + \underbrace{d_{model} \times \text{vocab\size}}{\text{输出层LM Head}}总参数=Embedding vocab_size×dmodel+M层Block M×(Attention+FFN+LayerNorm)+输出层LM Head dmodel×vocab_size

以 BERT-Base(vocab=30000, d_model=768, 12层)为例:

text 复制代码
Embedding:     30000 × 768 ≈ 23M
12层Block:     12 × ~7M    ≈ 85M
LM Head:       768 × 30000 ≈ 23M(通常与Embedding共享,不额外计算)
──────────────────────────
总计 ≈ 110M

💡 记忆要点

  • FFN 的参数量约是 Attention 的 2倍(因为 dff = 4 × d_model)
  • 一层 Block 中,FFN 占 2/3 参数,Attention 占 1/3
  • LayerNorm 参数极少,可忽略

Encoder-Only vs Decoder-Only 参数区别

架构 一层包含 参数量对比
Encoder Layer(BERT) Self-Attention + FFN 基准
原始 Decoder Layer(T5) Self-Attention + Cross-Attention + FFN 多了一套 Attention(约+33%)
GPT/Qwen/Llama Decoder Layer Masked Self-Attention + FFN(无Cross-Attention 和 Encoder 一样

📌 现代 GPT/Qwen/Llama 的 Decoder Layer 参数量和 Encoder Layer 基本相同------因为它删掉了 Cross-Attention。它和 Encoder 的唯一区别是 Attention 时有 Causal Mask。


4.9 Hidden State------Block 中真正流动的数据

学完了Block的所有组件后,我们需要回答一个更本质的问题:

Transformer 里面,到底是什么东西在一层一层地流动?

答案不是 Q、K、V,不是 Attention Matrix,甚至不是 Embedding------而是 Hidden State(隐藏状态)

4.9.1 Embedding 只存在于第一层

text 复制代码
Token IDs
   │
Embedding Layer(只执行一次)
   │
   ▼
 H₀  ← 这就是初始 Hidden State
   │
Block 1
   │
   ▼
 H₁  ← 第1层处理后的 Hidden State
   │
Block 2
   │
   ▼
 H₂
   │
 ...
   │
   ▼
 H₁₂ ← 最终 Hidden State(送去预测/分类)

从 Block 1 开始,再也没有 Embedding 了。每一层的输入都是上一层输出的 Hidden State。

4.9.2 Q/K/V 是临时变量,Hidden State 才是持久数据

text 复制代码
每一层的生命周期:

H_i  ──→ 计算 Q, K, V(临时)
            │
            ▼
         Attention(临时)
            │
            ▼
      + Residual + Norm
            │
            ▼
         FFN(临时)
            │
            ▼
      + Residual + Norm
            │
            ▼
H_{i+1}  ──→ 传递给下一层
数据 生命周期 角色
Hidden State 从第0层一直传到最后一层 正式文档(持续更新)
Q, K, V 本层计算完就丢弃 草稿纸(用完即扔)
Attention Matrix 本层计算完就丢弃 中间结果
Context Vector 本层计算完就丢弃 中间结果

精确定义 :Hidden State 在一个 Block 内部经过两次"更新提交"------Attention 后一次、FFN 后一次------但只有 Block 完整结束后的输出才算作正式的 Hi+1H_{i+1}Hi+1:

text 复制代码
H_i(Block输入)
  │
  ├─ Attention → Add → Norm → 中间状态(Intermediate)
  │                              ↓
  └─────────────────── FFN → Add → Norm → H_{i+1}(Block输出)

中间状态(Attention+Norm后、FFN之前)不算独立的一层 Hidden State------它只是 Block 内部正在加工中的数据。

💡 这也解释了为什么每层的 W_Q/W_K/W_V 必须独立(4.7.1节):因为每层接收的 Hidden State 已经不同了------它已经被上一层加工过,携带了更丰富的语义。基于不同的输入,当然需要不同的投影参数来提取有效的 Q/K/V。

4.9.3 重新理解 Transformer:Hidden State 演化系统

如果只用一句话定义 Transformer:

Transformer 是一个不断迭代 Hidden State 的系统。

组件 对 Hidden State 做了什么
Embedding 创建初始 H₀
Attention 让 H 吸收其他 Token 的信息(全局交互)
FFN 让 H 进行内部加工和抽象(独立思考)
Residual 保留旧 H,叠加新信息(增量更新)
LayerNorm 稳定 H 的数值范围(便于下一层处理)
text 复制代码
H₀ ──Attention──→ 吸收上下文 ──FFN──→ 独立思考 ──→ H₁
H₁ ──Attention──→ 更深理解   ──FFN──→ 更深抽象 ──→ H₂
...
H₁₁──Attention──→ 最终理解   ──FFN──→ 最终抽象 ──→ H₁₂

每一层的 Hidden State 都比上一层更接近模型对这句话真正的理解。

📌 后面第11章会展示:不同层的 Hidden State 确实编码了不同层次的特征(浅层=词法,中层=语义,深层=推理)。第14章会讲 Hidden State 还编码了当前语言、角色、任务等信息。

4.9.4 另一种视角:Transformer 在语义空间中移动点

如果把每个 Token 的 Hidden State 想象成高维空间中的一个"点",那么整个 Transformer 可以理解为:

不断把每个 Token 的"语义坐标"移动到越来越准确的位置。

text 复制代码
bank 的 Embedding → 初始坐标(模糊:可能是银行也可能是河岸)
  │
  经过多层 Transformer Block
  │
bank 的最终 Hidden State → 最终坐标(精确:金融银行区域)

从这个视角看,Block中的四个组件就是四种不同的移动方式

组件 移动方式 类比
Attention 参考其他Token的位置,决定自己应该往哪个方向移动 问路:附近的人告诉我怎么走
FFN 根据自身当前位置,做一次内部判断和调整 看地图:结合自己的目标再调整方向
Residual 不要一步跳太远,在旧位置基础上平滑移动 小步走:每次只移动一小段
LayerNorm 保持所有维度的数值在合理范围 校准:防止某个方向走得过远

这个视角解释了为什么:

  • 同一个词在不同上下文中有不同含义:同一个初始坐标,因为周围Token不同(Attention方向不同),最终移动到了不同区域
  • 最后 Linear Projection 能预测下一个词:最终坐标和词表中哪个 Token 的 Embedding 最近,就输出哪个
  • 维度没有固定含义(不是"第1维=语法,第2维=颜色"):是训练自然形成的连续空间,没有人工设计的对应关系

本章总结

一个 Transformer Block = 4 个组件:
#mermaid-svg-Rjtg9bxWlpWfy0OZ{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-Rjtg9bxWlpWfy0OZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .error-icon{fill:#552222;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .marker.cross{stroke:#333333;}#mermaid-svg-Rjtg9bxWlpWfy0OZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Rjtg9bxWlpWfy0OZ p{margin:0;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge{stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section--1 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section--1 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section--1 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section--1 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section--1 text{fill:#ffffff;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth--1{stroke-width:17;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-0 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-0 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-0 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-0 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-0 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-0{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-0{stroke-width:14;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-1 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-1 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-1 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-1 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-1 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-1{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-1{stroke-width:11;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 text{fill:#ffffff;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-2{stroke-width:8;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-3 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-3 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-3 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-3 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-3 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-3{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-3{stroke-width:5;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-4 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-4 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-4 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-4 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-4 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-4{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-4{stroke-width:2;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-5 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-5 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-5 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-5 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-5 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-5{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-5{stroke-width:-1;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-6 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-6 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-6 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-6 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-6 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-6{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-6{stroke-width:-4;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-7 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-7 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-7 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-7 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-7 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-7{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-7{stroke-width:-7;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-8 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-8 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-8 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-8 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-8 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-8{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-8{stroke-width:-10;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-9 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-9 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-9 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-9 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-9 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-9{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-9{stroke-width:-13;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-10 rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-10 path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-10 circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-10 polygon,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-10 text{fill:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .node-icon-10{font-size:40px;color:black;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge-depth-10{stroke-width:-16;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:lightgray;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .disabled text{fill:#efefef;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-root rect,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-root path,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-root circle,#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-root text{fill:#ffffff;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-root span{color:#ffffff;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .section-2 span{color:#ffffff;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .edge{fill:none;}#mermaid-svg-Rjtg9bxWlpWfy0OZ .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-Rjtg9bxWlpWfy0OZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Transformer Block
Multi-Head Attention
让Token互相交流
全局信息聚合
Residual
防止梯度消失
保留原始信息
LayerNorm
稳定训练
加速收敛
Feed Forward
非线性变换
维度扩展再压缩

每个模块的角色区分

模块 做什么 Token之间会交换信息吗? 数学操作类型
Multi-Head Attention 根据相关性从其他Token拉取信息 ✅ 会 矩阵乘法(QK^T, ×V)
Residual Add 保留原始表示,叠加新信息 逐元素加法
LayerNorm 稳定数值分布,便于训练 归一化(减均值除标准差)
Feed Forward 对每个Token独立做非线性变换 矩阵乘法 + 激活函数

💡 记忆要诀 :一个 Block 中,只有 Attention 涉及 Token 之间的信息交换。其他三个模块(Residual、LayerNorm、FFN)都是对每个 Token 独立操作的。

Transformer 中三种数学操作的角色

操作 在 Transformer 中的作用 例子
矩阵乘法 按可学习的规则重新组合、提取特征 Q=XW_Q, Attention×V, FFN
逐元素加法 保留旧信息,叠加新信息(增量修改) x + Attention(x), x + FFN(x)
归一化 调整数值分布到稳定范围 LayerNorm

最重要的一点:Block 的输入输出 Shape 相同,所以可以任意堆叠。


本章思考题

  1. 为什么 Block 的输入输出 Shape 必须相同?
  2. Pre-Norm 和 Post-Norm 在训练稳定性上有什么区别?
  3. 如果去掉残差连接,会发生什么?
  4. 为什么说 Q/K/V 是"临时变量"而 Hidden State 是"持久数据"?如果把上一层的 Q/K/V 直接传给下一层使用(不重新计算),会有什么问题?
  5. FFN 内部为什么要先扩展维度再压缩?

下一章预告

下一章我们讲 Attention 的思想

不用公式,只讲:

  • 为什么会想到 Attention?
  • Attention 解决了什么问题?
  • 为什么叫 Query、Key、Value?
相关推荐
XR1234567881 小时前
高校AI智算中心网络:RoCE优化与一体化交付怎么选
网络·人工智能
老衲の少女心1 小时前
【AI项目】AI辅助小说创作系统:规则引擎与LLM双校验的长文本一致性工程实践
人工智能
9i编程1 小时前
8. AI编写的SKILL,坑我一一试过,这次我自己改写:Beyond Compare逐行CodeReview:Trae写主体,WorkBuddy改bug
人工智能·openai·ai编程
艾伦_耶格宇1 小时前
【AI】-7 从知识库到 AI Agent -进阶
人工智能·知识库·obsidian·opencode·ai运维
千里码aicood1 小时前
基于知识图谱的《平凡的世界》知识问答系统设计与实现
人工智能·知识图谱
tachibana21 小时前
把RAGAS跑起来
数据库·人工智能·ai·架构·大模型·llm·rag
北京晶数信息科技1 小时前
加油机数据采集设备原厂 · OEM 定制 · 五位一体数据采集 · 成品油交易即开票全方案(一)
大数据·人工智能·物联网
AI发掘1 小时前
手写稿被AI检测误标58%?三款AI降重工具实测:只改疑似段,不动原创内容
人工智能·aigc
程序员差不多先生1 小时前
OpenAI 把 Codex Harness 开源:AI Agent 的“操作系统“之争正式开打
人工智能·开源