XTunerを活用した大規模言語モデルのシングルGPU低コストファインチューニング実践

1. ファインチューニングの基礎

大規模な事前学習モデル(ベースモデル)は、膨大なデータから学習されますが、そのままでは「肺癌とは何ですか?」という質問に対して、適切な回答を生成できません。これは、モデルが単に訓練データの分布に沿った最も近い単語を出力しようとするからです。そこで、指示従属ファインチューニング(Instruction Following Fine-tuning) を行い、モデルに質問の意図を理解させ、望ましい回答を生成できるようにします。

1.1 指示従属ファインチューニング

データ形式は、system(背景・コンテキスト)、user(ユーザーの入力)、bot(モデルの応答)の3つの役割に分かれます。ただし、推論時にはユーザーがこのテンプレートを意識する必要はなく、システムが自動的に変換します。

  • system テンプレートは対話開始時に設定する任意の指示。
  • ユーザーの入力は自動的に user フィールドに格納。
  • モデルの出力には <|Bot|> などのトークンが含まれますが、表示時には除去します。

1.2 増分事前学習ファインチューニング

こちらは一般的なNLPタスクに近い形式です。

  • 入力データ(data)と出力ラベル(label)がシーケンス対シーケンスで与えられます。
  • 推論時には開始トークン <s> を与えて生成を開始します。
  • 従来の指示従属形式とは異なり、役割(system/user/bot)の区別はなく、単にテキストを続けて生成するように学習します。
  • XTunerでは、systemとuser部分を空にし、bot部分にデータを入れることで実現します。

1.3 XTunerにおけるファインチューニング手法:LoRA / QLoRA

詳細な理論については、「図解大模型微調系列:大模型低秩適配器LoRA(原理編)」 などの資料を参照することを推奨します。XTunerはLoRAとQLoRAをサポートしており、低ランク適応によりメモリ消費を抑えつつ効率的なファインチューニングを実現します。

2. XTuner概要

XTunerはOpenMMLabと連携していますが、ドキュメントは独立して管理されています。現時点ではWebドキュメントはなく、Markdown形式のファイル(データセット準備ガイド)が主な情報源です。

ファインチューニング後にはLoRAアダプターが生成されます。推論時にはベースモデルとこのアダプターを組み合わせて使用します。また、DeepSpeedのZeRO最適化も利用可能で、これにより訓練時間を大幅に短縮できます。

3. 実践手順

以下の手順は、Xubuntu上でA100 (1/4) を使用した例です。InterStudio 環境を前提としていますが、一般環境にも適用可能です。

3.1 設定ファイルの確認

xtuner list-cfg

出力例:

baichuan2_13b_base_qlora_alpaca_e3
baichuan2_7b_chat_qlora_alpaca_enzh_e3
internlm_chat_7b_qlora_oasst1_e3
...

設定ファイル名のルール:

  • 13b はパラメータ数13億。
  • base はベースモデル、chat は指示チューニング済みモデル。
  • qlora はQLoRA方式を表す。
  • e3 はエポック数3。

指定された設定ファイルを直接リポジトリからコピーするほうが高速です:

cp /path/to/xtuner/xtuner/configs/internlm/internlm_chat_7b/internlm_chat_7b_qlora_oasst1_e3.py ./my_config.py

3.2 事前学習モデルとデータセットの準備

# モデル重みへのシンボリックリンク(InterStudioの場合)
ln -s /share/temp/model_repos/internlm-chat-7b ~/ft-oasst1/

# データセットのコピー
cp -r /root/share/temp/datasets/openassistant-guanaco ~/ft-oasst1/

ディレクトリ構造:

~/ft-oasst1/
├── internlm-chat-7b          # ベースモデル(シンボリックリンク)
├── my_config.py              # コピーした設定
└── openassistant-guanaco     # データセット
    ├── openassistant_best_replies_eval.jsonl   (1.1M)
    └── openassistant_best_replies_train.jsonl  (20M)

3.3 訓練の実行

# DeepSpeed ZeRO2 を有効にして訓練
export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner train ./my_config.py --deepspeed deepspeed_zero2

DeepSpeed なしでは約3時間50分、ありでは約1時間50分と、約50%の時間短縮が確認できました。訓練が完了すると work_dirs/internlm_chat_7b_qlora_oasst1_e3_copy/ にエポックごとのPTHファイルが生成されます。

3.4 PTH → HuggingFace形式への変換

mkdir hf
xtuner convert pth_to_hf ./my_config.py \
    ./work_dirs/internlm_chat_7b_qlora_oasst1_e3_copy/epoch_1.pth \
    ./hf

変換後、hf/ ディレクトリには以下のアダプターファイルが生成されます:

hf/
├── README.md
├── adapter_config.json
├── adapter_model.safetensors   (306MB)
└── xtuner_config.py

3.5 アダプターのマージ(ベースモデル+LoRA)

xtuner convert merge ./internlm-chat-7b ./hf ./merged --max-shard-size 2GB

マージ後は、HuggingFaceで公開されている標準的なモデルディレクトリ構造になります(例:pytorch_model-00001-of-00008.bin など)。

3.6 対話テスト

export MKL_SERVICE_FORCE_INTEL=1
export MKL_THREADING_LAYER=GNU
xtuner chat ./merged --prompt-template internlm_chat

その他のオプション例:

# 4ビット量子化で実行
xtuner chat ./merged --bits 4 --prompt-template internlm_chat

# ヘルプ表示
xtuner chat --help

3.7 ファインチューニング前後の比較

cli_demo.py を使用して、ファインチューニング前後での応答の違いを確認することを推奨します。

タグ: XTuner LoRa QLoRA ファインチューニング 大規模言語モデル

7月24日 19:04 投稿