【LLM核心】大脑和肌肉
FFN(前馈网络)是Transformer里最不性感但最重要的组件之一。
一、第一性原理
为什么需要FFN?
自注意力机制的局限:
- 只做线性变换 + softmax(也是线性的归一化)
- 只负责"信息路由"(把相关token的信息聚合起来)
- 但不做复杂的特征转换
类比:
javascript
// 自注意力 = 信息的"搬运工"
function attention(tokens) {
// "计算" 这个token需要 "生命周期" 的信息?
// 好,我帮你把"生命周期"的表示搬过来
return weightedSum(tokens, attentionScores)
}
// FFN = 信息的"加工厂"
function ffn(token) {
// 拿到聚合后的信息,现在要深度加工
return W2(relu(W1(token)))
// 把"计算+生命周期"的组合特征
// 转换成更抽象的语义表示
}
二、具体例子
理解"计算生命周期"
Step 1: 自注意力聚合信息
"计算" token 经过注意力后:
embedding_after_attention =
0.1 * embed("如何") +
0.15 * embed("优化") +
0.35 * embed("生命") +
0.35 * embed("周期") +
...
现在"计算"的表示包含了上下文,但还是各个词向量的线性组合
Step 2: FFN做非线性变换
javascript
javascript
function ffn(x) {
// 第一层:升维 (768 → 3072)
h = relu(W1 * x + b1)
// 在高维空间做复杂模式识别:
// - 识别"计算+生命+周期"的组合模式
// - 激活"软件工程领域"的神经元
// - 抑制"数学计算"的神经元
// 第二层:降维 (3072 → 768)
output = W2 * h + b2
return output // 现在是"计算生命周期"的抽象语义表示
}
三、FFN的本质
它是模型的"记忆库"和"知识库":
go
// 类比:FFN的参数矩阵存储了大量模式
type FFN struct {
W1 [3072][768]float // 这里存了海量知识
W2 [768][3072]float
}
// 比如W1的某一行可能学到:
// neuron_1024 激活 ← "计算" + "生命" + "周期" 同时出现
// neuron_2048 激活 ← "计算" + "资源" + "调度" 同时出现
数据对比
GPT-3的参数分布:
- 自注意力层: ~25%参数
- FFN: ~75%参数 ← 大头在这里!
为什么FFN占这么多参数?
- 自注意力: QKV投影矩阵,相对轻量
- FFN: 需要存储所有领域知识、概念关系、语言模式
和自注意力的分工
自注意力: "这个句子里哪些词相关?" (动态的,依赖输入)
FFN: "这种词组合模式代表什么概念?" (静态的,存在参数里)
完整流程:
输入:"优化计算生命周期"
↓
自注意力: "计算"需要关注"生命周期"
↓
FFN: 识别这是"software lifecycle"概念,激活相关知识
↓
输出: 关于软件生命周期管理的回答
对CML的启示
如果CML能标记语义单元:
xml
xml
<concept domain="software-engineering">计算生命周期</concept>
可能让FFN更快定位到正确的知识区域,减少不必要的神经元激活,提升推理效率。
FFN是"肌肉",自注意力是"大脑"——两者缺一不可。