门控:一路当开关,一路当内容(顺便数清楚有几块矩阵)
🎯 先猜一猜(下注解锁)
普通 MLP 升维只用 1 块矩阵就够了。SwiGLU 偏要拆成 gate + up 两块,凭空多花一倍参数——它图的到底是什么?
先押一个假设:SwiGLU 多花一块升维矩阵,最核心的目的是?
先补的知识
- Linear(d_in, d_out) 就是一块权重矩阵,把最后一维从 d_in 映射到 d_out。
- SiLU(x) = x · sigmoid(x),是一条平滑的激活曲线,输出可正可负、像“软开关”。
- 两个 shape 完全相同的张量可以逐元素相乘(Hadamard ⊙)。
图解原理
传统 MLP 升维后只过一次激活,像一条单行道;SwiGLU 把升维这步分成并行两条:gate 支路算“开关强度”,up 支路算“内容”,两者相乘后再降维。记住它一共用了 3 块矩阵——下一关的参数推导全靠这个数字。
x 先升维,过一次固定激活(如 ReLU 把负数一刀切成 0),再降维。开关是写死的,不会随数据变。
up 支路(W_up)产出“内容”;gate 支路(W_gate)产出一个经 SiLU 的“开关强度”。两条 shape 一样,逐元素相乘,再用 W_down 降回原维度。
开关由数据自己学:该放行的位置接近 1,该压制的接近 0,比固定的 ReLU 灵活得多——这就是 SwiGLU 表达力更强的来源。
数一数矩阵:W_gate、W_up、W_down 共 3 块。传统 MLP 只有 2 块。多出来的那块 gate 就是门控的“代价”,下一关要把它算进账。
语法热身:用“开关 × 内容”筛选数值
knob = torch.tensor([-1.0, 0.0, 2.0]) # 开关原始打分
value = torch.tensor([10.0, 10.0, 10.0]) # 内容
# sigmoid 把开关压到 0~1:负数→趋近 0(关),正数→趋近 1(开)
gate = torch.sigmoid(knob) # [0.27, 0.50, 0.88]
filtered = gate * value # [2.7, 5.0, 8.8]
# 真正的 SwiGLU 用 F.silu 代替 sigmoid,思路完全一样巩固一下
巩固:gate 和 up 两条支路的输出,必须满足什么条件才能执行 gate ⊙ up?
回到 notebook 的作业
这里不直接写答案。你已经拿到足够输入,最后用 notebook 的 TODO 做举一反三。