Model Merging 成功案例深度解析:基于 mergekit 的实战配置与生产化部署指南(AI-Research-SKILLs)
Model Merging 成功案例深度解析:基于 mergekit 的实战配置与生产化部署指南(AI-Research-SKILLs)
本文是 AI-Research-SKILLs 技能库中 model-merging 技能 的实战案例篇(对应 references/examples.md),围绕 mergekit 生态中真实存在的成功合并模型,逐条拆解其 SLERP、Task Arithmetic、TIES、DARE-TIES、passthrough、MoE 等方法的完整 YAML 配置。读者读完将掌握:如何复现 Open LLM Leaderboard 头部合并模型的配置、如何针对数学/代码/医疗/法律/多语言等任务设计合并策略,以及如何把渐进式合并、A/B 测试、批量合并与上传落地到生产流水线。
案例总览:从排行榜榜首到生产落地
模型合并(Model Merging)的核心价值在于:无需任何 GPU 训练,仅靠权重层面的代数运算,就能把多个微调模型的能力组合进一个模型,通常在几分钟内即可产出新变体。本文案例覆盖三大梯队:
| 梯队 | 代表案例 | 核心方法 |
|---|---|---|
| 排行榜级 | Marcoro14-7B-slerp、goliath-120b | SLERP、层特异 SLERP |
| 架构系 | Mixtral 系(Math+Code、Chat+Roleplay、TIES)、Llama 系(Platypus-Hermes、DARE-TIES) | Task Arithmetic、SLERP、TIES、Linear、DARE-TIES |
| 任务专项 | 医疗、法律、多语言 | Task Arithmetic、SLERP(filter 定向) |
| 生产策略 | 渐进式合并、A/B 测试、Frankenmerge、MoE | passthrough、moe、分步 SLERP |
若需要方法本身的算法级推导(TIES 的 TRIM/ELECT/MERGE、DARE 的丢放与重缩放、SLERP 的球面插值公式),参见 references/methods.md;合并后的评测基准与方法参见 references/evaluation.md。
排行榜级成功案例:SLERP 的巅峰之作
Marcoro14-7B-slerp:Open LLM Leaderboard 榜首
Marcoro14-7B-slerp 是 2024 年 2 月 Open LLM Leaderboard 排名第一的合并模型,采用 SLERP(Spherical Linear Interpolation,球面线性插值)将两个 Mistral-7B 架构的模型按 t = 0.5 等比例融合:
# marcoro14-7b-slerp.yml
merge_method: slerp
slices:
- sources:
- model: AIDC-ai-business/Marcoroni-7B-v3
layer_range: [0, 32]
- model: EmbeddedLLM/Mistral-7B-Merge-14-v0.1
layer_range: [0, 32]
parameters:
t: 0.5 # Equal blend
dtype: bfloat16
结果:Open LLM Leaderboard 平均分 74.32,各任务表现均衡,能力组合平滑、无断崖式退化。
原理深入:SLERP 与普通线性加权最大的区别在于“保持权重向量模长”。其核心公式为:
merged = (sin((1-t)*θ) / sin(θ)) * model1 + (sin(t*θ) / sin(θ)) * model2
其中 θ = arccos(dot(model1, model2)),t ∈ [0, 1]
当 θ 极小时(两模型权重几乎平行),SLERP 退化为线性插值。t 是唯一的插值系数:t=0 完全等于第一个模型,t=1 完全等于第二个模型,t=0.5 即对半融合。这正是本案例“Equal blend”的由来。完整的可运行实现见 references/methods.md。
goliath-120b:层特异 SLERP 的工程化实践
goliath-120b 是当时表现优异的 120B 级模型,其配置展示了 SLERP 的进阶用法——按层组(layer group)施加不同的插值系数:
# goliath-120b.yml
merge_method: slerp
slices:
- sources:
- model: alpindale/c4ai-command-r-plus-GPTQ
layer_range: [0, 40]
- model: CohereForAI/c4ai-command-r-v01
layer_range: [0, 40]
parameters:
t:
- filter: self_attn
value: [0, 0.5, 0.3, 0.7, 1] # Layer-specific blending
- filter: mlp
value: [1, 0.5, 0.7, 0.3, 0]
- value: 0.5 # Default
dtype: float16
filter 机制解读:parameters.t 不再是一个标量,而是一组带 filter 的规则:
filter: self_attn—— 仅作用于注意力模块,value: [0, 0.5, 0.3, 0.7, 1]表示沿 40 层按段施加t = 0 → 0.5 → 0.3 → 0.7 → 1的渐变混合;filter: mlp—— 仅作用于前馈网络模块,施加方向相反的[1, 0.5, 0.7, 0.3, 0];value: 0.5—— 其余未匹配模块的默认值。
注意力与 MLP 采用“互补”的插值曲线,是这类大模型合并中常见的做法:让不同模块从不同父模型中取长补短。这里选择 dtype: float16 而非 bfloat16,说明当模型规模巨大时,数据精度也是控制显存/内存开销的重要决策点(examples.md 中两个头部案例分别使用了 bfloat16 与 float16)。
Mixtral 系合并:多能力叠加与冲突消解
Mixtral 系模型(含 MoE 结构的 Mixtral-8x7B)在合并实践中非常活跃,本组案例覆盖 Task Arithmetic、SLERP、TIES 三种方法。
Math + Code 专家合并(Task Arithmetic)
目标是把数学推理与代码生成能力合入同一模型:
# math-code-mixtral.yml
merge_method: task_arithmetic
base_model: mistralai/Mixtral-8x7B-v0.1
models:
- model: WizardLM/WizardMath-7B-V1.1
parameters:
weight: 0.6 # Emphasize math
- model: ajibawa-2023/Code-Mixtral-8x7B
parameters:
weight: 0.4 # Add code
dtype: bfloat16
原理深入:Task Arithmetic 先为每个微调模型提取“任务向量”(task vector = 微调权重 − 基座权重),再加权求和后加回基座,即 merged = base + α₁·tv₁ + α₂·tv₂。这里 weight: 0.6 表示任务向量 1(数学)的放大系数更大,数学能力被优先强调;0.4 用于注入代码能力。注意 Task Arithmetic 的权重不要求相加等于 1,因为它是任务向量层面的叠加而非参数层面的加权平均——这与 Linear 方法有本质区别。
预期能力:强数学推理、代码生成与理解、综合技术问题求解。
Chat + Roleplay 合并(SLERP)
对话能力与角色扮演能力的双模型 SLERP 融合:
# chat-roleplay.yml
merge_method: slerp
slices:
- sources:
- model: teknium/OpenHermes-2.5-Mistral-7B
layer_range: [0, 32]
- model: Undi95/MLewd-ReMM-L2-Chat-20B-Part1
layer_range: [0, 32]
parameters:
t: 0.5
dtype: bfloat16
两个模型架构一致(同属 Mistral-7B 派生系),layer_range: [0, 32] 表示全 32 层参与融合,t: 0.5 对半混合。
多任务 TIES 合并
当要合并 3 个以上任务模型时,直接用 Task Arithmetic 会产生参数符号冲突与冗余干扰。TIES-Merging(NeurIPS 2023)通过“稀疏化 + 符号表决”缓解该问题:
# multi-task-mixtral.yml
merge_method: ties
base_model: mistralai/Mixtral-8x7B-v0.1
models:
- model: WizardLM/WizardMath-7B-V1.1
parameters:
density: 0.5
weight: 1.0
- model: teknium/OpenHermes-2.5-Mistral-7B
parameters:
density: 0.5
weight: 1.0
- model: ajibawa-2023/Code-Mixtral-8x7B
parameters:
density: 0.5
weight: 1.0
parameters:
normalize: true
dtype: bfloat16
算法三步走(完整实现见 references/methods.md):
- TRIM(裁剪):按幅度保留每个任务向量的前
density(此处 50%)的参数,其余置零; - ELECT(符号表决):对每个参数位置,统计各任务向量的符号,选举占多数的符号作为该位置的“当选符号”,平票时保留第一个模型符号;
- MERGE(对齐合并):只累加与当选符号一致的参数,取平均后按
λ缩放加回基座。
density: 0.5 是保守与激进的中间值(论文默认 0.2,实践中 0.5 常见);normalize: true 表示对任务向量做归一化处理,weight: 1.0 表示各任务权重相等。TIES 尤其适合“多任务专才”场景——数学、对话、代码三模型同源(均基于 Mixtral-8x7B),合并后可以同时保留三方面能力。
Llama 系合并:权重分配与 DARE 稀疏化
Platypus-Hermes 三模型线性合并
Linear(又称 Model Soup)是最简单的合并方式——对参数做加权平均:
# platypus-hermes-13b.yml
merge_method: linear
models:
- model: garage-bAInd/Platypus2-13B
parameters:
weight: 0.5
- model: WizardLM/WizardLM-13B-V1.2
parameters:
weight: 0.3
- model: psmathur/orca_mini_v3_13b
parameters:
weight: 0.2
dtype: float16
权重规则:Linear 的权重通常要求满足 w1 + w2 + ... = 1(此处 0.5 + 0.3 + 0.2 = 1.0)。三模型均为 13B 级 Llama 派生模型,架构一致是合并的前提。Linear 实现即 merged = w1·model1 + w2·model2 + w3·model3,见 methods.md 中的 linear_merge 实现与权重断言。
DARE-TIES Llama 合并
DARE(Drop And REscale,arXiv:2311.03099,论文标题直译为“语言模型是超级马里奥”)的核心思想是:微调产生的 delta 参数(δ = 微调权重 − 基座权重)中大部分是冗余的,可以随机丢弃并重缩放,从而以更低开销获得等价甚至更好的能力注入:
# dare-ties-llama.yml
merge_method: dare_ties
base_model: meta-llama/Llama-2-7b-hf
models:
- model: WizardLM/WizardLM-7B-V1.0
parameters:
density: 0.5 # Keep top 50%
weight: 0.6
dare:
drop_rate: 0.9 # Drop 90% of deltas
- model: garage-bAInd/Platypus-7B
parameters:
density: 0.5
weight: 0.4
dare:
drop_rate: 0.9
parameters:
int8_mask: true
dtype: bfloat16
DARE 数学原理(methods.md 中有完整实现):
- 随机丢弃:
m_t ~ Bernoulli(p),δ̃_t = (1 - m_t) ⊙ δ_t; - 重缩放:
δ̂_t = δ̃_t / (1 - p),以保持期望不变; - 重建:
θ̂_t = θ₀ + δ̂_t。
参数 dare.drop_rate: 0.9 表示丢弃 90% 的 delta 参数(论文实验显示大模型在 0.9~0.99 的高丢弃率下依然稳健);density: 0.5 是 TIES 裁剪保留率;int8_mask: true 表示用 int8 存储掩码以节省内存。DARE-TIES 即“先 DARE 再 TIES”,是目前多模型生产合并中综合效果最好的组合之一。
任务专项合并:医疗 / 法律 / 多语言
医疗领域专家
用 Task Arithmetic 在通用基座上叠加医学知识与对话能力:
# medical-specialist.yml
merge_method: task_arithmetic
base_model: mistralai/Mistral-7B-v0.1
models:
- model: medalpaca/medalpaca-7b
parameters:
weight: 0.7 # Strong medical knowledge
- model: teknium/OpenHermes-2.5-Mistral-7B
parameters:
weight: 0.3 # Add general chat ability
dtype: bfloat16
weight: 0.7 让医学任务向量占主导,weight: 0.3 补充通用对话能力,避免合并后模型“只会医学术语、不会聊天”。
法律助手:filter 定向插值
法律场景的配置展示了 SLERP 中 filter 的另一形态——按模块给不同插值系数:
# legal-assistant.yml
merge_method: slerp
slices:
- sources:
- model: law-ai/legal-bert-7b
layer_range: [0, 32]
- model: teknium/OpenHermes-2.5-Mistral-7B
layer_range: [0, 32]
parameters:
t:
- filter: self_attn
value: 0.7 # Emphasize legal model in attention
- filter: mlp
value: 0.3 # More general chat in MLPs
- value: 0.5
dtype: bfloat16
这里的 filter 用法与 goliath-120b 不同:不提供数组而是单一标量。注意力模块取 t=0.7(更偏向法律模型),MLP 模块取 t=0.3(更偏向通用对话模型),其余模块默认 t=0.5。经验上,注意力与 MLP 承担的功能不同,分而治之往往优于一刀切的全局系数——这也是 SKILL.md 中“Layer-specific Merging”最佳实践所强调的。
多语言合并
# multilingual-merge.yml
merge_method: linear
models:
- model: mistralai/Mistral-7B-v0.1
parameters:
weight: 0.4 # English
- model: CohereForAI/aya-23-7B
parameters:
weight: 0.3 # Multilingual
- model: Qwen/Qwen3-7B
parameters:
weight: 0.3 # Asian languages
dtype: bfloat16
注意事项:多语言合并虽然直观(三个模型按权重线性混合,覆盖英语、多语种、亚洲语言),但必须确认三者共享同一架构与词表兼容性。若词表差异过大,线性合并会在 embedding 层产生对齐问题,此时需要配合 Tokenizer 合并策略(见下文“生产级合并策略”中的 tokenizer 配置,以及 SKILL.md 的 Tokenizer Merging 章节)。
生产级合并策略
渐进式合并(Gradual Merge,更安全)
生产环境推荐“小步快跑”:每次只合并两个模型、用保守系数,逐步叠加第三、第四个专家,每步都做评测,质量退化即可止损:
# Step 1: Merge two models
# step1.yml
merge_method: slerp
slices:
- sources:
- model: base_model
layer_range: [0, 32]
- model: specialist_1
layer_range: [0, 32]
parameters:
t: 0.3 # Conservative blend
dtype: bfloat16
# Step 2: Add third model to result
# step2.yml
merge_method: slerp
slices:
- sources:
- model: ./merged_step1 # Previous merge
layer_range: [0, 32]
- model: specialist_2
layer_range: [0, 32]
parameters:
t: 0.3 # Conservative
dtype: bfloat16
注意第 2 步的 model: ./merged_step1 直接指向第 1 步的输出目录——mergekit 支持把上一次合并结果作为下一次的输入,这是“渐进式”得以成立的关键机制。收益:每步可测、易调试、质量劣化时可随时停止。
A/B 测试配置
对同一对基座模型与专家模型,准备保守与激进两个变体,跑同一批评测再择优上线:
# variant_a.yml - Conservative
merge_method: slerp
slices:
- sources:
- model: base_model
layer_range: [0, 32]
- model: specialist
layer_range: [0, 32]
parameters:
t: 0.3 # 30% specialist
dtype: bfloat16
# variant_b.yml - Aggressive
merge_method: slerp
slices:
- sources:
- model: base_model
layer_range: [0, 32]
- model: specialist
layer_range: [0, 32]
parameters:
t: 0.7 # 70% specialist
dtype: bfloat16
两个变体都测,选表现优者。评测框架可参考 references/evaluation.md 中的 A/B 测试、回归测试与部署检查清单。
Frankenmerge(实验性拼接)
merge_method: passthrough 允许从不同模型各取一段层直接拼接,构造非常规层数的模型:
# frankenmerge.yml
merge_method: passthrough
slices:
# First 8 layers from model A
- sources:
- model: model_a
layer_range: [0, 8]
# Middle 16 layers from model B
- sources:
- model: model_b
layer_range: [8, 24]
# Last 8 layers from model C
- sources:
- model: model_c
layer_range: [24, 32]
dtype: bfloat16
适用场景:创建非标准层数的模型。⚠️ 警告:这是实验性方案,层间连接可能不兼容,合并后不一定能正常推理。同样基于 passthrough 的还有 SKILL.md 中的“Layer-wise Merging”模式——保留基座的首尾层不动,只替换中间层,常用于稳定性要求高的场景。
MoE from Merges:提示词驱动的专家路由
将多个专家模型以 MoE(Mixture of Experts)方式组装,由提示词自动决定走哪个专家:
# moe-from-merges.yml
merge_method: moe
base_model: mistralai/Mistral-7B-v0.1
experts:
- source_model: WizardLM/WizardMath-7B-V1.1
positive_prompts:
- "math"
- "calculate"
- "solve"
- "equation"
- source_model: ajibawa-2023/Code-Mistral-7B
positive_prompts:
- "code"
- "python"
- "function"
- "programming"
- source_model: teknium/OpenHermes-2.5-Mistral-7B
positive_prompts:
- "chat"
- "conversation"
- "help"
- "question"
dtype: bfloat16
结果:模型会依据输入提示词与各专家 positive_prompts 的匹配度,动态选择专家,实现“数学题走数学专家、编程题走代码专家”的按需路由。这是不经过任何训练就把多个专才模型组织成 MoE 的轻量方案。
进阶组合:若在合并过程中涉及词表不同的模型,可参考 SKILL.md 的 Tokenizer Merging 配置(tokenizer.source: "union" 合并词表并指定特殊 token 来源);若不想手工调 t/weight/density 等系数,可采用 references/coefficient-tuning.md 记录的“生成一致性”无监督选参方法(AdaMMS,CVPR 2025,arXiv:2503.23733)——用少量无标注提示词评测各候选系数的邻域输出一致性,自动选出最稳定的系数。
命令行实战:从单次合并到批量流水线
所有 YAML 配置最终都通过 mergekit-yaml 命令执行,本节覆盖四种典型执行方式(命令来源于 examples.md 的命令行示例)。
基础合并(两模型 SLERP)
# Simple two-model SLERP
mergekit-yaml config.yml ./output-model \
--cuda \
--lazy-unpickle
--cuda 使用 GPU 加速合并;--lazy-unpickle 启用惰性反序列化,减少峰值内存占用。
大模型低显存合并
# Merge on CPU (slow but works with 8GB VRAM)
mergekit-yaml config.yml ./output-model \
--allow-crimes \ # Enable CPU offloading
--low-cpu-memory
当模型规模超过显存时,--allow-crimes 启用 CPU offloading(合并过程会变慢但能在 8GB 显存机器上运行),--low-cpu-memory 进一步压低 CPU 内存占用。注意:合并本身不需要训练,纯 CPU 也能跑完,这正是模型合并“零训练成本”优势的体现(SKILL.md 中同样强调 merges 可运行于 CPU)。
合并并上传 HuggingFace
# Merge and push to HuggingFace
mergekit-yaml config.yml ./merged-model --cuda
cd merged-model
python << EOF
from transformers import AutoModel, AutoTokenizer
model = AutoModel.from_pretrained("./")
tokenizer = AutoTokenizer.from_pretrained("./")
model.push_to_hub("username/my-merged-model")
tokenizer.push_to_hub("username/my-merged-model")
EOF
合并产物是标准 transformers 模型目录,加载后可直接通过 push_to_hub 发布;该流程与 SKILL.md 的“Save and Upload”章节一致。发布前建议先按 references/evaluation.md 的部署检查清单逐项验证。
批量合并
# Merge multiple configs
for config in configs/*.yml; do
output="./output/$(basename $config .yml)"
mergekit-yaml $config $output --cuda
done
把不同方法、不同权重的配置放入 configs/ 目录,一条循环即可批量产出候选模型——这正是 A/B 测试、无监督系数搜索(coefficient-tuning.md)所依赖的自动化基础。
成功合并的经验法则
来自头部合并案例的六条实战经验(examples.md 原文要点):
- 保守起步:SLERP 先取
t = 0.3~0.5,评测通过后再逐步调高; - 架构匹配:只合并同基座架构的模型(例如不要混搭 Llama 与 Mistral);
- 充分评测:上线前在多个任务上跑基准(可用 lm-evaluation-harness 技能 执行 Open LLM Leaderboard 等套件);
- 层特异合并:注意力与 MLP 使用不同
t值往往效果更好(见 goliath-120b、法律助手案例); - 多模型用 DARE:合并 3 个以上模型时,DARE-TIES 通常效果最佳;
- 渐进式合并:生产环境增量合并、逐步测试(见上文 Step1/Step2 配置)。
在此基础上可再补充一条:系数不要拍脑袋——当 t、weight、density 等系数难以人工确定时,用“生成一致性”无监督搜索自动选择(详见 coefficient-tuning.md),并注意边界候选(alpha_min/alpha_max)只有单侧邻居、分数会被低估,应从最终选择中剔除或扩大搜索范围。
相关资源与仓库导航
- SKILL.md —— 技能总览:安装、快速开始、配置结构、最佳实践与常见坑
- references/methods.md —— 五种合并算法的逐步推导与对比表
- references/examples.md —— 本文对应的真实案例配置源文档
- references/coefficient-tuning.md —— 无监督系数选择(生成一致性 / AdaMMS)完整流水线
- references/evaluation.md —— 评测套件(Open LLM Leaderboard、MT-Bench、MMLU、HumanEval)、回归测试与部署清单
- 11-evaluation/lm-evaluation-harness —— 仓库内可复用的开源评测框架
文中所有案例均以 mergekit 生态的 YAML 配置为核心骨架,配置中的模型标识符来自原始文档,实际运行时需替换为本地路径或可访问的模型仓库 ID,并确保各模型架构一致(同源 7B/13B 派生模型),方可复现稳定的合并效果。