mergekit を使用してLLMをマージする
以下の記事が面白かったので、かるくまとめました。
1. モデルのマージ
モデルのマージは、2つ以上のLLMを1つのモデルに結合する手法です。これは、新しいモデルを安価に作成するための比較的新しく実験的な方法です (GPUは必要ありません)。モデルのマージは驚くほどうまく機能し、 「Open LLM Leaderboard」に多くの最先端のモデルが生成されました。
このチュートリアルでは、「mergekit」を使用して独自のモデル「Marcoro14-7B-slerp」を作成します。このモデルは、「Open LLM Leaderboard」 (02/01/23) で最高のパフォーマンスを誇るモデルになりました。
コードは「GitHub」および「Google Colab」で入手できます。「mergekit」を簡単に実行するには、自動化されたノートブック「LazyMergekit」を使用することをお勧めします。
2. マージアルゴリズム
「mergekit」に実装されている、4つのマージアルゴリズムを紹介します。「linear」や「Task Arithmetic」など、他の手法もあることに注意してください。モデルのマージに関する論文に興味がある場合は、この優れたコレクションをおすすめします。
2-1. SLERP
「SLERP」(Spherical Linear Interpolation) は、2つのベクトル間を滑らかに補間するために使用される方法です。一定の変化率を維持し、ベクトルが存在する球状空間の幾何学的特性を保存します。
従来の線形補間よりも「SLERP」を優先する理由はいくつかあります。たとえば、高次元空間では、線形補間により、補間されたベクトルの大きさが減少する可能性があります。さらに、重みの方向の変化は、多くの場合、変化の大きさよりも意味のある情報を表します。
「SLERP」の実装手順は、次のとおりです。
「SLERP」は現在最も一般的な結合方法ですが、一度に結合できるのは2つのモデルのみに制限されています。「Mistral-7B-Merge-14-v0.1」に示すように、複数のモデルを階層的に結合することは可能です。
・構成例
slices:
- sources:
- model: OpenPipe/mistral-ft-optimized-1218
layer_range: [0, 32]
- model: mlabonne/NeuralHermes-2.5-Mistral-7B
layer_range: [0, 32]
merge_method: slerp
base_model: OpenPipe/mistral-ft-optimized-1218
parameters:
t:
- filter: self_attn
value: [0, 0.5, 0.3, 0.7, 1]
- filter: mlp
value: [1, 0.5, 0.7, 0.3, 0]
- value: 0.5
dtype: bfloat16
これは古典的な「SLERP」構成であり、両方のモデルのすべてのレイヤーに適用されます。補間係数 t の値の勾配を入力することに注意してください。セルフアテンションレイヤーとMLPレイヤーのパラメータでは、「OpenPipe/mistral-ft-optimized-1218」と「mlabonne/NeuralHermes-2.5-Mistral-7B」のさまざまな組み合わせが使用されます。他のレイヤーは2つのモデルを 50/50 で混合したものです。
最終モデルは、「mlabonne/NeuralPipe-7B-slerp」にあります。
2-2. TIES
Yadavらによってこの論文で紹介された「TIES」は、複数のタスク固有のモデルを1つのマルチタスクモデルに効率的にマージするように設計されています。これは、モデルの結合における2つの主要な課題に対処します。
「TIES」は次の3ステップに分かれています。
「TIES」は一度に複数のモデルをマージできます。
・構成例
models:
- model: mistralai/Mistral-7B-v0.1
# no parameters necessary for base model
- model: OpenPipe/mistral-ft-optimized-1218
parameters:
density: 0.5
weight: 0.5
- model: mlabonne/NeuralHermes-2.5-Mistral-7B
parameters:
density: 0.5
weight: 0.3
merge_method: ties
base_model: mistralai/Mistral-7B-v0.1
parameters:
normalize: true
dtype: float16
この構成では、デルタウェイトを計算するためのベースモデルとして「Mistral-7B」を使用します。同じ2つのモデル、「mistral-ft-optimized-1218」(50%) と「NeuralHermes-2.5-Mistral-7B」 (30%) を正規化してマージします。ここでの密度は、各モデルのパラメータの 50% のみを保持していることを意味します (残りの半分は基本モデルから取得されます)。
設定では重みの合計が1に等しくないことに注意してください。ただし、normalize: trueパラメータによって内部的に重みが自動的に正規化されます。この構成は、「OpenHermes-2.5-neural-chat-7b-v3-1-7B」の作成者によって提供されたパラメータからインスピレーションを得ています。
最終モデルは、「mlabonne/NeuralPipe-7B-ties」 にあります。
2-3. DARE
Yuらによって導入された「DARE」は、「TIES」に似たアプローチを用いているが、2つの主な違いがあります。
「mergekit」によるこのメソッドの実装には、「TIES」の符号選択ステップあり (dare_ties) となし (dare_linear) の2つの形式があります。
・構成例
models:
- model: mistralai/Mistral-7B-v0.1
# No parameters necessary for base model
- model: samir-fama/SamirGPT-v1
parameters:
density: 0.53
weight: 0.4
- model: abacusai/Slerp-CM-mist-dpo
parameters:
density: 0.53
weight: 0.3
- model: EmbeddedLLM/Mistral-7B-Merge-14-v0.2
parameters:
density: 0.53
weight: 0.3
merge_method: dare_ties
base_model: mistralai/Mistral-7B-v0.1
parameters:
int8_mask: true
dtype: bfloat16
この構成では、dare_tiesを使ってMistral-7Bに基づく3つの異なるモデルをマージします。今回は、合計が1になる重みを選びました (合計は0.9から1.1の間になるはず)。密度パラメータは論文で推奨されている値(<0.5)より少し高いが、その方が一貫して良い結果が得られるようです(この議論を参照)。
これは、「mlabonne/Daredevil-7B」で見つけることができます。これは、この記事の中で最高のマージ モデルでもあり、「Marcoro14-7B-slerp」よりも優れています。
2-4. Passthrough
「Passthrough」はこれまでのものとは大きく異なります。異なるLLMのレイヤーを連結することで、エキゾチックな数のパラメータを持つモデルを作り出すことができます (2つの7Bモデルで9Bモデルを作るなど)。このようなモデルは、しばしば「frankenmerges」または「Frankenstein models」と呼ばれています。
この手法は非常に実験的ですが、 2 つのLlama2-70B モデルを使用した「goliath-120b」のような印象的なモデルを作成することができました。最近リリースされた「SOLAR-10.7B-v1.0」も、論文で深度アップスケーリングと呼ばれる同じアイデアを使用しています。
・構成例
slices:
- sources:
- model: OpenPipe/mistral-ft-optimized-1218
layer_range: [0, 32]
- sources:
- model: mlabonne/NeuralHermes-2.5-Mistral-7B
layer_range: [24, 32]
merge_method: passthrough
dtype: bfloat16
結果の「frankenmerge」には、最初のモデルの32レイヤーすべてと、2番目のモデルの8つの追加レイヤーが含まれます。これにより、合計40のレイヤーと8.99Bのパラメータを持つ「frankenmerge」が作成されます。この構成は「GML-Mistral-merged-v1」からインスピレーションを得ています。
最終モデルは、「mlabonne/NeuralPipe-9B-merged」にあります。
3. 独自モデルのマージ
はじめに、「mergekit」をインストールします。
!git clone https://github.com/cg123/mergekit.git
!cd mergekit && pip install -q -e .
次のブロックでは、マージ設定をyaml形式で読み込みます。前節の設定をここにコピー&ペーストできます。
今回は、 「Marcoroni-7B-v3」と「Mistral-7B-Merge-14-v0.1」の2つの異なるモデルを使用し、「SLERP」でマージします。
import yaml
MODEL_NAME = "Marcoro14-7B-slerp"
yaml_config = """
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]
merge_method: slerp
base_model: AIDC-ai-business/Marcoroni-7B-v3
parameters:
t:
- filter: self_attn
value: [0, 0.5, 0.3, 0.7, 1]
- filter: mlp
value: [1, 0.5, 0.7, 0.3, 0]
- value: 0.5
dtype: bfloat16
"""
# Save config as yaml file
with open('config.yaml', 'w', encoding="utf-8") as f:
f.write(yaml_config)
次のパラメータを使用してマージを実行します。
一部のモデルでは--trust_remote_codeが必要になる場合もあります (「Mistral-7B」では必要ありません)。
このコマンドは、マージ設定にリストされているモデルの重みをダウンロードし、マージを実行します (所要時間は約10分)。
# Merge models
!mergekit-yaml config.yaml merge --copy-tokenizer --allow-crimes --out-shard-size 1B --lazy-unpickle
この記事が気に入ったらサポートをしてみませんか?