Skip to content

【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是"肌肉",自注意力是"大脑"——两者缺一不可。