Skip to content

LLMs 激活函数篇

来源:AI GC面试宝典 作者:宁静致远 日期:2023年09月29日


1. FFN(前馈神经网络)块

计算公式:

$$FFN(x) = f(xW_1 + b_1)W_2 + b_2$$

📝通俗解释:FFN是Transformer中每个注意力层后面的"加工车间"。它先把输入放大(通过$W_1$升维),经过激活函数处理,再压缩回来(通过$W_2$降维)。就像先把信息拆分成更多小碎片(升维),筛选处理后再组合成原来的样子(降维)。


2. GeLU(高斯误差线性单元)

计算公式:

$$GeLU(x) \approx 0.5x(1 + tanh(\sqrt{\frac{2}{\pi}}(x + 0.044715x^3)))$$

📝通俗解释:GeLU是一种"智能门控"的激活函数。它会根据输入值的大小来决定让多少信息通过:大的正值几乎完全通过,负值会被抑制,接近零的值会有选择性地通过。这比传统的ReLU更"平滑",能让模型学习更细腻的特征。


3. Swish

计算公式:

$$Swish_{\beta}(x) = x \cdot \sigma(\beta x)$$

其中 $\sigma$ 是Sigmoid函数,$\beta$ 是可训练参数。

📝通俗解释:Swish可以理解为"带参数的平滑门"。它把输入乘以一个经过Sigmoid处理的门控值 ($\beta x$)。$\beta$ 可以让模型自己学习门控的"松紧程度",比固定的门控更灵活。


4. GLU(线性门控单元)

计算公式:

$$GLU(x) = \sigma(xW + b) \otimes xV$$

使用GLU的FFN:

$$FFN_{GLU} = (f(xW_1) \otimes xV)W_2$$

📝通俗解释:GLU的核心思想是"用一部分信息控制另一部分信息的通过"。$\sigma(xW)$ 产生一个0~1之间的"门控值",然后用它来控制 $xV$ 的信息流量。这就像用一个开关来调节水流大小,比单一的非线性变换更有效。


5. GeGLU(GeLU + GLU)

计算公式:

$$GeGLU(x) = GeLU(xW) \otimes xV$$

📝通俗解释:GeGLU把GLU中的Sigmoid门控换成GeLU,让门控变得更"智能"。不再是简单的开/关,而是根据输入大小动态调整通过程度。


6. SwiGLU(Swish + GLU)

计算公式:

$$SwiGLU = Swish_{\beta}(xW) \otimes xV$$

📝通俗解释:SwiGLU结合了Swish的平滑特性和GLU的门控机制,是目前大语言模型中表现最好的激活函数之一。LLaMA系列模型就采用了这种设计。


7. 各LLM模型使用的激活函数

模型激活函数
GPT-3GeLU
LLaMASwiGLU
LLaMA2SwiGLU
BaichuanSwiGLU
ChatGLM-6BGeLU
ChatGLM2-6BSwiGLU
BloomGeLU
FalconGeLU

📝通俗解释:从表格可以看出,早期模型(如GPT-3、Bloom)倾向于使用GeLU,而较新的模型(如LLaMA、Baichuan)则选择SwiGLU。这反映了业界对激活函数认知的演进——SwiGLU的门控机制能带来更好的性能。


8. FFN中间维度的计算

以隐藏层维度 $h = 4096$ 为例:

  • 标准FFN(4h): $4 \times 4096 = 16384$
  • GLU类FFN(4h × 2/3): $\frac{2}{3} \times 4 \times 4096 \approx 10923$,向上取整到128的倍数得到 11008

📝通俗解释:FFN的中间层通常比输入大很多(通常是4倍),这样可以提供更大的"思考空间"。但GLU类FFN因为多了一个门控分支,中间层可以稍小一些(~2.67倍),减少计算量的同时保持类似性能。


9. 模型参数对比

LLaMA-7B

模块参数形状参数量
model.embed_tokens.weight[32000, 4096]131,072,000
model.layers.0.self_attn.q_proj.weight[4096, 4096]16,777,216
model.layers.0.self_attn.k_proj.weight[4096, 4096]16,777,216
model.layers.0.self_attn.v_proj.weight[4096, 4096]16,777,216
model.layers.0.self_attn.o_proj.weight[4096, 4096]16,777,216
model.layers.0.mlp.gate_proj.weight[11008, 4096]45,088,768
model.layers.0.mlp.down_proj.weight[4096, 11008]45,088,768
model.layers.0.mlp.up_proj.weight[11008, 4096]45,088,768
model.layers.0.input_layernorm.weight[4096]4,096
model.layers.0.post_attention_layernorm.weight[4096]4,096

📝通俗解释:LLaMA的FFN使用了3个投影矩阵(gate、up、down),这是SwiGLU的标准配置。相比传统的2个矩阵(up_proj、down_proj),多出来的gate_proj用于生成门控信号。


BLOOM-7B

模块参数形状参数量
transformer.word_embeddings.weight[250880, 4096]1,027,604,480
transformer.word_embeddings_layernorm.weight[4096]4,096
transformer.word_embeddings_layernorm.bias[4096]4,096
transformer.h.0.input_layernorm.weight[4096]4,096
transformer.h.0.input_layernorm.bias[4096]4,096
transformer.h.0.self_attention.query_key_value.weight[12288, 4096]50,331,648
transformer.h.0.self_attention.query_key_value.bias[12288]12,288
transformer.h.0.self_attention.dense.weight[4096, 4096]16,777,216
transformer.h.0.self_attention.dense.bias[4096]4,096
transformer.h.0.post_attention_layernorm.weight[4096]4,096
transformer.h.0.post_attention_layernorm.bias[4096]4,096
transformer.h.0.mlp.dense_h_to_4h.weight[16384, 4096]67,108,864
transformer.h.0.mlp.dense_h_to_4h.bias[16384]16,384
transformer.h.0.mlp.dense_4h_to_h.weight[4096, 16384]67,108,864
transformer.h.0.mlp.dense_4h_to_h.bias[4096]4,096

📝通俗解释:BLOOM使用的是标准的FFN结构(dense_h_to_4h和dense_4h_to_h),中间层维度是16384(4×4096),这与它使用GeLU激活函数的设计一致。相比LLaMA的SwiGLU,BLOOM的FFN只有2个投影矩阵。


参考来源: 知识星球 - AI GC面试宝典 整理日期: 2024年8月11日

基于 MIT 许可发布