ローカルでのLLMファインチューニング:LoRAによる手順付きの例 / QLoRA
LoRAとQLoRAを使ったローカルでのLLMのファインチューニングにより、8〜9Bのモデル(Qwen 3.5 9Bなど)を、業務で使う語彙や文章のスタイル、特定の回答形式に合わせて調整できます。しかも、すべて中古のRTX 3090で行えます。A100クラスターはもう必要ありません。このガイドでは、未経験の状態からGGUFモデルをOllamaに読み込むまで、データセットの形式、Unslothノートブックを使った手順、最後のエクスポートを順を追って解説します。
#ローカルLLMをファインチューニングする理由は何か?
基本となるLLMは汎用性がありますが、特定の用途には完全には適合しません。プロンプトエンジニアリングとRAGで80%のケースを解決でき、残りの20%にはファインチューニングが役立ちます。ファインチューニングを検討すべきなのは、モデルが厳密な形式(JSON、タグ、内部構造)で回答する必要がある場合、企業のスタイル(トーン、語彙)に従う必要がある場合、高度な専門分野(医療、法律、業務に関する技術)に精通する必要がある場合、またはどのプロンプトでも十分に安定させられない振る舞いを再現する必要がある場合です。
逆に、事実に関する知識を取り込むため(RAGの方が適しており、最新の状態を維持できます)、単発のハルシネーションを修正するため(より良いプロンプトで十分です)、あるいはベンチマークでGPT-5に対抗するため(勝てません)に、ファインチューニングを使わないでください。
#LoRAとフルファインチューニングの比較:なぜLoRAが優れているのか
お使いのマシンで、プライベートかつ無料のChatGPTを1時間で構築 — LM Studio、Ollama、Open WebUI、ご自身のドキュメント、クラウド不要。
- 永久に利用できるオンラインスペース
- PDF + ファイル
- 30日間返金対応
フルファインチューニングは、モデルのすべてのパラメータを更新します。7B モデルを FP16 で扱う場合、重みに14 GB、勾配と Adam オプティマイザーに約30 GB が必要です。合計で最低40~60 GB の VRAM が必要になります。A100 80GB または H100 がなければ実行できません。
LoRA(Low-Rank Adaptation)は、元の重みを凍結し、アテンション層に挿入されるランクrの小さな適応行列のみを学習します。具体的には、7Bモデルで r=16 の場合、70億ではなく約2,000万のパラメータを学習することになり、モデル全体の0.3%に相当します。勾配とオプティマイザーに必要なVRAMは大幅に減少します。
- 7Bのフルファインチューン
- ~60 GB VRAM、2〜4× A100、数時間、出力ファイルサイズ14 GB。
- LoRA 7B
- VRAM は約16 GBで、RTX 4080で十分です。所要時間は30分〜2時間、アダプターのサイズはわずか30〜200 MBです。
- QLoRA 7B
- VRAM 約6 GB。RTX 3060 12 GB で十分で、品質は従来の LoRA とほぼ同じです。
#QLoRA:VRAMの革命
QLoRAはこの考え方をさらに進めたものです。ベースモデルはFP16ではなく4ビット(NF4、NormalFloat 4-bit)で読み込まれます。学習中も重みは量子化されたままで、勾配を受け取るのはFP16のLoRAアダプターだけです。その結果、7Bモデルは5〜6 GBのVRAM、13Bモデルは10 GB、70Bモデルは48 GBに収まります。
2つの技術により、品質の低下は無視できる程度に抑えられます。NF4 量子化(重みのガウス分布に合わせて調整)と二重量子化(量子化定数自体も量子化)です。実際、ほとんどのベンチマークで、QLoRA と LoRA FP16 の差は1%未満です。
#モデルサイズごとの必要な VRAM
以下の数値は、Unsloth を使用し、バッチサイズ2、シーケンス長2,048トークン、勾配チェックポインティングを有効にした場合の現実的な下限値です。ピーク時と OS の分を見込んで、20% の余裕を加えてください。
- 2~3Bモデル(Qwen 3.5 2B、Granite 4.2 3B)
- QLoRA:4GB VRAM · LoRA FP16:8GB · GTX 1660 6GBまたはRTX 3050はQLoRAで十分です。
- 8-9Bモデル (Granite 4.2 8B, Qwen 3.5 9B)
- QLoRA:6GB VRAM · LoRA FP16:16GB · RTX 3060 12GBは快適、RTX 3090は最適です。
- 12Bモデル (Gemma 4 12B)
- QLoRA:10 GB VRAM · LoRA FP16:28 GB · RTX 3090/4090 24 GB でのQLoRA、A100 40GB でのLoRA
- モデル 27-35B (Qwen 3.8 27B, Qwen 3.6 35B-A3B)
- QLoRA:VRAM 22GB · LoRA FP16:一般消費者向けGPUでは不可能 · RTX 3090/4090またはRTX 5090ではQLoRAに限定。
- 70Bモデル(ハイエンドの密なモデル)
- QLoRA:48 GB VRAM · 2× RTX 3090 または 1× A100 80GB · Unsloth Pro でマルチGPU 必須
このガイドでは、RTX 3090 24 GBで8~9BモデルをQLoRAでファインチューニングすることを目標とします。これは最も幅広く使える組み合わせです。RTX 3060 12 GBでも足りますが、中古の3090(価格は変動します)なら、12Bまでのあらゆるサイズで余裕を持ってQLoRAを利用できます。RTX 4090や5090なら速度は1.5~2倍になりますが、必須ではありません。
#ハードウェアおよびソフトウェアの前提条件
- CUDA 11.8以降を備えた NVIDIA GPU
- 最低でもRTX 3060 12 GBが必要で、RTX 3090を推奨します。AMDのROCm対応GPUも部分的には動作しますが、UnslothはCUDAに最適化されています。まずはこのガイドではNVIDIAのGPUを使ってください。
- Python 3.10または3.11
- 3.12は使用しないでください(執筆時点ではbitsandbytesとの互換性に問題があります)。condaまたはpyenvを使用してください。
- 32GBのシステムRAM
- 16 GBでも足りる場合がありますが、モデルの初回読み込みとデータセットの準備は32 GBの方が余裕を持って行えます。
- 50 GBのディスク容量
- ベースモデル+チェックポイント+融合アダプタ+GGUF Q4_K_M形式のエクスポート。十分な余裕を確保してください。
- 十分な品質のインターネット接続
- 8〜9Bモデルの初期ダウンロードサイズは5〜8 GBです。一度だけです。
ソフトウェアにはUnsloth(github.com/unslothai/unsloth)を使用します。Tritonのカーネルを書き直すことで、標準のHugging Face PEFTと比べて速度を2倍にし、メモリ使用量を60%削減するフレームワークです。専用環境へのインストール:
#データセットを JSONL 形式で準備する
指示ファインチューニングの標準形式はJSONL(1行に1つのJSONオブジェクト)です。よく使われるバリアントは3つあります:
初めてのファインチューニングには、Alpacaを選んでください。会話は1ターンのみで、形式が分かりやすく、Unslothが標準で対応しています。品質を確保するための重要なルールをいくつか挙げます。
- 最小必要量
- 効果を確認するには300例、しっかりしたファインチューニングには1,000〜5,000例、本格的に取り組むには10,000例以上が必要です。300例未満では時間の無駄です。
- 品質 > 量
- 完璧な例100件は、ノイズを含む例5000件に勝ります。読み直してください。ほかの人にも読み直してもらってください。モデルはデータセットを、欠陥も含めて文字どおり学習します。
- 入力の多様性
- すべての入力が「翻訳して」で始まると、モデルはほかのことができなくなります。言い回しに変化をつけてください。
- バランスの取れた長さ
- 出力がすべて2文だけだと、モデルは長い回答を生成できなくなります。さまざまな長さの出力を混ぜてください。
- 10%を検証用に確保してください
- 過学習を測定するために、データをランダムに分けてtrain.jsonlとval.jsonlに保存してください。
#Unslothノートブックの解説
以下は、ご自身のデータセットを使ってQwen 3.5 9BをQLoRAでファインチューニングするための、最小限で完結したスクリプトです。.pyファイルまたはJupyterノートブックで実行する。
Unslothは、人気モデルの大半について、あらかじめ4ビットに量子化したバージョンをHugging Faceで公開しています(プレフィックスはunsloth/)。ダウンロードがより速く、すぐに起動できます。初回実行時には約5 GBをダウンロードします。
ランクr=16は、標準設定として適切です。データが多く(10k超)、かつ対象分野が事前学習の分野から大きく離れている場合は、32または64に上げてください。ランクが高いほど学習可能なパラメータ数が増え、モデルの表現能力が高まりますが、過学習のリスクも増します。
RTX 3090で、1000件のデータセットを使って3エポック学習する場合、20~40分を見込んでください。RTX 4090では12~25分、RTX 5090では約8~15分です。損失(loss)を監視してください。損失は着実に低下した後、安定する必要があります。検証データでの損失が再び上昇する場合は、過学習が起きています。
#GGUFをOllamaへエクスポート
LoRAアダプターは outputs/ にあります。数十 MBほどのファイルで、ベースモデルとは別です。Ollama で使うには、アダプターをモデルにマージしてから、量子化済みのGGUFに変換する二つの手順が必要です。
Unslothがすべてを処理します。アダプターとベースモデルの統合、llama.cppを使った変換、Q4_K_Mでの量子化です。その結果、9Bモデルの場合、約5.3GBのファイルmon-modele-gguf/unsloth.Q4_K_M.ggufが生成されます。より高い精度を求める場合は、Q5_K_MとQ8_0も利用できますが、ファイルサイズも大きくなります。
localhost:11434 で接続を待ち受けている Ollama にモデルを読み込むには、最小限の Modelfile を作成し、モデルを登録してください:
#ヒントとトラブルシューティング
- 起動時のOutOfMemoryError
- per_device_train_batch_sizeを1に下げ、その分に比例してgradient_accumulation_stepsを増やしてください。学習例が短い場合は、max_seq_lengthを1024に下げてください。
- 損失が低下しない
- 学習率が低すぎる(5e-4を試してください)か、プロンプトの形式が崩れています。ds[0]["text"]のような例を2〜3件表示し、意図した形式や内容になっているか目で確認してください。
- 損失が急増する(NaN)
- 学習率が高すぎます。1e-4に戻してください。または、Ampere以降でfp16を使っていた場合は、bf16を有効にしてください。fp16はオーバーフローしやすい傾向があります。
- 無限に繰り返すモデル
- トレーニング時のEOSトークンの欠落、またはModelfile内のstopパラメータの欠如。これらの2つの問題はしばしば同時に発生します。
- 過学習が確認できる
- 訓練損失が下がる一方、検証損失が上がっています。両者が乖離し始めるエポックで学習を停止してください。epochs を減らすか、lora_dropout を 0.05 に引き上げてください。
- GGUF ファイルのエクスポートでクラッシュ
- Unsloth は最初の実行時に llama.cpp を自動的にダウンロードします — Linux では git、cmake および build-essential がインストールされていることを確認してください。Mac では xcode-select --install を実行してください。
- 新しい指示を無視するモデル
- データセットの多様性が不足しているか、LoRAのランクが低いです。r=32、lora_alpha=64に設定し、再実行してください。
#さらに詳しく
最初のファインチューニング済みモデルがOllamaで動くようになりました。さらに掘り下げるなら、次の3つの方向が考えられます。
- 適切な量子化の選択
- デフォルトのQ4_K_Mでエクスポートしました。量子化方式の選び方ガイドでは、Q4_K_M、Q5_K_M、Q8_0、FP16を比較しています。ファインチューニングしたモデルの品質を考えて、Q5やQ8を使う価値があるか判断するのに役立ちます。
- 知識の取り込みには、ファインチューニングよりRAGを
- モデルにドキュメントの内容を把握させたい場合(文体だけでなく)、ローカルRAG入門ガイドでは、事実を取り込むにはファインチューニングよりもRAGがほぼ常に望ましい理由を説明しています。
- 大きなモデルへの移行に必要なハードウェア
- 32Bまたは70BのモデルをQLoRAでファインチューニングするには、それぞれ24GB、48GBのVRAMが必要です。「24GBのVRAMで使えるLLM」ガイドでは、RTX 3090、4090、RX 7900 XTXで何が可能かを整理しています。
ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。