7. 理解 FFN(SwiGLU)
2026/9/7 3:08:05 网站建设 项目流程

什么是 FFN(SwiGLU)?

如果说 Attention 负责“信息交换”,那么 FFN(Feed Forward Network,前馈网络)负责“信息加工”。

在现代大模型(LLaMA、Qwen、Gemma、Mistral、DeepSeek 等)里,Transformer Block 基本都是:

输入 │ ▼ Attention │ ▼ FFN(SwiGLU) │ ▼ 输出

很多人会把 Attention 当成 Transformer 的核心,但实际上:

模型参数的大头往往在 FFN 里,而不是 Attention。

在 LLaMA 系列中,大约 60%~70% 的参数都在 FFN 中。


1. 先看原始 Transformer 的 FFN

2017 年《Attention Is All You Need》中的 FFN 非常简单:

FFN(x)=W2(ReLU(W1x)) FFN(x)=W_2(ReLU(W_1x))FFN(x)=W2(ReLU(W1x))

流程:

x │ ▼ Linear(W1) │ ▼ ReLU │ ▼ Linear(W2) │ ▼ 输出

如果模型维度:

d_model = 4096

则:

4096 ↓ 16384 (扩张4倍) ↓ 4096

因此 FFN 又叫:

Expansion → Activation → Compression

即:

扩张 ↓ 非线性变换 ↓ 压缩

2. 为什么要改进 FFN?

研究人员发现:

ReLU

虽然简单,

但:

  • 信息利用率不高
  • 梯度不够平滑
  • 表达能力有限

后来出现:

ReLU ↓ GELU ↓ GLU ↓ GEGLU ↓ SwiGLU

2020 年 Noam Shazeer(Transformer 原作者之一)发表论文:

GLU Variants Improve Transformer

专门研究:

FFN 中的激活函数能不能换掉?

结果发现:

GEGLU SwiGLU

效果明显优于:

ReLU GELU

3. 什么是 GLU?

理解 SwiGLU 前必须先理解 GLU。

普通 FFN

普通 FFN:

h=ReLU(xW1) h = ReLU(xW_1)h=ReLU(xW1)

本质上:

输入 ↓ 激活 ↓ 输出

只有一条路。


GLU

GLU(Gated Linear Unit)增加了一条门控路径:

GLU(x)=(xW)⊗σ(xV) GLU(x)= (xW)\otimes \sigma(xV)GLU(x)=(xW)σ(xV)

其中:

⊗ \otimes

表示逐元素相乘。

流程:

┌────► Linear(V) │ x ────────┤ │ └────► Linear(W) │ ▼ Sigmoid │ ▼ Element-wise *

可以理解成:

Value × Gate

即:

真正的信息 × 通过比例

类似:

水流 × 阀门开度

4. SwiGLU 做了什么?

SwiGLU 把 GLU 中的 Sigmoid 换成了 Swish(SiLU)。

原始 GLU:

GLU(x)=(xW)⊗σ(xV) GLU(x)= (xW) \otimes \sigma(xV)GLU(x)=(xW)σ(xV)

SwiGLU:

SwiGLU(x)=(xV)⊗SiLU(xW) SwiGLU(x)= (xV) \otimes SiLU(xW)SwiGLU(x)=(xV)SiLU(xW)

其中:

SiLU(z)=zσ(z) SiLU(z)=z\sigma(z)SiLU(z)=zσ(z)


5. 为什么叫 SwiGLU?

因为:

Swish + GLU

合起来:

SwiGLU

而:

Swish ≈ SiLU

所以代码里经常看到:

F.silu(...)

实际上就是 SwiGLU 的一部分。


6. 现代大模型里的 SwiGLU

LLaMA 的 FFN:

不是

y=down_proj(silu(up_proj(x)))

而是:

y=down_proj(silu(gate_proj(x))*up_proj(x))

对应:

gate_proj │ ▼ x ─────────────────► SiLU │ ▼ Gate x ──► up_proj ─────► Value Gate * Value │ ▼ down_proj │ ▼ 输出

因此你会看到:

gate_proj up_proj down_proj

三个矩阵。

而传统 FFN 只有:

up_proj down_proj

两个矩阵。


7. 为什么 SwiGLU 更强?

这是很多人最关心的问题。

实际上论文作者自己都承认:

他们也没有严格理论解释,只知道实验效果更好。

但从直觉上理解:


普通 FFN

y = GELU(Wx)

对于所有特征:

统一处理

SwiGLU

y = Value × Gate

Gate 可以动态决定:

哪些维度保留 哪些维度抑制 哪些维度放大

类似:

注意力里的权重

但是发生在 FFN 内部。

因此表达能力更强。


8. 参数为什么变成 8/3 倍?

原始 FFN:

4096 ↓ 16384 ↓ 4096

中间层:

4d 4d4d


SwiGLU 有三组矩阵:

gate_proj up_proj down_proj

如果仍然用:

4d 4d4d

参数会暴涨。

于是论文采用:

83d \frac{8}{3}d38d

代替:

4d 4d4d

这样总参数量和原 FFN 基本一致。


9. 为什么 LLaMA 的 hidden_dim 是 11008?

例如:

dim=4096

理论上:

83×4096=10922 \frac{8}{3}\times4096= 1092238×4096=10922

再对齐到:

256倍数

得到:

11008

所以你会看到:

gate_proj:409611008up_proj:409611008down_proj:110084096

这正是 LLaMA 的实现。


10. 一句话理解 SwiGLU

如果说:

Attention = 让不同Token交流

那么:

FFN = 对每个Token进行加工

而:

普通FFN = 加工一次
SwiGLU = 先生成一个“阀门(Gate)” 再决定哪些信息该通过

即:

输出 = 信息(Value) × 门控(Gate)

这相当于给 FFN 增加了一个可学习的信息筛选器,因此在几乎相同参数量下,通常比 ReLU/GELU FFN 具有更好的表达能力和训练效果。

对于学习大模型源码,可以记住一个最核心的公式:

FFNSwiGLU(x)=(SiLU(xWg)⊙(xWu))Wd FFN_{SwiGLU}(x)= \bigl( SiLU(xW_g) \odot (xW_u) \bigr) W_dFFNSwiGLU(x)=(SiLU(xWg)(xWu))Wd

对应代码:

gate=F.silu(gate_proj(x))up=up_proj(x)hidden=gate*up out=down_proj(hidden)

这就是今天几乎所有主流 LLM(LLaMA、Qwen、Gemma、Mistral、DeepSeek)的 FFN 核心实现。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询