本节摘要:前馈神经网络(Feed-Forward Network,FFN)是 Transformer 每层中紧随注意力之后的子层:一个逐位置应用的两层全连接网络,先升维(通常到四倍模型维度)、经非线性激活、再降回原维,各位置共享同一套参数。它不负责词与词的交流——那是注意力的职责——而是对每个位置的表示做独立的非线性加工,是模型主要的参数存放地与"记忆"载体。本节讲清其结构、位置独立与参数共享的含义、升维的动机,以及激活函数的演化与参数占比的工程账。
阅读完本节,你应当能够:
先复位它在整机中的角色。一层 Transformer 内部,数据先过多头注意力——所有位置互相交换信息;随后每个位置的表示进入前馈网络做独立加工。两步的分工像开会与写报告:注意力是会议,各岗位同步对齐信息;前馈是会后,每个人回工位独自消化,把吸收的信息转化进自己的表示。
为什么注意力之后必须有这一步?注意力的输出是值向量的加权平均——线性组合。线性运算的复合仍是线性的,不补非线性,堆多少层都等价于一层线性变换。前馈网络中间夹着一个非线性激活函数,正是模型表达非线性关系的最低配置。同时它承担着"存储"职能:有研究把前馈网络类比为键值记忆——升维矩阵的各行像一组模式探测器,降维矩阵把命中的模式映射成输出修正,训练语料中的知识大量沉淀在这些权重里。大模型参数动辄数十亿,其中约三分之二躺在前馈层,这个数字值得记住。
网络结构出奇地简单。输入是单个位置的表示向量,维度为模型维度 d_model。第一层线性变换把它升到中间维度 d_ff——原论文取四倍关系,即 d_model 为五百一十二时 d_ff 为两千零四十八;经过非线性激活;第二层线性变换再降回 d_model。两次矩阵乘法、一次激活,结束。
为什么要先升四倍再降回来?升维给了激活函数更大的工作面:在高维空间里,更多方向上可以做非线性的取舍,模式的表达容量随之放大;降维则把结果压缩回统一接口,供残差连接与下一层使用。四倍不是铁律而是经验值,后续模型有取八倍的,也有在极高维度下适当缩小比例的——本质是在容量与显存之间找平衡点。
两个性质需要严格区分。"逐位置独立":网络对序列中每个位置分别应用,位置 A 的加工不使用位置 B 的信息——跨位置的信息交换已经由注意力完成,前馈只管精炼。"参数共享":所有位置用同一套权重加工——同一层内,不论词在第几位,加工方式一致。这与一维卷积的行为相同,所以它也常被描述为"逐位置的两层一维卷积"。参数共享让模型对位置平移保持一致的行为,也把参数量控制在单个网络的规模。
| 性质 | 含义 | 带来的效果 |
|---|---|---|
| 逐位置独立 | 各位置的加工互不影响 | 跨位置交互全部由注意力承担,职责清晰 |
| 参数共享 | 全部位置用同一套权重 | 对平移一致,参数量不随序列长度增长 |
| 先升维 | 中间维度约为四倍模型维度 | 扩大非线性表达的工作面 |
| 后降维 | 输出回到模型维度 | 与残差连接和下一层接口对齐 |

