08. FFN 在 Transformer 中起什么作用?SwiGLU 相比 ReLU 有什么优势?

整理 FFN 的作用,以及 SwiGLU 相比 ReLU 的优势。

简单回答

FFN(Feed-Forward Network)是 Transformer 中真正存储和处理知识的主要模块,Attention 负责"信息聚合",FFN 负责"信息变换"。SwiGLU 是一种带门控机制的激活函数,相比 ReLU 能让模型学到更平滑的非线性变换,实验表明它在同等参数量下效果更好,被 LLaMA、PaLM 等主流模型采用。

详细解释

FFN 的角色:知识存储与非线性变换

Transformer 每一层有两个核心组件:Multi-Head Attention 和 FFN。它们的分工可以这样理解:

Attention 是"路由器",决定从序列中的哪些 token 获取信息。它做的是 token 之间的交互——每个 token 基于与其他 token 的相关性,加权聚合信息。但 Attention 本身是线性操作(softmax 作用在权重上,对 V 的加权求和是线性的),如果没有 FFN 提供非线性,多层 Attention 叠加的表达能力会大打折扣。

FFN 是"处理器",对每个 token 独立做非线性变换。它不涉及 token 间交互——每个 token 的 FFN 输出只取决于该 token 自己的输入向量。FFN 的结构是一个升维-非线性-降维的瓶颈结构。

从参数量来看,FFN 通常占模型总参数的约 2/3。有研究(如 Dai et al. 的工作)把 FFN 的每个神经元类比为一个"键值对"——神经元的输入权重是"键"(决定什么输入会激活它),输出权重是"值"(被激活后输出什么信息)。这意味着 FFN 实际上是一个巨大的非参数化记忆体,存储了模型在预训练中学到的知识和模式。

有一些有趣的实验支持这个观点:直接编辑 FFN 的权重可以修改模型存储的事实知识(如 ROME、MEMIT 等知识编辑方法);FFN 某些神经元的激活和特定的概念、语言结构高度相关(如某个神经元专门响应"日期"概念)。

原始 FFN 的结构

原始 Transformer 的 FFN:

其中 。典型的 ,即隐层维度是模型维度的 4 倍。先升维到 4d 做非线性变换,再降维回 d。

激活函数的演进:从 ReLU 到 GELU 到 SwiGLU

ReLU。简单高效,但有"死神经元"问题——一旦某个神经元的输入持续为负,它的输出永远为零,梯度也为零,这个神经元就"死了",再也学不到东西。而且 ReLU 在零点不可导,虽然实际中不是大问题但数学上不够优雅。

GELU 是标准正态分布的 CDF)。可以理解为一种"平滑的 ReLU",在零点附近不是硬截断而是平滑过渡。GPT 系列和 BERT 使用 GELU。

Swish 是 sigmoid, 通常取 1)。和 GELU 非常相似,也是平滑的非线性。当 时称为 SiLU(Sigmoid Linear Unit)。

SwiGLU 的设计

SwiGLU 在 Swish 激活的基础上引入了 GLU(Gated Linear Unit)门控机制。它不是简单地把激活函数从 ReLU 换成 Swish,而是改变了 FFN 的结构:

这里 是逐元素相乘(Hadamard product)。和原始 FFN 相比,SwiGLU 多了一个权重矩阵 通过 Swish 激活后作为"门控信号", 提供"信息内容",两者逐元素相乘的效果是:门控信号决定哪些维度的信息可以通过,哪些被抑制。

这种门控机制赋予了网络"选择性激活"的能力,类似于 Attention 对不同 token 的选择,但 GLU 是在特征维度上做选择。模型可以学会"这个输入中哪些特征是有用的,应该保留;哪些是噪声,应该抑制"。

为什么 SwiGLU 的隐层维度是 8d/3 而不是 4d?

因为 SwiGLU 多了一个 矩阵,如果隐层维度仍然是 4d,那么参数量会比原始 FFN 多 50%(三个 d×4d 矩阵 vs 两个 d×4d 矩阵)。为了保持总参数量和计算量大致不变,需要把隐层维度从 4d 降到

原始 FFN 参数量:

SwiGLU 参数量:

实际模型中通常会取最近的能被 128 或 256 整除的值(为了 GPU 计算对齐),所以你看到的 FFN 隐层维度可能不是精确的 8d/3。比如 LLaMA 7B 的 d=4096,理论上 8d/3 ≈ 10923,实际取的是 11008。

SwiGLU vs ReLU 的实验对比

PaLM 论文做了系统的对比实验,结果表明在同等参数量和 FLOPs 下,SwiGLU 一致优于 ReLU 和 GELU。差距虽然不算巨大(通常在 0.x 个点的 loss 差异),但在大模型训练中这种差异会映射到下游任务的显著提升。LLaMA 的技术报告也验证了这一结论。

MoE 和 FFN 的关系

顺带提一下,MoE(Mixture of Experts)本质上是对 FFN 层做的改造——把单个 FFN 替换为多个"专家" FFN,用 Router 选择。为什么不对 Attention 做 MoE?一方面 FFN 占参数量的 2/3,扩展 FFN 性价比更高;另一方面 Attention 涉及 token 间交互,做 MoE 会使路由和通信更复杂。

面试时可以这样答

FFN 在 Transformer 里的角色,可以这样理解:Attention 负责 token 之间的信息聚合,FFN 负责对每个 token 做独立的非线性变换和知识检索。FFN 的参数量通常占整个模型的三分之二,可以认为它是模型存储知识的主要场所。有研究表明,直接编辑 FFN 权重就能修改模型存储的事实知识,这也侧面印证了 FFN 作为"知识存储体"的角色。

激活函数的演进线是 ReLU → GELU → SwiGLU。SwiGLU 有两个关键改进:一是用 Swish 替代 ReLU,更平滑没有死神经元问题;二是引入了 GLU 门控机制,多了一个投影矩阵做 gate,通过逐元素相乘让模型学会在特征维度上做选择性激活。PaLM 和 LLaMA 的实验都表明 SwiGLU 在同等参数量下效果一致更好。

工程上有个细节:因为 SwiGLU 多了一个投影矩阵,为保持参数量不变,隐层维度从 4d 调到了 8d/3。所以看 LLaMA 的代码会发现 FFN 中间层维度不是整 4 倍——比如 d=4096 对应的隐层是 11008,就是 8d/3 取整到 128 的倍数。

常见追问

  1. FFN 存储知识这个说法有什么实验证据?ROME 和 MEMIT 是怎么做知识编辑的?
  2. MoE 本质上是对 FFN 做了什么改造?为什么不对 Attention 做 MoE?
  3. 如果把 FFN 完全去掉,只保留 Attention,模型能力会怎样?