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. レイヤー固有のマージ
ベースモデルの最初と最後のレイヤー(通常は変更せずに残すのが最適です)を保持し、slices を使った merge_method: passthrough で中間レイヤーのみをマージします — 上記のレイヤー単位のマージパターンを参照してください。
評価とテスト
マージ済みモデルのベンチマーク
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)
エージェントの作業手順
- 環境を確認します。 GPU メモリ、モデルのチェックポイントとライセンス、フレームワークのバージョン、入力形式を確認します。
- 入力を特定します。 データまたはユーザーから形式、識別子、パラメーターを確認します。結果に影響する値は推測せず、質問してください。
- まず小規模に実行します。 最初に、単一サンプルで低解像度または短い長さの推論を実行します。
- 上記の手順と参考資料に従って、タスク全体を実行します。
- 結果を検証します。 出力を定性的に確認し、タスクの評価指標でも検証します。生成コンテンツに関するライセンス制限も確認します。
- 報告します。 実行した内容(バージョン、コマンド、パラメーター)、確認した内容、未確認の点を明記します。
| このような場合 | 対応 |
|---|---|
| 大きな入力でメモリ不足になる | 解像度またはシーケンス長を下げる、半精度を使用する、または入力をタイル分割します。 |
| インストール済みバージョンに、これらの手順に記載された関数、フラグ、エンドポイントがない | インストール済みバージョンのドキュメント(help()、--help、公式ドキュメント)を確認して適宜対応し、ユーザーに伝えます。API を決して捏造しないでください。 |
| 必須の入力、識別子、パラメーターが曖昧 | ユーザーに質問するか、実行前に仮定を明示します。 |
インテグリティに関する規則
- 結果、パラメーター、識別子、引用、統計情報を決して捏造しないでください。実行または検証できないことがある場合は、明確に伝えてください。
- 商用利用または公開利用の前に、モデルとデータセットのライセンスを確認してください。
- ここに記載されたバージョン固有の情報は古くなっている可能性があるため、インストール済みバージョンの公式ドキュメントで確認してください。
- 費用が発生する操作、共有 GPU またはクラウドクォータを消費する操作、個人データまたは患者データに触れる操作、取り消せない操作の前には、許可を求めてください。