上級 25 分Fine-tuning

ローカルでのLLMファインチューニング:LoRAによる手順付きの例 / QLoRA

LoRAとQLoRAを使ったローカルでのLLMのファインチューニングにより、8〜9Bのモデル(Qwen 3.5 9Bなど)を、業務で使う語彙や文章のスタイル、特定の回答形式に合わせて調整できます。しかも、すべて中古のRTX 3090で行えます。A100クラスターはもう必要ありません。このガイドでは、未経験の状態からGGUFモデルをOllamaに読み込むまで、データセットの形式、Unslothノートブックを使った手順、最後のエクスポートを順を追って解説します。

著者 Mohamed Meguedmi·更新 2026-08-27·Windows・macOS・Linuxでテスト済み

#ローカルLLMをファインチューニングする理由は何か?

基本となるLLMは汎用性がありますが、特定の用途には完全には適合しません。プロンプトエンジニアリングとRAGで80%のケースを解決でき、残りの20%にはファインチューニングが役立ちます。ファインチューニングを検討すべきなのは、モデルが厳密な形式(JSON、タグ、内部構造)で回答する必要がある場合、企業のスタイル(トーン、語彙)に従う必要がある場合、高度な専門分野(医療、法律、業務に関する技術)に精通する必要がある場合、またはどのプロンプトでも十分に安定させられない振る舞いを再現する必要がある場合です。

逆に、事実に関する知識を取り込むため(RAGの方が適しており、最新の状態を維持できます)、単発のハルシネーションを修正するため(より良いプロンプトで十分です)、あるいはベンチマークでGPT-5に対抗するため(勝てません)に、ファインチューニングを使わないでください。

i
経験則
プロンプト内の5例未満で求めることを表現できるなら、システムプロンプトを作成してください。50例以上あってもモデルが意図から外れるなら、ファインチューニングしてください。

#LoRAとフルファインチューニングの比較:なぜLoRAが優れているのか

ローカルAIキット

お使いのマシンで、プライベートかつ無料の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 とほぼ同じです。
→
実用上はほぼ同等
比較的小規模なデータセット(10,000例未満)では、LoRAはフルファインチューニングの95〜99%の品質に達します。差が目立つのは、事前学習の内容から大きく離れたタスクだけです。初めてファインチューニングするなら、迷わず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%未満です。

i
標準の選択肢としておすすめ
初めてローカルでファインチューニングするなら、QLoRA がほぼ常に適切な選択です。品質の低下を感じることなく、VRAM 使用量を60~70%削減できます。RTX 4090 以上の GPU を使い、重要度の高い本番用途を目指す場合に限って、従来の LoRA に切り替えてください。

#モデルサイズごとの必要な 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%削減するフレームワークです。専用環境へのインストール:

Unslothのインストール
conda create -n unsloth python=3.11 -y
conda activate unsloth
pip install --upgrade pip
pip install "unsloth[cu121-torch240] @ git+https://github.com/unslothai/unsloth.git"
pip install --no-deps trl peft accelerate bitsandbytes
!
CUDAバージョン
cu121-torch240をお使いの環境に合わせて変更してください。CUDA 11.8ならcu118、CUDA 12.4ならcu124を使用します。nvidia-smiの出力の右上で確認してください。バージョンが合っていないと、最初のインポート時に分かりにくいエラーが発生します。

#データセットを JSONL 形式で準備する

指示ファインチューニングの標準形式はJSONL(1行に1つのJSONオブジェクト)です。よく使われるバリアントは3つあります:

Alpaca フォーマット(最もシンプル)
{"instruction": "Traduis en français formel.", "input": "Hey, what's up?", "output": "Bonjour, comment allez-vous ?"}
{"instruction": "Résume en une phrase.", "input": "Le chat noir a sauté...", "output": "Un chat noir saute sur la table."}
ShareGPT形式(複数ターン)
{"conversations": [
  {"from": "system", "value": "Tu es un assistant juridique."},
  {"from": "human", "value": "Qu'est-ce qu'une clause léonine ?"},
  {"from": "gpt", "value": "Une clause léonine est une disposition contractuelle..."}
]}

初めてのファインチューニングには、Alpacaを選んでください。会話は1ターンのみで、形式が分かりやすく、Unslothが標準で対応しています。品質を確保するための重要なルールをいくつか挙げます。

最小必要量
効果を確認するには300例、しっかりしたファインチューニングには1,000〜5,000例、本格的に取り組むには10,000例以上が必要です。300例未満では時間の無駄です。
品質 > 量
完璧な例100件は、ノイズを含む例5000件に勝ります。読み直してください。ほかの人にも読み直してもらってください。モデルはデータセットを、欠陥も含めて文字どおり学習します。
入力の多様性
すべての入力が「翻訳して」で始まると、モデルはほかのことができなくなります。言い回しに変化をつけてください。
バランスの取れた長さ
出力がすべて2文だけだと、モデルは長い回答を生成できなくなります。さまざまな長さの出力を混ぜてください。
10%を検証用に確保してください
過学習を測定するために、データをランダムに分けてtrain.jsonlとval.jsonlに保存してください。
→
合成データセットを生成する
1000例のデータが手元にない場合は、大きなモデル(Claude、GPT-5、またはQwen 3.8 27Bをローカルで使用)を活用して、内部ドキュメントからインストラクション/出力の合成ペアを生成してください。これは標準的な手法で、「self-instruct」と呼ばれます。1000例の生成には1〜2時間かかると予想されます。

#Unslothノートブックの解説

以下は、ご自身のデータセットを使ってQwen 3.5 9BをQLoRAでファインチューニングするための、最小限で完結したスクリプトです。.pyファイルまたはJupyterノートブックで実行する。

