从 Bit 到 AGI第五章:Transformer
Feed Forward 层
从 Bit 到 AGI · 第五章:Transformer · 每个 token 上的两层 MLP 在算什么
作者 David更新于 第 72 篇(共 186 篇)
Attention 负责** token 之间交换信息;Feed-Forward Network(FFN,前馈网络)则在每个 token 内部**做非线性变换。原论文结构:先扩维到 ,激活,再压回 。BERT-base 里 ,这一层占了单层参数的大头。
直觉:Attention 开完会后的「个人笔记整理」
Attention 像全体对表讨论;FFN 像每个人回到座位,独立把汇总的 768 维笔记扩成 3072 维草稿(中间层),提炼重点,再压缩成 768 维定稿。同一层里各 token 的 FFN 参数共享,但输入不同,输出各异。
定义
对每个 token 向量 :
- ,
- :原论文 ReLU;BERT 用 GELU;LLaMA 用 SwiGLU(门控变体)
BERT-base:,(即 )。
例子
例 1:参数量
单层 FFN 约 4.7M 参数;同层 Multi-Head Attention 约 2.4M——FFN 是参数大户。
例 2:FLOPs()
代入: FLOPs/层,与 attention 的 QKV+矩阵乘同量级。
import torch
import torch.nn as nn
d_model, d_ff = 768, 3072
ffn = nn.Sequential(
nn.Linear(d_model, d_ff),
nn.GELU(),
nn.Linear(d_ff, d_model),
)
x = torch.randn(128, d_model) # (seq, hidden)
y = ffn(x)
assert y.shape == (128, d_model)量化
| 模型 | FFN 参数/层 | ||
|---|---|---|---|
| BERT-base | 768 | 3072 | 4.7M |
| GPT-2 small | 768 | 3072 | 4.7M |
| LLaMA-7B | 4096 | 11008 | M(SwiGLU 三矩阵) |
- MoE 变体:多个 FFN 专家,router 选 top-k,推理只激活部分参数(见第 7 章 MoE)
- 字节数:4.7M 参数 × 4 B(fp32)≈ 18.9 MB/层;12 层 FFN 权重约 227 MB
常见误区
- FFN 跨 token 混合信息:错;形状 时在 seq 维无连接,纯 per-token MLP。
- 是铁律:常见启发式;GPT-3 175B 用 ;LLaMA 用 (SwiGLU 三矩阵补偿容量)。
- 去掉 FFN 只留 Attention:表达能力大降;两者分工不同,缺一不可。
动手试一试
对比 ReLU 与 GELU 在中间层的稀疏度:
import torch
import torch.nn.functional as F
x = torch.randn(768)
h_relu = F.relu(x @ W1.T)
h_gelu = F.gelu(x @ W1.T)
print((h_relu == 0).float().mean()) # ReLU 约 50% 置零
print(h_gelu.abs().mean()) # GELU 平滑,无硬零小结
FFN 是 的两层 MLP,per-token、参数共享。BERT-base 每层约 4.7M 参数,与 Attention 并列构成 Transformer Block 的两大子层。下一篇:Attention 如何拆成 12 个头并行工作。