midori290〜293 に格納されたノートブックを最終成果物として整理しました。本ページでは、 データ加工から学習・推論までを網羅した最新版ノートブックをすぐに利用できるようリンクとダウンロードを用意し、 併せて読みやすいドキュメント構成へリファインしています。
各フォルダには同じ最新版のノートブックを配置しています。ここから取得して Google Colab にアップロードすれば、 そのまま学習・推論の手順を再現できます。
データ前処理、LoRA/QLoRA 設定、トレーニング、保存・量子化までを一貫して実行できる最終版です。
ファインチューニング済みモデルをロードし、日本語チャット推論を行うための UI 付きノートブックです。
!pip install -U "transformers>=4.41" "peft>=0.11" "accelerate>=0.30" "datasets>=3.0" "bitsandbytes>=0.43" sentencepiece pandas
!pip install -U huggingface_hub
bitsandbytes が必須になります。from huggingface_hub import login; login() を実行してトークンを入力してください。huggingface-cli login)でも構いませんが、トークンをノートブックにハードコードしないのが推奨です。
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
model_name = "google/gemma-3-1b-it"
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map="auto",
torch_dtype=torch.float16,
)
device_map="auto" と torch_dtype=torch.float16 を指定し、Colab 上の GPU メモリに収まる形でモデルをロードします。より厳しいメモリ制約では 4bit 量子化(QLoRA)を検討します。| ステップ | 内容 |
|---|---|
| 1 | LoRAの設定とモデルへの適用 |
| 2 | データセットのトークナイズ(前処理) |
| 3 | トレーニングパラメータの設定 |
| 4 | Trainerオブジェクトの作成 |
| 5 | 学習の実行 |
from peft import LoraConfig, get_peft_model, TaskType
lora_config = LoraConfig(
r=16,
lora_alpha=32,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
task_type=TaskType.CAUSAL_LM
)
model = get_peft_model(model, lora_config)
def tokenize_function(example):
tokens = tokenizer(
example["text"],
truncation=True,
max_length=512,
padding="max_length",
return_tensors="pt",
)
tokens = {k: v.squeeze(0) for k, v in tokens.items()}
tokens["labels"] = tokens["input_ids"].clone()
return tokens
tokenized_train = train_dataset.map(tokenize_function, batched=False)
tokenized_test = test_dataset.map(tokenize_function, batched=False)
from transformers import TrainingArguments
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=2,
num_train_epochs=1,
evaluation_strategy="steps",
save_steps=500,
eval_steps=500,
logging_steps=50,
learning_rate=2e-4,
fp16=True,
report_to="none"
)
| パラメータ | 意味 |
|---|---|
| output_dir | 結果の保存先ディレクトリ |
| per_device_train_batch_size | 1デバイスあたりの学習バッチサイズ(Colab無料枠を想定し小さめに設定) |
| gradient_accumulation_steps | 小さなバッチサイズでも実効バッチを大きくするための蓄積回数 |
| num_train_epochs | 学習エポック数 |
| evaluation_strategy | 検証タイミング(steps=一定ステップごと) |
| save_steps, eval_steps, logging_steps | 500/500/50ステップごとに保存・検証・ログ出力 |
| learning_rate | 学習率 例: 5e-5(=0.00005)、1e-4(=0.0001) 学習率(learning_rate)は、モデルの重みをどれだけ一度に更新するかを決める重要な値です。
learning_rate=5e-5(=0.00005)例: learning_rate=1e-4(=0.0001)
|
| fp16 | 16bit精度で学習(GPUメモリ節約) |
| load_best_model_at_end | 最良モデルを最後に自動ロード |
| metric_for_best_model | 評価指標(eval_loss=損失) |
callbacks=[EarlyStoppingCallback(early_stopping_patience=2)])。
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=4, # VRAMが少ない場合
per_device_eval_batch_size=4,
num_train_epochs=3, # 精度重視でエポック数増
evaluation_strategy="steps",
save_steps=500,
eval_steps=500,
logging_steps=100,
learning_rate=1e-4, # 学習率を上げてみる
fp16=True,
report_to="none",
load_best_model_at_end=True,
metric_for_best_model="eval_loss"
)
# --- 超短時間で動作確認したい場合の例 ---
training_args = TrainingArguments(
output_dir="./results",
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
num_train_epochs=0.2, # 0.2など小数もOK。全データの20%だけ学習してすぐ終了
evaluation_strategy="steps",
save_steps=50,
eval_steps=50,
logging_steps=10,
learning_rate=5e-5,
fp16=True,
report_to="none",
load_best_model_at_end=True,
metric_for_best_model="eval_loss"
)
→ 目的や環境に応じて柔軟に調整しましょう。from transformers import Trainer, EarlyStoppingCallback
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_train,
eval_dataset=tokenized_test,
callbacks=[EarlyStoppingCallback(early_stopping_patience=2)]
)
trainer.train()
output_dir(例:./results/)配下には、チェックポイントごとのサブディレクトリ(例:checkpoint-1000/)が作成されます。./results/
checkpoint-1000/
config.json
pytorch_model.bin
adapter_config.json
trainer_state.json
training_args.bin
tokenizer.json
...
checkpoint-2000/
...
./results/直下に保存したい場合:trainer.save_model("./results/")やtokenizer.save_pretrained("./results/")を明示的に実行してください。
checkpoint-xxxx/ディレクトリ内のpytorch_model.binやadapter_config.json、tokenizer.jsonなどを使います。
trainer.save_model("lora_only_dir")
tokenizer.save_pretrained("lora_only_dir")
推論例:from transformers import AutoModelForCausalLM
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("google/gemma-3-1b-it")
model = PeftModel.from_pretrained(base_model, "lora_only_dir")
メリット:ファイルサイズが小さい/配布しやすいfrom peft import PeftModel
# LoRA適用済みモデルをロード
model = PeftModel.from_pretrained(base_model, lora_dir)
# LoRA重みをベースモデルにマージ
model = model.merge_and_unload()
# 1つのモデルとして保存
model.save_pretrained("merged_model_dir")
tokenizer.save_pretrained("merged_model_dir")
推論例:from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("merged_model_dir")
メリット:そのまま推論・配布ができる/LoRAの仕組みを意識しなくてよい| 保存方法 | ベースモデルも一緒に保存? | 推論時の手間 | ファイルサイズ | 用途・特徴 |
|---|---|---|---|---|
| LoRAのみ | ×(保存しない) | ベースモデル+LoRAを組み合わせて使う | 小さい | 研究・複数LoRA切替・配布 |
| マージ保存 | ○(一緒に保存) | そのまま使える | 大きい | 配布・再利用・Hub公開 |
import os
from datetime import datetime
# 保存先のベースディレクトリ名(あとで変更しやすいように定数化)
BASE_DIR = "/content/drive/MyDrive/colab/lora_finetuned_model"
# 今日の日時(例: 2024-06-09_15-30-45)
today = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
# 1. LoRAのみ(マージしない)保存
save_dir_non_merged = f"{BASE_DIR}_non_merged_{today}"
os.makedirs(save_dir_non_merged, exist_ok=True)
trainer.save_model(save_dir_non_merged)
tokenizer.save_pretrained(save_dir_non_merged)
# 2. LoRAをベースモデルにマージして保存
save_dir_merged = f"{BASE_DIR}_merged_{today}"
os.makedirs(save_dir_merged, exist_ok=True)
from peft import PeftModel
# すでにLoRA適用済みのmodelがある前提
tmp_model = model.merge_and_unload()
tmp_model.save_pretrained(save_dir_merged)
tokenizer.save_pretrained(save_dir_merged)
このように、同じ日時(today)で両方の保存ディレクトリを作成できます。
adapter_model.binやadapter_config.jsonなどが含まれるディレクトリ。from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
import torch
base_model_name = "google/gemma-3-1b-it" # 保存時と同じベースモデル名
lora_dir = "保存したLoRAディレクトリ"
# ベースモデルとトークナイザーをロード
base_model = AutoModelForCausalLM.from_pretrained(
base_model_name,
device_map="auto",
torch_dtype=torch.float16,
)
tokenizer = AutoTokenizer.from_pretrained(base_model_name)
tokenizer.pad_token = tokenizer.eos_token
# LoRA重みを適用
model = PeftModel.from_pretrained(base_model, lora_dir)
model.eval()
# 推論(例)
inputs = tokenizer("質問文", return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
ポイント:必ず同じベースモデルを用意し、LoRA重みを適用してから推論します。
pytorch_model.binやconfig.jsonなど)。from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
model_dir = "保存したマージ済みモデルのディレクトリ"
model = AutoModelForCausalLM.from_pretrained(model_dir, device_map="auto", torch_dtype=torch.float16)
tokenizer = AutoTokenizer.from_pretrained(model_dir)
tokenizer.pad_token = tokenizer.eos_token
# 推論(例)
inputs = tokenizer("質問文", return_tensors="pt").to(model.device)
with torch.no_grad():
outputs = model.generate(**inputs, max_new_tokens=100)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
ポイント:マージ済みモデルは、そのまま通常のTransformersモデルとして推論できます。