你训练了三个不同风格的模型:一个擅长写代码,一个擅长数学推理,一个擅长遵循指令。正常思路是三选一,或者三个都部署然后做集成推理。但社区里有一群人做了一件听起来很荒谬的事——他们把三个模型的权重直接做加权平均,得到一个新模型。没有任何训练,没有任何梯度更新,纯粹是把几十亿个浮点数按位置加起来除以三。结果这个”缝合怪”模型往往比任何一个原始模型都更强,还同时具备了三种能力。这篇文章讲清楚这件事凭什么能成立。

故事从这里开始

如果你只在深度学习课上学过神经网络训练,第一次听说”模型合并”(model merging)这个想法,本能反应应该是怀疑。神经网络的损失函数是极度非凸的——高维空间里有无数个局部最小值,两个网络即便结构完全相同,只要初始化的随机种子不同,它们最终收敛到的那组权重在数值上可能相差极大。把两组”看起来毫不相关”的权重直接相加、取平均,直觉上应该会落在两个山谷之间的某个山脊上,性能应该会比两边都差,甚至可能完全失效。

这不是凭空的直觉。事实上早在深度学习兴起的头几年,”权重空间平均两个独立训练的模型”确实是行不通的——你会得到一个准确率跌到接近随机猜测的废物模型。所以长期以来,业界的默认做法是:如果你想结合多个模型的能力,要么做集成(ensemble,多个模型分别跑一遍推理再综合输出),要么做多任务联合训练(把所有数据混在一起从头训一个模型)。前者推理成本随模型数量线性增长,后者需要同时访问所有任务的训练数据、算力成本高、且经常互相”打架”(一个任务的梯度更新会伤害另一个任务的表现)。

那”模型合并”这个反直觉的操作,是怎么从”行不通”变成了 2023-2024 年间开源社区最热门的技术之一,催生出 Mistral 社区无数个”缝合”出来的开源榜单 SOTA 模型的?答案藏在一个关键限定条件里:这些被合并的模型,不是从随机初始化独立训练出来的,而是从同一个预训练模型出发,各自微调(fine-tune)出来的。 这个”共享起点”的限定,改变了整个几何图景——它是这篇文章要讲清楚的第一件事。

两种起点,两种命运 独立随机初始化训练 模型 A 模型 B 高损失山脊(不可平均) 同一预训练模型分别微调 预训练 θ₀ 微调 A 微调 B 同一低损失盆地(可平均)

第一个概念:为什么共享起点让平均权重变得可行

问题是什么

要理解模型合并的合法性,得先搞清楚一件事:两个神经网络的权重能不能”插值”(即沿着连接两组权重的直线走,中间点是否也表现良好),本质上取决于损失函数在权重空间里的形状。如果 A 和 B 之间横着一座”高山”(损失升高的区域),那么线性插值出来的中间模型必然很差——这就是所谓的损失壁垒(loss barrier)。如果 A 和 B 之间是一片平坦的”盆地”,插值就是安全的,这种情况被称为线性模式连通(Linear Mode Connectivity, LMC)。

独立随机初始化训练出的两个模型,几乎必然横着一座高山——不是因为它们学到的知识天差地别,而是因为一个更微妙、更”技术性”的原因:神经网络存在大量的排列对称性(permutation symmetry)。

直觉:核心想法

想象一个隐藏层有 512 个神经元。这些神经元没有”身份编号”——第 37 号神经元和第 261 号神经元在功能上是完全对称的,你可以把它们互换位置(同时把连接它们的权重也相应互换),网络的输出完全不变。这意味着,对于任何一个训练好的网络,都存在着 512! (512 的阶乘,一个天文数字)种”看起来不同但功能完全相同”的权重排列方式。Git Re-Basin 论文算过一笔账:一个三层、每层 512 宽的 MLP 就有 10^3498 种排列对称——这个数字远远超过可观测宇宙中原子的数量。

