一、什么是 FFN?
FFN(Feed-Forward Network,前馈网络)是 Transformer 架构中的核心组成部分之一,位于多头注意力(Multi-Head Attention)层之后。
它的作用可以这样理解:注意力层负责“收集信息”(哪里重要、谁和谁相关),而 FFN 层负责“处理信息”(对收集到的信息进行非线性变换和特征映射)。两者分工明确,缺一不可。
在标准的 Transformer 层中,结构为:
输入 → 多头注意力 → 残差连接 + LayerNorm → FFN → 残差连接 + LayerNorm → 输出
二、FFN 的标准数学形式
Transformer 原文中,FFN 是一个两层的全连接网络,中间有一个非线性激活函数(通常为 ReLU 或其变种):
或者写成分层形式:
其中:
直观理解:FFN 先把输入向量“升维”到一个更高维的空间,让模型有更多“表达自由度”,然后非线性激活引入复杂模式,最后再“降维”回原来的维度。
三、FFN 的核心作用
| 功能 | 详细解释 |
|---|---|
| 特征非线性变换 | 注意力层是线性的(加权求和),没有非线性能力;FFN 通过激活函数引入非线性,让模型能拟合复杂函数 |
| 特征维度拓展 | dff 通常设置为 4× dmodel,提供更丰富的中间表示空间 |
| 位置独立处理 | 对每个 token 独立应用相同的 FFN,不涉及 token 间的交互(这部分由注意力完成) |
| 知识存储 | 研究表明,预训练模型中的大量“知识记忆”实际上存储在 FFN 层中,而非注意力层 |
| 跨 token 信息整合的补充 | 注意力层关注“谁和谁相关”,FFN 层则基于相关信息进行推理和变换 |
四、FFN 的各种变体
随着大模型的发展,研究者提出了多种 FFN 变体,各有优劣:
| 变体名称 | 公式 | 特点 |
|---|---|---|
| 标准 FFN (ReLU) | 原始 Transformer 设计,简单有效 | |
| GELU FFN | GPT、BERT、LLaMA 等常用,更平滑 | |
| SwiGLU FFN | LLaMA、PaLM 等使用,效果更好 | |
| GeGLU FFN | GLU 系列变体之一 | |
| GLU 变体系列 | 多种门控线性单元 | 引入门控机制,增强表达能力 |
实际应用现状:
LLaMA 1/2/3:使用 SwiGLU(SwiGLU 是目前最主流的选择)
GPT-3:使用 GELU
BERT / 原始 Transformer:使用 ReLU 或 GELU
SwiGLU 之所以流行,是因为它结合了 Swish 激活和门控机制,在不同规模模型上都表现出更稳定的训练和更好的性能。
五、FFN 中的关键参数:膨胀率
膨胀率 =
| 模型 | 膨胀率 | 说明 |
|---|---|---|
| 原始 Transformer | 4 | 标准设计 |
| BERT-base | 4 (3072/768) | 沿用经典比例 |
| GPT-3 | 4 | 标准比例 |
| LLaMA | 约 2.7~3.5 | 略低于 4,更高效 |
| 小型模型 | 可低至 2 | 为了降低参数量 |
设计权衡:
更高的膨胀率 → 更多参数 → 更强表达能力 → 更多训练和推理成本
更低的膨胀率 → 更高效 → 可能损失容量
六、FFN 的参数量与计算占比
以BERT-base为例(dmodel=768,dff=3072dmodel=768,dff=3072):
| 组件 | 参数量 | 占比 |
|---|---|---|
| 多头注意力 | ~2.36M | ~25% |
| FFN(两层) | ~7.08M | ~75% |
| LayerNorm、Embedding 等 | 少量 | 少量 |
关键发现:FFN 占用了 Transformer 层中约 2/3 到 3/4 的参数!这也是为什么 MoE(混合专家模型)会将专家放在 FFN 位置进行替换。
计算量:在推理时,FFN 的计算占比同样很高(约 60%~70%),因为需要为每个 token 独立做两次大维度的矩阵乘法。
七、FFN 的局限性
参数量大:占模型总参数的大部分,成为存储和传输的瓶颈
计算密集:是推理延迟的主要来源之一
位置无关处理:对每个 token 独立应用,无法利用 token 间已建立的交互关系(这可能也是缺点,但本质上是设计选择)
知识存储过于集中:实验发现,破坏 FFN 的某些神经元会显著损害模型对特定事实的召回,这既有鲁棒性隐患,也为“模型编辑”提供了抓手
八、优化 FFN 的方式
| 优化方法 | 思路 | 代表工作 |
|---|---|---|
| 低秩分解 | 将 W1,W2 分解为低秩矩阵 | LoRA(微调时) |
| 稀疏 FFN | 只激活部分神经元 | MoE 架构、ReLU 等天然稀疏 |
| 共享 FFN | 跨层共享 FFN 参数 | ALBERT |
| 剪枝 | 移除不重要的神经元 | 模型压缩 |
| 结构化压缩 | 减少 dff | TinyBERT、DistilBERT |
| 替代激活函数 | 降低计算密度 | GELU、SwiGLU 替代 ReLU |
九、Mermaid 总结框图
十、一句话总结
FFN 是 Transformer 中的“计算核心”和“知识仓库”:它占据模型大部分参数,通过先升维后降维的非线性变换,为每个 token 独立地注入推理能力和知识记忆。虽然注意力负责“连接”,但真正让模型“思考”并记住事实的,很大程度上是 FFN。理解 FFN,就抓住了大模型设计的半壁江山。