datawhale--llm-algo-leetcode5️⃣

链接:笔记

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 任务要求

请补全 LlamaMLPLlamaDecoderLayer 的实现。

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 的模型都能快速定位结构
  • 计算图连通性是基本检查:反向传播能到达所有参数,说明前向传播连接正确
相关推荐
λqaq71 小时前
MySQL 数据库基础(2)约束、用户权限、远程连接、外键与 TCP/UDP 理解
linux·数据库·python·tcp/ip·mysql
人工干智能1 小时前
科普:pandas 时间偏移别名:ts.resample(“5Min“).sum()
python·pandas
开源量化GO1 小时前
最新AI辅助量化表达:先理清规则,再按需求选工具
人工智能·python
Zane19941 小时前
为什么 del 一个对象有时立刻消失,有时却纹丝不动?一文讲透引用计数与垃圾回收
后端·python
yichudu2 小时前
Python 装饰器 decorator
开发语言·python
一晌小贪欢2 小时前
Python办公14:批量解压文件夹内的所有 ZIP/RAR 并自动分类
开发语言·python·excel·数据可视化·python办公
Python 实战手记2 小时前
企业微信主体变更公证书办理全解析:适用场景、材料规范、踩坑点与Python信息校验脚本
开发语言·python·企业微信
郝学胜_神的一滴2 小时前
Effective Python 条款 2:遵循 PEP 8 编码风格,写出高质量 Python 代码
python·算法
郝学胜-神的一滴2 小时前
Effective Python 条款 1:确认你正在使用的 Python 版本
开发语言·数据结构·python·程序人生·算法