现在问题来了:两个独立训练的模型,虽然本质上可能学到了几乎一样的特征(比如都学会了”检测边缘”这个视觉特征),但各自把这个特征存在了完全不同的神经元编号位置上。当你直接平均它们的权重时,你相当于是在把”A 模型编号 37 号神经元学到的特征”和”B 模型编号 37 号神经元学到的完全不同的特征”强行加在一起——这就像把两份不同菜谱按页码对齐平均,结果自然是一团乱码。这才是独立训练模型无法直接平均的真正原因,而不是”知识不兼容”。

Git Re-Basin(Ainsworth et al., 2022)验证了这个猜想的反面:如果你先用算法找出一个排列,把模型 B 的神经元重新编号,使它和模型 A 尽量对齐,那么对齐之后的两个模型,权重插值路径上的损失壁垒会大幅消失,甚至可以做到零壁垒的线性连通。他们提出了三种对齐算法(基于激活值匹配、基于权重直接匹配、基于可微分的直通估计器),其中权重匹配的方法只需要求解一个经典的线性分配问题,几秒钟就能跑完,且完全不需要访问训练数据。

技术细节(选读)

排列对称的数学表达很简单:对于一个 L 层的多层感知机,如果在第 ℓ 层插入一对互逆的置换矩阵 P 和 P^T:

\[z_{\ell+1} = P^\top P\, \sigma(W_\ell z_\ell + b_\ell) = P^\top \sigma(P W_\ell z_\ell + P b_\ell)\]

只要把第 ℓ 层权重换成 $PW_\ell$、下一层权重换成 $W_{\ell+1}P^\top$,网络的输入输出映射完全不变。这就是”排列不变性”的来源。Git Re-Basin 提出的权重匹配算法要解的问题是:

\[\arg\max_{\pi} \; \text{vec}(\Theta_A) \cdot \text{vec}(\pi(\Theta_B))\]

翻译回人话:找一个排列 π,让模型 B 重新编号后的权重向量,尽可能”看起来像”模型 A 的权重向量(内积最大化)。这个问题本身是 NP-hard 的(叫”双线性分配问题的和”),但可以用坐标下降近似求解——每次固定其他层的排列,只优化一层,反复迭代直到收敛,实践中通常几秒到几分钟就能跑完。

那这跟”模型合并”有什么关系? 关系是:当我们说的是微调场景——两个模型都是从同一个预训练权重 θ₀ 出发训练出来的——排列对齐这一步已经天然完成了,因为两个模型的权重结构在微调过程中从没有大幅偏离,神经元编号从头到尾就是一致的。Model Soups 论文明确指出,”微调后的模型往往落在同一个低误差盆地里”这个现象,正是他们方法能生效的理论基础。也就是说:模型合并技术的合法性边界,就是”是否共享预训练起点”——这也是为什么几乎所有实用的合并方法(模型汤、任务算术、TIES、DARE)都默认要求被合并的模型来自同一个基座模型微调而来,而 Git Re-Basin 式的排列对齐主要用于处理”从零训练、完全独立”的更困难场景。

第二个概念:模型汤(Model Soups)——最朴素的合并方法

问题是什么

深度学习工程里有一个大家都习惯的浪费:你为了调超参数(学习率、数据增强、训练步数……),训练出了几十个微调后的候选模型,然后只留下验证集上表现最好的那一个,剩下的全部扔掉。这是标准操作,但也是明显的浪费——那些”没被选中”的模型未必一无是处,它们可能在某些方面比冠军模型更强,只是综合分数略低。

直觉:核心想法

Model Soups(Wortsman et al., 2022)的想法极其朴素:既然这些候选模型都是从同一个预训练检查点微调出来的(都在同一个”盆地”里),那干脆别选了,把它们的权重直接做算术平均。得到的新模型,作者称之为”模型汤”——你把很多食材(模型)一起下锅炖成一碗汤,而不是从里面挑一块”最好吃的肉”。

这样做的效果超出直觉:在 ImageNet 上微调 CLIP 模型的一次大规模超参数搜索中,”贪心汤”(Greedy Soup,见下)比搜索中最好的单个模型准确率还要高,而且计算成本几乎为零——不需要额外训练,推理时也只是一个模型,没有集成推理的额外开销。作者甚至用这个方法把一个 ViT-G 模型在 ImageNet 上刷到了 90.94% 的新纪录。

