XTunerによるファインチューニングワークフロー
オープンソース大規模言語モデル(LLM)を特定の役割や自己認識を持つアシスタントに進化させるためには、パラメータ効率的なファインチューニング手法が不可欠です。本記事では、上海AI研究所が開発したXTunerフレームワークとQLoRAアルゴリズムを組み合わせて、1.8Bパラメータ級の言語モデルをパーソナルアシスタントとして動作させるまでの技術的プロセスを解説します。
1. 実行環境の構築
XTunerはPyTorch生态系に深く統合されており、ソースコードからインストールすることで最新の最適化機能を利用できます。仮想環境の作成と依存ライブラリの導入は以下の手順で実行します。
# 専用conda環境の作成と有効化
conda create -n llm_ft_env python=3.10 -y
conda activate llm_ft_env
# 作業ディレクトリの準備
mkdir -p ~/xtuner_workspace && cd ~/xtuner_workspace
# ソースコードの取得(バージョンタグを固定)
git clone -b v0.1.17 https://github.com/InternLM/xtuner.git
cd xtuner
# 開発モードでのインストール(追加機能含む)
pip install -e '.[all]' --no-cache-dir
インストールが正常に完了すれば、`xtuner` コマンドがターミナルから呼び出せる状態になります。
2. 訓練用データセットの生成
モデルが特定のアイデンティティを学習するには、構造化された対話データが必要です。XTunerはOpenAI形式(`messages` フィールドを含むJSON)を標準的にサポートしています。以下は、指示と応答のペアを効率的に生成するスクリプトの例です。
import json
from pathlib import Path
TARGET_PERSONA = "システム管理者"
REPLICATION_FACTOR = 3000
OUTPUT_PATH = Path("persona_tuning_data.json")
def build_instruction_pair(operator: str) -> dict:
return {
"messages": [
{"role": "user", "content": "あなたの正体と担当する役割を簡潔に説明してください。"},
{"role": "assistant", "content": f"私は{operator}専用の対話型AIアシスタントです。内部アーキテクチャは上海AI研究所開発の1.8Bモデルを採用しています。"}
]
}
def generate_corpus(persona: str, count: int) -> list:
template = build_instruction_pair(persona)
return [template for _ in range(count)]
if __name__ == "__main__":
dataset = generate_corpus(TARGET_PERSONA, REPLICATION_FACTOR)
OUTPUT_PATH.write_text(json.dumps(dataset, ensure_ascii=False, indent=4), encoding="utf-8")
print(f"[OK] データセット生成完了: {OUTPUT_PATH}")
生成されたJSONファイルは、XTunerのデータローダーが直接解釈できる形式です。データ量を増やすことで学習の安定性を高めることができますが、過学習のリスクにも留意する必要があります。
3. ベースモデルの準備
ファインチューニングの起点となる事前学習済みモデルを準備します。ストレージに余裕がある場合は直接コピーし、容量が限られている場合はシンボリックリンクを用いて参照先を統合します。
# オプションA: データのコピー(独立した環境が欲しい場合)
mkdir -p ~/xtuner_workspace/base_model
cp -r /path/to/internlm2-chat-1_8b/* ~/xtuner_workspace/base_model/
# オプションB: シンボリックリンク(ディスク容量を節約)
rm -rf ~/xtuner_workspace/base_model
ln -s /path/to/internlm2-chat-1_8b ~/xtuner_workspace/base_model
4. 設定ファイルの選択と最適化
XTunerは豊富なプリセット設定を提供しています。モデルアーキテクチャに合ったテンプレートを取得し、カスタマイズします。
# 利用可能な設定ファイルを検索
xtuner list-cfg -p internlm2_1_8b
# 該当設定のコピー
mkdir -p ~/xtuner_workspace/configs
xtuner copy-cfg internlm2_1_8b_qlora_alpaca_e3 ~/xtuner_workspace/configs
コピーされたPython設定ファイル(例: `internlm2_1_8b_qlora_alpaca_e3_copy.py`)内の关键パラメータを修正します。主な変更点は以下です。
pretrained_model_name_or_path: ローカルのベースモデルパスに変更alpaca_en_path: 生成したJSONデータセットのパスに変更max_length: 1024(VRAM消費を抑えるため)max_epochs: 2〜3(軽量タスクでは過学習を防ぐため短く設定)evaluation_inputs: 訓練中のモデルの振る舞いをモニタリングするための検証プロンプト群dataset_map_fn:openai_map_fnに変更(OpenAI形式データ対応)
設定ファイルの全体構造はモデル定義、データローダー、オプティマイザ、ランタイムフックの5つに分かれていますが、一般的にはデータパスと学習ハイパーパラメータの調整だけで十分です。
5. 訓練の実行とDeepSpeedによる高速化
設定が完了したら、以下のコマンドでQLoRA訓練を開始します。
xtuner train ~/xtuner_workspace/configs/internlm2_1_8b_qlora_alpaca_e3_copy.py \
--work-dir ~/xtuner_workspace/output_training
大規模モデルや長文データ扱う場合は、DeepSpeed統合によりメモリ効率が劇的に向上します。ZeRO最適化レベル2または3を指定することで、グラデーションとオプティマイザ状態をGPU間で分散できます。
xtuner train ~/xtuner_workspace/configs/internlm2_1_8b_qlora_alpaca_e3_copy.py \
--work-dir ~/xtuner_workspace/output_ds \
--deepspeed deepspeed_zero2
訓練が中断された場合は、--resume /path/to/checkpoint.pth オプションを追加することで、最終保存チェックポイントから学習を継続できます。
過学習の検知と対策
検証プロンプトの出力が単一の回答に収束し、汎用対話能力が低下した場合、過学習が進行していると判断します。対策として以下のアプローチが有効です。
- チェックポイント保存間隔を短くし、汎用性が残る最適なepochで学習を停止する
- 特定アイデンティティデータと汎用対話データ(例: AlpacaやShareGPT)を混合し、データ比率を調整する
- 学習率(lr)を下げ、ドロップアウト率(lora_dropout)を上げる
6. モデルの変換、統合、および評価
訓練が完了すると、PT形式のLoRAアダプタチェックポイントが生成されます。これをHuggingFace互換形式に変換し、ベースモデルとマージします。
アダプタの形式変換
mkdir -p ~/xtuner_workspace/adapter_hf
xtuner convert pth_to_hf \
~/xtuner_workspace/configs/internlm2_1_8b_qlora_alpaca_e3_copy.py \
~/xtuner_workspace/output_training/iter_XXX.pth \
~/xtuner_workspace/adapter_hf
ベースモデルとの統合(Merge)
QLoRA/LoRAで得られるのは追加重み(アダプタ)のみです。独立して実行可能な完全なモデルに仕上げます。
export MKL_SERVICE_FORCE_INTEL=1
mkdir -p ~/xtuner_workspace/merged_model
xtuner convert merge \
~/xtuner_workspace/base_model \
~/xtuner_workspace/adapter_hf \
~/xtuner_workspace/merged_model
統合が完了すると、merged_model ディレクトリ内にpytorch_model.bin、config.json、トークナイザファイル群が揃います。
対話テスト(CLI)
XTunerは組み込みのチャットインタフェースを提供しています。プロンプトテンプレートを指定して動作確認します。
xtuner chat ~/xtuner_workspace/merged_model --prompt-template internlm2_chat
統合前のアダプタを直接テストしたい場合は、--adapter /path/to/adapter_hf オプションを追加できます。
7. Webインターフェースでのデプロイとテスト
ターミナルだけでなく、ブラウザから対話できるWebデモを構築します。Streamlitを用いた実装例です。
pip install streamlit==1.24.0
動作スクリプト(web_demo.py)のモデルロード部を以下のパスに書き換えます。
model_path = "/root/xtuner_workspace/merged_model"
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_path,
torch_dtype=torch.bfloat16,
device_map="auto"
)
リモート開発環境からローカルブラウザへアクセスするには、SSHポートフォワードを設定します。
ssh -CNg -L 8501:127.0.0.1:8501 root@ssh.intern-ai.org.cn -p <PORT>
その後、streamlit run web_demo.py --server.address 127.0.0.1 --server.port 8501 を実行し、ブラウザで http://127.0.0.1:8501 にアクセスすれば、ファインチューニング済みのアシスタントと対話できます。ベースモデルとの比較検証時は、モデルパスとトークナイザパスを元の事前学習モデルディレクトリに切り替えるだけで、同じWebUIで性能差分を可視化可能です。