ローカルLLM ファインチューニング入門 — LoRA/QLoRA/Unsloth
自分用メモとして書きました。ローカルLLMをファインチューニングしたい人向け。LoRA/QLoRA/Unslothを中心にカバー。
1. ファインチューニングとは — いつ使うべきか、RAGとの比較
ファインチューニング(FT)とは、事前学習済みのLLMに対して追加の学習データで重みを更新し、特定のタスクやドメインに特化させる手法。プロンプトエンジニアリングやRAGでは対処しきれないケースで威力を発揮する。
FT が向いているケース
- 出力フォーマットの固定:常にJSON、常に特定の口調、常に決まったスキーマで出力させたい場合
- ドメイン知識の内在化:医療・法律・社内用語など、プロンプトに毎回入れるにはコンテキストが多すぎる場合
- 推論コストの削減:RAGのように毎回検索+長いコンテキストを渡す必要がなく、FT済みモデルだけで完結する
- レイテンシの短縮:検索パイプラインを挟まないため、応答が速い
RAG が向いているケース
- 情報が頻繁に更新される(FTは再学習が必要)
- 根拠の明示(ソース引用)が求められる
- 学習データが少なすぎてFTが不安定になる
結論として、「RAGとFTは二者択一ではなく、組み合わせるのが最強」 というのが現在の主流。FTでベースの能力を底上げし、RAGで最新情報を補完するパターンが実務では多い。
2. LoRA vs QLoRA vs フルファインチューニング — 手法の選び方
LLMファインチューニングには大きく3つのアプローチがある。
フルファインチューニング
- モデルの全パラメータを更新する。品質は最も高くなりうるが、必要なVRAMが膨大(7Bモデルでも80GB以上)
- 複数台のA100/H100が必要になるため、個人には現実的でない
- 企業がFoundationモデルを作る場合や、大規模なドメイン適応に使う
LoRA(Low-Rank Adaptation)
- モデル本体の重みは凍結し、小さなアダプタ行列(rank分の追加パラメータ)だけを学習する
- 出力ファイルは数十MB〜数百MB程度。ベースモデルに後からマージ可能
- 7Bモデルなら16GB VRAM程度で学習可能
- フルFTに比べて品質がわずかに落ちるとされるが、実用上は十分なケースが大半
QLoRA(Quantized LoRA)
- ベースモデルを4bit量子化した状態でLoRA学習を行う手法
- VRAMをさらに劇的に削減(7Bモデルが8GB VRAMで学習可能に)
- 量子化による精度劣化は意外と小さく、コスパ最強と評価するユーザーが多い
- 2024年後半〜2025年にかけて安定性が大幅に改善され、現在はデファクトスタンダード
個人ユーザーレベルなら基本QLoRA一択。VRAMに余裕があるならLoRA。フルFTは企業向け。
3. Unsloth — 2倍速・70%メモリ削減のファインチューニングフレームワーク
Unslothは、LLMファインチューニングを高速化・省メモリ化するオープンソースライブラリ。界隈では「FTするならまずUnsloth」が定番の回答になっている。
主な特徴
- 2倍の学習速度:カスタムカーネルとTritonベースの最適化で、HuggingFace Transformers比で約2倍の高速化
- 70%のメモリ削減:勾配チェックポイントの最適化、4bit量子化のネイティブサポートにより、同じモデルを大幅に少ないVRAMで学習可能
- Google Colab対応:T4(16GB)やL4(24GB)の無料/有料枠で7B〜13Bモデルの学習が可能
- Llama、Mistral、Qwen、Gemma、Phi対応:主要なオープンモデルを幅広くカバー
- ノートブックテンプレート:Jupyter Notebookのテンプレートが充実しており、コピペで始められる
基本的な使い方
from unsloth import FastLanguageModel
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Qwen2.5-7B-bnb-4bit",
max_seq_length=2048,
load_in_4bit=True,
)
model = FastLanguageModel.get_peft_model(
model,
r=16,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
lora_alpha=16,
lora_dropout=0,
bias="none",
)
4. データセット準備 — 合成データ活用のすすめ
ファインチューニングの成否はデータセットの質で9割決まる。量ではなく質が重要。
データ形式
LLMのFTでは主に以下の形式が使われる:
-
Instruction形式:
instruction/input/outputの3カラム。Alpaca形式とも呼ばれる -
Chat形式:
messages配列にsystem/user/assistantのターンを並べる。ChatMLやShareGPT形式 - Completion形式:単純なテキスト補完。特定のドメインテキストを大量に学習させる場合に使う
合成データの活用
高品質なデータセットを手作業で用意するのは大変。そこで注目されているのが大規模モデルで学習データを生成する手法。ただし規約は要確認。
- Seed データ → 拡張:手作業で10〜20件の高品質サンプルを作成し、それを元にAPIで数百〜数千件に拡張する
- Self-Instruct / Evol-Instruct:既存の質問を複雑化・多様化させてデータを増やすテクニック
- 品質フィルタリング:生成したデータを別のモデルで評価し、低品質なものを除外する
- データ量の目安:特定タスク特化なら500〜2000件、汎用能力の底上げなら5000件以上
「100件の高品質データ > 10000件のノイズだらけデータ」
5. VRAM要件 — 8GBでも始められる
「ファインチューニングにはA100が必要」というのは過去の話。QLoRA + Unslothの組み合わせで、一般消費者向けGPUでもFTが可能になった。
VRAM別の目安
| VRAM | 学習可能なモデルサイズ | 備考 |
|---|---|---|
| 8GB(RTX 3060等) | 3B〜7B(4bit) | バッチサイズ1、勾配累積必須 |
| 12GB(RTX 3060 12GB) | 7B〜8B(4bit) | 実用的な最低ライン |
| 16GB(RTX 4060 Ti等) | 7B〜13B(4bit) | 快適にFTできる |
| 24GB(RTX 3090/4090) | 13B〜14B(4bit)、7B(16bit LoRA) | コスパ最強GPU |
| 48GB(RTX A6000等) | 34B〜70B(4bit) | 大型モデルのFTが可能 |
メモリ節約テクニック
- 勾配累積(gradient accumulation):実効バッチサイズを上げつつVRAMは増やさない
- 勾配チェックポイント(gradient checkpointing):計算速度を犠牲にメモリを節約。Unslothでは自動で最適化される
- max_seq_length の調整:シーケンス長を短くするだけでVRAM消費が激減する。タスクに必要な最小限に設定すべき
- Flash Attention 2:メモリ効率と速度の両方を改善。対応GPUなら必ず有効にする
「RTX 3060 12GBでQwen2.5-7Bを普通にFTできてる」という報告が複数あった。
6. 学習パラメータ — lr/epochs/rank の設定指針
FTで最も迷うのがハイパーパラメータの設定。Reddit等で共有されていたベストプラクティスをまとめる。
学習率(Learning Rate)
-
QLoRA の場合:
2e-4〜5e-5が一般的な範囲 - 高すぎると既存の能力が崩壊する(catastrophic forgetting)
- cosine スケジューラーを使うのがデフォルト。warmup ratio は 0.03〜0.1 程度
エポック数(Epochs)
- 1〜3エポックが推奨。多すぎると過学習する
- データ量が少ない場合(500件以下)は1〜2エポックで十分
- 「lossが下がり続けているから」と回し続けるのは過学習の典型パターン
LoRA Rank(r)
- r=16〜64 が一般的。タスクが複雑なほど高いrankが必要
- r=8 でも単純なタスク(フォーマット変換等)には十分
- r=128以上はフルFTに近づくが、メリットは薄いことが多い
- lora_alpha は通常 rank と同じ値に設定する(alpha=16ならr=16)
その他の重要パラメータ
- batch_size:大きいほど学習が安定するが、VRAMと相談。勾配累積で実効バッチサイズ16〜32を目指す
- weight_decay:0.01〜0.1。過学習防止に効く
- target_modules:基本的に全Linear層(q/k/v/o_proj, gate/up/down_proj)を対象にする。一部だけにすると品質が落ちる報告あり
7. 評価方法 — FTモデルの性能をどう測るか
FTの難しいところは 「良くなったのか悪くなったのか」の判断が曖昧になりがちなこと。
定量評価
- Training Loss:下がっていれば学習は進んでいるが、過学習との区別がつかない
- Validation Loss:学習データと別のデータで評価。training lossが下がり続けてもval lossが上がり始めたら過学習
- Perplexity:言語モデルの一般的な指標。ただしタスク特化の場合はあまり参考にならない
- ベンチマーク(MMLU、HellaSwag等):汎用能力の確認用。FTで特化させると汎用ベンチは下がることがある(これは必ずしも悪いことではない)
定性評価
- テストプロンプト集:FT前後で同じプロンプトを投げて出力を比較する。最低20〜30パターンは用意する
- A/Bテスト:FT前後のモデルの出力を並べて人間が判定。最も信頼性が高いが手間がかかる
- LLM-as-Judge:GPT-4oやClaude等の大規模モデルに「どちらの出力が良いか」を評価させる手法。最近はこれがメインストリーム
「val lossのグラフを見ずにFTしてる人が多すぎる」という意見もあり、最低限validation splitは設定すべきという人が多い。
8. GGUFへの変換 — ローカル推論用フォーマット
FTが完了したモデルをllama.cppやOllamaで使うには、GGUF形式に変換する必要がある。
変換手順
-
LoRAアダプタのマージ:FTで生成されたアダプタをベースモデルにマージして、単一のモデルにする
# Unslothの場合 model.save_pretrained_merged( "merged_model", tokenizer, save_method="merged_16bit", # or "merged_4bit" ) -
GGUF変換:llama.cppの
convert_hf_to_gguf.pyを使用python convert_hf_to_gguf.py ./merged_model --outtype f16 --outfile model-f16.gguf -
量子化:推論時のVRAM/RAM削減のために量子化
./llama-quantize model-f16.gguf model-Q4_K_M.gguf Q4_K_M
量子化レベルの選び方
- Q8_0:品質最優先。FTの効果を正確に確認したい場合に
- Q6_K:品質と速度のバランス良好
- Q4_K_M:最も人気のある量子化レベル。品質と効率のバランスが良い
- Q4_K_S / Q3_K_M:VRAM/RAMが厳しい場合に。品質の劣化が目立ち始める
Unslothには save_pretrained_gguf メソッドがあり、マージとGGUF変換を一発で行えるのが便利。
model.save_pretrained_gguf(
"model_gguf", tokenizer,
quantization_method="q4_k_m",
)
9. よくある失敗 — 過学習・データ品質・catastrophic forgetting
FTでハマりやすいポイントを、スレッドで報告されていた失敗例から抽出。
過学習(Overfitting)
- 症状:学習データに含まれるフレーズをそのままオウム返しする。汎化能力がゼロ
- 原因:エポック数が多すぎる、データが少なすぎる、rankが高すぎる
- 対策:val lossモニタリング、早期停止(early stopping)、データ量を増やす、rankを下げる
データ品質の問題
- 症状:FTしたのに全然良くならない、むしろ悪化した
- 原因:学習データにノイズが多い、フォーマットが不統一、ラベルが間違っている
- 対策:全データを目視確認(面倒でもやる)、品質フィルタリング、少量から始めて段階的に増やす
Catastrophic Forgetting(破滅的忘却)
- 症状:特定タスクはできるようになったが、日本語力が壊滅した、常識がなくなった
- 原因:学習率が高すぎる、データが偏りすぎている
- 対策:学習率を下げる、汎用データを混ぜる(全体の10〜20%程度)、LoRA rankを下げる
その他の落とし穴
- Chat Template の不一致:ベースモデルのchat templateと学習データのフォーマットが合っていないと、推論時に意味不明な出力になる
- BOS/EOSトークンの設定ミス:Unslothでは自動処理されるが、手動で設定する場合は要注意
- 学習時と推論時のtokenizer不一致:特にマージ後にtokenizerを忘れてコピーするケースが多い
「FTで一番大事なのはデータ。二番目に大事なのもデータ。パラメータチューニングは三番目」という格言がある模様。
10. 小モデルFTの可能性 — 4Bでも専用タスクに強い
最近特に盛り上がっているのが 「小さいモデルをFTして特定タスクに特化させる」 アプローチ。
なぜ小モデルFTが注目されているか
- 推論コストが圧倒的に低い:4Bモデルは70Bモデルの1/10以下のVRAMで動作し、レスポンスも10倍以上速い
- FTコストも低い:8GB VRAMのGPUで学習可能。Google Colabの無料枠でも回せる
- 専用タスクなら大型モデルに匹敵:分類、エンティティ抽出、フォーマット変換などの特定タスクでは、FT済み4Bモデルが汎用70Bモデルを上回る報告が多数
実例として挙がっていたもの
- Qwen2.5-3B をFTして社内チャットボットの意図分類に使用 → GPT-4o比で精度95%以上、コスト1/100
- Phi-4-mini(3.8B) をFTしてJSON構造化出力に特化 → 100%正しいJSON出力を達成
- Gemma-3-4B をFTして日本語要約タスクに使用 → 14Bモデルと同等の要約品質
小モデルFTのコツ
- タスクを絞る:1モデル1タスクが原則。複数タスクを1つのモデルに詰め込むと小モデルは能力が分散して弱くなる
- データ品質を極限まで高める:小モデルはデータのノイズに大モデルより敏感
- 推論時のプロンプトも学習時に合わせる:学習データと推論時のプロンプト形式を完全に一致させる
- 複数モデルのルーティング:タスクごとにFT済み小モデルを用意し、入力に応じてルーティングする構成が実用的
「70Bモデルを1台のサーバーで動かすより、タスク特化の4Bモデルを10個並べた方が実用性が高い」という意見も多い。