finetune.py — ステップ1:ロード
from unsloth import FastLanguageModel
import torch

MODEL = "unsloth/Qwen3.5-9B-Instruct-bnb-4bit"
MAX_SEQ = 2048

model, tokenizer = FastLanguageModel.from_pretrained(
    model_name = MODEL,
    max_seq_length = MAX_SEQ,
    dtype = None,           # auto : bf16 sur Ampere+, fp16 sinon
    load_in_4bit = True,    # QLoRA : modèle quantifié 4-bit
)

Unslothは、人気モデルの大半について、あらかじめ4ビットに量子化したバージョンをHugging Faceで公開しています(プレフィックスはunsloth/)。ダウンロードがより速く、すぐに起動できます。初回実行時には約5 GBをダウンロードします。

finetune.py — ステップ2:LoRA設定
model = FastLanguageModel.get_peft_model(
    model,
    r = 16,                  # rang de la décomposition LoRA
    target_modules = [
        "q_proj", "k_proj", "v_proj", "o_proj",
        "gate_proj", "up_proj", "down_proj",
    ],
    lora_alpha = 16,
    lora_dropout = 0,
    bias = "none",
    use_gradient_checkpointing = "unsloth",  # économie VRAM
    random_state = 42,
)

ランクr=16は、標準設定として適切です。データが多く(10k超)、かつ対象分野が事前学習の分野から大きく離れている場合は、32または64に上げてください。ランクが高いほど学習可能なパラメータ数が増え、モデルの表現能力が高まりますが、過学習のリスクも増します。

finetune.py — ステップ3:データセット
from datasets import load_dataset

ALPACA_PROMPT = """### Instruction:
{}

### Input:
{}

### Réponse:
{}"""

EOS = tokenizer.eos_token

def format_prompt(ex):
    texts = [
        ALPACA_PROMPT.format(i, inp or "", out) + EOS
        for i, inp, out in zip(ex["instruction"], ex["input"], ex["output"])
    ]
    return {"text": texts}

ds = load_dataset("json", data_files="train.jsonl", split="train")
ds = ds.map(format_prompt, batched=True)
!
EOSトークンを忘れないでください
各学習例の末尾にEOSがないと、モデルは生成を止めないように学習してしまいます。典型的な症状として、ファインチューニングしたモデルが延々と生成し続けたり、同じ内容を繰り返したり、架空の新しい質問まで続けて生成したりします。tokenizer.eos_tokenが確実に追加されていることを、必ず確認してください。
finetune.py — ステップ4:トレーニング
from trl import SFTTrainer
from transformers import TrainingArguments

trainer = SFTTrainer(
    model = model,
    tokenizer = tokenizer,
    train_dataset = ds,
    dataset_text_field = "text",
    max_seq_length = MAX_SEQ,
    args = TrainingArguments(
        per_device_train_batch_size = 2,
        gradient_accumulation_steps = 4,    # batch effectif = 8
        warmup_steps = 10,
        num_train_epochs = 3,
        learning_rate = 2e-4,
        fp16 = not torch.cuda.is_bf16_supported(),
        bf16 = torch.cuda.is_bf16_supported(),
        logging_steps = 10,
        optim = "adamw_8bit",
        weight_decay = 0.01,
        lr_scheduler_type = "linear",
        seed = 42,
        output_dir = "outputs",
    ),
)

trainer.train()

RTX 3090で、1000件のデータセットを使って3エポック学習する場合、20~40分を見込んでください。RTX 4090では12~25分、RTX 5090では約8~15分です。損失(loss)を監視してください。損失は着実に低下した後、安定する必要があります。検証データでの損失が再び上昇する場合は、過学習が起きています。

→
いつ終了するか
1k〜5kの例を含むデータセットに対して、3エポックは適切なデフォルトです。5エポックを超えると、過学習のリスクが高まり、モデルは暗記するようになります。20k以上の例がある場合は、1〜2エポックに設定してください。

#GGUFをOllamaへエクスポート

LoRAアダプターは outputs/ にあります。数十 MBほどのファイルで、ベースモデルとは別です。Ollama で使うには、アダプターをモデルにマージしてから、量子化済みのGGUFに変換する二つの手順が必要です。

finetune.py — ステップ 5:GGUF Q4_K_M のエクスポート
model.save_pretrained_gguf(
    "mon-modele-gguf",
    tokenizer,
    quantization_method = "q4_k_m",  # le défaut recommandé
)

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 を作成し、モデルを登録してください:

Modelfile
cat > Modelfile <<EOF
FROM ./mon-modele-gguf/unsloth.Q4_K_M.gguf

TEMPLATE """### Instruction:
{{ .Prompt }}

### Réponse:
"""

PARAMETER temperature 0.7
PARAMETER stop "### Instruction:"
EOF

ollama create mon-modele -f Modelfile
ollama run mon-modele
i
テンプレートが一致する必要があります
Ollamaのテンプレートは、学習時に使用した形式(ここでは ### Instruction: と ### Réponse: を使うAlpaca形式)を正確に再現する必要があります。そうしないと、モデルは学習時に見たことのないプロンプトを受け取り、ハルシネーションを起こします。ShareGPTやChatMLを使用した場合は、それに合わせて調整してください。

#ヒントとトラブルシューティング

起動時の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に設定し、再実行してください。
→
アダプタを別途保持する
すばやく試行を繰り返せるよう、model.save_pretrained("adapter")を使って、マージしていないアダプター(約100MB)も保存しておいてください。後で別のベースモデルに再利用したり、ほかのアダプターと組み合わせたりする際に、すべてを再ダウンロードせずに済みます。

#さらに詳しく

最初のファインチューニング済みモデルが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で何が可能かを整理しています。
このガイドは役に立ちましたか?

ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。