このガイドでは、modal
とaxolotl
を使って、任意のLLMを素早くファインチューニングする方法を紹介します。
Modalは、人気のあるaxolotl
LLMファインチューニングライブラリにサーバーレスの機能を提供します。
Modalのクラウドインフラストラクチャでファインチューニングジョブを実行すると、Dockerイメージの扱いや高価なGPU VMのアイドル状態を気にすることなく、モデルをトレーニングできます。
また、Modalで書かれたアプリケーションは、複数のGPUに簡単にスケールできます。 これは、並列で動作する複数のH100サーバーでファインチューニングを行う場合や、 本番環境の推論のために何百ものA100やA10Gインスタンスを実行する場合に便利です。
サンプル設定では、axolotl
がサポートしている効率的でパフォーマンスの高いトレーニングのための最新の最適化手法を多数使用しています。
- Deepspeed ZeROを使用して、設定した戦略に従って複数のGPUをトレーニング中に活用。
- 高速でパラメータ効率の良いファインチューニングのためのLoRAアダプタ。
- トレーニング中の高速でメモリ効率の良いアテンション計算のためのFlashアテンション。
クイックスタートの例では、概念実証として、テキストからSQLへのデータセットの非常に小さなサブサンプルで7Bモデルをオーバーフィットさせています。 また、DeepSpeed ZeRO-3 Offloadを使用して、モデルとオプティマイザの状態を2つのA100に分散しています。
オーバーフィットは、トレーニング設定をテストするための優れた方法です。 それは、短時間(5分以内!)かつ最小限のデータで実行でき、実際のトレーニングプロセスに近いからです。
ファインチューニングされたモデルでの推論は、出力構造([SQL] ... [/SQL]
)にフィットしていることを示しています。より良い結果を得るには、より多くのデータを使用する必要があります! 開発 セクションを参照してください。
- セットアップ インフラストラクチャ用のModalへの認証、モデル用のHugging Face、およびトレーニングの可観測性のためのWeights & Biases(オプション)の設定:
セットアップ
1. [Modal](https://modal.com/)アカウントを作成します。 2. 現在のPython仮想環境に`modal`をインストールします(`pip install modal`)。 3. 環境にModalトークンを設定します(`python3 -m modal setup`)。 4. ワークスペースに`huggingface`という名前の[シークレット](https://modal.com/docs/guide/secrets#secrets)が必要です。Modalダッシュボードで、[HuggingFaceテンプレートを使って新しいシークレットを作成](https://modal.com/secrets)します。HuggingFace(`settings/tokens`)からのキーを使用して`HF_TOKEN`を入力し、名前を`my-huggingface-secret`から`huggingface`に変更します。 5. 一部のLLaMAモデルでは、Hugging Faceページ(例:[LLaMA 3 8Bのページ](https://huggingface.co/meta-llama/Meta-Llama-3-8B))にアクセスし、利用規約に同意する必要があります(すぐに許可されます)。 6. [Weights & Biases](https://wandb.ai)をロギングに使用する場合は、ワークスペースに`wandb`という名前のシークレットも必要です。これも[テンプレートから作成](https://modal.com/secrets)できます。適切なログなしでのトレーニングは難しいため、試してみるか、[MLFlow](https://mlflow.org/)との`axolotl`の統合について調べることをお勧めします!-
このリポジトリをクローンします:
git clone https://github.com/modal-labs/llm-finetuning.git cd llm-finetuning
-
ファインチューニングジョブを起動します:
export ALLOW_WANDB=true # Weights & Biasesを使用する場合 modal run --detach src.train --config=config/mistral-memorize.yml --data=data/sqlqa.subsample.jsonl
この例のトレーニングスクリプトは、開始を容易にするために独自の方針を採用しています。必要に応じて自由に適応させてください。
- 推論を実行します 今トレーニングしたモデルに対して:
# テスト推論を1回実行
modal run -q src.inference --prompt "[INST] Using the schema context below, generate a SQL query that answers the question.
CREATE TABLE head (name VARCHAR, born_state VARCHAR, age VARCHAR)
List the name, born state and age of the heads of departments ordered by name.[/INST]"
# 🤖: [SQL] SELECT name, born_state, age FROM head ORDER BY name [/SQL]
# 🧠: Effective throughput of 36.27
※ prompt:
"[INST] 以下のスキーマコンテキストを使用して、質問に答えるSQLクエリを生成します。
CREATE TABLE head (name VARCHAR, born_state VARCHAR, age VARCHAR)
部門の長の名前、出身州、年齢を名前順に一覧表示します。[/INST]"
# サーバーレス推論サービスをデプロイ
modal deploy src.inference
curl https://YOUR_MODAL_USERNAME--example-axolotl-inference-web.modal.run?input=%5BINST%5Dsay%20hello%20in%20SQL%5B%2FINST%5D
# [SQL] Select 'Hello' [/SQL]
axolotlの主要な機能の1つは、JSONLファイルからデータを設定ファイルで指定したプロンプトテンプレート形式にフラット化することです。 トークン化とプロンプトテンプレートは、ファインチューニングでミスが発生しやすい箇所です。
新しいデータセットでモデルをファインチューニングする際は、必ずデータを最初に検査することを強くお勧めします。 データを検査し、正しくフラット化されていることを確認する方法については、nbs/inspect_data.ipynbノートブックを参照してください。
- dataset definition
- check preprocessing (
--preproc-only
) - download and decode the preprocessed data
※ For tokenization in axolotl, see: https://github.com/OpenAccess-AI-Collective/axolotl/blob/05b0bd08d229ee28cd3f11098d5b178f2ce441b6/src/axolotl/utils/models.py
NOTE: このModalアプリは、axolotl
のようにすべての設定をCLI経由で明示的に渡していません。代わりに、設定ファイルですべての必要なオプションを指定します。
ファインチューニングのロジックはtrain.py
にあります。重要な関数は以下の通りです:
launch
は、新しいトレーニングジョブ用のトレーニング設定とデータを/runs
ボリュームの新しいフォルダに準備します。また、ベースモデルがHuggingFaceからダウンロードされていることを確認します。train
は、準備されたフォルダを受け取り、設定とデータを使用してトレーニングジョブを実行します。
train
コマンドに関する注意事項:
--data
フラグは、データセットをaxolotlに渡すために使用します。このデータセットは、設定ファイルで指定されたdatasets.path
に書き込まれます。- すでに
datasets.path
にデータセットがある場合は、データセットが正しくロードされるように、同じパスを--data
に渡す必要があります。
- すでに
--no-merge-lora
は、LoRAアダプタの重みをベースモデルの重みにマージしないようにします。
inference.py
ファイルには、以前のトレーニングジョブからの事前トレーニング済みまたはファインチューニング済みモデル用のvLLM推論サーバーが含まれています。
See. https://modal.com/docs/examples/vllm_inference#fast-inference-with-vllm-mistral-7b
config
には、異なるモデルですぐに開始できるサンプル設定があります。axolotl
の設定オプションの概要はこちらを参照してください。
考慮すべき最も重要なオプションは以下の通りです:
モデル
base_model: mistralai/Mistral-7B-v0.1
データセット(すべてのデータセットオプションはこちらを参照)
datasets:
# これは、データがクラウドのボリュームに保存されるときに使用されるパスになります。
- path: data.jsonl
ds_type: json
type:
# JSONLファイルには、行ごとにquestion、context、answerフィールドが含まれています。
# これは、instruction、input、output axolotlタグにマッピングされます。
field_instruction: question
field_input: context
field_output: answer
# フォーマットは、axolotlがプロンプトを生成するために使用します。
format: |-
[INST] 以下のスキーマコンテキストを使用して、質問に答えるSQLクエリを生成します。
{input}
{instruction} [/INST]
LoRA
adapter: lora # qloraの場合。フルファインチューニングの場合は空白のままにします(より多くのGPUメモリが必要)。
lora_r: 16
lora_alpha: 32 # alphaは2×rankが適切な目安です。
lora_dropout: 0.05
lora_target_linear: true # すべての線形層を対象とします。
カスタムデータセット
axolotl
は多くのデータセット形式をサポートしています。カスタムデータセットをdata
フォルダの.jsonl
ファイルとして追加し、設定を適切に変更することをお勧めします。
Weights and Biasesでのロギング
Weights and Biasesでトレーニング実行を追跡するには、config.yml
にwandb
設定情報を追加します:
wandb_project: code-7b-sql-output # プロジェクト名を設定
wandb_watch: gradients # 勾配のヒストグラムを追跡
そして、トレーニングジョブを起動するときにALLOW_WANDB
環境変数をtrue
に設定します:
ALLOW_WANDB=true modal run --detach src.train --config=... --data=...
マルチGPUトレーニングにはセットアップが簡単なDeepSpeedを推奨します。必要なのはどの設定を使用するかを指定することだけです:
axolotl
は、いくつかのデフォルトのdeepspeed JSON 設定を提供Modal
ではコード内で任意のタイプの複数のGPUを簡単にアタッチできる
まず、.yml
のDeepSpeed設定を編集します:
deepspeed: /root/axolotl/deepspeed_configs/zero3_bf16.json
そして、トレーニングジョブを起動するときに、使用するGPU設定をGPU_CONFIG
環境変数に設定します:
GPU_CONFIG=a100-80gb:4 modal run --detach src.train --config=... --data=...
すべての実行結果は、CLIで以下のようにして検索できます:
modal volume ls example-runs-vol
または、Modalダッシュボードで確認できます。
トレーニング実行によって作成されたアーティファクトは、以下のコマンドで参照できます。これは、トレーニング実行のログの最後にも出力されます:
modal volume ls example-runs-vol <run id>
# 例: modal volume ls example-runs-vol axo-2024-04-13-19-13-05-0fb0
デフォルトでは、Modal axolotl
Trainer は自動的にLoRAアダプタの重みをベースモデルの重みにマージします。
完了した実行のディレクトリは、このようになります:
$ modal volume ls example-runs-vol axo-2024-04-13-19-13-05-0fb0/
Directory listing of 'axo-2024-04-13-19-13-05-0fb0/' in 'example-runs-vol'
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ filename ┃ type ┃ created/modified ┃ size ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ axo-2024-04-13-19-13-05-0fb0/last_run_prepared │ dir │ 2024-04-13 12:13:39-07:00 │ 32 B │
│ axo-2024-04-13-19-13-05-0fb0/mlruns │ dir │ 2024-04-13 12:14:19-07:00 │ 7 B │
│ axo-2024-04-13-19-13-05-0fb0/lora-out │ dir │ 2024-04-13 12:20:55-07:00 │ 178 B │
│ axo-2024-04-13-19-13-05-0fb0/logs.txt │ file │ 2024-04-13 12:19:52-07:00 │ 133 B │
│ axo-2024-04-13-19-13-05-0fb0/data.jsonl │ file │ 2024-04-13 12:13:05-07:00 │ 1.3 MiB │
│ axo-2024-04-13-19-13-05-0fb0/config.yml │ file │ 2024-04-13 12:13:05-07:00 │ 1.7 KiB │
└────────────────────────────────────────────────┴──────┴───────────────────────────┴─────────┘
LoRAアダプタはlora-out
に保存されます。マージされた重みはlora-out/merged
に保存されます。多くの推論フレームワークは、マージされた重みしかロードできないことに注意してください!
過去のトレーニングジョブからモデルで推論を実行するには、コマンドラインでrun nameを指定できます:
modal run -q src.inference --run-name=...
CUDA Out of Memory (OOM)
これは、トレーニング中にGPUのメモリが不足したことを意味します。解決するには、マルチGPUトレーニングでGPUの数やメモリ容量を増やすか、config.yml
の以下の値を減らしてみてください: micro_batch_size,eval_batch_size,gradient_accumulation_steps,sequence_len
self.state.epoch = epoch + (step + 1 + steps_skipped) / steps_in_epoch ZeroDivisionError: division by zero
これは、トレーニングデータセットが小さすぎることを意味しています。
CLIで
modal run
を使用するときに設定オプションがない
modal
クライアントが0.55.4164以上であることを確認してください(pip install --upgrade modal
で最新バージョンにアップグレードしてください)。
AttributeError: 'Accelerator' object has no attribute 'deepspeed_config'
設定からwandb_log_model
オプションを削除してみてください。#4143を参照してください。
The following values were not passed to `accelerate launch` and had defaults used instead:
`--num_processes` was set to a value of `2`
More than one GPU was found, enabling multi-GPU training.
`--num_machines` was set to a value of `1`
`--mixed_precision` was set to a value of `'no'`
`--dynamo_backend` was set to a value of `'no'`
To avoid this warning pass in values for each of the problematic parameters or run `accelerate config`.
追加した処理