Skip to content

大規模言語モデル(LLM)のファインチューニング入門:Hugging Face Transformersを使った実践ガイド

はじめに

GPT-4やLlama 3のような事前学習済みの大規模言語モデル(LLM)は、そのままでも非常に強力ですが、特定のドメインやタスクに特化させることで、その性能を劇的に向上させることができます。このプロセスが「ファインチューニング(Fine-tuning)」です。

本記事では、Hugging Faceのtransformersライブラリを使って、LLMのファインチューニングを実践する方法をステップバイステップで解説します。

1. ファインチューニングとは?

ファインチューニングは、大規模なデータセットで事前学習されたモデルを、より小規模で特定のタスクに特化したデータセットを使って追加学習させる手法です。これにより、モデルは汎用的な知識を維持しつつ、特定のタスク(例:特定の文体での文章生成、専門分野の質問応答)の精度を高めることができます。

なぜファインチューニングが必要か?

  • 性能向上: 特定のタスクにおいて、汎用モデルを大きく上回る性能を達成できます。
  • 知識の注入: 社内ドキュメントや特定の専門知識など、事前学習データに含まれていない情報をモデルに教え込めます。
  • 振る舞いの制御: モデルの出力スタイルやトーンを、望む形に調整することができます。

2. 準備:環境とライブラリ

まず、必要なライブラリをインストールします。GPU環境での実行を強く推奨します。

bash
pip install transformers datasets accelerate bitsandbytes
  • transformers: Hugging Faceのコアライブラリ。
  • datasets: データセットの読み込みと前処理を簡単にするライブラリ。
  • accelerate: PyTorchでの分散学習や混合精度学習を簡素化します。
  • bitsandbytes: 4-bit/8-bit量子化などを通じて、メモリ効率の良い学習を可能にします。

3. 実践:テキスト分類タスクでのファインチューニング

ここでは、感情分析タスクを例にファインチューニングのプロセスを見ていきましょう。

ステップ1:データセットの準備

Hugging Face Hubから、IMDb(映画レビュー)データセットを読み込みます。

python
from datasets import load_dataset

# データセットの読み込み
dataset = load_dataset("imdb")

# データの中身を確認
print(dataset)
# DatasetDict({
#     train: Dataset({
#         features: ['text', 'label'],
#         num_rows: 25000
#     })
#     test: Dataset({
#         features: ['text', 'label'],
#         num_rows: 25000
#     })
#     unsupervised: Dataset({
#         features: ['text', 'label'],
#         num_rows: 50000
#     })
# })

ステップ2:モデルとトークナイザの読み込み

次に、ファインチューニングのベースとなる事前学習済みモデルと、それに対応するトークナイザを読み込みます。ここでは、軽量で扱いやすいdistilbert-base-uncasedを使用します。

python
from transformers import AutoTokenizer, AutoModelForSequenceClassification

model_name = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2) # labelはpositive/negativeの2値

ステップ3:データの前処理

データセットのテキストを、モデルが理解できる形式(トークンID)に変換します。

python
def preprocess_function(examples):
    return tokenizer(examples["text"], truncation=True, padding="max_length", max_length=512)

tokenized_datasets = dataset.map(preprocess_function, batched=True)

ステップ4:学習の実行

Trainer APIを利用すると、学習ループを自分で書くことなく、簡単にファインチューニングを実行できます。

python
from transformers import TrainingArguments, Trainer

# 学習に関する設定
training_args = TrainingArguments(
    output_dir="./results",          # 結果の出力先
    num_train_epochs=1,              # エポック数
    per_device_train_batch_size=16,  # バッチサイズ
    per_device_eval_batch_size=16,   # 評価時のバッチサイズ
    warmup_steps=500,                # 学習率のウォームアップ
    weight_decay=0.01,               # 重み減衰
    logging_dir="./logs",            # ログの出力先
    logging_steps=10,
    evaluation_strategy="epoch",     # エポックごとに評価
)

# Trainerの初期化
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"].shuffle(seed=42).select(range(1000)), # 時間短縮のため一部データを使用
    eval_dataset=tokenized_datasets["test"].shuffle(seed=42).select(range(1000)),
)

# 学習の開始
trainer.train()

ステップ5:モデルの保存と評価

学習が完了したら、モデルを保存します。

python
# モデルの保存
trainer.save_model("./fine-tuned-imdb-model")
tokenizer.save_pretrained("./fine-tuned-imdb-model")

# 評価
eval_results = trainer.evaluate()
print(f"Evaluation results: {eval_results}")

4. QLoRAによる効率的なファインチューニング

LLMのサイズが大きくなるにつれて、ファインチューニングに必要な計算リソースも増大します。QLoRA(Quantized Low-Rank Adaptation)は、モデルの重みを4-bitに量子化し、LoRAと呼ばれる小さなアダプタ層のみを学習することで、コンシューマ向けGPUでも大規模モデルのファインチューニングを可能にする画期的な手法です。

transformersライブラリとbitsandbytesを組み合わせることで、比較的簡単にQLoRAを実装できます。

まとめ

ファインチューニングは、汎用的なLLMを特定のニーズに合わせて最適化するための強力な手段です。Hugging Faceのエコシステムを活用することで、データセットの準備から学習、評価までの一連のプロセスを効率的に進めることができます。

まずは小規模なモデルでプロセスに慣れ、その後、QLoRAのような技術を駆使して、より大規模なモデルのファインチューニングに挑戦してみることをお勧めします。

AI が自動生成した技術記事をまとめたテックブログ