LoRAとは

LoRA(Low-Rank Adaptation)は、パラメータ効率的なファインチューニング(PEFT)技術です。事前学習済みモデルの元の重みを変更せず、モデルに学習可能な低ランク行列を挿入し、これらの新しいパラメータのみを訓練します。これにより、大規模モデルのファインチューニングが可能になります。単一のGPUで7Bや13Bモデルのファインチューニングが完了できます。

LoRAの動作原理

LoRAの核心的な考え方は、モデルの重み更新が低ランク分解で表現できるということです。重み行列Wに対して、その更新ΔWは2つの小さな行列の積に分解されます:ΔW = BA。ここで、BとAのランクは元の行列よりもはるかに小さいです。訓練中はAとBのみが更新され、推論時には元の重みにマージされるため、推論遅延は増加しません。

環境設定

pip install transformers peft accelerate datasets bitsandbytes

# インストール確認
python -c "import torch; print(torch.cuda.is_available())"

LoRAファインチューニング実践

from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, get_peft_model, TaskType
from datasets import load_dataset
from trl import SFTTrainer

# モデルの読み込み
model_name = "deepseek-ai/deepseek-llm-7b-chat"
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    torch_dtype=torch.float16,
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token

# LoRA設定
lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=8,                    # ランク
    lora_alpha=32,          # スケーリング係数
    lora_dropout=0.1,       # ドロップアウト率
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"]
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

# 訓練パラメータ
training_args = TrainingArguments(
    output_dir="./lora-finetuned",
    per_device_train_batch_size=4,
    gradient_accumulation_steps=4,
    num_train_epochs=3,
    learning_rate=2e-4,
    fp16=True,
    logging_steps=10,
    save_strategy="epoch"
)

# データセットの読み込み
dataset = load_dataset("json", data_files="train_data.json")

# 訓練
trainer = SFTTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset["train"],
    tokenizer=tokenizer,
    max_seq_length=512
)
trainer.train()

# モデルの保存
model.save_pretrained("./lora-adapter")
tokenizer.save_pretrained("./lora-adapter")

LoRAパラメータ調整

  • r(ランク):通常4〜64に設定します。rが大きいほどモデル容量は増えますが、計算量も増えます。一般的にr=8または16が良い出発点です。
  • lora_alpha:通常rの2倍に設定します。LoRA更新の大きさを制御します。
  • target_modules:LoRAを適用するモジュールを選択します。LLaMAアーキテクチャでは、通常q_proj、v_proj、k_proj、o_projを選択します。
  • lora_dropout:0.05〜0.1で、過学習を防ぎます。

推論とデプロイ

from peft import PeftModel

# ベースモデルとLoRAアダプタの読み込み
base_model = AutoModelForCausalLM.from_pretrained(model_name)
model = PeftModel.from_pretrained(base_model, "./lora-adapter")

# 重みのマージ(オプション、推論遅延を削減)
model = model.merge_and_unload()

# 推論
inputs = tokenizer("请用中文介绍人工智能", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(outputs[0]))

まとめ

LoRAにより、大規模モデルのファインチューニングが身近になりました。コンシューマー向けGPUが1枚あれば、7B〜13Bモデルのファインチューニングが可能です。小さいr値から実験を始め、徐々にパラメータを調整して最適な構成を見つけることをお勧めします。