第8章 Feed Forward Network
本章目标:
理解 FFN 在 Transformer Block 中的作用,以及为什么维度要扩大四倍,GELU/SwiGLU 的原理。
8.1 如果没有 FFN 会怎样?
在进入 FFN 的结构之前,我们先问一个关键问题:如果 Transformer Block 只有 Attention,没有 FFN,会发生什么?
假设一句话:
text
The bank approved my loan.
Attention 工作以后,bank 去查看所有 Token,算出注意力权重:
text
The 5%
approved 40%
loan 55%
于是 bank 的新向量变成了:
text
bank_new = 0.05×The + 0.40×approved + 0.55×loan
请问:bank 现在理解自己的含义了吗?
没有。
因为 Attention 只做了一件事:把别人的信息拿过来。它没有对收集到的信息进行任何"加工"或"推理"。
一个生活中的类比
假设你准备买房,于是问了三个朋友:
- 朋友 A:"位置很好"
- 朋友 B:"学区不错"
- 朋友 C:"价格偏贵"
这就是 Attention 干的事------收集意见。
但收集完意见之后,你做出决定了吗?当然没有。你还需要自己思考:综合位置、学区、价格,结合自己的预算和需求,形成判断。
FFN 就是那个"自己思考"的环节。
text
Attention = 和别人聊天,收集信息
FFN = 回家自己思考,形成判断
所以 FFN 更准确的名字应该叫 Per-Token Thinker(每个 Token 的独立思考器)。
8.2 FFN 的结构
理解了 FFN 的定位,再来看它的数学形式就很自然了:
FFN(x)=Activation(xW1+b1)W2+b2\text{FFN}(x) = \text{Activation}(x W_1 + b_1) W_2 + b_2FFN(x)=Activation(xW1+b1)W2+b2
#mermaid-svg-ijBlFxdJMEi3u9Rk{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-ijBlFxdJMEi3u9Rk .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ijBlFxdJMEi3u9Rk .error-icon{fill:#552222;}#mermaid-svg-ijBlFxdJMEi3u9Rk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ijBlFxdJMEi3u9Rk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .marker.cross{stroke:#333333;}#mermaid-svg-ijBlFxdJMEi3u9Rk svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ijBlFxdJMEi3u9Rk p{margin:0;}#mermaid-svg-ijBlFxdJMEi3u9Rk .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .cluster-label text{fill:#333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .cluster-label span{color:#333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .cluster-label span p{background-color:transparent;}#mermaid-svg-ijBlFxdJMEi3u9Rk .label text,#mermaid-svg-ijBlFxdJMEi3u9Rk span{fill:#333;color:#333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .node rect,#mermaid-svg-ijBlFxdJMEi3u9Rk .node circle,#mermaid-svg-ijBlFxdJMEi3u9Rk .node ellipse,#mermaid-svg-ijBlFxdJMEi3u9Rk .node polygon,#mermaid-svg-ijBlFxdJMEi3u9Rk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ijBlFxdJMEi3u9Rk .rough-node .label text,#mermaid-svg-ijBlFxdJMEi3u9Rk .node .label text,#mermaid-svg-ijBlFxdJMEi3u9Rk .image-shape .label,#mermaid-svg-ijBlFxdJMEi3u9Rk .icon-shape .label{text-anchor:middle;}#mermaid-svg-ijBlFxdJMEi3u9Rk .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ijBlFxdJMEi3u9Rk .rough-node .label,#mermaid-svg-ijBlFxdJMEi3u9Rk .node .label,#mermaid-svg-ijBlFxdJMEi3u9Rk .image-shape .label,#mermaid-svg-ijBlFxdJMEi3u9Rk .icon-shape .label{text-align:center;}#mermaid-svg-ijBlFxdJMEi3u9Rk .node.clickable{cursor:pointer;}#mermaid-svg-ijBlFxdJMEi3u9Rk .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .arrowheadPath{fill:#333333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ijBlFxdJMEi3u9Rk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ijBlFxdJMEi3u9Rk .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ijBlFxdJMEi3u9Rk .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ijBlFxdJMEi3u9Rk .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ijBlFxdJMEi3u9Rk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ijBlFxdJMEi3u9Rk .cluster text{fill:#333;}#mermaid-svg-ijBlFxdJMEi3u9Rk .cluster span{color:#333;}#mermaid-svg-ijBlFxdJMEi3u9Rk 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-ijBlFxdJMEi3u9Rk .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ijBlFxdJMEi3u9Rk rect.text{fill:none;stroke-width:0;}#mermaid-svg-ijBlFxdJMEi3u9Rk .icon-shape,#mermaid-svg-ijBlFxdJMEi3u9Rk .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ijBlFxdJMEi3u9Rk .icon-shape p,#mermaid-svg-ijBlFxdJMEi3u9Rk .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ijBlFxdJMEi3u9Rk .icon-shape .label rect,#mermaid-svg-ijBlFxdJMEi3u9Rk .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ijBlFxdJMEi3u9Rk .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ijBlFxdJMEi3u9Rk .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ijBlFxdJMEi3u9Rk :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入
batch, seq, d_model
例: 2, 5, 512
Linear W_1
d_model, dff
512, 2048
Activation
GELU/ReLU
Linear W_2
dff, d_model
2048, 512
输出
batch, seq, d_model
例: 2, 5, 512
关键参数:
d_model:输入/输出维度(如 512)dff:中间层维度(如 2048,通常是 d_model 的 4 倍)
其中 W1:dmodel,dffW_1: d_{model}, d_{ff}W1:dmodel,dff、b1:dffb_1: d_{ff}b1:dff、W2:dff,dmodelW_2: d_{ff}, d_{model}W2:dff,dmodel、b2:dmodelb_2: d_{model}b2:dmodel 全部是通过反向传播训练出来的可学习参数 ------和 Attention 中的 WQW_QWQ、WKW_KWK、WVW_VWV、WOW_OWO 一样,它们在训练过程中不断更新,学习如何对 Token 进行最有效的非线性变换。
注意:FFN 对每个 Token 独立计算,Token 之间互不干扰 。这和 Attention 完全不同------Attention 是 Token 之间的交流,FFN 是每个 Token 的内部加工。同一层内所有 Token 共享同一套 W1W_1W1、W2W_2W2(参数共享),但不同层的 FFN 参数是完全独立的 ------第 1 层有自己的 W1(1)W_1^{(1)}W1(1)、W2(1)W_2^{(1)}W2(1),第 2 层有自己的 W1(2)W_1^{(2)}W1(2)、W2(2)W_2^{(2)}W2(2),互不共享。这使得不同层的 FFN 可以学习不同层次的知识和变换模式。
8.3 为什么需要 FFN?
继续 bank 的例子。
Attention 之后,bank_new 里已经融合了 loan 和 approved 的信息。但 Transformer 还不知道"哦,这是金融银行!"------因为 Attention 只做融合,不做推理。
FFN 收到 bank_new 后,开始"思考"。它内部可能学到了这样的模式:
text
如果:loan 信息很强 + approved 信息很强
那么:bank → 金融银行(而不是河岸)
于是输出一个更精确的语义向量------bank 从"可能是银行也可能是河岸"变成了"确定是金融银行"。
这是第一次真正发生"语义加工"。
| 组件 | 做什么 | 类比 | Token 之间交互? |
|---|---|---|---|
| Self-Attention | 收集其他 Token 的信息 | 开会讨论 | ✅ |
| FFN | 对收集到的信息独立加工 | 回家自己整理笔记 | ❌ |
💡 为什么 FFN 是独立计算而不是再次全局交互? 因为 Attention 已经把需要的信息收集完了。就像开会时你已经听到了所有人的意见,回家整理笔记时不需要再打电话给同事------你需要的是安静思考,不是继续收集信息。
8.4 为什么维度扩大四倍?
原始论文中 dff = 4 × d_model(512 → 2048)。
这也可以用"思考过程"来类比。
当别人告诉你"苹果发布新手机"时,你的脑子里不会只有"苹果"两个字。你会联想到:
text
iPhone → 发布会 → Tim Cook → 股价 → Apple Store → AI ...
这就是展开(Expansion)------大脑需要一个比输入更大的"思考空间",才能充分处理信息。
FFN 的三步过程:
| 步骤 | 维度变化 | 做什么 | 类比 |
|---|---|---|---|
| 第一层 W1W_1W1 | 512 → 2048 | 展开到更大空间 | 把文件夹的纸全部摊开,联想更多内容 |
| 激活函数 | 2048 → 2048 | 非线性变换 | 做出判断:哪些联想有用,哪些要丢弃 |
| 第二层 W2W_2W2 | 2048 → 512 | 压缩回原始维度 | 整理总结,形成最终观点 |
#mermaid-svg-UxbLihXPkECPMe0I{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-UxbLihXPkECPMe0I .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UxbLihXPkECPMe0I .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UxbLihXPkECPMe0I .error-icon{fill:#552222;}#mermaid-svg-UxbLihXPkECPMe0I .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UxbLihXPkECPMe0I .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UxbLihXPkECPMe0I .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UxbLihXPkECPMe0I .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UxbLihXPkECPMe0I .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UxbLihXPkECPMe0I .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UxbLihXPkECPMe0I .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UxbLihXPkECPMe0I .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UxbLihXPkECPMe0I .marker.cross{stroke:#333333;}#mermaid-svg-UxbLihXPkECPMe0I svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UxbLihXPkECPMe0I p{margin:0;}#mermaid-svg-UxbLihXPkECPMe0I .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-UxbLihXPkECPMe0I .cluster-label text{fill:#333;}#mermaid-svg-UxbLihXPkECPMe0I .cluster-label span{color:#333;}#mermaid-svg-UxbLihXPkECPMe0I .cluster-label span p{background-color:transparent;}#mermaid-svg-UxbLihXPkECPMe0I .label text,#mermaid-svg-UxbLihXPkECPMe0I span{fill:#333;color:#333;}#mermaid-svg-UxbLihXPkECPMe0I .node rect,#mermaid-svg-UxbLihXPkECPMe0I .node circle,#mermaid-svg-UxbLihXPkECPMe0I .node ellipse,#mermaid-svg-UxbLihXPkECPMe0I .node polygon,#mermaid-svg-UxbLihXPkECPMe0I .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-UxbLihXPkECPMe0I .rough-node .label text,#mermaid-svg-UxbLihXPkECPMe0I .node .label text,#mermaid-svg-UxbLihXPkECPMe0I .image-shape .label,#mermaid-svg-UxbLihXPkECPMe0I .icon-shape .label{text-anchor:middle;}#mermaid-svg-UxbLihXPkECPMe0I .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-UxbLihXPkECPMe0I .rough-node .label,#mermaid-svg-UxbLihXPkECPMe0I .node .label,#mermaid-svg-UxbLihXPkECPMe0I .image-shape .label,#mermaid-svg-UxbLihXPkECPMe0I .icon-shape .label{text-align:center;}#mermaid-svg-UxbLihXPkECPMe0I .node.clickable{cursor:pointer;}#mermaid-svg-UxbLihXPkECPMe0I .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-UxbLihXPkECPMe0I .arrowheadPath{fill:#333333;}#mermaid-svg-UxbLihXPkECPMe0I .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-UxbLihXPkECPMe0I .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-UxbLihXPkECPMe0I .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UxbLihXPkECPMe0I .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-UxbLihXPkECPMe0I .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UxbLihXPkECPMe0I .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-UxbLihXPkECPMe0I .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-UxbLihXPkECPMe0I .cluster text{fill:#333;}#mermaid-svg-UxbLihXPkECPMe0I .cluster span{color:#333;}#mermaid-svg-UxbLihXPkECPMe0I 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-UxbLihXPkECPMe0I .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-UxbLihXPkECPMe0I rect.text{fill:none;stroke-width:0;}#mermaid-svg-UxbLihXPkECPMe0I .icon-shape,#mermaid-svg-UxbLihXPkECPMe0I .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-UxbLihXPkECPMe0I .icon-shape p,#mermaid-svg-UxbLihXPkECPMe0I .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-UxbLihXPkECPMe0I .icon-shape .label rect,#mermaid-svg-UxbLihXPkECPMe0I .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-UxbLihXPkECPMe0I .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-UxbLihXPkECPMe0I .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-UxbLihXPkECPMe0I :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} d_model=512
压缩状态:收集到的原始信息
dff=2048
展开:充分联想和思考
d_model=512
压缩:形成最终结论
为什么一定要有中间的非线性激活?
如果没有激活函数:
xW1W2=xWcombinedx W_1 W_2 = x W_{combined}xW1W2=xWcombined
两个线性变换的组合还是一个线性变换------相当于什么都没做。加入非线性(ReLU/GELU),FFN 才能学习复杂的、非线性的语义模式。
8.5 激活函数
8.4.1 ReLU
ReLU(x)=max(0,x)\text{ReLU}(x) = \max(0, x)ReLU(x)=max(0,x)
|
/ |
/ |
/ |
─────┼─────
|
优点:简单,计算快
缺点:负数区域梯度为 0(Dead ReLU 问题)
8.4.2 GELU
GELU(x)=x⋅Φ(x)\text{GELU}(x) = x \cdot \Phi(x)GELU(x)=x⋅Φ(x)
其中 Φ(x)\Phi(x)Φ(x) 是标准正态分布的累积分布函数。
近似公式:
GELU(x)≈0.5x(1+tanh2π(x+0.044715x3))\text{GELU}(x) \approx 0.5x\left(1 + \tanh\left\\sqrt{\\frac{2}{\\pi}}\\left(x + 0.044715x\^3\\right)\\right\right)GELU(x)≈0.5x(1+tanhπ2 (x+0.044715x3))
GELU 的特点:
- 在负数区域也有非零梯度(平滑过渡)
- 比 ReLU 更平滑
- BERT、GPT-2 使用 GELU
8.4.3 SwiGLU
SwiGLU(x,W,V,b,c)=Swish(xW+b)⊗(xV+c)\text{SwiGLU}(x, W, V, b, c) = \text{Swish}(xW + b) \otimes (xV + c)SwiGLU(x,W,V,b,c)=Swish(xW+b)⊗(xV+c)
其中 Swish(x)=x⋅σ(x)\text{Swish}(x) = x \cdot \sigma(x)Swish(x)=x⋅σ(x),⊗\otimes⊗ 是逐元素乘法。
SwiGLU 的特点:
- 使用门控机制(GLU = Gated Linear Unit)
- Llama、Qwen、PaLM 使用 SwiGLU
- 通常比 GELU 效果更好
8.4.4 SwiGLU 的维度调整
SwiGLU 有一个重要的实现细节:它有三个权重矩阵(W_gate、W_up、W_down),而标准 FFN 只有两个(W_1、W_2)。
#mermaid-svg-um2Ia5QLjFUuDdMu{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-um2Ia5QLjFUuDdMu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-um2Ia5QLjFUuDdMu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-um2Ia5QLjFUuDdMu .error-icon{fill:#552222;}#mermaid-svg-um2Ia5QLjFUuDdMu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-um2Ia5QLjFUuDdMu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-um2Ia5QLjFUuDdMu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-um2Ia5QLjFUuDdMu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-um2Ia5QLjFUuDdMu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-um2Ia5QLjFUuDdMu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-um2Ia5QLjFUuDdMu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-um2Ia5QLjFUuDdMu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-um2Ia5QLjFUuDdMu .marker.cross{stroke:#333333;}#mermaid-svg-um2Ia5QLjFUuDdMu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-um2Ia5QLjFUuDdMu p{margin:0;}#mermaid-svg-um2Ia5QLjFUuDdMu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-um2Ia5QLjFUuDdMu .cluster-label text{fill:#333;}#mermaid-svg-um2Ia5QLjFUuDdMu .cluster-label span{color:#333;}#mermaid-svg-um2Ia5QLjFUuDdMu .cluster-label span p{background-color:transparent;}#mermaid-svg-um2Ia5QLjFUuDdMu .label text,#mermaid-svg-um2Ia5QLjFUuDdMu span{fill:#333;color:#333;}#mermaid-svg-um2Ia5QLjFUuDdMu .node rect,#mermaid-svg-um2Ia5QLjFUuDdMu .node circle,#mermaid-svg-um2Ia5QLjFUuDdMu .node ellipse,#mermaid-svg-um2Ia5QLjFUuDdMu .node polygon,#mermaid-svg-um2Ia5QLjFUuDdMu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-um2Ia5QLjFUuDdMu .rough-node .label text,#mermaid-svg-um2Ia5QLjFUuDdMu .node .label text,#mermaid-svg-um2Ia5QLjFUuDdMu .image-shape .label,#mermaid-svg-um2Ia5QLjFUuDdMu .icon-shape .label{text-anchor:middle;}#mermaid-svg-um2Ia5QLjFUuDdMu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-um2Ia5QLjFUuDdMu .rough-node .label,#mermaid-svg-um2Ia5QLjFUuDdMu .node .label,#mermaid-svg-um2Ia5QLjFUuDdMu .image-shape .label,#mermaid-svg-um2Ia5QLjFUuDdMu .icon-shape .label{text-align:center;}#mermaid-svg-um2Ia5QLjFUuDdMu .node.clickable{cursor:pointer;}#mermaid-svg-um2Ia5QLjFUuDdMu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-um2Ia5QLjFUuDdMu .arrowheadPath{fill:#333333;}#mermaid-svg-um2Ia5QLjFUuDdMu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-um2Ia5QLjFUuDdMu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-um2Ia5QLjFUuDdMu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-um2Ia5QLjFUuDdMu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-um2Ia5QLjFUuDdMu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-um2Ia5QLjFUuDdMu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-um2Ia5QLjFUuDdMu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-um2Ia5QLjFUuDdMu .cluster text{fill:#333;}#mermaid-svg-um2Ia5QLjFUuDdMu .cluster span{color:#333;}#mermaid-svg-um2Ia5QLjFUuDdMu 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-um2Ia5QLjFUuDdMu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-um2Ia5QLjFUuDdMu rect.text{fill:none;stroke-width:0;}#mermaid-svg-um2Ia5QLjFUuDdMu .icon-shape,#mermaid-svg-um2Ia5QLjFUuDdMu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-um2Ia5QLjFUuDdMu .icon-shape p,#mermaid-svg-um2Ia5QLjFUuDdMu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-um2Ia5QLjFUuDdMu .icon-shape .label rect,#mermaid-svg-um2Ia5QLjFUuDdMu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-um2Ia5QLjFUuDdMu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-um2Ia5QLjFUuDdMu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-um2Ia5QLjFUuDdMu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SwiGLU 3个矩阵
x
d_model
W_gate
d_model, dff
W_up
d_model, dff
Swish
⊗ 逐元素乘
W_down
dff, d_model
标准FFN 2个矩阵
x
d_model
W_1
d_model, 4×d_model
GELU
W_2
4×d_model, d_model
如果 dff 仍然是 4×d_model,SwiGLU 的参数量是标准 FFN 的 1.5 倍(3个矩阵 vs 2个矩阵)。
为了保持总参数量不变,现代 LLM 会缩小 dff:
SwiGLU 的 dff=23×4×dmodel=83dmodel\text{SwiGLU 的 dff} = \frac{2}{3} \times 4 \times d_{model} = \frac{8}{3} d_{model}SwiGLU 的 dff=32×4×dmodel=38dmodel
实际上还会向上取整到 128 的倍数(为了 GPU 计算效率)。
| 模型 | d_model | dff | 比例 | 说明 |
|---|---|---|---|---|
| 原始 Transformer | 512 | 2048 | 4× | ReLU, 标准FFN |
| GPT-2 | 768 | 3072 | 4× | GELU, 标准FFN |
| Llama 2 7B | 4096 | 11008 | 2.69× | SwiGLU, 缩小dff |
| Qwen2 7B | 3584 | 18944 | 5.29× | SwiGLU, 更大dff |
💡 记忆要点:SwiGLU 多了一个矩阵,所以要把 dff 缩小到约 2/3×4=8/3 倍,才能保持和标准 FFN 相同的参数量。
| 激活函数 | 使用模型 | 特点 |
|---|---|---|
| ReLU | 原始 Transformer | 简单,有 Dead ReLU |
| GELU | BERT, GPT-2 | 平滑,效果好 |
| SwiGLU | Llama, Qwen | 门控,现代LLM首选,需调整dff |
8.6 FFN 存储了什么?
这是近年来 Transformer 研究的一个重要发现:FFN 不仅仅是"变换器",它还是"知识库"。
研究论文(Geva et al., 2021)发现,FFN 的每个神经元可以看作一个 Key-Value 记忆单元:
- W1W_1W1 的每一行相当于一个 Key(匹配模式)
- W2W_2W2 的每一列相当于一个 Value(存储的知识)
当输入匹配某个 Key 时,对应的 Value 就被"激活"并输出。
例如,FFN 内部可能学到了这些知识:
text
Key: "...capital of France..." → Value: 巴黎相关的向量
Key: "...wrote Harry Potter..." → Value: J.K. Rowling 相关的向量
Key: "...Python creator..." → Value: Guido van Rossum 相关的向量
这解释了一个重要现象:
Attention 负责"什么时候调用知识",FFN 负责"存储知识本身"。
#mermaid-svg-QtR8RBPZeDEZSWzp{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-QtR8RBPZeDEZSWzp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QtR8RBPZeDEZSWzp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QtR8RBPZeDEZSWzp .error-icon{fill:#552222;}#mermaid-svg-QtR8RBPZeDEZSWzp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QtR8RBPZeDEZSWzp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QtR8RBPZeDEZSWzp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QtR8RBPZeDEZSWzp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QtR8RBPZeDEZSWzp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QtR8RBPZeDEZSWzp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QtR8RBPZeDEZSWzp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QtR8RBPZeDEZSWzp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QtR8RBPZeDEZSWzp .marker.cross{stroke:#333333;}#mermaid-svg-QtR8RBPZeDEZSWzp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QtR8RBPZeDEZSWzp p{margin:0;}#mermaid-svg-QtR8RBPZeDEZSWzp .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QtR8RBPZeDEZSWzp .cluster-label text{fill:#333;}#mermaid-svg-QtR8RBPZeDEZSWzp .cluster-label span{color:#333;}#mermaid-svg-QtR8RBPZeDEZSWzp .cluster-label span p{background-color:transparent;}#mermaid-svg-QtR8RBPZeDEZSWzp .label text,#mermaid-svg-QtR8RBPZeDEZSWzp span{fill:#333;color:#333;}#mermaid-svg-QtR8RBPZeDEZSWzp .node rect,#mermaid-svg-QtR8RBPZeDEZSWzp .node circle,#mermaid-svg-QtR8RBPZeDEZSWzp .node ellipse,#mermaid-svg-QtR8RBPZeDEZSWzp .node polygon,#mermaid-svg-QtR8RBPZeDEZSWzp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QtR8RBPZeDEZSWzp .rough-node .label text,#mermaid-svg-QtR8RBPZeDEZSWzp .node .label text,#mermaid-svg-QtR8RBPZeDEZSWzp .image-shape .label,#mermaid-svg-QtR8RBPZeDEZSWzp .icon-shape .label{text-anchor:middle;}#mermaid-svg-QtR8RBPZeDEZSWzp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QtR8RBPZeDEZSWzp .rough-node .label,#mermaid-svg-QtR8RBPZeDEZSWzp .node .label,#mermaid-svg-QtR8RBPZeDEZSWzp .image-shape .label,#mermaid-svg-QtR8RBPZeDEZSWzp .icon-shape .label{text-align:center;}#mermaid-svg-QtR8RBPZeDEZSWzp .node.clickable{cursor:pointer;}#mermaid-svg-QtR8RBPZeDEZSWzp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QtR8RBPZeDEZSWzp .arrowheadPath{fill:#333333;}#mermaid-svg-QtR8RBPZeDEZSWzp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QtR8RBPZeDEZSWzp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QtR8RBPZeDEZSWzp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QtR8RBPZeDEZSWzp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QtR8RBPZeDEZSWzp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QtR8RBPZeDEZSWzp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QtR8RBPZeDEZSWzp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QtR8RBPZeDEZSWzp .cluster text{fill:#333;}#mermaid-svg-QtR8RBPZeDEZSWzp .cluster span{color:#333;}#mermaid-svg-QtR8RBPZeDEZSWzp 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-QtR8RBPZeDEZSWzp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QtR8RBPZeDEZSWzp rect.text{fill:none;stroke-width:0;}#mermaid-svg-QtR8RBPZeDEZSWzp .icon-shape,#mermaid-svg-QtR8RBPZeDEZSWzp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QtR8RBPZeDEZSWzp .icon-shape p,#mermaid-svg-QtR8RBPZeDEZSWzp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QtR8RBPZeDEZSWzp .icon-shape .label rect,#mermaid-svg-QtR8RBPZeDEZSWzp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QtR8RBPZeDEZSWzp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QtR8RBPZeDEZSWzp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QtR8RBPZeDEZSWzp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 问题: 法国的首都是?
Attention
理解问题结构
决定需要调用什么知识
FFN
内部神经元匹配
输出'巴黎'的表示
输出: 巴黎
这也是为什么 GPT 这么大时,FFN 的参数量远超 Attention------因为知识需要存储空间。Attention 只需要学会"如何路由信息",而 FFN 要记住整个世界的知识。
很多关于"知识编辑"的论文(如 ROME、MEMIT)发现:只修改 FFN 中某几个神经元的权重,就可以改变模型对某个事实的记忆(比如让模型认为"埃菲尔铁塔在伦敦"),而不需要重新训练整个模型。这进一步证明了 FFN 的"知识存储"角色。
8.7 TensorFlow 实现
python
import tensorflow as tf
class FeedForward(tf.keras.layers.Layer):
def __init__(self, d_model, dff, activation='gelu'):
super().__init__()
self.dense1 = tf.keras.layers.Dense(dff, activation=activation)
self.dense2 = tf.keras.layers.Dense(d_model)
def call(self, x):
# x: [batch, seq, d_model]
x = self.dense1(x) # [batch, seq, dff]
x = self.dense2(x) # [batch, seq, d_model]
return x
# SwiGLU 实现
class SwiGLU(tf.keras.layers.Layer):
def __init__(self, d_model, dff):
super().__init__()
self.W = tf.keras.layers.Dense(dff, use_bias=False)
self.V = tf.keras.layers.Dense(dff, use_bias=False)
self.W2 = tf.keras.layers.Dense(d_model, use_bias=False)
def call(self, x):
# Swish(xW) ⊗ (xV)
gate = tf.nn.silu(self.W(x)) # Swish = SiLU
value = self.V(x)
return self.W2(gate * value)
# 测试
ffn = FeedForward(d_model=512, dff=2048)
x = tf.random.normal([2, 5, 512])
output = ffn(x)
print(output.shape) # (2, 5, 512)
8.8 参数量分析
| 参数 | Shape | 参数量 |
|---|---|---|
| W_1 | d_model, dff | d_model × dff |
| b_1 | dff | dff |
| W_2 | dff, d_model | dff × d_model |
| b_2 | d_model | d_model |
| 总计 | ≈ 2 × d_model × dff |
对于 d_model=512, dff=2048:2 × 512 × 2048 = 2,097,152 ≈ 200万参数。
注意:FFN 的参数量是 Multi-Head Attention 的 2 倍!
8.9 FFN 与 CNN 的对比
FFN 本质上是一个 1×1 卷积:
| 特性 | FFN | 1×1 CNN |
|---|---|---|
| 感受野 | 单个位置 | 单个位置 |
| 参数共享 | 所有位置共享 | 所有位置共享 |
| 并行计算 | ✅ | ✅ |
| 本质 | 逐位置 MLP | 逐像素 MLP |
本章总结
FFN = 两层全连接 + 激活函数:
#mermaid-svg-ZB86eRxnI9qSmE1Z{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-ZB86eRxnI9qSmE1Z .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ZB86eRxnI9qSmE1Z .error-icon{fill:#552222;}#mermaid-svg-ZB86eRxnI9qSmE1Z .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ZB86eRxnI9qSmE1Z .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ZB86eRxnI9qSmE1Z .marker.cross{stroke:#333333;}#mermaid-svg-ZB86eRxnI9qSmE1Z svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ZB86eRxnI9qSmE1Z p{margin:0;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge{stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section--1 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section--1 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section--1 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section--1 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section--1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section--1 text{fill:#ffffff;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon--1{font-size:40px;color:#ffffff;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge--1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth--1{stroke-width:17;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section--1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-0 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-0 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-0 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-0 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-0 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-0{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-0{stroke-width:14;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-1 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-1 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-1 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-1 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-1 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-1{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-1{stroke-width:11;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 text{fill:#ffffff;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-2{stroke-width:8;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-3 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-3 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-3 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-3 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-3 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-3{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-3{stroke-width:5;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-4 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-4 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-4 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-4 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-4 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-4{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-4{stroke-width:2;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-5 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-5 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-5 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-5 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-5 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-5{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-5{stroke-width:-1;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-6 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-6 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-6 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-6 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-6 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-6{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-6{stroke-width:-4;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-7 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-7 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-7 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-7 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-7 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-7{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-7{stroke-width:-7;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-8 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-8 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-8 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-8 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-8 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-8{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-8{stroke-width:-10;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-9 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-9 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-9 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-9 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-9 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-9{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-9{stroke-width:-13;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-10 rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-10 path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-10 circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-10 polygon,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-10 text{fill:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .node-icon-10{font-size:40px;color:black;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge-depth-10{stroke-width:-16;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:lightgray;}#mermaid-svg-ZB86eRxnI9qSmE1Z .disabled text{fill:#efefef;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-root rect,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-root path,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-root circle,#mermaid-svg-ZB86eRxnI9qSmE1Z .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-root text{fill:#ffffff;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-root span{color:#ffffff;}#mermaid-svg-ZB86eRxnI9qSmE1Z .section-2 span{color:#ffffff;}#mermaid-svg-ZB86eRxnI9qSmE1Z .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-ZB86eRxnI9qSmE1Z .edge{fill:none;}#mermaid-svg-ZB86eRxnI9qSmE1Z .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-ZB86eRxnI9qSmE1Z :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} FFN
结构
Linear d_model→dff
Activation
Linear dff→d_model
维度
dff = 4 × d_model
先扩展再压缩
激活函数
ReLU 原始
GELU BERT/GPT
SwiGLU Llama/Qwen
作用
逐Token非线性变换
存储事实知识
本章思考题
- 为什么 FFN 对每个 Token 独立计算,而不是像 Attention 一样考虑所有 Token?
- 如果把 FFN 去掉,只保留 Attention,模型会有什么问题?
- SwiGLU 中的"门控"机制有什么好处?
- 为什么说 FFN 存储了"知识"?这和 Attention 存储的信息有什么区别?
下一章预告
下一章我们讲 LayerNorm。
为什么不用 BatchNorm?LayerNorm 的数学推导是什么?Qwen 为什么用 RMSNorm?