原论文用的是 ReLU:负值归零、正值保留,简单粗暴,计算近乎免费。它的缺陷是"死区"问题——某些神经元的输入长期为负时梯度恒为零,单元永久失活。后续主流模型转向 GELU:一种平滑的概率性门控,把"硬开关"换成"软开关",负区间不完全归零,梯度更连续,训练更平稳。再后来还有 SwiGLU 等带门控的变体,在升维层引入乘性门控,近年大模型采用较多。选择激活函数属于"便宜的性能优化":从 ReLU 换到 GELU 通常有小幅稳定收益,且几乎不增加计算负担。
另一个实践细节是偏置项。原论文公式里带偏置,后续不少实现发现去掉前馈与注意力的偏置对性能影响甚微,还能略微提速与省显存——工程取舍的典型案例:先按论文实现,再按测量结果裁剪。
⚠️ 常见坑:把前馈网络写成对整个序列矩阵做"一层大线性",导致各位置的信息在升维前就发生混合。正确做法保证第一层的作用严格逐行——矩阵乘法本身逐行独立,容易在拼接多头输出或 reshape 时不经意间破坏行结构。排查方法:构造只有一行非零的输入,检查其他行的输出是否严格为零。
💡 理解检验:向别人解释"为什么注意力之后必须跟一个逐位置的非线性网络",如果你的回答包含"注意力输出是线性组合、多层线性复合仍是线性"这层因果,说明这部分已经吃透。
算一笔具体的账帮助建立量级感。设模型维度 d_model,中间维度取四倍。单个前馈网络的参数量约为八倍的 d_model 平方(两层,各约 d_model 乘四倍 d_model)。多头注意力的参数约为四倍的 d_model 平方(三组输入投影加一组输出投影)。也就是说,单看一层,前馈的参数量约为注意力的两倍;层数堆多后,全模型约三分之二的参数在前馈层。裁剪模型规模时砍前馈的中间维度,往往比砍头数更见效;反过来,做知识容量分析时,前馈层也是首要观察对象。
显存方面,推理时前馈层的中间激活是峰值显存的重要贡献者——四倍升维的中间结果即使瞬时也要落地。工程上因此有算子融合、激活重算等手段摊平这一段的开销,属于部署优化入门必碰的墙。
参数量上前馈约为注意力的两倍(八倍维度平方对四倍维度平方),但计算量占比随序列长度变化:序列短时前馈主导,序列拉长后注意力的平方项反超。这带来一个实用的调优直觉——长上下文场景优化注意力(稀疏化、分块),短序列高吞吐场景优化前馈(算子融合、量化),瓶颈诊断先看序列长度再下结论。这也解释了为什么第 1 章反复强调平方复杂度:它不仅影响显存,还改写了两个子层的算力天平。
两层是容量与训练难度的平衡点。加深到三层、五层并非不可行,但残差连接已经把"多层堆叠"的任务交给了整个 Transformer 塔的层级——每层一个浅前馈、跨层叠加,等价于把深度摊到架构的纵向维度。模块内部保持浅平,模块之间堆深度,这是 Transformer 整体设计哲学的一部分:复杂度来自组合,而非单点。
它是量化的重点对象——参数占比高、结构规整(纯矩阵乘加激活),量化与稀疏化的收益立竿见影;中间激活的显存峰值也可通过激活重算摊薄(用时间换空间)。近年研究还探索把前馈层视为大稀疏记忆、按需激活部分神经元的方案,进一步压低推理成本。对应用者的落点:选推理引擎时关注其对前馈层的优化说明,这部分往往决定整体的吞吐表现。
⚠️ 一个数据流的隐蔽陷阱:多头注意力的输出拼接后直接进前馈是安全的(拼接发生在特征维、行结构未动),但若上游有自定义的序列重排或截断操作,进入前馈前务必确认"行等于位置"的约定未被破坏。前馈对序列结构一无所知,它不会报错,只会安静地算出错误结果——这类静默错误比崩溃更难排查,值得单测覆盖。
💡 记忆锚点:给同事讲 Transformer 时,把前馈网络说成"每个词的私人车间",把注意力说成"全体词汇的会议室"。两个比喻分别强调"逐位置独立"与"跨位置交互",一private一public,配对出现就不易张冠李戴。
可以改,且改动效果可预期。降到两倍:参数与显存立减,小数据任务常无感甚至更好(容量匹配数据);升到八倍:知识容量增大,大语料训练常有收益,显存与推理成本同步上涨。近年大模型的趋势是高维下适当回落比例(避免参数爆炸),小模型维持四倍。这组事实再次印证本节主线:前馈维度是"知识容量旋钮",转动它之前先问数据量撑不撑得起。
交流、多视角、顺序、消化都齐了。下一节补上最后一块:让几十层深网训得动的残差连接与层归一化。
问:前馈网络为什么先升维到四倍再降回来,中间那层宽通道是干嘛的?
答:升维-非线性-降维的结构相当于把每个位置的信息先「展开」到高维空间做充分的非线性组合,再压缩回标准宽度。四倍这个比例(d_ff 等于四倍 d_model)是原论文的默认配置,后续研究在压缩计算量时也多围绕它做文章。可以粗略理解为:注意力负责「收集别的词的信息」,前馈负责「把收集来的信息消化成这个位置的新表示」,消化需要空间,宽中间层就是那个工作台。
问:每个位置过的是同一个前馈网络吗?
答:是同一个——所有位置共享同一组权重,各算各的。这正是「逐位置独立」的含义:同一套加工逻辑施加于每个词,不因位置而异。位置间的交互完全交给了注意力,两层分工因此干净:注意力管横向交流,前馈管纵向加工。共享权重也带来参数效率,模型不随序列长度增加参数。