技术笔记 | 一个容易混淆的点:中间 hidden activation 的坐标变了,不代表模型函数变了。FFN intermediate 维度是一个内部坐标系;只要写入它的矩阵和读出它的矩阵同步换坐标,FFN 交给 residual stream 的输出可以严格不变。| 2026-07
起点:hidden 变了,函数未必变
剪枝或合并 FFN neuron 时,一个自然困惑是:如果我把 intermediate neuron 的顺序重排了,中间 hidden state 明明变了,模型怎么还能等价?
关键区分是:中间 维表示是 FFN 内部坐标,FFN 输出的 维向量才是写回 residual stream 的对象。如果只看 hidden activation 的第几个位置,重排当然会改变它;但如果读这个 hidden 的下一层权重也同步重排,外部看到的函数可以完全不变。
这不是直觉上的“差不多”,而是一个严格的重参数化不变性。
命题:FFN 对 intermediate 维排列不变
设两层 FFN 的 intermediate size 为 :
其中
是逐元素激活函数。对任意排列矩阵 ,令
那么新 FFN
满足
也就是说:同步重排 的行与 的列,FFN 作为函数不变。
证明
只需要一个小引理:逐元素函数与排列可交换。
对任意 ,有
证明很直接。设 对应一个 index 双射 ,即 。那么
而
逐分量相等,所以 。
回到主命题:
第三行用的是逐元素激活的排列等变性,第四行用的是 。
这解决的是哪个困惑
令
重排之后的中间激活是
所以,如果把 当作一个 维向量逐坐标比较,它确实变了:原来第 7 个位置上的数可能跑到了第 2 个位置。这就是“hidden state 看起来不一样”的来源。
但 的坐标轴不是 residual stream 的坐标轴。它只是 FFN 内部那 个 intermediate neuron 的编号。 会用相反方向把这个坐标变换抵消掉,因此最终写回 residual stream 的 维输出不变。
一句话:中间 维表示重排,输出 维表示不变。 前者是内部坐标,后者才是 FFN 暴露给模型其余部分的接口。
实现里的行列约定
上面的证明采用 column-vector 记法: 是列向量, 的每一行对应一个 intermediate neuron, 的每一列对应同一个 neuron 的读出方向。
很多框架里 forward 写成 row-vector 形式:
这时常见实现里第 个 intermediate neuron 对应 的第 列、 的第 列。若 perm 表示“新顺序对应的旧位置”,则同步重排通常写成:
W_up_new = W_up[:, perm]
W_down_new = W_down[:, perm]
b_up_new = b_up[perm]真正的判断标准不是“行”或“列”这个词,而是:同一个 intermediate neuron 在 up projection 里被写入的方向,必须和 down projection 里被读出的方向一起移动。
如果 FFN 带 bias,
则需要同步设 ;输出侧 bias 位于 维 residual 坐标,不属于 intermediate 坐标,所以不动。
Gated FFN 也是同一逻辑。例如 SwiGLU 里若
则 与 的 intermediate 行用同一个 重排, 的 intermediate 列用 抵消。因为逐元素乘法也与排列交换:
它不是 merge 的证明
这个命题只说明:对同一个 FFN 施加同步 permutation,是 function-preserving reparameterization。
它不说明剪枝本身不改变函数。剪枝删掉 neuron 后,函数通常已经变了;permutation 只是对剪枝后的模型重新编号。
它也不说明多个 expert 平均后函数不变。跨 expert merge 时,不再是“一个模型的两端用 与 抵消”,而是在平均多份不同权重。平均之后的行为会改变;这正是 merge 方法要赌的地方,而不是这个命题能保证的东西。
所以最安全的说法是:permutation 可以把一个 expert 内部的 neuron index 调整到我们想要的顺序,并且这一步本身零损失、零函数变化。至于后续把哪些 neuron 平均、哪些保留、是否再剪回原宽度,是另一个问题。
一个更一般的判据
FFN intermediate 维不是孤例。它揭示的是一类更一般的结构:某个内部维度如果只是并行子单元的坐标,并且两侧有同步抵消的读写变换,那么这个维度通常存在排列自由度。
这句话里有三个条件。
第一,中间操作要对这个维度的各分量独立,或者至少对排列等变。逐元素激活、逐元素乘法、per-channel scale 都属于这一类。第二,这个维度两侧要有一写一读的线性变换,允许一侧乘 、另一侧乘 抵消。第三,这个维度不能被外部系统按固定 index 直接赋予语义;如果 index 本身携带位置、频率、词表 id 之类的外部含义,就不能随便排。
这个判据比背结论更重要。它解释了为什么有些 LLM 内部维度像 FFN intermediate 一样自由,而另一些看起来也是“维度”的东西并不自由。
LLM 里的几个代表性位置
最接近 FFN intermediate 的,是 attention 的 head 顺序。多头注意力里,各个 head 并行计算,最后 concat 到一起,再由 读出。只要把 的 head block 同步重排,并把 的对应输入 block 反向重排,head 的排列会在 处抵消。head 的编号本身不是 residual stream 的语义坐标;它更像一组并行模块的内部顺序。
value 侧的 head dimension 也比较接近这个模式。 写出 value 向量,attention weights 对 value 做线性加权,之后 读出 value 维。若只讨论 value 通道本身,同步重排 value 维与 的对应输入方向,可以保持输出不变。
QK 侧更受限制。query 和 key 不是简单地被下一层线性读出,而是要先做内积:
如果没有位置旋转等额外结构,同时用同一个排列重排 和 ,内积仍然不变:
但这已经不是 FFN 那种“一侧 、另一侧 夹住逐元素非线性”的结构,而是一个成对约束:Q 与 K 必须一起动。若模型使用 RoPE,这个自由度还会进一步收紧,因为 RoPE 把 head dimension 按二维 pair 和频率绑定到位置旋转上。任意打乱 QK 维度会破坏这种固定结构;除非同时修改 RoPE 的维度组织,否则不能把它当作普通可排列坐标。
residual 维度则是另一个极端。理论上,如果对整个模型的 residual stream 统一施加同一个全局排列,并同步修改所有读写 residual 维的矩阵,函数也可以不变。embedding、每层的 QKV 输入侧、MLP 输入侧、attention/MLP 输出侧、LayerNorm/RMSNorm 的 per-channel 参数、最后 unembedding,都要一起换坐标。均值、方差、RMS 这类归一化统计本身对排列不敏感,通道参数跟着排即可。
但这是一种全局 symmetry,不是 FFN intermediate 那种局部 symmetry。任何一处漏排都会破坏函数;而且 residual stream 是跨层共享的通信空间,所有组件都在读写它。换句话说,residual 维理论上可换坐标,实践上高度纠缠。
也有一些维度根本不该类比。token 位置不是内部并行坐标,因为 causal mask 和位置编码把序列位置固定成了计算结构的一部分;层顺序也不是可交换的并行单元,因为 Transformer layer 是串行函数复合。词表 index 在数学上可以通过同步重排 embedding 行和 unembedding 列保持 logits 的相对结构,但 token id 有外部字典语义,重排它等于换了一本字典,通常不是有意义的模型内部对齐操作。
Takeaway
FFN intermediate permutation 的本质,是一种局部重参数化对称性:neuron index 只是内部坐标,不是模型输出语义本身。同步重排读写两端,hidden activation 的坐标会变,FFN 写回 residual stream 的向量不变。
这是 参数空间与计算图 中「同一个函数可以对应多组参数坐标」的一个具体例子。
这个视角有两个用处。
第一,它能避免把“内部坐标差异”误读成“函数差异”。看到两个剪枝后的 FFN neuron 顺序不同,不应立即认为模型行为不同;先问这些 index 是否只是同一组内部坐标的不同排列。
第二,它也提醒我们不要滥用这个对称性。FFN intermediate 和 attention head 顺序是局部、并行、可抵消的;QK/RoPE 维、residual 维、token 位置、层顺序则分别受内积、位置结构、全局通信或串行组合约束。排列不变性不是“所有维度都能随便排”,而是只在特定内部坐标上成立。
因此,若一个压缩或合并方法选择先在 FFN intermediate 维做 neuron-level 对齐,它利用的是一个干净的局部自由度:对齐这一步可以严格不改变单个 expert 的函数。真正会改变行为、也真正需要实验验证的,是之后的剪枝、平均、保留和再压缩。