0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LoRA入門:軽量な大規模言語モデルのファインチューニング手法

Posted at

大規模言語モデル(LLM)は高性能ですが、そのままファインチューニングすると膨大な計算リソースやストレージを必要とします。例えば、数十億パラメータを持つモデル全体を更新するのは現実的ではありません。

そこで登場するのが LoRA(Low-Rank Adaptation) です。LoRAは「全パラメータを更新する代わりに、低ランク行列を追加して学習」する手法で、以下のような特徴があります。

  • 低コスト:更新するパラメータがごく一部に限られる
  • 高速:GPUメモリ使用量が大幅に削減される
  • 柔軟:複数のLoRAアダプタを組み合わせて利用可能

本記事では、LoRAを使ったファインチューニングの実装を具体的なコードとともに紹介します。


解決策:LoRAの実装手順

1. 環境構築

まずは必要なライブラリをインストールします。

pip install transformers peft datasets accelerate bitsandbytes
  • transformers: Hugging Faceのモデル管理
  • peft: LoRAを含む効率的ファインチューニングのライブラリ
  • datasets: サンプルデータの取得
  • accelerate: 分散学習の最適化
  • bitsandbytes: 量子化(メモリ削減)に便利

2. モデルとデータの準備

今回はサンプルとして distilbert-base-uncased をLoRAでファインチューニングします。

from datasets import load_dataset
from transformers import AutoTokenizer

# サンプルデータ:SST-2 (感情分類)
dataset = load_dataset("glue", "sst2")
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")

def tokenize_fn(batch):
    return tokenizer(batch["sentence"], truncation=True, padding="max_length", max_length=128)

encoded_dataset = dataset.map(tokenize_fn, batched=True)

3. LoRA構成の設定

PEFTライブラリを用いてLoRAを適用します。

from transformers import AutoModelForSequenceClassification
from peft import LoraConfig, get_peft_model

# 元のモデル
model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased", num_labels=2)

# LoRA設定
lora_config = LoraConfig(
    r=8,                # 低ランク次元
    lora_alpha=16,      # スケーリング係数
    target_modules=["q_lin", "v_lin"],  # LoRAを適用する層
    lora_dropout=0.1,
    bias="none",
    task_type="SEQ_CLS"
)

# LoRAモデルに変換
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

print_trainable_parameters() を実行すると、更新対象のパラメータが全体の数%に削減されていることが確認できます。


4. トレーニング

LoRAモデルを実際にファインチューニングします。

from transformers import TrainingArguments, Trainer

# データセット分割
train_dataset = encoded_dataset["train"].shuffle(seed=42).select(range(2000))
eval_dataset = encoded_dataset["validation"].shuffle(seed=42).select(range(500))

# 訓練設定
training_args = TrainingArguments(
    output_dir="./lora-distilbert",
    per_device_train_batch_size=16,
    per_device_eval_batch_size=16,
    num_train_epochs=3,
    evaluation_strategy="epoch",
    save_strategy="epoch",
    logging_dir="./logs",
    logging_steps=50,
    learning_rate=5e-4
)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    tokenizer=tokenizer
)

trainer.train()

これで、DistilBERTにLoRAを適用した軽量なファインチューニングが可能になります。


5. 学習済みLoRAアダプタの保存と読み込み

LoRAは「アダプタ」として独立保存でき、後から合成・再利用できます。

# 保存
model.save_pretrained("./lora-adapter")

# 再利用
from peft import PeftModel
base_model = AutoModelForSequenceClassification.from_pretrained("distilbert-base-uncased", num_labels=2)
lora_model = PeftModel.from_pretrained(base_model, "./lora-adapter")

6. 推論の実行

ファインチューニング済みのLoRAモデルを使って推論します。

from transformers import pipeline

inference = pipeline("sentiment-analysis", model=lora_model, tokenizer=tokenizer)
print(inference("I really enjoyed this movie!"))
print(inference("This was the worst film I have ever seen."))

まとめ

  • 従来の課題
    モデル全体のファインチューニングはコストが高い。

  • LoRAの利点

    • パラメータ更新がごく一部に限定される
    • GPUメモリ消費を大幅に削減
    • 複数のアダプタを合成可能(マルチタスク対応)
  • 実装手順

    1. Hugging Faceのモデルを準備
    2. LoRA設定を定義
    3. Trainerで学習
    4. アダプタを保存・再利用

LoRAは、LLMのような大規模モデルを扱う際の強力な武器になります。特に「自分のドメインに合わせたカスタマイズ」を低コストで実現できるため、実務導入のハードルを大幅に下げられるでしょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?