如果你只盯着模型结构图,你很可能以为 SwiGLU 是 Swish 的“升级版”——名字像,功能应该也像。我第一次在 LLaMA 的代码里看到 SwiGLU 时就是这么想的,直到翻到 Noam Shazeer 2020 年的论文才愣住:SwiGLU 并不是 Swish 的直系后代,它更接近另一个分支——GLU。而 Swish 自己,也有一个更早的名字叫 SiLU。

这个家族比你想的更复杂,也比你想的更简单:复杂的是名字,简单的是数学。
同一个函数,两个名字
在深度学习早期,ReLU 靠“简单、不饱和、梯度好算”统治了激活函数。但 ReLU 有一个很明显的毛病:负数输入直接变 0,一旦某个神经元持续输出为负,它就再也不会被激活,俗称“神经元死亡”。于是很多人开始想:能不能找一个有下界、又不会把梯度直接砍没的替代品?
2017 年,Elfwing 等人在强化学习论文里给出了一个答案:f(x)=x·σ(x),σ 是 sigmoid。这个函数叫 SiLU(Sigmoid-Weighted Linear Units)。它的形状很优美:x 很大时,σ(x) 接近 1,输出接近 x;x 很小时,σ(x) 接近 0,输出接近 0;x 在 0 附近时,它有一个平滑的转折,既保留了 ReLU 的无界增长,又避免了 ReLU 在负数区域的“硬摔”。
一年后,Google Brain 的 Ramachandran 等人用自动化搜索重新发现了同一个函数,命名为 Swish,并加了一个可学习参数 β:f(x)=x·σ(βx)。当 β=1 时,Swish 就是 SiLU。由于 Swish 这篇论文(Searching for Activation Functions)影响力太大,Swish 这个名字几乎成了标准称呼。
SwiGLU 的真身:GLU 的门控骨架
如果说 SiLU/Swish 是一条血脉,那么 SwiGLU 其实来自另一条血脉——GLU。GLU(Gated Linear Unit)来自 2016 年 Dauphin 等人的论文(Language Modeling with Gated Convolutional Networks)。它的核心思想是:用一个线性变换的输出和另一个经过 sigmoid 的门控信号逐元素相乘,让网络自己学会“放行多少信息”。
标准 GLU 的公式是:
GLU(x) = (xW1 + b) ⊗ σ(xW2 + c)
2020 年,Noam Shazeer 在《GLU Variants Improve Transformer》中做了一件事:把 GLU 里的 σ 换成各种其他激活函数,看哪个效果最好。结果 Swish 赢了。他给这个变体命名为 SwiGLU,形式是:
SwiGLU(x) = (Swish(xW1) ⊗ xW2) W3
注意,这里的 Swish 不是主输出的激活函数,而是“门控信号的压缩器”。真正的结构是:输入先分成两路,一路直接经过线性变换作为“主信号”,另一路用 Swish 映射到接近 (0,1) 的范围作为“门”,两者相乘后再过第三个线性变换。这是门控,不是简单地把某个激活函数套在隐藏层上。
从 ReLU 到 SwiGLU:一张谱系表
把几个名字放在一起看,关系就清晰了:
| 名称 | 表达式 | FFN 权重数 | 关键出处 |
|---|---|---|---|
| ReLU | max(0,x) | 2 | Nair and Hinton, 2010 |
| GELU | x·Φ(x) | 2 | Hendrycks and Gimpel, 2016 |
| SiLU / Swish | x·σ(x) | 2 | Elfwing et al., 2017; Ramachandran et al., 2017 |
| SwiGLU | (Swish(xW1)⊗xW2)W3 | 3 | Shazeer, 2020 |
注意,GELU 和 SiLU 的形状很接近,它们都是“平滑的 ReLU”。但 SwiGLU 的结构和它们有本质差别:它不是一个单输入单输出的激活函数,而是一个需要两个输入并产生门控输出的模块。
大模型为什么离不开它
在 Transformer 的前馈网络里,最原始的设计是线性变换加 ReLU:FFN(x)=ReLU(xW1)W2,需要两个权重矩阵。GPT 后来改用 GELU,LLaMA 则直接采用了 SwiGLU。LLaMA 论文(LLaMA: Open and Efficient Foundation Language Models)里有一句话:
“We use the SwiGLU activation function following PaLM. The hidden dimension is 2/3 · 4d instead of 4d as in PaLM, because SwiGLU has three matrices instead of two.”
翻译过来就是:我们跟随 PaLM 用 SwiGLU,为了保持总参数不变,中间维度从 4d 缩小到 8d/3,因为 SwiGLU 有三个矩阵,而原来只有两个。这句话点破了关键:SwiGLU 不是免费的午餐,而是用更多参数换更好的拟合能力。在相同参数量下,它的效果通常优于 ReLU/GELU,所以现代大模型愿意为它多付一份矩阵运算的成本。
我栽过的那个坑
我第一次在 Transformer 代码里看到 activation=’swiglu’ 时,想当然地以为它只是把 FFN 里的 ReLU 换成了 Swish。改完以后 loss 不降,参数量也莫名多了一大截,查了很久才意识到:SwiGLU 不是一个“激活函数位”的替换,它意味着一整个 FFN 结构都变了。你不光要换激活函数,还要把隐藏层变成两条并行分支,最后再接一个输出线性层。很多框架的 LLaMA 配置里已经把隐藏层维度调小了,如果你直接套普通 FFN 的 config,参数量就会对不上。
这个教训让我后来看模型代码时多了一个习惯:先看结构图,再认名字。
三个常见误解
- SiLU 和 Swish 是完全一样的函数吗?
- 当 β=1 时完全一样。SiLU 就是固定 β=1 的情况,Swish 论文中的 β 可以是常数或可学习参数。所以在绝大多数框架实现里,两者没有任何区别。
- SwiGLU 能直接替换任意位置的 ReLU 吗?
- 不能。SwiGLU 多了一个门控分支和线性层,会改变参数量和计算结构。它主要被用在 Transformer 的前馈层,直接替换卷积网络里的 ReLU 收益不大,还可能拖慢训练。
- GeGLU、SwiGLU、GLU 是什么关系?
- GLU 是基底,GeGLU 和 SwiGLU 都是把 GLU 里的 sigmoid 换成别的激活函数:GeGLU 用 GELU,SwiGLU 用 Swish。Shazeer 的实验里,SwiGLU 在语言建模目标上的效果最好。
这个代价,值不值得
SwiGLU 最大的代价是参数和内存。三个权重矩阵意味着更高的显存占用和更长的推理延迟。大模型推理往往受“内存带宽”限制,每多一个矩阵,权重读取量就多一分。LLaMA 里把维度缩到 8d/3,就是在补偿这个代价。
因此,如果你的项目不是在训练一个千亿参数模型,而是在边缘设备上做推理,SwiGLU 不一定是最优选择。在你的场景里,瓶颈是模型效果还是参数量、推理速度?这笔账要自己算。
我的判断是:短期之内,SwiGLU 仍然会是主流大模型的前馈层默认选择,但它的“三矩阵”结构给未来留下了空间。研究者们仍在寻找更省参数、同时保持门控优势的替代方案。也许下一个突破不是发明新的激活函数,而是把门控结构做得更轻。
回头看这个家族,SiLU、Swish、SwiGLU 并不是一条直线上的三个台阶,而是两条血脉的交汇:一条是“让神经元死得优雅一点”的 SiLU/Swish,另一条是“给线性变换装个门”的 GLU。SwiGLU 之所以流行,不是因为它名字里带 Swish,而是因为它把门控机制融进了 Transformer 的骨架。
所以下次再看到 SwiGLU,别急着把它归类为“Swish 的加强版”。它提醒我们:深度学习中真正重要的往往是结构,而不是名字。看清这个谱系,你才算真正认识今天的大模型。
原创文章,作者:guanweilu,如若转载,请注明出处:https://guanweilu.cn/article/599.html