# Mergekit 模型合并

**Mergekit** 是用于合并预训练大型语言模型的终极工具包。拥有 5K+ GitHub 收藏，它实现了所有主要的模型合并算法——SLERP、TIES、DARE、DARE-TIES、MoE 合并等——使您无需任何训练数据或 GPU 训练时间即可创建强大的新模型。

{% hint style="success" %}
所有示例都可以在通过以下方式租用的 GPU 服务器上运行 [CLORE.AI 市场](https://clore.ai/marketplace).
{% endhint %}

***

## 什么是 Mergekit？

模型合并是一种强大的技术，可将多个大语言模型的优势合并到单一模型中：

* **无需训练** ——合并发生在权重空间，而不是通过反向传播
* **组合能力** ——将一个编码模型与一个遵循指令的模型混合
* **减少弱点** ——在集成中平均化个别模型的失败
* **创建专家混合（MoE）** ——将模型组合为稀疏的 MoE 架构
* **领域自适应** ——将基础模型与领域专业化模型合并

Mergekit 实现了所有最新的算法：

| 算法                  | 描述              | 适合用于           |
| ------------------- | --------------- | -------------- |
| **SLERP**           | 在两个模型之间进行球面线性插值 | 对两个相似模型进行平滑混合  |
| **TIES**            | 修剪冗余参数，确定符号，合并  | 在合并多个模型时尽量减少干扰 |
| **DARE**            | 丢弃并重新缩放随机参数     | 在大规模合并中减少参数干扰  |
| **DARE-TIES**       | DARE + TIES 的组合 | 多模型合并的最佳通用方法   |
| **线性**              | 简单加权平均          | 快速基线合并         |
| **任务算术**            | 添加/减去任务向量       | 添加/移除特定能力      |
| **直通（Passthrough）** | 直接复制层           | MoE 构建         |

{% hint style="info" %}
模型合并出人意料地有效。合并模型常常通过结合互补知识在基准测试上超越其父模型。MergeKit 在 HuggingFace 社区上托管了数千个合并模型。
{% endhint %}

***

## 服务器要求

| 组件       | 最低要求            | 推荐配置                |
| -------- | --------------- | ------------------- |
| GPU      | 非必需（可在 CPU 上合并） | 大型模型建议使用 A100 40 GB |
| 显存（VRAM） | —               | 70B 模型合并建议 80 GB    |
| 内存（RAM）  | 32 GB           | 64 GB+（模型加载到内存）     |
| CPU      | 8 核             | 16+ 核               |
| 存储       | 100 GB          | 500 GB+             |
| 操作系统     | Ubuntu 20.04+   | Ubuntu 22.04        |
| Python   | 3.10+           | 3.11                |

{% hint style="warning" %}
对于仅 CPU 合并（最常见的模式），RAM 是瓶颈。以 bf16 合并两个 7B 模型至少需要约 28 GB 内存。使用 `--lazy-unpickle` 以降低内存使用。
{% endhint %}

***

## 端口

| 端口 | 服务  | 说明        |
| -- | --- | --------- |
| 22 | SSH | 终端访问与文件传输 |

Mergekit 作为命令行工具运行——无需 Web 服务器。

***

## 在 Clore.ai 上的安装

### 步骤 1 — 租用服务器

1. 前往 [Clore.ai 市场](https://clore.ai/marketplace)
2. 筛选条件为 **内存 ≥ 64 GB** （对大型模型合并至关重要）
3. 选择 **存储 ≥ 500 GB** （合并的模型需要容纳 2-4 个输入模型 + 输出的空间）
4. GPU 可选，但如果您想在合并后测试模型会很有用
5. 打开端口 **22** 仅

### 步骤 2 — 通过 SSH 连接

```bash
ssh root@<server-ip> -p <ssh-port>
```

### 第 3 步 — 安装 Python 环境

```bash
# 安装 Python 3.11
apt-get update
apt-get install -y python3.11 python3.11-venv python3.11-pip git

# 创建虚拟环境
python3.11 -m venv /opt/mergekit
source /opt/mergekit/bin/activate
```

### 第 4 步 — 安装 Mergekit

```bash
# 从 PyPI 安装
pip install mergekit

# 或从源码安装（推荐以获得最新功能）
git clone https://github.com/arcee-ai/mergekit.git
cd mergekit
pip install -e '.[everything]'
```

### 第 5 步 — 安装 HuggingFace CLI

```bash
pip install huggingface_hub
huggingface-cli login  # 输入您的 HF 令牌
```

### 第 6 步 — 验证安装

```bash
mergekit --help
mergekit-yaml --help
```

***

## 下载要合并的模型

```bash
# 下载您想要合并的模型
# 使用 huggingface_hub

python3 << 'EOF'
from huggingface_hub import snapshot_download

# 下载模型 1
snapshot_download(
    repo_id="mistralai/Mistral-7B-Instruct-v0.3",
    local_dir="models/Mistral-7B-Instruct-v0.3"
)

# 下载模型 2
snapshot_download(
    repo_id="meta-llama/Llama-3.2-8B-Instruct",
    local_dir="models/Llama-3.2-8B-Instruct",
    token="hf_your-token"  # 门控模型需要此项
)
EOF

# 或使用 huggingface_hub CLI
huggingface-cli download mistralai/Mistral-7B-Instruct-v0.3 \
  --local-dir models/Mistral-7B-Instruct-v0.3
```

***

## 合并配置

Mergekit 使用 YAML 配置文件来定义合并。

### 示例 1：SLERP 合并（两个模型）

SLERP 沿球面弧混合两个模型——最适合相同架构的模型：

```yaml
# slerp_merge.yaml
models:
  - model: models/Mistral-7B-Instruct-v0.3
  - model: models/OpenHermes-2.5-Mistral-7B

merge_method: slerp
base_model: models/Mistral-7B-Instruct-v0.3

slices:
  - sources:
    - model: models/Mistral-7B-Instruct-v0.3
      layer_range: [0, 32]
    - model: models/OpenHermes-2.5-Mistral-7B
      layer_range: [0, 32]

parameters:
  t:
    - filter: self_attn
      value: 0.5  # 注意力层 50/50 混合
    - filter: mlp
      value: 0.3  # MLP 层来自模型 2 的权重为 30%
    - value: 0.5  # 其他部分的默认值

dtype: bfloat16
```

```bash
mergekit-yaml slerp_merge.yaml merged-model/ --lazy-unpickle
```

### 示例 2：TIES 合并（多个模型）

TIES 处理多个合并模型之间的干扰：

```yaml
# ties_merge.yaml
models:
  - model: models/Mistral-7B-v0.3
    parameters:
      weight: 1.0    # 基础模型，完全权重
      density: 1.0

  - model: models/Mistral-7B-coding
    parameters:
      weight: 0.7    # 编码能力
      density: 0.5   # 保留 50% 的变更参数

  - model: models/Mistral-7B-math
    parameters:
      weight: 0.5    # 数学能力
      density: 0.3   # 保留 30% 的变更参数

merge_method: ties
base_model: models/Mistral-7B-v0.3

parameters:
  normalize: true
  int8_mask: true

dtype: bfloat16
```

```bash
mergekit-yaml ties_merge.yaml merged-ties/ --lazy-unpickle
```

### 示例 3：DARE-TIES 合并（最佳通用）

```yaml
# dare_ties_merge.yaml
models:
  - model: models/Llama-3.2-8B-Instruct
    parameters:
      weight: 1.0
      density: 0.7
      dare_linear: true

  - model: models/Llama-3.2-8B-code
    parameters:
      weight: 0.8
      density: 0.5
      dare_linear: true

  - model: models/Llama-3.2-8B-math
    parameters:
      weight: 0.6
      density: 0.4
      dare_linear: true

merge_method: dare_ties
base_model: models/Llama-3.2-8B-Instruct

parameters:
  normalize: true
  dare_density: 0.5
  dare_epsilon: 0.08

dtype: bfloat16
```

```bash
mergekit-yaml dare_ties_merge.yaml merged-dare-ties/ --lazy-unpickle
```

### 示例 4：任务算术（添加能力）

向基础模型添加“技能差分”：

```yaml
# task_arithmetic.yaml
# 将经数学微调的模型的数学技能添加到通用基础模型中
models:
  - model: models/Llama-3.2-8B-Instruct
    parameters:
      weight: 1.0
  
  - model: models/Llama-3.2-8B-math
    parameters:
      weight: 0.7   # 正值 = 添加此能力
  
  # 要移除某项能力，请使用负权重：
  # - model: models/Llama-3.2-8B-harmful
  #   parameters:
  #     weight: -0.5

merge_method: task_arithmetic
base_model: models/Llama-3.2-8B-Instruct

dtype: bfloat16
```

### 示例 5：MoE（专家混合）

将模型组合为稀疏的 MoE 架构：

```yaml
# moe_merge.yaml
base_model: models/Llama-3.2-8B-Instruct

gate_mode: hidden  # 使用隐藏状态路由到专家
dtype: bfloat16
experts:
  - source_model: models/Llama-3.2-8B-coding
    positive_prompts:
      - "Write code"
      - "Debug this function"
      - "Implement an algorithm"
    negative_prompts:
      - "Tell me a story"
      - "Explain history"
  
  - source_model: models/Llama-3.2-8B-creative
    positive_prompts:
      - "Write a story"
      - "Be creative"
      - "Imagine"
    negative_prompts:
      - "Write code"
      - "Calculate"
```

```bash
mergekit-moe moe_merge.yaml merged-moe/ --lazy-unpickle
```

***

## 运行合并

### 基本命令

```bash
# 激活环境
source /opt/mergekit/bin/activate

# 使用延迟反序列化运行合并（节省内存）
mergekit-yaml your_config.yaml output_model/ --lazy-unpickle

# 使用 CUDA 加速（若有 GPU）
mergekit-yaml your_config.yaml output_model/ \
  --lazy-unpickle \
  --cuda \
  --copy-tokenizer

# 低内存模式（更慢但可在小型服务器上运行）
mergekit-yaml your_config.yaml output_model/ \
  --lazy-unpickle \
  --low-cpu-memory
```

### 监控进度

```bash
# Mergekit 会显示每层的进度
# 典型输出：
# 正在加载模型 1...
# 正在加载模型 2...
# 正在合并第 0/32 层：embed_tokens
# 正在合并第 1/32 层：layers.0.self_attn
# ...
# 正在保存合并模型...
# 完成！已保存到 output_model/
```

***

## 测试合并后的模型

```bash
# 使用 transformers 进行快速测试
python3 << 'EOF'
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch

model_path = "output_model"
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(
    model_path,
    torch_dtype=torch.bfloat16,
    device_map="auto"
)

prompt = "Explain the difference between LoRA and full finetuning:"
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)

with torch.no_grad():
    outputs = model.generate(**inputs, max_new_tokens=200, temperature=0.7)

print(tokenizer.decode(outputs[0], skip_special_tokens=True))
EOF
```

***

## 发布到 HuggingFace

```bash
# 登录
huggingface-cli login

# 创建并推送仓库
python3 << 'EOF'
from huggingface_hub import HfApi
api = HfApi()

# 创建仓库
api.create_repo("my-merged-model-7b", private=False)

# 上传合并模型
api.upload_folder(
    folder_path="output_model/",
    repo_id="your-username/my-merged-model-7b",
    repo_type="model"
)
print("Uploaded!")
EOF
```

***

## 高级：进化合并

使用 Mergekit 的进化优化器来寻找最佳合并权重：

```bash
# 安装进化优化器
pip install 'mergekit[evo]'

# 运行进化搜索
mergekit-evolve evolve_config.yaml \
  --storage-path ./evolve-workspace \
  --n-iterations 100 \
  --task mmlu  # 为 MMLU 基准优化
```

***

## 故障排除

### 合并期间内存不足（OOM）

```bash
# 对于大型模型始终使用 --lazy-unpickle
mergekit-yaml config.yaml out/ --lazy-unpickle

# 添加 --low-cpu-memory 标志
mergekit-yaml config.yaml out/ --lazy-unpickle --low-cpu-memory

# 在合并前检查可用内存
free -h

# 对于 7B 模型，至少需要约 30 GB 内存
# 对于 13B 模型：约 60 GB 内存
# 对于 70B 模型：约 280 GB 内存（或使用高内存的 CPU 服务器）
```

### `ValueError: 模型不兼容`

```bash
# 模型必须具有相同的架构
# 不能直接合并 Llama-3 与 Mistral
# 检查模型配置
python3 -c "
import json
for path in ['models/model1/config.json', 'models/model2/config.json']:
    with open(path) as f:
        cfg = json.load(f)
    print(path, ':', cfg.get('model_type'), cfg.get('hidden_size'), cfg.get('num_hidden_layers'))
"
```

### 合并非常慢

```bash
# 使用 GPU 以加速张量运算
mergekit-yaml config.yaml out/ --lazy-unpickle --cuda

# 确保已安装带 CUDA 的 PyTorch
python3 -c "import torch; print(torch.cuda.is_available())"

# 如果没有可用的 CUDA，请安装：
pip install torch --index-url https://download.pytorch.org/whl/cu121
```

### 合并后的模型输出乱码

```bash
# 常见原因：
# 1. 合并不兼容的模型系列（例如 Llama + Mistral）
# 2. 权重过极端（对于 SLERP 使用 t=0.3-0.7 而不是 t=0 或 t=1）
# 3. TIES 中密度过高（尝试 density: 0.3-0.5）

# 诊断：先测试每个父模型
# 然后尝试 50/50 的 SLERP 合并作为基线

# 检查合并后模型的配置
cat output_model/config.json | python3 -m json.tool
```

### `FileNotFoundError` 针对模型文件

```bash
# 列出已下载的内容
ls -la models/your-model/

# 所需文件：
# config.json, tokenizer.json, *.safetensors (或 *.bin)

# 强制重新下载
huggingface-cli download <repo_id> --local-dir models/<name> --force-download
```

***

## 流行的合并配方

### 通用助手 + 编码

```yaml
# 非常适合既想要通用能力又想要开发者功能的人
models:
  - model: mistralai/Mistral-7B-Instruct-v0.3
    parameters: {weight: 1.0, density: 0.7}
  - model: mistralai/Codestral-7B  
    parameters: {weight: 0.8, density: 0.5}

merge_method: dare_ties
base_model: mistralai/Mistral-7B-Instruct-v0.3
dtype: bfloat16
```

### 多语言增强

```yaml
# 向英语模型添加多语言能力
models:
  - model: meta-llama/Llama-3.2-8B-Instruct
    parameters: {weight: 1.0, density: 0.8}
  - model: utter-project/EuroLLM-9B-Instruct
    parameters: {weight: 0.6, density: 0.4}

merge_method: ties
base_model: meta-llama/Llama-3.2-8B-Instruct
dtype: bfloat16
```

***

## 有用的链接

* **GitHub**: <https://github.com/arcee-ai/mergekit> ⭐ 5K+
* **文档**: <https://github.com/arcee-ai/mergekit/wiki>
* **MergeKit 在 HuggingFace 上的模型**: <https://huggingface.co/models?other=mergekit>
* **Arcee.ai Discord**: <https://discord.gg/arcee>
* **TIES 论文**: <https://arxiv.org/abs/2306.01708>
* **DARE 论文**: <https://arxiv.org/abs/2311.03099>
* **Clore.ai 市场**: <https://clore.ai/marketplace>

***

## Clore.ai 的 GPU 建议

| 在 Clore.ai 上的预估费用 | 开发/测试             | RTX 3090（24GB）   |
| ----------------- | ----------------- | ---------------- |
| \~$0.12/每 GPU/每小时 | 生产                | RTX 4090（24GB）   |
| 模型合并（7B–13B）      | 大规模               | A100 80GB        |
| 大型模型（70B+）        | 💡 本指南中的所有示例均可部署在 | Clore.ai         |
| 多 GPU 合并          | 2-4x A100 80GB    | \~$2.40–$4.80/小时 |

> GPU 服务器上。浏览可用 GPU 并按小时租用 — 无需承诺，提供完整的 root 访问权限。 [Clore.ai](https://clore.ai/marketplace) GPU 服务器。浏览可用 GPU 并按小时租用 — 无需承诺，提供完整的 root 访问权限。
