关于 model-merging
面向模型实践者的指南,介绍如何在不重新训练的情况下组合预训练及微调模型,以融合不同能力。内容涵盖 mergekit 等工具的合并方法、配置、评估与部署。
主要功能
- 01线性、SLERP 与任务向量合并
- 02TIES 和 DARE 方法
- 03按层及分词器合并
- 04YAML 合并配置示例
- 05评估与部署指南
适用场景
- 01融合微调模型的不同能力
- 02创建领域专用模型变体
- 03比较合并方法和系数
- 04评估并准备合并后的模型
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ kalarislabs/ research-agent-skills --skill model-merging安装后在 Claude Code 中输入/model-merging确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/coefficient-tuning.mdevaluation.mdexamples.mdmerge-methods-guide.mdmethods.md详细介绍
模型合并:组合预训练模型
何时使用此技能
在以下情况下使用模型合并:
- 组合多种能力,无需重新训练多个微调模型
- 创建专用模型,融合特定领域的专长(数学 + 编码 + 聊天)
- 提升性能,超越单个模型(基准测试中通常提高 5-10%)
- 降低训练成本——无需 GPU,可在 CPU 上运行合并
- 快速实验——几分钟内创建新的模型变体,而不是几天
- 保留多种技能——合并时避免灾难性遗忘
成功案例:Marcoro14-7B-slerp(2024 年 2 月在 Open LLM Leaderboard 上排名第一),许多 HuggingFace 顶尖模型都使用了合并
工具:mergekit(Arcee AI)、LazyMergekit、Model Soup
安装
# Install mergekit
git clone https://github.com/arcee-ai/mergekit.git
cd mergekit
pip install -e .
# Or via pip
pip install mergekit
# Optional: Transformer library
pip install transformers torch
快速开始
简单线性合并
# config.yml - Merge two models with equal weights
merge_method: linear
models:
- model: mistralai/Mistral-7B-v0.1
parameters:
weight: 0.5
- model: teknium/OpenHermes-2.5-Mistral-7B
parameters:
weight: 0.5
dtype: bfloat16
# Run merge
mergekit-yaml config.yml ./merged-model --cuda
# Use merged model
python -m transformers.models.auto --model_name_or_path ./merged-model
SLERP 合并(最适合 2 个模型)
# config.yml - Spherical interpolation
merge_method: slerp
slices:
- sources:
- model: mistralai/Mistral-7B-v0.1
layer_range: [0, 32]
- model: teknium/OpenHermes-2.5-Mistral-7B
layer_range: [0, 32]
parameters:
t: 0.5 # Interpolation factor (0=model1, 1=model2)
dtype: bfloat16
核心概念
1. 合并方法
线性(Model Soup)
- 对参数进行简单的加权平均
- 速度快,适用于相似的模型
- 可合并 2 个或更多模型(
w1 + w2 + ... = 1)
SLERP(球面线性插值)
- 沿权重空间中的球面进行插值
- 保留权重向量的大小
- 最适合合并 2 个模型
- 比线性方法平滑
# SLERP formula
merged = (sin((1-t)*θ) / sin(θ)) * model1 + (sin(t*θ) / sin(θ)) * model2
# where θ = arccos(dot(model1, model2))
# t ∈ [0, 1]
任务算术
- 提取“任务向量”(微调模型 - 基础模型)
- 组合任务向量并加到基础模型上
- 适合合并多个专用模型(
merged = base + α₁·tv₁ + α₂·tv₂)
TIES-Merging
- 任务算术 + 稀疏化
- 解决参数中的符号冲突
- 最适合合并多个特定任务的模型
DARE(Drop And REscale)
- 随机丢弃微调后的参数
- 对剩余参数重新缩放
- 减少冗余并维持性能
2. 配置结构
# Basic structure
merge_method: <method> # linear, slerp, ties, dare_ties, task_arithmetic
base_model: <path> # Optional: base model for task arithmetic
models:
- model: <path/to/model1>
parameters:
weight: <float> # Merge weight
density: <float> # For TIES/DARE
- model: <path/to/model2>
parameters:
weight: <float>
parameters:
# Method-specific parameters
dtype: <dtype> # bfloat16, float16, float32
# Optional
slices: # Layer-wise merging
tokenizer: # Tokenizer configuration
合并方法指南
详细说明、代码示例和参数表:references/merge-methods-guide.md。适用时请阅读。
高级模式
逐层合并
# Different models for different layers
merge_method: passthrough
slices:
- sources:
- model: mistralai/Mistral-7B-v0.1
layer_range: [0, 16] # First half
- sources:
- model: teknium/OpenHermes-2.5-Mistral-7B
layer_range: [16, 32] # Second half
dtype: bfloat16
从合并模型创建 MoE
# Create Mixture of Experts
merge_method: moe
base_model: mistralai/Mistral-7B-v0.1
experts:
- source_model: WizardLM/WizardMath-7B-V1.1
positive_prompts:
- "math"
- "calculate"
- source_model: teknium/OpenHermes-2.5-Mistral-7B
positive_prompts:
- "chat"
- "conversation"
- source_model: ajibawa-2023/Code-Mistral-7B
positive_prompts:
- "code"
- "python"
dtype: bfloat16
合并分词器
merge_method: linear
models:
- model: mistralai/Mistral-7B-v0.1
- model: custom/specialized-model
tokenizer:
source: "union" # Combine vocabularies from both models
tokens:
<|special_token|>:
source: "custom/specialized-model"
最佳实践
1. 模型兼容性
# ✅ Good: Same architecture
models = [
"mistralai/Mistral-7B-v0.1",
"teknium/OpenHermes-2.5-Mistral-7B", # Both Mistral 7B
]
# ❌ Bad: Different architectures
models = [
"meta-llama/Llama-2-7b-hf", # Llama
"mistralai/Mistral-7B-v0.1", # Mistral (incompatible!)
]
2. 权重选择
# ✅ Good: Weights sum to 1.0
models:
- model: model_a
parameters:
weight: 0.6
- model: model_b
parameters:
weight: 0.4 # 0.6 + 0.4 = 1.0
# ⚠️ Acceptable: Weights don't sum to 1 (for task arithmetic)
models:
- model: model_a
parameters:
weight: 0.8
- model: model_b
parameters:
weight: 0.8 # May boost performance
无监督系数调优(无需标注数据)
无需手动搜索,可使用生成一致性:使用多个候选系数进行合并,在少量未标注子集上生成响应,然后选择输出与相邻系数最相似的系数。一致的输出表明合并区域稳定且性能良好(AdaMMS,arXiv:2503.23733)。
# Pseudocode — see references/coefficient-tuning.md for full implementation
candidates = [0.3, 0.4, 0.5, 0.6, 0.7]
for alpha in candidates:
merged_paths[alpha] = merge_with_coefficient(alpha, model_a, model_b)
responses[alpha] = generate_responses(merged_paths[alpha], eval_prompts)
# Score each alpha by similarity to its neighbors (alpha ± 0.1)
best_alpha = max(candidates, key=lambda a: generation_consistency(a, responses))
有关完整算法、相似度指标、多系数搜索和端到端流程,请参阅 references/coefficient-tuning.md。
3. 方法选择
# Choose merge method based on use case:
# 2 models, smooth blend → SLERP
merge_method = "slerp"
# 3+ models, simple average → Linear
merge_method = "linear"
# Multiple task-specific models → Task Arithmetic or TIES
merge_method = "ties"
# Want to reduce redundancy → DARE
merge_method = "dare_ties"
4. 密度调优(TIES/DARE)
# Start conservative (keep more parameters)
parameters:
density: 0.8 # Keep 80%
# If performance good, increase sparsity
parameters:
density: 0.5 # Keep 50%
# If performance degrades, reduce sparsity
parameters:
density: 0.9 # Keep 90%
5. 特定层合并
保留基础模型的首层和末层(通常最好不要改动),并使用 merge_method: passthrough 和 slices 仅合并中间层——参见上文的逐层合并模式。
评估与测试
对合并模型进行基准测试
from transformers import AutoModelForCausalLM, AutoTokenizer
# Load merged model
model = AutoModelForCausalLM.from_pretrained("./merged-model")
tokenizer = AutoTokenizer.from_pretrained("./merged-model")
# Test on various tasks
test_prompts = {
"math": "Calculate: 25 * 17 =",
"code": "Write a Python function to reverse a string:",
"chat": "What is the capital of France?",
}
for task, prompt in test_prompts.items():
inputs = tokenizer(prompt, return_tensors="pt")
outputs = model.generate(**inputs, max_length=100)
print(f"{task}: {tokenizer.decode(outputs[0])}")
常用基准
- Open LLM Leaderboard:通用能力
- MT-Bench:多轮对话
- MMLU:多任务准确率
- HumanEval:代码生成
- GSM8K:数学推理
生产部署
保存并上传
from transformers import AutoModelForCausalLM, AutoTokenizer
# Load merged model
model = AutoModelForCausalLM.from_pretrained("./merged-model")
tokenizer = AutoTokenizer.from_pretrained("./merged-model")
# Upload to HuggingFace Hub
model.push_to_hub("username/my-merged-model")
tokenizer.push_to_hub("username/my-merged-model")
量化合并模型
# Quantize with GGUF
python convert.py ./merged-model --outtype f16 --outfile merged-model.gguf
# Quantize with GPTQ
python quantize_gptq.py ./merged-model --bits 4 --group_size 128
常见问题
- 架构不匹配——只合并架构相同的模型(例如,不要混合 Llama 和 Mistral)。
- 某个模型权重过高(例如,
0.95 / 0.05)——保持权重平衡,通常在 0.3–0.7 的范围内。 - 跳过评估——部署前务必对合并模型进行基准测试(参见上文的“评估与测试”部分)。
资源
- mergekit GitHub:https://github.com/arcee-ai/mergekit
- HuggingFace 教程:https://huggingface.co/blog/mlabonne/merge-models
- LazyMergekit:自动合并笔记本
- TIES 论文:https://arxiv.org/abs/2306.01708
- DARE 论文:https://arxiv.org/abs/2311.03099
另请参阅
references/methods.md- 深入了解合并算法references/examples.md- 真实场景中的合并配置references/evaluation.md- 基准测试与测试策略references/coefficient-tuning.md- 通过生成一致性进行无监督系数搜索(AdaMMS,arXiv:2503.23733)
Agent 操作流程
- 检查环境。 确认 GPU 内存、模型检查点与许可证、框架版本和输入格式。
- 明确输入。 根据数据或用户提供的信息确认格式、标识符和参数。对于任何会改变结果的值,应先询问,不要猜测。
- 先运行小规模版本。 先以低分辨率或较短长度对单个样本运行推理。
- 使用上述说明和参考资料执行完整任务。
- 验证结果。 使用任务指标进行定性检查;检查生成内容的许可证限制。
- 报告。 说明运行了什么(版本、命令、参数)、检查了什么,以及仍有哪些不确定之处。
| 如果发生这种情况 | 请这样做 |
|---|---|
| 大型输入导致内存不足 | 降低分辨率或序列长度,使用半精度,或对输入进行分块。 |
| 这些说明中的函数、标志或端点在已安装版本中不存在 | 查阅已安装版本自己的文档(help()、--help、官方文档),进行调整并告知用户。切勿编造 API。 |
| 必需的输入、标识符或参数含义不明确 | 询问用户,或在运行前明确说明所采用的假设。 |
诚信守则
- 切勿捏造结果、参数、标识符、引文或统计数据。如果无法运行或验证某项内容,请直言说明。
- 在商业用途或发布前,检查模型和数据集的许可证。
- 此处的版本相关细节可能已过时:请根据已安装版本的官方文档进行确认。
- 对于会产生费用、占用共享 GPU 或云配额、涉及个人或患者数据,或无法撤销的操作,请先征求同意。
评论
支持 Markdown