翻 LLaMA、Qwen、DeepSeek 的配置,FFN 里常跳出 gate_proj、up_proj、silu。名字很碎,其实在问同一件事:非线性要不要、怎么给、给在哪。
一句话:激活函数给网络注入非线性。没有它,再多层也只是一次矩阵乘法。历史走过三问——像不像神经元、能不能训得深、大模型 FFN 里用什么门——今天的默认答案,多半是 SwiGLU。
这是一篇有意写长的文章。激活函数看起来只是「一层里的一个小函数」,却串起了感知机冬天、深网爆发、Transformer 配方迁移,以及你今天读开源权重时看到的那三个投影。你可以顺着读;也可以当手册,按目录跳到卡壳的那一幕。
写给三类读者,不妨对号入座:
- 入门者:先读第 1、2、3、11 节,建立「为什么需要它、为何换代」
- 做模型的人:重点看第 6、7、9 节,把 GELU → SwiGLU 的迁移做对
- 做推理 / 平台的人:盯第 7.8、8.3、9.3,关心融合核、量化和同名不同实现
目录
1 | 1. 它到底在干什么 |
1. 它到底在干什么
1.1 一个神经元的两步
人工神经元几乎都长这样:先把输入加权求和,再过一个函数 (f):
[
y = f(w^\top x + b)
]
线性部分负责「混合信号」,(f) 负责「改写形状」。少了后者,网络再深也只是在做坐标变换。
一个不严谨但好用的比喻:
矩阵乘法像搅拌;激活函数像火候。只搅拌不加热,厨房再大也做不出菜。
1.2 没有非线性,深度是假的
假设两层都用恒等激活 (f(z)=z):
[
h = W_2(W_1 x + b_1)+b_2 = (W_2 W_1)x + (W_2 b_1 + b_2)
]
还是一次仿射变换。一百层也一样——参数矩阵可以乘成一块。于是:
- 决策边界只能是「超平面切一刀」
- XOR 这种「对角线同类」学不会
- 所谓深度,只是把算力浪费在等价的一层上
XOR 为什么要命?因为它要求边界弯一下:
1 | (0,0)→0 (0,1)→1 |
一条直线分不开这四类点。你需要至少一段非线性,把空间折一折,再切开。激活函数存在的第一性原理,就是:造出真正的深度。
1.3 它其实同时办三件事
光说「非线性」太笼统。选型时,工程师其实在权衡:
| 职责 | 通俗说法 | 典型权衡 |
|---|---|---|
| 表达力 | 能不能弯、能不能稀疏、能不能门控 | 更强往往更贵 |
| 可训练性 | 梯度能不能传回去 | 饱和 → 梯度消失;硬阈值 → 神经元死亡 |
| 表示风格 | 有界?零中心?负半轴留不留 | 影响后面层的输入分布 |
后面整部历史,几乎都在这三件事上换假设。可以先记住一条主线:
1 | 开关(阶跃) |
1.4 和「万能逼近」的关系
教科书常说:带非线性的单隐层网络,在温和条件下可以逼近任意连续函数。这句话容易被误解成「激活函数随便选都行」。
更准确的读法是:
- 非线性是前提,线性网络没有这张入场券
- 逼近定理不保证好训——存在性和可优化性是两回事
- 宽度与深度可互换,但成本不可互换——理论存在,不等于算得起、训得稳
- 现代网络靠整套脚手架——残差、Norm、初始化、学习率、数据;激活只是其中一环
所以本文不会神话某一个 (f)。好的激活,是在「表达 / 训练 / 算力 / 服务」四边形里,找到当下任务的甜点。
1.5 读大模型时,为什么还要懂这个
你可能觉得:反正 Hugging Face 里写死了,懂不懂有什么关系?至少三件事会卡住你:
- 复现论文:换错
hidden_act,基线直接歪 - 改结构:LoRA / 蒸馏 / 剪枝时,门控 FFN 的参数分组与普通 MLP 不同
- 读报告:作者写「我们用了 SwiGLU」,你要知道他多半同时改了中间层宽度,而不只是换了个函数名
再补一个更「产品向」的理由:当你把模型量化、蒸馏、投机解码、或者给不同客户挂不同 adapter 时,FFN 往往是体积与算力最大的那块肉。你若分不清「两投影 GELU」和「三投影 SwiGLU」,后面所有压缩比、可替换模块边界、kernel 选择都会从第一层就偏掉。
激活函数是小零件,却是配方里的硬约束。
1.6 两个常被一起讨论、其实不同的问题
讨论激活时,桌上其实常摆着两个问题,最好拆开:
问题 A:函数形状。
ReLU、GELU、SiLU 比的是「同一个通道上,输入到输出的曲线长什么样」。
问题 B:信息路由结构。
GLU / SwiGLU 比的是「要不要额外开一条可学习的门支路」。
把 B 误当成 A,就会出现奇怪操作:只把 nn.GELU() 换成 nn.SiLU(),却不加 gate_proj,然后奇怪「为什么没论文里说的提升」。论文里的 SwiGLU,指的通常是整块 FFN,不是单换一个逐元素函数。
2. 第一幕:仿神经元,却训不深
2.1 1943–1958:阈值与阶跃
故事从「大脑能不能被形式化」开始。1943 年 McCulloch & Pitts 把神经元写成阈值逻辑单元:输入加权,超过阈值就输出 1,否则 0。1958 年 Rosenblatt 的感知机把它做成可学习的分类器,媒体一度把「电子脑」吹上了天。
阶跃函数长这样:
[
f(x)=\begin{cases}1,&x\ge 0\0,&x<0\end{cases}
]
直觉漂亮:全或无,像生物神经元「开火 / 沉默」。训练却完蛋——几乎处处导数为 0,梯度下降无处下手;在 (x=0) 还不可导。它是逻辑开关,不是可微深网的零件。
1969 年 Minsky & Papert 指出单层感知机搞不定 XOR,连接主义大幅降温。很多人以为「神经网络不行了」;更精确的说法是:
非线性叠层当时既缺可靠训练手段,也缺算力。理论局限、训不动、算不动,三连击。
这条线并没有死绝。它把一个问题留给后人:如果智能来自加权连接,怎样才能把很多层真正训起来?
2.2 反向传播来了,需要可微的软开关
1980 年代,反向传播被讲透并开始实用。训练规则变了:参数沿损失对参数的梯度下降。链式法则要求中间每个变换几乎处处可微。于是激活函数的规格书改写为:
- 几乎处处可微
- 导数别处处接近 0
- 最好计算不太荒唐
- 最好别把数值轻易打爆
Sigmoid 成了那个时代的默认答案——它像阶跃,但可微;像开关,但软。
2.3 Sigmoid:能反传,深了却发暗
[
\sigma(x)=\frac{1}{1+e^{-x}},\quad \sigma’(x)=\sigma(x)\bigl(1-\sigma(x)\bigr)
]
优点清楚:
- 输出在 ((0,1)),可解释成概率或「软开关」
- 处处可微,形状像平滑版阶跃
- 早期多层感知机、早期 RNN,几乎人手一份
致命伤同样清楚。
(1)导数上限太低。 (\sigma’(x)) 最大只有 (0.25)(在 (x=0))。反向传播时,梯度大致按层相乘。若每层都贡献一个 (\le 0.25) 的因子,二十层之后梯度会小到荒谬。
用最粗糙的量级估算:即便每层都取到最大值 (0.25),
[
0.25^{10}\approx 9\times 10^{-7},\quad 0.25^{20}\approx 9\times 10^{-13}
]
还没算上权重本身的缩放。深网还没来得及表达,梯度已经先死了。
(2)输出不正中心。 Sigmoid 输出均值偏正,后面层的输入分布容易整体漂移,优化更别扭。Tanh 后来部分缓解了这一点。
(3)指数贵。 在 CPU 时代这点很痛;今天相对矩阵乘不值一提,但对「为什么社区渴望更便宜的激活」仍有历史意义。
(4)饱和会自我加强。 单元一旦被推到两端,导数更小,更新更弱,更容易继续待在两端——正反馈式的「死区」。机制不同于后面的 Dying ReLU,症状却相似:某些单元不再学习。
2.4 Tanh:零中心了,饱和还在
[
\tanh(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} = 2\sigma(2x)-1
]
值域 ((-1,1)),过原点,比 Sigmoid 更「零中心」。经验上,很多浅层网络换 Tanh 会收敛更快。RNN / LSTM / GRU 里,Tanh 至今仍大量出现在细胞状态候选值上——因为结构本身需要有界的状态更新。
但它没有解决根本矛盾:两端照样饱和。没有残差、没有归一化的深层前馈网络,Tanh 依然难训。
2.5 第一幕结束时,人们学会了什么
平滑非线性 + 反传,可行;饱和激活 + 深度,互相打架。
下一幕的突破,不是找到「更像大脑」的函数,而是找到正半轴不饱和、又足够便宜的函数。审美从生物学转向了工程学。
如果只用一个生活场景类比这一幕:Sigmoid/Tanh 像装了限速器的车——市区(浅层)开得稳,一上高速公路(深层)就怎么踩油门都起不来。下一幕 ReLU 的做法很粗暴:拆掉限速器,只保留半边油门。
3. 第二幕:ReLU,把深网点着
3.1 ReLU:简单到不像正确答案
ReLU(Rectified Linear Unit)的定义几乎侮辱智商:
[
\mathrm{ReLU}(x)=\max(0,x)
]
2011 年前后它在深度网络实验里持续冒头;2012 AlexNet 把它带进大众视野。正半轴梯度恒为 1,负半轴直接掐断。好处是实打实的:
- 缓解梯度消失(正半轴不饱和)
- 算得极快(阈值比较,无指数)
- 稀疏激活:不少单元输出为 0,表示更省,有时还带一点隐式正则
对比 Sigmoid「处处软、处处弱」,ReLU 选择「半边硬、半边猛」。在 GPU 与大数据终于到位的年代,这个选择击中了甜点。
有个常被忽略的配套故事:初始化也要跟着换。
粗略直觉是:前向时希望每层激活方差别爆炸或坍缩;反向时希望梯度方差也别失控。Xavier / Glorot 初始化更契合对称的饱和激活(Sigmoid/Tanh 一类);ReLU 更常搭配 He 初始化,补偿「负半轴被掐掉大约一半」带来的方差损失。
你可以把它记成:
1 | 换激活 ≈ 换了方差传播规则 |
这也是为什么「只改一行 activation=」在浅模型上偶尔能蒙对,在深模型上却经常训练曲线怪——你改的不是一个装饰品,是动力学。
3.2 Dying ReLU:另一间停尸房
ReLU 的坏处同样直白。若某个单元的输入长期为负,输出恒为 0,梯度也恒为 0——这条通路不再更新,俗称 Dying ReLU。
常见诱因:
- 学习率过大,一次更新把大量权重打飞
- 初始化不当,预激活分布整体偏负
- 数据分布漂移后,某些通道再也进不了正半轴
- 没有合适的归一化,激活分布越走越歪
注意比较:
| Sigmoid 饱和 | Dying ReLU | |
|---|---|---|
| 导数 | 很小,但不恒为 0 | 精确为 0 |
| 比喻 | 半透明玻璃 | 焊死的门 |
| 可否被「救回」 | theoretically 可能慢慢蠕动 | 若输入回不去正区,就真死了 |
3.3 负半轴留门缝:Leaky / PReLU / RReLU
[
\mathrm{LeakyReLU}(x)=\begin{cases}x,&x>0\\alpha x,&x\le 0\end{cases}
]
(\alpha) 常取 (0.01) 或 (0.1)。负半轴不再完全封死,dying 风险下降,计算仍然便宜。PReLU 让 (\alpha) 可学习——多一点点参数,换一点适配能力。RReLU 则在训练时把 (\alpha) 随机化,带一点正则味道。
这些变体在视觉模型里很常见,思想也很朴素:别把负半轴焊死。 它们没有推翻 ReLU,而是给 ReLU 家族补上「容错模式」。
3.4 ELU / SELU:负半轴也要平滑
ELU 在负区用指数拉出平滑曲线:
[
\mathrm{ELU}(x)=\begin{cases}x,&x>0\\alpha(e^{x}-1),&x\le 0\end{cases}
]
均值更容易靠近 0,有时收敛更稳。SELU(Self-Normalizing)再配上特定初始化与架构约束,理论上能推动激活走向零均值、单位方差——像一种「激活自带的弱归一化」。
它们在全连接网、部分序列模型里有过热度。最终没能在 Transformer LLM 主路上压过 GELU / 门控一族,不是因为「更差」,而是生态位变了:
- Transformer 有残差和 Norm,「自归一化」刚需下降
- 语言建模更吃门控 FFN 的容量分配
- 大规模训练更看重现成 kernel 与可复现配方
3.5 为什么 ReLU「赢了十年」
把第二幕压缩成一句:
当算力、数据、深度同时到位,便宜且正区不饱和的非线性,比「更像生物神经元」的平滑饱和曲线更重要。
ReLU 不是理论上最优,它是工程上最先让深网规模化的那把钥匙。CNN 时代默认选项之一,至今在小模型、边缘部署、极致延迟场景里仍然很难被掀翻。
值得补一句「历史公正」:ReLU 并不是 2012 才被发明的数学对象,相关整流思想更早;真正改变行业的是——它遇上了卷积、GPU、ImageNet 和愿意把网络叠深的人。技术史里,想法出土和想法爆发经常隔着几十年。激活函数这条线,同样如此。
4. 插曲 A:LSTM 已经用过「门」,只是战场不同
很多人以为「门控」是 Transformer / SwiGLU 的发明。其实 LSTM(1997)早就把门控用得出神入化:
- 遗忘门:过去记忆留多少
- 输入门:新候选写进去多少
- 输出门:细胞状态对外暴露多少
门通常是 Sigmoid(0 到 1 的阀门),候选状态常用 Tanh(有界)。这里的门控服务的是时间轴上的记忆读写。
SwiGLU 的门控服务的是另一件事:
在同一个 token 位置内部,哪些特征通道该通过 FFN 的非线性加工。
同叫「门」,战场不同:
| LSTM 门 | SwiGLU 门 | |
|---|---|---|
| 作用对象 | 跨时间步的记忆 | 单位置的特征通道 |
| 典型函数 | Sigmoid + Tanh | SiLU × 线性内容 |
| 目的 | 缓解长程依赖遗忘 | 提高 FFN 容量利用 |
把这层关系看清,有助于理解:深度学习里真正被反复证明的,不是某一个具体公式,而是 「用可学习的阀门分配信息流」 这个设计模式。
也可以说得更锋利一点:
1990 年代的门,管的是「时间上记不记得住」;
2020 年代的门,管的是「通道上留不留得下」。
智能系统越做越大,稀缺的往往不是「再多一个非线性形状」,而是「把有限容量分给真正有用的信号」。门控反复出现,正是因为分配问题一遍遍回来。
5. 插曲 B:Transformer 里其实有两套激活故事
读现代模型时,最好先分清两条轨道:
| 轨道 | 发生在哪 | 常见非线性 | 在干什么 |
|---|---|---|---|
| 注意力路径 | (QK^\top/\sqrt{d}) 之后 | Softmax(及其近似) | 在位置之间分配权重 |
| FFN 路径 | 每个位置的 MLP | GELU / SwiGLU … | 在位置内部做特征加工 |
Softmax 严格说常被视为归一化,但它和激活函数同属「把线性分数变成可用信号」的家族:
[
\mathrm{softmax}(z)_i=\frac{e^{z_i}}{\sum_j e^{z_j}}
]
分类头用它把 logits 变成概率;注意力用它把相似度变成权重。温度、top-k、nucleus sampling,都是在 Softmax 家族上做文章。
一个有用的分工口诀:
1 | Attention:决定「看谁」 |
再补一个温度直觉。语言模型采样时写 temperature=0.7,本质上是在 Softmax 前缩放 logits:温度越低,分配越尖、越「果断」;温度越高,分配越平、越「随机」。它改的是注意力/词表头这类 Softmax 轨道的锋利度,并不是去改 FFN 里的 SiLU 曲线。
后文「前沿」主要谈 FFN;但你会在工程里同时撞到两者。换 FFN 激活,不等于动注意力;做 Sparse Softmax / 线性注意力,也不等于换了 SwiGLU。混谈这两条线,是很多讨论越聊越乱的根源。
还有一个结构事实值得放在心上:在标准 Transformer 里,参数量和算力大头常常在 FFN(尤其宽中间层时),不在注意力的 QKV。所以「FFN 里用什么非线性 / 门控」对质量与成本都敏感——它不是边角料,是主干道。
6. 第三幕:平滑随机门——GELU / SiLU / Mish
ReLU 的折角在 (x=0) 不可导(次梯度能用,但不优雅)。Transformer 兴起后,隐藏层更爱处处平滑、负区略带回灌的曲线:既不像 Sigmoid 两头死饱和,也不像 ReLU 一刀切。
6.1 GELU:2018–2020 的默认文化
GELU(Gaussian Error Linear Unit,Hendrycks & Gimpel, 2016)有一个很好记的故事:
别对输入做硬阈值;按「它有多大概率像来自标准正态」来随机决定保留还是丢弃,再取期望。
写成式子:
[
\mathrm{GELU}(x)=x\cdot\Phi(x)
]
其中 (\Phi) 是标准正态 CDF。直觉上,(x) 越大,越可能被保留;(x) 很负,多半被丢掉——但不是硬切,而是软概率。实现里常用 tanh 近似:
[
\mathrm{GELU}(x)\approx 0.5,x\left(1+\tanh\left[\sqrt{\frac{2}{\pi}}\left(x+0.044715,x^{3}\right)\right]\right)
]
也有基于 (\mathrm{erf}) 的精确实现。框架里你常看到 gelu、gelu_new、gelu_pytorch_tanh 等名字,细节差一点点,思想一样——复现时却要以论文 / 权重实际用的为准,别自以为「都是 GELU」就混用。
BERT、GPT-2、GPT-3 的 FFN 都用 GELU。相对 ReLU:
- 零点附近更平滑,优化景观更「好走」
- 负半轴有一小段非零输出与梯度,不像 ReLU 一刀切
- 计算比 ReLU 贵,但对大模型训练成本来说通常可接受
若你读 2018–2020 的 Transformer 论文,「隐藏层激活 = GELU」几乎是默认文化,像今天写
dtype=bfloat16一样自然。
6.2 SiLU / Swish:自己乘自己的软门
[
\mathrm{SiLU}(x)=x\cdot\sigma(x)=\frac{x}{1+e^{-x}}
]
Google Brain 当初用自动搜索找到 Swish(Ramachandran et al., 2017),后来在 PyTorch 等框架里常叫 SiLU(Sigmoid Linear Unit)。形状与 GELU 很像:正半轴近似线性,负区有一个浅浅的「凹坑」。
它有个有趣性质:非单调——在负区先降后升回 0。是否因为非单调才更好,学界有过争论;工程上更务实的观察是:它平滑、实现简单、在视觉模型里反复验证有效。EfficientNet、不少 YOLO 后续版本都很常见。
对今天更关键的一点:SiLU 成了 SwiGLU 的门控内核。你在 LLM 配置里看到 silu,常常不是「整层只用 SiLU」,而是「门控支路用 SiLU」。
6.3 Mish:几乎贴着 SiLU 的近亲
[
\mathrm{Mish}(x)=x\cdot\tanh\bigl(\mathrm{softplus}(x)\bigr)=x\cdot\tanh\bigl(\ln(1+e^{x})\bigr)
]
自下有界、上不封顶、处处平滑,曲线几乎贴着 SiLU。部分视觉与检测任务报过增益,但生态位与 SiLU/GELU 重叠。LLM 主线最终没把它推成默认——不是它不行,是社区已经在 GELU → SwiGLU 的轨道上形成了惯性与基础设施(fused kernel、现成配置、复现基线)。
6.4 GELU 与 SiLU,到底差在哪
对大多数读者,记住这张表就够:
| GELU | SiLU | |
|---|---|---|
| 故事 | 高斯 CDF 门控的期望 | 自己 × Sigmoid |
| 负区 | 有浅凹坑 | 凹坑通常更深一点 |
| 经典舞台 | BERT / GPT-2 / GPT-3 | EfficientNet;以及 SwiGLU 的门 |
| 今天在 LLM | 仍见于老配方与部分编码器 | 更多作为门控组件出现 |
它们都很「软」。真正改变游戏规则的,不是再找一个更软的曲线,而是把软门从「逐元素函数」升级成「第二条可学习支路」。
6.5 平滑激活解决了什么,又没解决什么
GELU/SiLU 主要改善的是:
- 零点附近的可微性与曲率
- 负区「完全无梯度」的极端情况
- 与 Transformer + 残差 + Norm 搭配时的训练手感
它们并不自动解决:
- FFN 容量如何在通道间分配(这是门控的戏)
- 长上下文算力(这是注意力与系统的戏)
- 数据质量与对齐(这是训练目标的戏)
把第三幕理解成「把路修顺」,把第四幕理解成「在路上设收费站与匝道」,就不容易神化任何一条曲线。
7. 第四幕:前沿主场——从「扭曲」到「开门」
到了千亿参数时代,问题变了:不是「有没有非线性」,而是 FFN 里如何用差不多的算力换更高质量的表示。答案是把激活从「逐元素映射」升级成「一条支路产生内容,一条支路产生门」。
7.1 GLU:门控思想进入前馈层
GLU(Gated Linear Unit,Dauphin et al., 2016/17)把输入投到两路,再逐元素相乘:
[
\mathrm{GLU}(x)=\bigl(xW+b\bigr)\otimes\sigma\bigl(xV+c\bigr)
]
左边像「候选内容」,右边像「开多大门」。门接近 0 就掐掉,接近 1 就放行——比单纯 (f(xW)) 多了一个可学习的信息阀门。
可以把它想成:
ReLU/GELU 是给每个通道「拧一把」;GLU 是先问「这条通道今晚还开不开门」。
7.2 GEGLU / SwiGLU:把门换成更好的形状
Shazeer 在 GLU Variants Improve Transformer(2020)里系统比较了门控变体。把 Sigmoid 门换成别的平滑函数,就得到一族亲戚:
| 名称 | 门控用什么 | 形式(示意) |
|---|---|---|
| GLU | Sigmoid | ((xW)\otimes\sigma(xV)) |
| GEGLU | GELU | ((xW)\otimes\mathrm{GELU}(xV)) |
| SwiGLU | SiLU/Swish | ((xW)\otimes\mathrm{SiLU}(xV)) |
| ReGLU | ReLU | ((xW)\otimes\mathrm{ReLU}(xV)) |
实验里,门控变体在语言建模上整体强于普通 ReLU/GELU FFN。后来 PaLM、LLaMA 一脉把 SwiGLU 做成了事实标准。
7.3 落到 Transformer FFN 的写法
忽略 bias(LLaMA 风格常常无 bias):
1 | # 标准 FFN(GPT-2/3) |
对应到 Hugging Face 权重名,通常是:
1 | mlp.gate_proj → W_gate |
看到三投影,基本就可以判定:这不是普通 GELU MLP,而是 GLU 家族。
PyTorch 风格的最小实现:
1 | import torch.nn as nn |
注意一个命名陷阱:有的实现把「先 SiLU 的那路」叫 gate,有的把 chunk 的左右半边顺序写反。数学上只要保持「一路激活、一路不激活、再相乘」,本质相同;对接权重时却必须以该模型约定为准。
7.4 参数量怎么对齐:为什么是「约 8/3 倍」
SwiGLU 多一路投影,若中间宽度仍取经典的 (4d),参数会明显变多。LLaMA 等做法是:把中间宽度略缩,使总参数与「两投影 × 4d」大致打平。
粗算:
- 标准 FFN:(2 \times d \times 4d = 8d^2)
- SwiGLU 三投影:(3 \times d \times d_{ff})
- 令 (3 d, d_{ff} \approx 8d^2) ⇒ (d_{ff}\approx \tfrac{8}{3}d)
再按硬件友好的倍数(如 256)取整。所以你在配置里看到 intermediate_size 不是整整 4 倍,往往就是为了给 SwiGLU「腾名额」。
比较激活函数时,一定要问:比的是同参数、同 FLOPs,还是同中间宽度?三套尺子会给出三种故事。
7.5 从 BERT/GPT-3 到 LLaMA:一次配方迁移
把激活放回更大的配方变迁里,会更好懂:
1 | GPT-2/3 配方(简化) |
SwiGLU 不是单独上场的明星,它是一整套「更稳、更好扩」的 Decoder-only 配方中的一环。这也是为什么「只把 GELU 改成 SiLU、却不加 gate_proj」通常不算完成迁移。
7.6 今天真实模型里你会撞到什么
| 模型族 | FFN / 隐藏激活 | 备注 |
|---|---|---|
| BERT / GPT-2 / GPT-3 | GELU | 两投影 FFN |
| PaLM | SwiGLU | 门控进入超大规模配方 |
| LLaMA / LLaMA 2 / 3 | SwiGLU | 开源生态定锚 |
| Mistral / Mixtral | SwiGLU | MoE 专家内部同样门控 |
| Qwen 系列 | SwiGLU(及同类) | 配置里常见 silu + 三投影 |
| DeepSeek 系列 | SwiGLU 风格门控 | MoE 场景常融量化/融合核 |
所以「当前前沿在用什么激活函数」——若问的是 LLM 的 Feed-Forward,答案几乎就是:
SwiGLU(SiLU 门控的 GLU)
分位置问,答案会变:
- 视觉 CNN 骨干 → SiLU / ReLU 仍很常见
- 注意力权重 → Softmax(及其高效近似)才是主角
- 输出头 → 线性 / Sigmoid / Softmax,跟隐藏层不是一回事
7.7 为什么门控更吃香(直观版)
- 选择性:不是「每个通道都非线性扭曲一点」,而是「先决定听不听这条特征」
- 表达力:同等参数预算下,门控 FFN 往往在语言建模上更强
- 与规模兼容:实现简单,能融进 CUDA / Transformer Engine,和 FlashAttention、分布式训练栈不打架
- 梯度路径更丰富:内容支路与门控支路同时回传,优化更灵活
它不是魔法:多一路矩阵乘,激活阶段的显存与带宽都更紧;小模型、小数据上未必稳定赢。但在「大模型默认配方」里,它已经赢了。
7.8 推理侧的现实:融合核与量化
训练论文写的是数学式;推理引擎写的是 kernel。现代服务里,SwiGLU 常被融合成:
1 | Grouped / Fused GEMM → SiLU(gate)*up →(可选)动态量化 → Down GEMM |
NVIDIA Transformer Engine、各类推理框架都有 SwiGLU 融合实现。MoE 模型里,专家数量多、token 路由不规则,融合与量化更关键——激活函数不再只是「数学课上的 (f)」,而是「内存带宽叙事的一部分」。
这也解释了为什么工业界换激活很谨慎:换一个名字,意味着重做 kernel、重做数值稳定性、重做量化校准。论文里涨 0.1 perplexity,未必盖得过服务侧掉 10% 吞吐。
7.9 MoE 里,激活函数站在更窄的瓶颈上
Mixtral、DeepSeek 一类模型把 FFN 拆成多个专家。对每个 token,只有少数专家被激活。于是:
- 每个专家内部仍然常是 SwiGLU
- 但计算变得「不规则」:不同专家吃到的 token 数不同
- 激活与量化更容易被融进专家 GEMM 的 epilogue,以省显存带宽
这时你优化的已经不只是「函数形状美不美」,而是「在路由稀疏的前提下,非线性算子会不会变成带宽尖刺」。同一套数学,在 dense LLM 和 MoE LLM 里的工程权重不一样。
8. 再往前走:主航道之外的前沿
主航道是 SwiGLU。旁边仍有几条值得认真看一眼的支线——不是为了立刻替换生产,而是理解「下一轮可能改什么假设」。
8.1 ReLU²(Squared ReLU):更猛的半波,也更稀疏
[
\mathrm{ReLU}^2(x)=\bigl(\max(0,x)\bigr)^2
]
它保留 ReLU 的半波整流,再用平方加强正区响应。后果之一是激活往往更稀疏——这对可解释性、条件计算、某些硬件友好存储都有吸引力。部分新架构与开源模型会在非门控 MLP 里使用它(社区实现里也常注册为 relu2)。
直觉对比:
| ReLU | ReLU² | |
|---|---|---|
| 正区 | 线性 | 二次放大 |
| 稀疏性 | 有 | 通常更强 |
| 平滑性 | 0 点折角 | 仍不平滑,但正区更「陡」 |
它像在问:如果正区可以更激进,我们是否还需要那么宽的门控 FFN?答案尚未定论,但这是一条与「继续加门」不同的研究方向。
8.2 xIELU:从「设计函数」转向「设计导数」
2024 年前后的工作 Deriving Activation Functions Using Integration 提出一个很有启发的视角:
别先拍脑袋画 (f);先规定你想要的梯度行为,再积分得到激活。
由此得到 xIELU(Expanded Integral of the ELU):正半轴希望有类似 ReLU² 那样「随输入增大而增强」的梯度;负半轴希望仍可训练、甚至允许梯度取负。参数可学习,使网络在更深的高层表示里有机会自适应地「减弱非线性」。
在公开实验设定下(十亿到数十亿参数量级的 Llama 风格模型、匹配算力与参数),作者报告 xIELU 相对 ReLU²、SwiGLU 有更低的困惑度。这当然还要看更大规模、更多任务的复现;但它提示了一个值得记住的趋势:
1 | 过去:先选一个好看的 f,再看训练顺不顺 |
若这一思路成立,未来「激活函数论文」可能越来越像在设计优化器的局部几何,而不是在选一条好看的曲线。
对工程读者,我建议用更保守的态度消化它:
- 把它当作「梯度优先」设计观的样本,值得学
- 在没有多团队复现、没有推理栈支持前,不要急着写进默认配置
- 若你自己做研究模型,倒是很适合拿来做对照实验:同参数、同数据、同步数,只换 FFN 非线性
前沿文章的正确打开方式,从来不是「立刻站队」,而是「先学会它在优化哪一个瓶颈」。
8.3 夹紧 / 缩放版 SwiGLU:服务稳定性的变体
当模型进入 MoE、低精度、超长上下文服务时,纯教科书 SwiGLU 有时会在数值上「调皮」。工程上出现了变体,例如:
- 对 gate / 预激活做 clamp(限制幅度)
- 用 (\sigma(\alpha x)) 代替 (\sigma(x)),让门的陡峭度可调
- 与动态量化融在同一 epilogue 里
这些变体不一定改变「门控」哲学,却改变「门在半精度与路由噪声下还稳不稳」。读推理框架源码时,看到 ClampedSwiGLU、swiglu_quant 一类名字,多半属于这一层:不是新理论,是生产硬化。
8.4 注意力侧的平行竞赛
与 FFN 平行,注意力权重也在竞赛:
- Softmax 本体(仍是主流)
- Sparse Softmax / Entmax(更稀疏的分配)
- 线性注意力 / 核方法(绕开显式 Softmax,换长上下文成本)
它们改变的是位置之间的路由,不是位置内部的 FFN 非线性。写文章、做选型时,把两条线分开,能少很多概念纠缠。
8.5 可学习激活会不会翻盘?
把激活本身参数化(PReLU 是早期例子),或用样条 / 分段仿射去拟合「每层自己的 (f)」,研究从未停止。工业默认仍偏「固定解析式 + 门控」,原因很现实:
- 更容易融进 CUDA kernel
- 行为可预期,方便数值与量化
- 超参更少,大规模复现成本更低
可学习激活更可能先在中小模型、特殊模态、研究性架构里冒头;要撼动 SwiGLU 的默认地位,需要的不只是论文分数,还有生态与推理栈。
8.6 如何看待「每年都有新激活」
每年都会冒出新名字。有品味的读法不是追新,而是归类:
1 | A. 修负半轴(Leaky / ELU…) |
新工作多半落在其中一类。你先归类,再决定要不要认真做对比实验——比看到名字就焦虑,有效得多。
8.7 一个冷静的预测(不一定对,但好用)
短期内(以开源 LLM 主航道论):
- SwiGLU 仍会是默认——生态与 kernel 惯性太强
- 变体会集中在数值与融合,而不是天天换品牌名
- ReLU² / xIELU 一类更可能先在研究模型、稀疏/可解释场景证明自己
- 真正的大换代,大概率伴随新的训练目标或新的块结构,而不是单独冒出一个激活函数横扫一切
把预期放在这个位置,读论文会轻松很多:你在看的是支流涨水,还是河床改道。
9. 工程手册:怎么选、怎么认、怎么别踩坑
9.1 一张实用对照表
| 场景 | 更稳妥的默认 | 为什么 |
|---|---|---|
| 经典 CNN / 简单 MLP | ReLU 或 Leaky ReLU | 快、成熟、好调 |
| 预训练 Transformer(BERT / 早期 GPT) | GELU | 与文献和现成权重一致 |
| 现代 Decoder-only LLM 的 FFN | SwiGLU | 事实标准 |
| 高效视觉骨干 | SiLU | EfficientNet 等验证充分 |
| RNN 细胞内部 | Tanh / Sigmoid 门 | 结构本身依赖有界门控 |
| 分类输出 | Softmax / Sigmoid | 概率语义清晰 |
| 极小模型 / 极致延迟 / 端侧 | ReLU | kernel 最便宜 |
| 研究新架构、追 SOTA 论文 | 跟论文走 | 复现优先于「更时髦」 |
选型口诀:
1 | 先问位置:隐藏层?注意力?输出头? |
9.2 读权重时怎么「一眼认出」
打开 config.json 或模型定义,抓这些信号:
1 | hidden_act: "gelu" / "gelu_new" → 多半是两投影 GELU FFN |
不必背公式,先认结构。结构对了,名字差一个字母通常无妨。
9.3 六个容易混的点
(1)激活 ≠ 归一化
LayerNorm / RMSNorm 管分布尺度;激活管非线性。现代 LLM 通常是:
1 | x → Norm → Attention → +残差 |
有人把「训练不稳」一股脑怪到激活上,其实先查 Norm 位置、残差有没有接上、学习率是否炸了,往往更管用。
(2)「最新」不一定「该换」
你的任务若对齐 GPT-2 配方,硬改 SwiGLU 却不改宽度与学习率,可能只是引入新超参。换激活是一次小手术,要配:
- 中间层宽度(参数对齐)
- 学习率与 warmup
- 初始化
- 是否有现成 fused kernel
(3)导数故事要落到层数与脚手架
两层 MLP 上 Sigmoid 未必崩;五十层没残差没 Norm,才会把饱和激活的问题放大。今天大模型能用平滑/门控激活,靠的是 残差 + Norm + 合理初始化 + 大规模数据,不只是 (f) 本身变先进了。
(4)输出头别跟风
隐藏层用 SwiGLU,不代表词表头也要门控。回归用线性;二分类可用 Sigmoid;多分类 / 语言模型头几乎总是 Softmax(温度采样仍在 Softmax 家族里)。
(5)同名不一定同实现gelu 有 erf 版和 tanh 近似版;SiLU 与 Swish 在 (\beta=1) 时等价,但旧代码可能留着可学的 (\beta)。对权重敏感的复现,以具体实现为准。
(6)训练友好 ≠ 推理友好
某个激活在 loss 上略好,若没有融合核、又增加显存往返,线上可能整体更慢。研究论文与推理产品的最优解,经常不是同一个。
9.4 一个最小实验建议(真要自己换时)
别一上来全量预训练。更便宜的验证路径:
- 固定数据与步数,只换 FFN 激活 / 门控
- 对齐参数量(尤其 SwiGLU 要缩
intermediate_size) - 看三条曲线:训练 loss、验证 perplexity、吞吐(tokens/s)
- 再看一条工程曲线:峰值显存
- 若走量化部署,再补一条:INT8/FP8 下的质量掉点
如果质量只涨一点、吞吐掉一截,对推理型产品未必划算;如果质量明显更好且 kernel 跟得上,才值得晋级到更长训练。
9.5 和历史的对照:为什么「好答案」一直在变
把各幕叠在同一张决策表上,会发现每次换代都在回答不同瓶颈:
| 时代瓶颈 | 激活给出的答案 |
|---|---|
| 不可微 | Sigmoid / Tanh |
| 深了梯度没了 | ReLU |
| 折角 + 想要更顺滑的 Transformer | GELU / SiLU |
| 大模型 FFN 要更好的容量分配 | SwiGLU |
| 稀疏 / 梯度可设计 / 服务数值稳定 | ReLU²、xIELU、Clamped SwiGLU… |
所以不要问「哪个激活绝对最好」。要问:我现在卡的是表达、优化、算力,还是服务稳定性?
9.6 一份「改 FFN 激活」检查清单
真要动手时,可以按这张单子走一遍:
1 | [ ] 1. 我改的是函数,还是整块门控结构? |
八条里如果有四五条答不上来,说明还没到「值得全量重训」的时刻。先做小规模 ablation,比先改生产默认值更便宜。
10. 常见问题
Q1:我做小分类器,也要上 SwiGLU 吗?
通常不必。数据少、模型浅时,ReLU + 好一点的正则化,往往比复杂门控更稳。SwiGLU 的优势在大规模语言建模配方里更明显。
Q2:SiLU 和 Swish 是不是一个东西?
在最常见设定 (\mathrm{Swish}_{\beta=1}(x)=x\sigma(x)) 时,就是 SiLU。旧文献里的可学 (\beta),今天相对少见。
Q3:为什么注意力还用 Softmax,FFN 却换来换去?
因为职责不同。注意力需要一组和为 1 的权重,Softmax 提供的是概率单纯形上的分配;FFN 需要的是高维特征加工,未必要有界、未必要归一。工具不同,不是品味分裂。
Q4:看见 act_fn = silu 就一定是 SwiGLU?
不一定。有的 CNN 骨干整层都用 SiLU。关键看有没有 gate/up/down 三投影,以及 forward 里是不是 silu(gate(x)) * up(x)。
Q5:残差已经很强了,激活还能有多重要?
残差解决的是「路通不通」;激活解决的是「路上的变换长什么样」。两者互补。没有残差,再好的激活也难训极深;只有残差而激活很差,表达力和优化景观仍会吃亏。
Q6:未来会不会回到更简单的 ReLU?
在端侧、超低延迟、某些稀疏计算场景,完全可能。主航道与所有航道不是一回事。甚至在研究里,ReLU² 也在以「更简单但更猛」的方式回潮。简单与复杂会在不同约束下轮流坐庄。
Q7:生物神经元是脉冲式的,为什么人工网络不用更「像脑」的激活?
脉冲网络(SNN)一直是独立研究方向,但主流深度学习走的是可微、可批处理、可规模化的连续值路线。历史一再表明:在通用智能工程上,「好训、好扩、好部署」往往压过「更像生物」。像,是灵感;不像,常常是为了把规模做上去。
Q8:我微调时要不要改激活?
默认不要。微调是在预训练造好的表示空间里做小步调整;改激活等于改了空间的几何,通常得不偿失。除非你在做架构蒸馏、重构 FFN,或论文明确要求,否则保持与基座一致。
Q9:如何快速判断一篇新激活论文值不值得复现?
看四件事:是否报告同参数 / 同算力对比;是否在你关心的规模(不是只有 MNIST);是否给出稳定超参与多次种子;是否讨论推理成本。四条里缺两条,多半先收藏,别立刻改生产线。
Q10:Softmax 会不会也被换掉?
在注意力主干上,Softmax 仍然极难撼动,因为它提供了清晰的概率归一与良好的优化经验。真正被替换得更多的,是「完整 Softmax 的计算方式」(分块、在线、稀疏、核近似),而不是「不要归一化权重」这件事本身。
11. 收束
激活函数的前世今生,是三条问题的接力:
- 表达:没有非线性,网络是假深
- 优化:饱和曲线训不深,ReLU 把它救回来
- 分配:大模型 FFN 用门控(尤其 SwiGLU)决定哪些特征该过去
从阶跃到 Sigmoid,从 ReLU 到 GELU,再到几乎写进 LLM 标准配方的 SwiGLU——名字在变,目标没变:
在可训练的前提下,把非线性用在刀刃上。
如果只能带走一张心智图,请带走这个:
1 | 开关 → 平滑饱和 → 半波整流 → 平滑软门 → 可学习的门 |
下次打开某一层的配置,不妨先问:这里要的是开关、平滑扭曲,还是一扇可学习的门?
若门上还写着 gate_proj,恭喜你——你已经站在这条历史的最前端了。
最后送一句写给自己用的判词,也适合贴在显示器边:
激活函数不负责让模型「更有智能」;
它负责让智能在可训练、可扩展、可部署的约束下,还有地方安放。
懂了这句话,再看满天飞的新名字,就会轻松很多。
延伸阅读(按出场顺序)
不必全读,遇到卡住的概念再翻:
- McCulloch & Pitts(1943):形式化神经元
- Rumelhart / Hinton / Williams(1986 前后):反向传播普及语境
- Glorot & Bengio;He et al.:初始化与激活的配套
- Nair & Hinton;AlexNet:ReLU 进入深网主流
- Hendrycks & Gimpel:GELU
- Ramachandran et al.:Swish / SiLU
- Dauphin et al.:GLU
- Shazeer:GLU Variants Improve Transformer(SwiGLU 关键来源)
- LLaMA / PaLM 技术报告:工业配方如何把 SwiGLU 写死
- Deriving Activation Functions Using Integration:xIELU 与「先设计导数」思路
历史会继续往前写。但只要你抓住「非线性、可训练、可分配」三条线,新名字出现时,就不容易迷路。
附录:一张「看见名字就知道大概」速查
| 你看见 | 多半意味着 |
|---|---|
| Step / Threshold | 早期感知机,不可训深网 |
| Sigmoid | 概率 / 门;深层前馈易梯度消失 |
| Tanh | 零中心饱和;RNN 细胞常见 |
| ReLU | 深网默认之一;当心 dying |
| Leaky/PReLU | 给负区留坡 |
| ELU/SELU | 平滑负区;非 LLM 主航道 |
| GELU | BERT/GPT-2/3 风格 FFN |
| SiLU/Swish | 平滑软门;也是 SwiGLU 组件 |
| Mish | SiLU 近亲 |
| Softmax | 注意力 / 分类头分配器 |
| GLU/GEGLU/SwiGLU | 门控 FFN;现代 LLM 主菜 |
| ReLU² | 更猛更稀疏的半波 |
| xIELU | 先设计导数再积分的新方向 |
把它当索引,而不是背诵材料。真正用时,仍要回到结构:两投影还是三投影,隐藏层还是输出头,训练还是推理。
如果读完全文只记三句,就记这三句:
- 没有非线性,深度是假的。
- 没有梯度,深度训不动。
- 没有分配,深度浪费在噪音上。
阶跃、Sigmoid、ReLU、GELU、SwiGLU,不过是这三句话在不同年代的不同写法。
也正因为如此,激活函数适合被写成「前世今生」:它不是孤立的公式图鉴,而是一整部深度学习的压缩史。你若能顺着这条线把非线性、反传、残差、Norm、门控、融合核串起来,读大模型论文时会少很多雾,改架构时也会少很多想当然。
从感知机的阈值开关,到今天配置文件里的 gate_proj,中间换过很多次名字,却没有换过那件最硬的事:让层与层之间的变换既足够弯,又足够可训,还足够肯把容量花在刀刃上。明白这一点,这篇长文就算读完了。