链接:笔记
05. LLaMA3 Block 教程
模型架构总览
LLaMA3 Decoder Layer 在完整 Transformer 中的位置和内部结构:
#mermaid-svg-UwIQVd0KSPZLCo1p{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-UwIQVd0KSPZLCo1p .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UwIQVd0KSPZLCo1p .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UwIQVd0KSPZLCo1p .error-icon{fill:#552222;}#mermaid-svg-UwIQVd0KSPZLCo1p .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UwIQVd0KSPZLCo1p .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UwIQVd0KSPZLCo1p .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UwIQVd0KSPZLCo1p .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UwIQVd0KSPZLCo1p .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UwIQVd0KSPZLCo1p .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UwIQVd0KSPZLCo1p .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UwIQVd0KSPZLCo1p .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UwIQVd0KSPZLCo1p .marker.cross{stroke:#333333;}#mermaid-svg-UwIQVd0KSPZLCo1p svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UwIQVd0KSPZLCo1p p{margin:0;}#mermaid-svg-UwIQVd0KSPZLCo1p .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UwIQVd0KSPZLCo1p .cluster-label text{fill:#333;}#mermaid-svg-UwIQVd0KSPZLCo1p .cluster-label span{color:#333;}#mermaid-svg-UwIQVd0KSPZLCo1p .cluster-label span p{background-color:transparent;}#mermaid-svg-UwIQVd0KSPZLCo1p .label text,#mermaid-svg-UwIQVd0KSPZLCo1p span{fill:#333;color:#333;}#mermaid-svg-UwIQVd0KSPZLCo1p .node rect,#mermaid-svg-UwIQVd0KSPZLCo1p .node circle,#mermaid-svg-UwIQVd0KSPZLCo1p .node ellipse,#mermaid-svg-UwIQVd0KSPZLCo1p .node polygon,#mermaid-svg-UwIQVd0KSPZLCo1p .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UwIQVd0KSPZLCo1p .rough-node .label text,#mermaid-svg-UwIQVd0KSPZLCo1p .node .label text,#mermaid-svg-UwIQVd0KSPZLCo1p .image-shape .label,#mermaid-svg-UwIQVd0KSPZLCo1p .icon-shape .label{text-anchor:middle;}#mermaid-svg-UwIQVd0KSPZLCo1p .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UwIQVd0KSPZLCo1p .rough-node .label,#mermaid-svg-UwIQVd0KSPZLCo1p .node .label,#mermaid-svg-UwIQVd0KSPZLCo1p .image-shape .label,#mermaid-svg-UwIQVd0KSPZLCo1p .icon-shape .label{text-align:center;}#mermaid-svg-UwIQVd0KSPZLCo1p .node.clickable{cursor:pointer;}#mermaid-svg-UwIQVd0KSPZLCo1p .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UwIQVd0KSPZLCo1p .arrowheadPath{fill:#333333;}#mermaid-svg-UwIQVd0KSPZLCo1p .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UwIQVd0KSPZLCo1p .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UwIQVd0KSPZLCo1p .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UwIQVd0KSPZLCo1p .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UwIQVd0KSPZLCo1p .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UwIQVd0KSPZLCo1p .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UwIQVd0KSPZLCo1p .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UwIQVd0KSPZLCo1p .cluster text{fill:#333;}#mermaid-svg-UwIQVd0KSPZLCo1p .cluster span{color:#333;}#mermaid-svg-UwIQVd0KSPZLCo1p 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-UwIQVd0KSPZLCo1p .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UwIQVd0KSPZLCo1p rect.text{fill:none;stroke-width:0;}#mermaid-svg-UwIQVd0KSPZLCo1p .icon-shape,#mermaid-svg-UwIQVd0KSPZLCo1p .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UwIQVd0KSPZLCo1p .icon-shape p,#mermaid-svg-UwIQVd0KSPZLCo1p .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UwIQVd0KSPZLCo1p .icon-shape .label rect,#mermaid-svg-UwIQVd0KSPZLCo1p .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UwIQVd0KSPZLCo1p .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UwIQVd0KSPZLCo1p .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UwIQVd0KSPZLCo1p :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入 x
(batch, seq_len, hidden_size)
RMSNorm
Attention 前
Multi-Head Attention
GQA + RoPE
残差连接
x + Attention(...)
RMSNorm
MLP 前
SwiGLU MLP
本节重点
残差连接
h + MLP(...)
输出
(batch, seq_len, hidden_size)
结构说明: LLaMA3 使用 Pre-Norm 架构,在 Attention 和 MLP 之前分别进行 RMSNorm,然后通过残差连接与原始输入相加。
Decoder Layer 内部数据流
#mermaid-svg-9pMzRuL9GVEo1kAi{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-9pMzRuL9GVEo1kAi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-9pMzRuL9GVEo1kAi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-9pMzRuL9GVEo1kAi .error-icon{fill:#552222;}#mermaid-svg-9pMzRuL9GVEo1kAi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-9pMzRuL9GVEo1kAi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-9pMzRuL9GVEo1kAi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-9pMzRuL9GVEo1kAi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-9pMzRuL9GVEo1kAi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-9pMzRuL9GVEo1kAi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-9pMzRuL9GVEo1kAi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-9pMzRuL9GVEo1kAi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-9pMzRuL9GVEo1kAi .marker.cross{stroke:#333333;}#mermaid-svg-9pMzRuL9GVEo1kAi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-9pMzRuL9GVEo1kAi p{margin:0;}#mermaid-svg-9pMzRuL9GVEo1kAi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-9pMzRuL9GVEo1kAi .cluster-label text{fill:#333;}#mermaid-svg-9pMzRuL9GVEo1kAi .cluster-label span{color:#333;}#mermaid-svg-9pMzRuL9GVEo1kAi .cluster-label span p{background-color:transparent;}#mermaid-svg-9pMzRuL9GVEo1kAi .label text,#mermaid-svg-9pMzRuL9GVEo1kAi span{fill:#333;color:#333;}#mermaid-svg-9pMzRuL9GVEo1kAi .node rect,#mermaid-svg-9pMzRuL9GVEo1kAi .node circle,#mermaid-svg-9pMzRuL9GVEo1kAi .node ellipse,#mermaid-svg-9pMzRuL9GVEo1kAi .node polygon,#mermaid-svg-9pMzRuL9GVEo1kAi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-9pMzRuL9GVEo1kAi .rough-node .label text,#mermaid-svg-9pMzRuL9GVEo1kAi .node .label text,#mermaid-svg-9pMzRuL9GVEo1kAi .image-shape .label,#mermaid-svg-9pMzRuL9GVEo1kAi .icon-shape .label{text-anchor:middle;}#mermaid-svg-9pMzRuL9GVEo1kAi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-9pMzRuL9GVEo1kAi .rough-node .label,#mermaid-svg-9pMzRuL9GVEo1kAi .node .label,#mermaid-svg-9pMzRuL9GVEo1kAi .image-shape .label,#mermaid-svg-9pMzRuL9GVEo1kAi .icon-shape .label{text-align:center;}#mermaid-svg-9pMzRuL9GVEo1kAi .node.clickable{cursor:pointer;}#mermaid-svg-9pMzRuL9GVEo1kAi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-9pMzRuL9GVEo1kAi .arrowheadPath{fill:#333333;}#mermaid-svg-9pMzRuL9GVEo1kAi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-9pMzRuL9GVEo1kAi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-9pMzRuL9GVEo1kAi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9pMzRuL9GVEo1kAi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-9pMzRuL9GVEo1kAi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9pMzRuL9GVEo1kAi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-9pMzRuL9GVEo1kAi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-9pMzRuL9GVEo1kAi .cluster text{fill:#333;}#mermaid-svg-9pMzRuL9GVEo1kAi .cluster span{color:#333;}#mermaid-svg-9pMzRuL9GVEo1kAi 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-9pMzRuL9GVEo1kAi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-9pMzRuL9GVEo1kAi rect.text{fill:none;stroke-width:0;}#mermaid-svg-9pMzRuL9GVEo1kAi .icon-shape,#mermaid-svg-9pMzRuL9GVEo1kAi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-9pMzRuL9GVEo1kAi .icon-shape p,#mermaid-svg-9pMzRuL9GVEo1kAi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-9pMzRuL9GVEo1kAi .icon-shape .label rect,#mermaid-svg-9pMzRuL9GVEo1kAi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-9pMzRuL9GVEo1kAi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-9pMzRuL9GVEo1kAi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-9pMzRuL9GVEo1kAi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} MLP Block
Attention Block
输入 x
(batch, seq_len, d)
RMSNorm
input_layernorm
GQA Attention
含 RoPE
残差相加
x + attn_out
RMSNorm
post_attention_layernorm
SwiGLU MLP
gate/up/down
残差相加
h + mlp_out
输出
(batch, seq_len, d)
LLaMA3 架构五大创新
#mermaid-svg-caeWDqBAU1dPjTXQ{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-caeWDqBAU1dPjTXQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-caeWDqBAU1dPjTXQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-caeWDqBAU1dPjTXQ .error-icon{fill:#552222;}#mermaid-svg-caeWDqBAU1dPjTXQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-caeWDqBAU1dPjTXQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-caeWDqBAU1dPjTXQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-caeWDqBAU1dPjTXQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-caeWDqBAU1dPjTXQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-caeWDqBAU1dPjTXQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-caeWDqBAU1dPjTXQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-caeWDqBAU1dPjTXQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-caeWDqBAU1dPjTXQ .marker.cross{stroke:#333333;}#mermaid-svg-caeWDqBAU1dPjTXQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-caeWDqBAU1dPjTXQ p{margin:0;}#mermaid-svg-caeWDqBAU1dPjTXQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-caeWDqBAU1dPjTXQ .cluster-label text{fill:#333;}#mermaid-svg-caeWDqBAU1dPjTXQ .cluster-label span{color:#333;}#mermaid-svg-caeWDqBAU1dPjTXQ .cluster-label span p{background-color:transparent;}#mermaid-svg-caeWDqBAU1dPjTXQ .label text,#mermaid-svg-caeWDqBAU1dPjTXQ span{fill:#333;color:#333;}#mermaid-svg-caeWDqBAU1dPjTXQ .node rect,#mermaid-svg-caeWDqBAU1dPjTXQ .node circle,#mermaid-svg-caeWDqBAU1dPjTXQ .node ellipse,#mermaid-svg-caeWDqBAU1dPjTXQ .node polygon,#mermaid-svg-caeWDqBAU1dPjTXQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-caeWDqBAU1dPjTXQ .rough-node .label text,#mermaid-svg-caeWDqBAU1dPjTXQ .node .label text,#mermaid-svg-caeWDqBAU1dPjTXQ .image-shape .label,#mermaid-svg-caeWDqBAU1dPjTXQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-caeWDqBAU1dPjTXQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-caeWDqBAU1dPjTXQ .rough-node .label,#mermaid-svg-caeWDqBAU1dPjTXQ .node .label,#mermaid-svg-caeWDqBAU1dPjTXQ .image-shape .label,#mermaid-svg-caeWDqBAU1dPjTXQ .icon-shape .label{text-align:center;}#mermaid-svg-caeWDqBAU1dPjTXQ .node.clickable{cursor:pointer;}#mermaid-svg-caeWDqBAU1dPjTXQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-caeWDqBAU1dPjTXQ .arrowheadPath{fill:#333333;}#mermaid-svg-caeWDqBAU1dPjTXQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-caeWDqBAU1dPjTXQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-caeWDqBAU1dPjTXQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-caeWDqBAU1dPjTXQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-caeWDqBAU1dPjTXQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-caeWDqBAU1dPjTXQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-caeWDqBAU1dPjTXQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-caeWDqBAU1dPjTXQ .cluster text{fill:#333;}#mermaid-svg-caeWDqBAU1dPjTXQ .cluster span{color:#333;}#mermaid-svg-caeWDqBAU1dPjTXQ 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-caeWDqBAU1dPjTXQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-caeWDqBAU1dPjTXQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-caeWDqBAU1dPjTXQ .icon-shape,#mermaid-svg-caeWDqBAU1dPjTXQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-caeWDqBAU1dPjTXQ .icon-shape p,#mermaid-svg-caeWDqBAU1dPjTXQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-caeWDqBAU1dPjTXQ .icon-shape .label rect,#mermaid-svg-caeWDqBAU1dPjTXQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-caeWDqBAU1dPjTXQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-caeWDqBAU1dPjTXQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-caeWDqBAU1dPjTXQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} LLaMA3 架构创新
Pre-Norm
归一化位置
RMSNorm
简化归一化
SwiGLU
门控激活
RoPE
旋转位置编码
GQA
分组查询注意力
本节讲解的模型架构模块
| 模块 | 章节 | 形状变化 | 核心作用 |
|---|---|---|---|
| 输入张量 | #2.1 | [batch, seq_len, hidden_size] |
Decoder Layer 输入 |
| Attention RMSNorm | #2.1 | [batch, seq_len, hidden_size] |
归一化 Attention 输入 |
| GQA Attention | #2.1 | [batch, seq_len, hidden_size] → [batch, seq_len, hidden_size] |
多头注意力 + RoPE |
| Attention 残差 | #2.1 | x + attn_out |
保持梯度流动 |
| MLP RMSNorm | #2.1 | [batch, seq_len, hidden_size] |
归一化 MLP 输入 |
| SwiGLU MLP | #2.1 | [batch, seq_len, hidden_size] → [batch, seq_len, hidden_size] |
门控前馈网络 |
| MLP 残差 | #2.1 | h + mlp_out |
保持梯度流动 |
数据流详解(含具体数值)
#mermaid-svg-7AnceSLb6FVI5W1j{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-7AnceSLb6FVI5W1j .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7AnceSLb6FVI5W1j .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7AnceSLb6FVI5W1j .error-icon{fill:#552222;}#mermaid-svg-7AnceSLb6FVI5W1j .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7AnceSLb6FVI5W1j .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7AnceSLb6FVI5W1j .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7AnceSLb6FVI5W1j .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7AnceSLb6FVI5W1j .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7AnceSLb6FVI5W1j .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7AnceSLb6FVI5W1j .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7AnceSLb6FVI5W1j .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7AnceSLb6FVI5W1j .marker.cross{stroke:#333333;}#mermaid-svg-7AnceSLb6FVI5W1j svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7AnceSLb6FVI5W1j p{margin:0;}#mermaid-svg-7AnceSLb6FVI5W1j .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-7AnceSLb6FVI5W1j .cluster-label text{fill:#333;}#mermaid-svg-7AnceSLb6FVI5W1j .cluster-label span{color:#333;}#mermaid-svg-7AnceSLb6FVI5W1j .cluster-label span p{background-color:transparent;}#mermaid-svg-7AnceSLb6FVI5W1j .label text,#mermaid-svg-7AnceSLb6FVI5W1j span{fill:#333;color:#333;}#mermaid-svg-7AnceSLb6FVI5W1j .node rect,#mermaid-svg-7AnceSLb6FVI5W1j .node circle,#mermaid-svg-7AnceSLb6FVI5W1j .node ellipse,#mermaid-svg-7AnceSLb6FVI5W1j .node polygon,#mermaid-svg-7AnceSLb6FVI5W1j .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-7AnceSLb6FVI5W1j .rough-node .label text,#mermaid-svg-7AnceSLb6FVI5W1j .node .label text,#mermaid-svg-7AnceSLb6FVI5W1j .image-shape .label,#mermaid-svg-7AnceSLb6FVI5W1j .icon-shape .label{text-anchor:middle;}#mermaid-svg-7AnceSLb6FVI5W1j .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-7AnceSLb6FVI5W1j .rough-node .label,#mermaid-svg-7AnceSLb6FVI5W1j .node .label,#mermaid-svg-7AnceSLb6FVI5W1j .image-shape .label,#mermaid-svg-7AnceSLb6FVI5W1j .icon-shape .label{text-align:center;}#mermaid-svg-7AnceSLb6FVI5W1j .node.clickable{cursor:pointer;}#mermaid-svg-7AnceSLb6FVI5W1j .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-7AnceSLb6FVI5W1j .arrowheadPath{fill:#333333;}#mermaid-svg-7AnceSLb6FVI5W1j .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-7AnceSLb6FVI5W1j .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-7AnceSLb6FVI5W1j .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7AnceSLb6FVI5W1j .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-7AnceSLb6FVI5W1j .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7AnceSLb6FVI5W1j .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-7AnceSLb6FVI5W1j .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-7AnceSLb6FVI5W1j .cluster text{fill:#333;}#mermaid-svg-7AnceSLb6FVI5W1j .cluster span{color:#333;}#mermaid-svg-7AnceSLb6FVI5W1j 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-7AnceSLb6FVI5W1j .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-7AnceSLb6FVI5W1j rect.text{fill:none;stroke-width:0;}#mermaid-svg-7AnceSLb6FVI5W1j .icon-shape,#mermaid-svg-7AnceSLb6FVI5W1j .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-7AnceSLb6FVI5W1j .icon-shape p,#mermaid-svg-7AnceSLb6FVI5W1j .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-7AnceSLb6FVI5W1j .icon-shape .label rect,#mermaid-svg-7AnceSLb6FVI5W1j .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-7AnceSLb6FVI5W1j .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-7AnceSLb6FVI5W1j .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-7AnceSLb6FVI5W1j :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Step 6: 残差连接
h + mlp_out
(2, 16, 4096)
Step 5: SwiGLU MLP
gate_up_proj + down_proj
(2, 16, 4096)
Step 4: MLP 前置归一化
RMSNorm
(2, 16, 4096)
Step 3: 残差连接
x + attn_out
(2, 16, 4096)
Step 2: GQA Attention
Q/K/V 投影 + RoPE
(2, 16, 4096)
Step 1: Attention 前置归一化
RMSNorm
(2, 16, 4096)
输入 x
(2, 16, 4096)
输出
(2, 16, 4096)
0. 学习本章前先认识这些名词
LLaMA3 Block 是将前面学过的 RMSNorm、SwiGLU、RoPE 和 GQA 组装成完整 Decoder Layer,需要先理解 Pre-Norm 和残差连接这两个关键概念。
0.1 基础架构
| 名词 | 英文 | 简单理解 | 在 LLaMA3 中的作用 |
|---|---|---|---|
| Transformer Block | Transformer Block | 模型的基本重复单元 | LLaMA3 由多个 Block 堆叠 |
| Decoder Layer | Decoder Layer | 仅用 Masked Attention 的 Block | LLaMA3 的标准层 |
| Pre-Norm | Pre-Norm | 在子层之前进行归一化 | LLaMA3 的稳定训练关键 |
| Post-Norm | Post-Norm | 在子层之后进行归一化 | 早期 Transformer 使用 |
必须先懂: 残差连接的基本概念(y = x + f(x))。
0.2 LLaMA3 核心组件回顾
| 组件 | 来源章节 | 核心作用 | 关键代码 |
|---|---|---|---|
| RMSNorm | 01_RMSNorm | 归一化层(无偏置) | x_norm = x / RMS(x) * w |
| SwiGLU | 02_SwiGLU | 门控激活函数 | SiLU(gate) * up |
| RoPE | 03_RoPE | 旋转位置编码 | x * e^(imθ) |
| GQA | 04_Attention | 分组查询注意力 | repeat_kv 扩充 KV 头 |
必须先懂: 前面 4 个组件的基本实现。
0.3 残差连接
| 名词 | 说明 | 公式 |
|---|---|---|
| 残差连接 | 将子层输入与输出相加 | output = x + SubLayer(x) |
| 梯度高速公路 | 梯度可以直接流回浅层 | ∂L/∂x = ∂L/∂output + ... |
| 恒等映射 | 初始化时子层近似恒等 | 便于训练深层网络 |
必须先懂: 为什么残差连接能缓解梯度消失。
0.4 LLaMA 系列对比
| 模型 | 归一化 | 激活函数 | 位置编码 | 注意力机制 | 特殊配置 |
|---|---|---|---|---|---|
| LLaMA-1 | RMSNorm | SwiGLU | RoPE | MHA | - |
| LLaMA-2 | RMSNorm | SwiGLU | RoPE | GQA | 8B: 32Q/8KV, 70B: 64Q/8KV |
| LLaMA-3 | RMSNorm | SwiGLU | RoPE | GQA | 同上 + 更大词表 |
0.5 推荐学习顺序
text
第一步:理解 Pre-Norm 和残差连接
↓
第二步:回顾 RMSNorm 和 SwiGLU 的实现
↓
第三步:理解 Decoder Layer 的前向流程
↓
第四步:动手组装 LlamaMLP 和 LlamaDecoderLayer
↓
第五步:测试并验证计算图连通性
1. LLaMA3 架构概览
1.1 五大核心创新
LLaMA 系列在标准 Transformer 基础上做了 5 项关键改进:
1.1.1 Pre-Norm(归一化位置)
Post-Norm(早期 Transformer):
text
x → Attention → Add & Norm → MLP → Add & Norm
Pre-Norm(LLaMA):
text
x → Norm → Attention → Add → Norm → MLP → Add
为什么 Pre-Norm 更好?
- Post-Norm 在深层网络中容易出现梯度爆炸
- Pre-Norm 使每个子层的输入都是归一化的,梯度更稳定
- 支持更深的网络(LLaMA-3 80 层)
1.1.2 RMSNorm(归一化算法)
标准 LayerNorm:
LayerNorm ( x ) = γ ⋅ x − μ σ 2 + ϵ + β \text{LayerNorm}(x) = \gamma \cdot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta LayerNorm(x)=γ⋅σ2+ϵ x−μ+β
RMSNorm(LLaMA):
RMSNorm ( x ) = γ ⋅ x mean ( x 2 ) + ϵ \text{RMSNorm}(x) = \gamma \cdot \frac{x}{\sqrt{\text{mean}(x^2) + \epsilon}} RMSNorm(x)=γ⋅mean(x2)+ϵ x
改进:
- 去除均值计算( μ \mu μ),减少同步开销
- 去除偏置项( β \beta β),参数更少
- 速度提升约 10-15%
1.1.3 SwiGLU(激活函数)
标准 MLP:
text
x → Linear(4d) → GELU → Linear(d) → output
SwiGLU MLP(LLaMA):
text
x → [gate: Linear(d→h), up: Linear(d→h)] → SiLU(gate) * up → Linear(h→d) → output
改进:
- 门控机制带来更强的表达能力
- 参数量对齐: 3 d h 3dh 3dh vs 2 d h 2dh 2dh,调整 h = 8 3 d h = \frac{8}{3}d h=38d
1.1.4 RoPE(位置编码)
- 放弃绝对位置编码
- 使用复数旋转让 Q/K 天然携带相对位置信息
- 支持长度外推
1.1.5 GQA(注意力机制)
- 从 LLaMA-2 开始引入
- Query 头数 > KV 头数(如 32:8)
- KV Cache 减少 4 倍,效果损失极小
1.2 完整 Decoder Layer 公式
Attention Block:
h = x + Attention ( RMSNorm ( x ) ) h = x + \text{Attention}(\text{RMSNorm}(x)) h=x+Attention(RMSNorm(x))
MLP Block:
out = h + MLP ( RMSNorm ( h ) ) \text{out} = h + \text{MLP}(\text{RMSNorm}(h)) out=h+MLP(RMSNorm(h))
其中:
- Attention 内部包含 RoPE 旋转(作用于 Q/K 投影后)
- MLP 使用 SwiGLU 门控机制
2. 核心公式与架构
2.1 Decoder Layer 结构
text
输入 x: [batch, seq_len, hidden_size]
┌─────────────────────────────────────┐
│ Attention Block │
│ 1. input_layernorm(x) │
│ 2. self_attn(normed_x) │
│ 3. x + attn_out │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ MLP Block │
│ 1. post_attention_layernorm(h) │
│ 2. mlp(normed_h) │
│ 3. h + mlp_out │
└─────────────────────────────────────┘
↓
输出
2.2 SwiGLU MLP 公式
SwiGLU ( x ) = ( SiLU ( x W gate ) ⊙ ( x W up ) ) W down \text{SwiGLU}(x) = (\text{SiLU}(x W_{\text{gate}}) \odot (x W_{\text{up}})) W_{\text{down}} SwiGLU(x)=(SiLU(xWgate)⊙(xWup))Wdown
其中:
- W gate , W up ∈ R d × h W_{\text{gate}}, W_{\text{up}} \in \mathbb{R}^{d \times h} Wgate,Wup∈Rd×h:升维投影
- W down ∈ R h × d W_{\text{down}} \in \mathbb{R}^{h \times d} Wdown∈Rh×d:降维投影
- SiLU ( z ) = z ⋅ σ ( z ) \text{SiLU}(z) = z \cdot \sigma(z) SiLU(z)=z⋅σ(z)
- ⊙ \odot ⊙:逐元素相乘
中间层维度:
h = 8 3 d ≈ 2.67 d h = \frac{8}{3}d \approx 2.67d h=38d≈2.67d
对齐传统 MLP( h = 4 d h=4d h=4d)的参数量:
- 传统 MLP: 2 × d × 4 d = 8 d 2 2 \times d \times 4d = 8d^2 2×d×4d=8d2
- SwiGLU: 3 × d × 8 3 d = 8 d 2 3 \times d \times \frac{8}{3}d = 8d^2 3×d×38d=8d2
2.3 参数量对比(以 LLaMA-7B 为例)
| 组件 | 参数量 |
|---|---|
| Embedding | 4096 × 128256 ≈ 524M |
| 32 × Decoder Layer | 约 6.5B |
| LM Head | 4096 × 128256 ≈ 524M |
| 总计 | 约 7B |
3. 动手实战
3.1 任务要求
请补全 LlamaMLP 和 LlamaDecoderLayer 的实现。
python
import torch
import torch.nn as nn
import torch.nn.functional as F
# ---------------------------------------------------------
# 占位组件(实际项目中替换为真实实现)
# ---------------------------------------------------------
class DummyRMSNorm(nn.Module):
"""占位 RMSNorm,仅用于验证结构"""
def __init__(self, dim):
super().__init__()
self.w = nn.Parameter(torch.ones(dim))
def forward(self, x):
return x * self.w
class DummyAttention(nn.Module):
"""占位 Attention,仅用于验证结构"""
def __init__(self, dim):
super().__init__()
self.proj = nn.Linear(dim, dim)
def forward(self, x):
return self.proj(x)
# ---------------------------------------------------------
# TODO 实现区
# ---------------------------------------------------------
class LlamaMLP(nn.Module):
def __init__(self, hidden_size: int, intermediate_size: int):
super().__init__()
# ==========================================
# TODO 1: 定义 SwiGLU 的三个线性层(无 bias)
# 提示: gate_proj / up_proj 映射到 intermediate_size
# down_proj 映射回 hidden_size
# ==========================================
raise NotImplementedError("请先完成 TODO 部分的代码!")
def forward(self, x: torch.Tensor) -> torch.Tensor:
# ==========================================
# TODO 2: 实现 SwiGLU 前向传播
# 提示: SiLU(gate) * up,然后 down_proj
# ==========================================
raise NotImplementedError("请先完成 TODO 部分的代码!")
class LlamaDecoderLayer(nn.Module):
def __init__(self, hidden_size: int, intermediate_size: int):
super().__init__()
self.hidden_size = hidden_size
# Attention 部分
self.input_layernorm = DummyRMSNorm(hidden_size)
self.self_attn = DummyAttention(hidden_size)
# MLP 部分
self.post_attention_layernorm = DummyRMSNorm(hidden_size)
self.mlp = LlamaMLP(hidden_size, intermediate_size)
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
"""
Args:
hidden_states: [batch, seq_len, hidden_size]
Returns:
output: [batch, seq_len, hidden_size]
"""
# ==========================================
# TODO 3: 实现 Pre-Norm 残差连接
# 提示: Attention Block → MLP Block
# ==========================================
raise NotImplementedError("请先完成 TODO 部分的代码!")
3.2 测试代码
python
def test_llama_block():
try:
batch_size, seq_len, hidden_size = 2, 16, 512
# LLaMA 风格中间层维度
intermediate_size = 1376
layer = LlamaDecoderLayer(hidden_size, intermediate_size)
x = torch.randn(batch_size, seq_len, hidden_size)
out = layer(x)
# 检查 1: 输出形状
assert out.shape == (batch_size, seq_len, hidden_size), "输出形状错误!"
# 检查 2: 计算图连通性(所有参数都有梯度)
out.sum().backward()
for name, param in layer.named_parameters():
assert param.grad is not None, f"参数 {name} 没有梯度!"
print("\n✅ All Tests Passed! LLaMA-3 Decoder Layer 组装完成!")
except NotImplementedError:
print("请先完成 TODO 部分的代码!")
raise
test_llama_block()
4. 参考代码与解析
4.1 完整实现
python
class LlamaMLP(nn.Module):
def __init__(self, hidden_size: int, intermediate_size: int):
super().__init__()
# SwiGLU 的三个线性层
self.gate_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
self.up_proj = nn.Linear(hidden_size, intermediate_size, bias=False)
self.down_proj = nn.Linear(intermediate_size, hidden_size, bias=False)
def forward(self, x: torch.Tensor) -> torch.Tensor:
# SwiGLU: SiLU(gate) * up → down_proj
return self.down_proj(F.silu(self.gate_proj(x)) * self.up_proj(x))
class LlamaDecoderLayer(nn.Module):
def __init__(self, hidden_size: int, intermediate_size: int):
super().__init__()
self.hidden_size = hidden_size
# Pre-Norm + Attention
self.input_layernorm = DummyRMSNorm(hidden_size)
self.self_attn = DummyAttention(hidden_size)
# Pre-Norm + MLP
self.post_attention_layernorm = DummyRMSNorm(hidden_size)
self.mlp = LlamaMLP(hidden_size, intermediate_size)
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
# Attention Block(Pre-Norm + 残差)
residual = hidden_states
hidden_states = self.input_layernorm(hidden_states)
hidden_states = self.self_attn(hidden_states)
hidden_states = residual + hidden_states
# MLP Block(Pre-Norm + 残差)
residual = hidden_states
hidden_states = self.post_attention_layernorm(hidden_states)
hidden_states = self.mlp(hidden_states)
hidden_states = residual + hidden_states
return hidden_states
4.2 答案与直觉
TODO 1:SwiGLU 的三个线性层
这一题要解决什么: 定义 SwiGLU 所需的投影矩阵。
为什么是三个:
gate_proj:生成门控信号up_proj:生成被门控的信息down_proj:降维回原始维度
为什么 bias=False:
- LLaMA 标准配置,减少参数量
- 在大规模模型中,偏置项作用相对较小
TODO 2:SwiGLU 前向传播
这一题要解决什么: 按公式组装 SwiGLU 计算。
计算流程:
text
x: [batch, seq_len, hidden_size]
↓ gate_proj, up_proj
gate, up: [batch, seq_len, intermediate_size]
↓ SiLU(gate) * up
gated: [batch, seq_len, intermediate_size]
↓ down_proj
output: [batch, seq_len, hidden_size]
TODO 3:Pre-Norm 残差连接
这一题要解决什么: 实现 LLaMA 的 Pre-Norm 残差结构。
核心模式:
python
# 每个 Block 都遵循相同的模式
residual = x # 1. 保存残差
x = norm(x) # 2. 归一化
x = sublayer(x) # 3. 子层计算
x = residual + x # 4. 残差相加
为什么 Pre-Norm 更稳定:
- 每个子层的输入都是归一化的,梯度更稳定
- 残差提供"梯度高速公路",缓解梯度消失
- 支持训练更深的网络(80+ 层)
带走的直觉
- Pre-Norm + Residual 是 LLaMA 稳定训练的关键:顺序不能随意交换
- SwiGLU 的 gate/up/down 缺一不可:少了任何一个都会破坏门控机制
- Decoder Layer 是一个"归一化 → 变换 → 残差"的流水线:理解这个模式,看任何基于 LLaMA 的模型都能快速定位结构
- 计算图连通性是基本检查:反向传播能到达所有参数,说明前向传播连接正确