Gemma 4はそのままでも十分印象的ですが、ブランドの声で話してほしい、特定の出力フォーマットに従ってほしい、一般モデルがつまずくニッチな分野を打ち破りたい、そんな場合はどうすればいいでしょうか?そこでファインチューニングの出番です。
朗報:もうA100のクラスターは必要ありません。LoRAとUnslothというツールを使えば、1時間以内に1台のGPUでGemma 4をファインチューニングできます。全プロセスを解説します。
そもそもなぜファインチューニングするのか?
労力を投資する前に、本当にファインチューニングが必要か確認しましょう。クイックガイド:
| 状況 | 解決策 |
|---|---|
| モデルがあなたの領域を知らない | ドメインデータでファインチューニング |
| モデルが出力フォーマットを無視する | フォーマット例でファインチューニング |
| モデルに最新情報が必要 | 代わりにRAGを使用 |
| モデルが冗長/簡潔すぎる | まずプロンプトエンジニアリングを試す |
| モデルが時々間違った答えを出す | まずfew-shotプロンプティングを試す |
プロンプトエンジニアリングとRAGが不十分なら、ファインチューニングが次の一手です。始める前に、Gemma 4おすすめプロンプトを試してみてください — より良いプロンプトだけで問題が解決するかもしれません。カスタマイズを始める前にGemma 4で何ができるかを広く知りたい場合は、ユースケースガイドをご覧ください。
LoRAとQLoRAをシンプルに解説
LoRA(Low-Rank Adaptation)は元のモデルの重みを変更しません。代わりに、ベースモデルの上に座る小さなアダプター重みのセットを訓練します。カメラを作り直すのではなく、カスタムレンズを付けるようなものです。
- ベースモデル:凍結、変更なし
- アダプター:小さい(通常ベースモデルサイズの1-5%)
- 結果:コストのわずかでフルファインチューニングに近い品質
QLoRAはさらに一歩進み — ベースモデルを4bit量子化形式でロードし、メモリ使用量を約半分にします。LoRA品質の90%以上を得ながら、はるかに小さなGPUに収まります。
| 方法 | 必要VRAM(Gemma 4 E4B) | 必要VRAM(Gemma 4 26B) | 品質 |
|---|---|---|---|
| フルファインチューン | 32GB以上 | 100GB以上 | 最高 |
| LoRA | 16GB | 48GB | フルの約98% |
| QLoRA | 8GB | 24GB | フルの約95% |
Unslothのセットアップ
UnslothはLoRAでGemma 4をファインチューニングする最速の方法です。モデルにパッチを当て、バニラのHuggingFaceと比較して2倍高速な訓練と60%少ないメモリ使用量を実現します。
# 仮想環境を作成
python -m venv gemma4-finetune
source gemma4-finetune/bin/activate
# Unslothをインストール(すべての依存関係を含む)
pip install unsloth
# 古いGPUでQLoRAを使う場合、追加で:
pip install bitsandbytesセットアップの確認:
import torch
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"VRAM: {torch.cuda.get_device_properties(0).total_mem / 1e9:.1f} GB")訓練データの準備
データはJSONL形式で、各行に会話を含める必要があります。Gemma 4が期待する構造:
{"messages": [{"role": "user", "content": "What's the return policy?"}, {"role": "assistant", "content": "Our return policy allows returns within 30 days of purchase with original receipt."}]}
{"messages": [{"role": "user", "content": "Do you ship internationally?"}, {"role": "assistant", "content": "Yes, we ship to 45 countries. Shipping takes 7-14 business days."}]}
{"messages": [{"role": "system", "content": "You are a medical coding assistant."}, {"role": "user", "content": "Code: Patient presents with acute bronchitis"}, {"role": "assistant", "content": "ICD-10: J20.9 - Acute bronchitis, unspecified"}]}データ品質のヒント:
- 500-1000例がほとんどのタスクの最適ゾーン
- 多ければ良いとは限らない — 500の高品質例は5000の雑な例に勝る
- エッジケースとネガティブ例を含める
- レスポンスをフォーマットとトーンで一貫させる
- 訓練前にJSONLを検証:
import json
def validate_jsonl(filepath):
valid = 0
errors = 0
with open(filepath, 'r') as f:
for i, line in enumerate(f, 1):
try:
data = json.loads(line)
assert "messages" in data, "Missing 'messages' key"
assert len(data["messages"]) >= 2, "Need at least 2 messages"
valid += 1
except (json.JSONDecodeError, AssertionError) as e:
print(f"Line {i}: {e}")
errors += 1
print(f"\nValid: {valid}, Errors: {errors}")
validate_jsonl("training_data.jsonl")訓練設定
Unslothを使った完全な訓練スクリプト:
from unsloth import FastLanguageModel
import torch
# QLoRA(4bit)でモデルをロード
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="google/gemma-4-e4b",
max_seq_length=4096,
dtype=None, # 自動検出
load_in_4bit=True, # QLoRA
)
# LoRAアダプターを追加
model = FastLanguageModel.get_peft_model(
model,
r=16, # ランク — 高いほど容量増、VRAM増
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
],
lora_alpha=16,
lora_dropout=0, # Unsloth最適化 — 0を維持
bias="none",
use_gradient_checkpointing="unsloth",
)
# 訓練データをロード
from datasets import load_dataset
dataset = load_dataset("json", data_files="training_data.jsonl", split="train")
# 訓練引数
from trl import SFTTrainer
from transformers import TrainingArguments
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
max_seq_length=4096,
args=TrainingArguments(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
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,
output_dir="outputs",
optim="adamw_8bit",
seed=42,
),
)
# 訓練
trainer.train()
# LoRAアダプターを保存
model.save_pretrained("gemma4-finetuned-lora")
tokenizer.save_pretrained("gemma4-finetuned-lora")調整する主要パラメータ:
r=16:LoRAランク。16から始めて、品質が足りなければ32や64へnum_train_epochs=3:通常2-5で十分。過学習に注意learning_rate=2e-4:デフォルトがよく動く。訓練が不安定なら1e-4に下げるper_device_train_batch_size=2:VRAMに余裕があれば増やす
GGUFへのエクスポート
アダプターが訓練されたら、おそらくOllamaでローカル実行したいでしょう。つまりGGUF形式への変換です。量子化オプションとそのトレードオフの詳細については、GGUFガイドをご覧ください。
# アダプターをマージしてGGUFにエクスポート(Q4_K_M量子化)
model.save_pretrained_gguf(
"gemma4-finetuned-gguf",
tokenizer,
quantization_method="q4_k_m",
)
# または複数の量子化レベルでエクスポート
for method in ["q4_k_m", "q5_k_m", "q8_0"]:
model.save_pretrained_gguf(
f"gemma4-finetuned-{method}",
tokenizer,
quantization_method=method,
)| 量子化 | ファイルサイズ(E4B) | 品質損失 | 最適 |
|---|---|---|---|
| Q4_K_M | 約2.5 GB | 最小 | ほとんどのユーザー |
| Q5_K_M | 約3.2 GB | 非常に小さい | 品質重視 |
| Q8_0 | 約4.8 GB | 無視できる | VRAMに余裕がある時 |
Ollamaでデプロイ
ファインチューンしたモデルをOllamaに持ち込むためのModelfileを作成:
# Modelfile
FROM ./gemma4-finetuned-gguf/gemma4-finetuned-q4_k_m.gguf
PARAMETER temperature 0.7
PARAMETER top_p 0.9
SYSTEM "You are a helpful assistant fine-tuned for customer support."そしてビルドと実行:
# カスタムモデルを作成
ollama create my-gemma4 -f Modelfile
# テスト
ollama run my-gemma4 "What's your return policy?"
# リストに表示されることを確認
ollama listファインチューンされたモデルは、他のOllamaモデルと同様に動作します。Ollama APIで使用したり、上にアプリを構築したり、チームと共有したりできます。
よくある問題と解決策
訓練中にメモリ不足: per_device_train_batch_sizeを1に下げるか、gradient_checkpointingを有効にするか、より小さなベースモデルに切り替えましょう。
ファインチューニング後にモデルがガベージ出力: データにフォーマット問題があるか、エポック数が多すぎる可能性。エポックを減らしてJSONLを検証してください。
GGUFエクスポートが失敗: 変換中にモデルサイズの3-5倍のディスク容量があることを確認し、Unslothのバージョンが最新か確認してください。
訓練損失が減らない: 学習率が低すぎるかもしれません。5e-4を試してください。また、データがモデルに学ばせたいパターンを実際に持っているか確認してください。
次のステップ
- ファインチューニング用のベストなベースモデルを選ぶためにGemma 4モデルサイズを探る
- ファインチューンしたモデル用の適切なデプロイパイプラインをセットアップ
- ファインチューニングと信頼できる出力フォーマットを組み合わせる構造化JSON出力について学ぶ
- 訓練セットアップを計画するためにハードウェア要件を確認
Stop reading. Start building.
~/gemma4 $ Get hands-on with the models discussed in this guide. No deployment, no friction, 100% free playground.
Launch Playground />