为什么会这样?论文给出的解释很有画面感:他们把两个独立微调出的模型 θ₁、θ₂ 和它们共同的起点 θ₀ 画在一个二维平面上,观察损失地形——结果损失曲面呈现出一个平滑的盆地形状,而这个盆地的最低点,往往不在 θ₁ 或 θ₂ 上,而在它们连线的中间某处。换句话说:微调本身就像是在盆地边缘找到了两个还不错的点,而这两点连线中间的那个点往往更靠近盆底。

技术细节(选读)

模型汤有三种做法。均匀汤(uniform soup)最简单,直接把所有候选模型权重取平均:

\[\theta_S = \frac{1}{|S|}\sum_{i \in S} \theta_i\]

但均匀汤有个明显的风险:如果候选模型里混进了一个训练失败(比如学习率过高导致跑飞)的烂模型,平均下来会拖累整体表现。贪心汤(Greedy Soup)解决了这个问题——先按验证集准确率从高到低排序,然后依次尝试把每个候选模型加入汤里,只有当加入后在验证集上的表现不下降时才真正保留它,否则跳过。这保证了贪心汤的效果永远不会比排序第一的单模型差,同时可以吸收所有”真正有用”的候选模型的优点。

论文里还有一个很漂亮的量化发现:两个模型之间的”平均收益”(平均权重的准确率减去两个模型各自准确率的平均值)和它们权重向量之间的夹角强相关——夹角越接近 90 度(即两个微调方向越”独立”、越不重叠),平均带来的增益越大。这给了后续所有合并方法一个重要的设计指引:想让合并有效,你需要模型之间学到”互补”而不是”雷同”的知识。

第三个概念:任务算术(Task Arithmetic)——把”能力”变成可加减的向量

问题是什么

模型汤解决的是”多个候选模型选最好的那个”这类场景——本质上大家都在解决同一个任务。但如果你想做更野心勃勃的事情呢?比如说:把一个模型在”毒性文本检测”任务上学到的行为反向减掉,让它少说脏话;或者把”数学推理”能力和”代码生成”能力同时叠加到一个通用底座上,得到一个既会算数又会写代码的模型;甚至更极端——用三个已有任务的组合关系,去”推断”出第四个从未见过的任务该往哪个方向调整?

模型汤只会取平均,没有”方向感”,处理不了这种带符号、带算术结构的操作。

直觉:核心想法

Task Arithmetic(Ilharco et al., 2023)提出了一个极其优雅的抽象:把”微调”这件事本身表示成一个向量。具体来说,拿微调后的权重减去微调前(预训练)的权重,得到的差值 τ = θ_ft − θ_pre,就是这个任务的”任务向量”。这个向量指向权重空间里的一个方向——沿着这个方向移动,模型在这个任务上的表现就会变好。

一旦把”能力”表示成了向量,你就可以对它做向量运算了。这是整篇论文最动人的地方:能力变成了可以做算术的对象

  • 取反(negation):τ_new = −τ。如果 τ 是”模型学会说脏话”这个方向,那么往反方向走,模型就会”忘记”怎么说脏话,同时对其他任务几乎没有影响。论文的实验里,对 GPT-2 做负向任务向量编辑,把生成毒性内容的比例从 4.8% 压到 0.8%,而在 WikiText-103 上的困惑度几乎不变(16.4 → 16.9)。这比直接用梯度上升”反向训练”(会把模型训崩,困惑度飙到 10^10 以上)安全得多。
  • 相加(addition):τ_new = τ_A + τ_B。同时把两个能力的方向叠加到预训练模型上,得到一个多任务模型。论文对 8 个图像分类任务两两组合实验,发现叠加两个任务向量能达到单独微调两个模型的 98.9% 归一化准确率——几乎没有性能损失,却把两个模型压缩成了一个。
  • 类比(analogy):如果任务 A、B、C、D 之间存在”A 之于 B,如同 C 之于 D”的关系(比如 A=亚马逊评论情感分析,B=亚马逊语言建模,C=Yelp 语言建模,D=Yelp 情感分析——你缺少 D 的标注数据),你可以构造 τ_D ≈ τ_C + (τ_B − τ_A),用类比关系”无中生有”地推断出一个从未直接训练过的任务方向。实验显示这种做法在完全没有目标任务标注数据的情况下,性能能接近直接在目标任务上微调。

技术细节(选读)

数学形式非常简单——任务向量的定义:

\[\tau_t = \theta_{ft}^t - \theta_{pre}\]

应用任务向量(可选缩放系数 λ,通常在验证集上调):

\[\theta_{new} = \theta_{pre} + \lambda \tau_{new}\]

其中 τ_new 可以是单个任务向量的负值、多个任务向量的和,或者类比构造出的组合。这套操作全部是逐元素(element-wise)加减,计算成本几乎为零——不需要梯度、不需要训练数据、不需要额外的推理开销。之所以能”work”,后续理论工作(Ortiz-Jiménez et al., 2023,Task Arithmetic in the Tangent Space)给出了解释:预训练模型往往具有一种叫权重解耦(weight disentanglement)的性质——不同任务对应的权重更新方向,在模型的函数空间里近似正交、互不干扰,这解释了为什么”往一个方向走”通常不会破坏另一个方向已经学到的能力。这个性质在模型的”切空间”(NTK 线性化视角)下会被进一步增强,从而让任务算术更加稳健。

第四个概念:TIES-Merging——当合并的模型变多,”打架”开始了

问题是什么

Task Arithmetic 在合并两三个任务向量时效果不错,但论文自己也观察到:随着要合并的任务数量增加,合并模型和”联合训练的多任务模型”之间的差距会越拉越大。简单相加多个任务向量,本质上假设了不同任务的更新方向彼此不冲突——但现实中随着任务数量增多,这个假设越来越站不住脚。

TIES-Merging(Yadav et al., 2023)把这种冲突归结为两种具体机制,非常值得拆开讲清楚,因为这是这篇文章里最”接地气”的洞察:

冲突一:冗余参数的淹没效应。 微调会改动模型里的每一个参数,但绝大多数改动其实无关紧要——只有一小部分参数的变化对任务性能真正起决定作用(TIES 的实验显示,只保留每个任务向量中变化幅度最大的前 20% 参数,性能几乎不受影响)。当你合并多个模型时,一个参数如果对模型 A 很关键、但对模型 B 只是”随机抖动的噪音”,直接平均就会让 B 里那些无意义的噪音,把 A 里真正重要的信号”稀释”掉。

冲突二:符号冲突。 更麻烦的情况是:同一个参数,模型 A 认为应该往正方向调,模型 B 认为应该往负方向调——两者方向完全相反。简单平均的结果是这两个更新互相抵消,谁都没调成,参数几乎被拉回了原点,两个任务的能力都被削弱。TIES 的实验测量发现,符号冲突的比例会随着要合并的模型数量增加而稳定上升——合并的模型越多,”打架”越激烈。

直觉:核心想法

TIES 的解法可以用一场”投票会议”来类比。设想每个微调模型对每个参数该往哪个方向调整都有一张”选票”,选票上写着方向(正/负)和这一票的”权重”(变化幅度大小)。

第一步”修剪“(Trim):先把每个模型里那些”变化幅度很小、不太当真”的参数改动直接清零——相当于先把那些心不在焉、随便画个票的委员会成员的票排除掉,只留下真正有明确意见(大幅度改动)的选票。

第二步”选举符号“(Elect Sign):对剩下的选票,按方向分组求和总权重,哪个方向的总票量更大,就选那个方向作为这个参数的”最终决议”——这就像投票时不是数人头,而是按发言影响力(改动幅度)加权计票。

第三步”不相交合并“(Disjoint Merge):只对那些投票方向和最终决议一致的模型取平均,忽略那些”唱反调”、方向不一致的模型的这一票。这样保证了合并结果不会被相互抵消的冲突方向拉回零点。

技术细节(选读)

TIES 的三步可以写成一套简洁的算法。首先把任务向量分解为符号向量 γ 和幅度向量 μ 的逐元素乘积:τ = γ ⊙ μ。

修剪:只保留每个任务向量里幅度最大的前 k% 参数,其余置零,得到 τ̂。

选举符号:对每个参数 p,把所有模型在该位置的(修剪后)值按符号分组求和,哪边总和的绝对值更大就选哪个符号:

\[\gamma_m^p = \text{sgn}\left(\sum_{t=1}^{n} \hat\tau_t^p\right)\]

不相交合并:设 $A_p = {t : \hat\gamma_t^p = \gamma_m^p}$(即在参数 p 上,方向和最终决议一致的模型集合),只对这个集合里的模型做平均:

\[\tau_m^p = \frac{1}{|A_p|}\sum_{t \in A_p} \hat\tau_t^p\]

最后加回预训练权重:θ_m = θ_init + λ·τ_m。TIES 在 T5 和 ViT 系列模型上的实验里,比简单平均在语言任务上高出约 6-13 个百分点,比 Task Arithmetic 也稳定高出 1-3 个百分点,且随着合并任务数增多,优势更明显——这正好验证了”冲突随任务数增长”的诊断。

第五个概念:DARE——大部分参数改动,删掉也没事

问题是什么

TIES 通过修剪解决了冗余参数的问题,但修剪比例(top-k%)是一个需要手动设定、按经验调的超参数。有没有更简单粗暴、甚至有点”违反直觉”的做法?

直觉:核心想法

DARE(”Drop And REscale”,Yu et al., 2023,论文题目诙谐地叫”语言模型是超级马里奥”)的发现更加惊人:对于监督微调(SFT)得到的模型,任务向量里的绝大多数参数改动,其实幅度都非常小(论文测量显示,绝大多数改动幅度在 0.005 以内),你可以随机地(不需要按重要性排序,纯随机丢弃)删掉高达 90%,甚至 99% 的这些改动,把它们清零,模型的性能几乎不受影响。

这个发现之所以反直觉,是因为它说明了微调过程本身存在惊人的冗余——你以为微调改动的每一个参数都在”做功”,但实际上绝大多数改动只是无关紧要的噪声,真正带来能力提升的只是少数关键改动。DARE 的做法是:用一个概率 p 随机丢弃任务向量中的每个元素,然后把剩下没被丢弃的元素乘以 1/(1-p) 做补偿放大——这个补偿的目的,是让剩下参数改动的”总期望强度”和原始改动保持一致,近似还原微调前后输出分布的整体统计特性。

技术细节(选读)

DARE 的操作定义在任务向量 τ 上,对每个元素独立采样一个掩码:

\[m \sim \text{Bernoulli}(1-p), \quad \hat\tau = \frac{m \odot \tau}{1-p}\]

DARE 之所以被拿来和 TIES 组合使用(也就是 mergekit 里常见的 “dare_ties” 方法),是因为两者解决的其实是同一个问题的不同侧面:DARE 用随机丢弃降低了参数冲突的绝对数量(丢的越多,能冲突的就越少),TIES 用符号选举解决了剩下没丢的参数之间还存在的方向冲突。两者叠加,在多模型合并场景下往往比单用任一个更稳。论文里的一个限制条件值得诚实地提一句:DARE 这种”随机丢弃大部分改动仍不影响性能”的现象,主要在标准 SFT 模型上观察到,一旦模型经过了持续预训练(continued pre-training,改动幅度会显著变大,通常到 0.03 量级),DARE 的丢弃比例就必须大幅降低,否则会开始伤害性能。

第六个概念:SLERP——当”直线”不是最好的路径

问题是什么

前面所有方法本质上都是在做线性插值/平均——把权重看成普通向量,直接加权求和。但深度学习里的权重矩阵,尤其是像注意力层那种维度很高的矩阵,它们的”有效信息”很大程度上体现在向量的方向上,而不只是长度上。直线插值有一个不那么直观的副作用:两个方向差异较大、但长度相近的向量,做线性平均后,得到的中间向量的长度会缩短——你可以想象两个指向不同方向、长度都是 1 的箭头,它们的中点箭头长度通常小于 1。对权重矩阵来说,这种”长度缩水”可能意味着某种表示能力的损失。

直觉:核心想法

SLERP(球面线性插值,Spherical Linear Interpolation)最初是图形动画里做旋转插值的经典技巧(比如让一个 3D 物体从一个朝向平滑旋转到另一个朝向,而不是”抽走再插入”式的生硬直线过渡)。把这个想法搬到模型合并上的直觉是:不要在两个权重向量之间画直线,而是把它们都看作单位球面上的两个点,沿着球面上连接这两点的弧线走。这样插值路径上的每一个点,长度都和两个端点保持一致(都在球面上),不会出现直线插值那种”中点变短”的问题,走的路径也更贴合两个模型”方向”之间真正的角度关系,而不是简单的坐标平均。

技术细节(选读)

给定两个向量 v₁、v₂ 之间的夹角 Ω(可由夹角余弦 cosΩ = v₁·v₂/(‖v₁‖‖v₂‖) 求出),SLERP 在插值系数 t ∈ [0,1] 处的公式是:

\[\text{Slerp}(v_1, v_2; t) = \frac{\sin((1-t)\Omega)}{\sin\Omega}v_1 + \frac{\sin(t\Omega)}{\sin\Omega}v_2\]

翻译回人话:这是加权平均的一个”弧线修正版”——当两个向量夹角很小时(sinΩ 趋近于 0,接近线性插值的极限情况),SLERP 退化为普通线性插值;当夹角较大时,公式里的正弦项会自动补偿”长度缩水”的问题,保证插值出来的向量长度介于两端之间、方向沿弧线平滑过渡。在 mergekit 等实际合并工具里,SLERP 通常只用于两个模型之间的合并(多于两个模型需要递归两两合并或者用 TIES/DARE 这类天然支持多模型的方法),是社区里”分层混搭”式合并(比如底层用模型 A 的权重、高层混合模型 A 和 B)最常用的插值方式之一。

LERP vs SLERP 模型 A 模型 B LERP 中点(长度缩短) SLERP 弧线(长度保持)

这意味着什么

把这几种方法串在一起看,你会发现模型合并这套技术,本质上是在同一个物理事实上不断打磨出更精细的操作方式:微调后的模型都活在预训练模型划定的同一个损失盆地里。正是这个共享的起点,让权重空间里的算术运算变得有意义——你可以把”能力”表示成向量并做加减(Task Arithmetic),可以识别并化解多个方向叠加时产生的冲突(TIES),可以发现绝大多数改动根本无关紧要(DARE),还可以沿着更贴合几何直觉的路径插值(SLERP)。而当共享起点这个前提不成立——比如两个从零训练的独立模型——你就需要先做排列对齐(Git Re-Basin),把两组权重”搬”到同一个盆地里,才谈得上合并。

这套技术为什么重要,不只是因为它省训练成本。它悄悄改变了开源社区构建模型的方式:以前你要获得一个”既会写代码又会算数学”的模型,唯一的路径是拿到两份数据、投入算力、重新训练。现在,只要这两种能力已经分别存在于两个开源微调模型里,你可以在几分钟内、不用一块 GPU 训练时长、只靠 CPU 做几次矩阵运算,把它们缝合成一个新模型——这也是 Mistral、Llama 系微调生态里那些排行榜”缝合怪”模型层出不穷的技术根源。它也提出了一个更深的问题:如果权重空间里的方向真的对应着可分解、可组合的”能力”,这是否说明神经网络学到的知识,远比我们想象得更有结构、更模块化?这个问题,目前还没有定论。

下一篇预告

模型合并把多个模型的”能力方向”揉进了同一组权重里,推理时看起来还是一个普通模型。但如果我们换一个思路——不是把多个专家的知识永久融合进一组权重,而是让模型在推理时按需动态调用不同的”专家子网络”,这就是 Mixture of Experts 的核心设计哲学,本系列此前已经详细讨论过 MoE 的路由与训练机制。而模型合并技术本身也在持续演进——从两两插值到多模型”重心”估计(Model Stock),从静态合并到激活值感知的动态合并,这仍是一个飞速发展的方向,值得持续关注。