AI モデルに新しいスキルを教えるための完全ガイド:教師ありファインチューニング(SFT)、LoRA/QLoRA、RLHF、DPO、GRPO、モデル蒸留、モデルマージ、評価。コンセプトから本番まで — 各ステップに動作するコード付き。
事前学習はモデルに世界に関する広範な知識を与えるが、与えるスキルは一つだけ:次の token を予測することだ。モデルは Wikipedia、コード、書籍、ウェブを見てきた — しかし、役に立つこと、指示に従うこと、危険な要求を拒否することは知らない。ファインチューニングは、事前学習の後にこれらの振る舞いを教えるプロセスである。
業界は、すべての主要なフロンティアモデル(GPT-4o、Claude Opus 4.6、Llama 4、Gemini 2.5)が従う標準的な学習の梯子へと収束した。各段階は前の段階の上に築かれる — SFT を飛ばして RLHF に直接進むことはできない。
graph LR A[Raw Text Corpus] -->|Pretraining cross-entropy| B[Base Model] B -->|Supervised Fine-Tuning| C[Instruction-Following Model] C -->|RLHF / DPO / GRPO| D[Aligned Model] D -->|Evaluation & Red-teaming| E[Production Model]
巨大なコーパスでの自己教師あり次 token 予測。世界知識を符号化する。
指示-応答ペアでの教師ありファインチューニング。モデルに役立つことを教える。
人間の嗜好データでの RLHF、DPO、または GRPO。出力を安全で好ましいものにする。
自動ベンチマーク + レッドチーミング。出荷前に回帰を捕捉する。
SFT は、会話コンテキストが与えられたときにアシスタントの token を予測するようモデルを学習させる。重要な詳細は loss masking である:交差エントロピー損失はアシスタントの token のみで計算され、システムプロンプトやユーザーのターンでは計算されない。これにより、モデルが会話のユーザー側を「学習」するのを防ぐ。
三つの形式が SFT の全体像を支配している。ChatML は曖昧さのない特殊 token のおかげで最も広く採用されている。
<|im_start|>system You are a helpful AI assistant specialized in European AI regulation. <|im_end|> <|im_start|>user What are the key obligations under the EU AI Act for high-risk systems? <|im_end|> <|im_start|>assistant High-risk AI systems under the EU AI Act (in force August 2024) must comply with... <|im_end|>
| パラメータ | 典型値 | 備考 |
|---|---|---|
| Learning rate | 2e-5 | 事前学習より低め;コサイン減衰 |
| Epochs | 2–3 | エポック数が多いほど → 小規模データセットでの過学習 |
| Batch size (effective) | 64–128 | GPU メモリが小さい場合は勾配累積を使用 |
| Warmup ratio | 0.1 | LR ウォームアップにステップの10% |
| Max sequence length | 2048–8192 | 推論コンテキストウィンドウに合わせる |
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import SFTConfig, SFTTrainer
from datasets import load_dataset
import torch
model_name = "meta-llama/Llama-4-Scout-17B-16E-Instruct" # 2026: Llama 4 Scout replaces Llama 3.1 8B
model = AutoModelForCausalLM.from_pretrained(
model_name, torch_dtype=torch.bfloat16, device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained(model_name)
dataset = load_dataset("HuggingFaceH4/ultrachat_200k", split="train_sft")
sft_config = SFTConfig(
output_dir="./sft-llama-4-scout",
num_train_epochs=3,
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=2e-5,
lr_scheduler_type="cosine",
warmup_ratio=0.1,
logging_steps=10,
save_strategy="epoch",
bf16=True,
)
trainer = SFTTrainer(
model=model,
args=sft_config,
train_dataset=dataset,
processing_class=tokenizer,
)
trainer.train()
trainer.save_model()フルファインチューニングは 7B モデルの全 ~70億パラメータを変更する。bfloat16 ではパラメータの保存だけで14 GB、さらに勾配とオプティマイザの状態が加わる。LoRA(Low-Rank Adaptation、Hu et al. 2021)は重要な経験的観察を活用する:ファインチューニング中の重みの変化は低ランクである。
完全な重み更新 ΔW ∈ ℝ^(d×k) を学習する代わりに、LoRA は二つの小さな行列を学習する:A ∈ ℝ^(d×r) と B ∈ ℝ^(r×k)、ここで r ≪ min(d, k)。推論時、アダプタは折り戻される:W′ = W + αAB/r。マージされると、推論のオーバーヘッドはゼロになる。
from peft import LoraConfig, TaskType, get_peft_model
config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=16,
lora_alpha=32,
lora_dropout=0.05,
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
],
bias="none",
)
model = get_peft_model(base_model, config)
model.print_trainable_parameters()
# trainable params: 83,886,080 || all params: 8,030,261,248 || trainable%: 1.044
# After training, merge adapter back into the base weights
merged = model.merge_and_unload()
merged.save_pretrained("./my-lora-merged")| 手法 | 学習可能パラメータ | GPU RAM (8B) | 品質 | 学習速度 |
|---|---|---|---|---|
| Full Fine-Tuning | 7B (100%) | ~80 GB | 最良 | 最も遅い |
| LoRA r=4 | ~21M (0.3%) | ~16 GB | 良好 | 高速 |
| LoRA r=16 | ~83M (1.0%) | ~18 GB | 非常に良好 | 高速 |
| LoRA r=64 | ~335M (4.1%) | ~24 GB | フル FT に近い | 中程度 |
LoRA を使っても、bfloat16 で読み込んだベースモデルは 8B モデルで16 GB を必要とし — コンシューマー GPU の予算を超える。QLoRA(Dettmers et al. 2023)は、凍結したベースモデルを4ビット NormalFloat(NF4)に量子化し、LoRA アダプタを bfloat16 精度で学習することでこれを解決する。
NormalFloat4 は正規分布するニューラルネットワークの重みに対して情報理論的に最適である。int4 や fp4 より誤差が小さい。
GPU メモリが一杯になると、オプティマイザの状態が自動的に CPU RAM へページングされ、学習中の OOM クラッシュを防ぐ。
量子化定数そのものを量子化し、パラメータあたり追加で約0.5ビットを節約する。
| モデル | FP16 VRAM | QLoRA VRAM | 最小 GPU |
|---|---|---|---|
| Llama 4 Scout (17B) | 34 GB | 10 GB | RTX 4090 24GB |
| Llama 4 Maverick (70B-class) | 140 GB | 40 GB | 2× A100 40GB |
| Llama 4 Behemoth (frontier) | 800+ GB | ~200 GB | 8× H100 80GB |
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
import torch
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-4-Maverick-17B-128E-Instruct", # 2026: Llama 4 Maverick replaces Llama 3.1 70B
quantization_config=bnb_config,
device_map="auto",
)
# Now apply LoRA to the 4-bit model — same LoraConfig + get_peft_model as before人間のフィードバックからの強化学習(RLHF)は、GPT-3 を InstructGPT に、そして最終的に GPT-4o に変えたブレークスルーだった。これはモデルの振る舞いを人間の嗜好に整合させる — 単なる指示の遵守ではなく、出力を真に好ましく、安全で、役立つものにする。
高品質な指示遵守デモのキュレーションされたセットでベースモデルをファインチューニングする。これにより RLHF が改善する出発点となるポリシーが作られる。
ペアごとの人間の嗜好で分類器を学習する:同じプロンプトに対する二つの補完(y_w、y_l)のうち、どちらが良いか? 損失:log σ(r(x, y_w) − r(x, y_l))。
Proximal Policy Optimization を用いて、SFT ポリシーに近いまま報酬モデルのスコアを最大化する(KL ダイバージェンスのペナルティが報酬ハッキングを防ぐ)。
graph LR A[Base Model] -->|SFT on demos| B[SFT Model] B -->|Sample completions| C[Completion Pairs] C -->|Human labelers rank| D[Preference Dataset] D -->|Train| E[Reward Model] B -->|Initialize policy| F[Policy Model] F -->|Rollout + PPO| G[RL Optimization] E -->|Score rollouts| G G -->|Converged| H[RLHF Model]
DPO(Direct Preference Optimization)(Rafailov et al. 2023)は報酬モデルを完全に排除する。最適な RLHF ポリシーが嗜好データの関数として直接表現できることを数学的に示し、三段階のパイプラインを単一のファインチューニングステップへと折りたたんだ。
DPO 損失は、SFT モデルを凍結された参照として用い、嗜好ペア(prompt、chosen、rejected)でポリシーを直接最適化する。PPO もなく、報酬モデルもなく、報酬モデル用の学習データの個別収集もない。
from trl import DPOConfig, DPOTrainer
from datasets import load_dataset
# Dataset needs: prompt, chosen, rejected columns
dataset = load_dataset("HuggingFaceH4/ultrafeedback_binarized", split="train_prefs")
dpo_config = DPOConfig(
output_dir="./dpo-output",
num_train_epochs=3,
per_device_train_batch_size=2,
gradient_accumulation_steps=8,
learning_rate=5e-7, # much smaller than SFT lr
beta=0.1, # KL penalty coefficient
bf16=True,
)
trainer = DPOTrainer(
model=sft_model, # your SFT fine-tuned model
ref_model=sft_ref_model, # frozen reference
args=dpo_config,
train_dataset=dataset,
processing_class=tokenizer,
)
trainer.train()Group Relative Policy Optimization(GRPO)(DeepSeek-R1 で使用)は参照モデルを排除する。各プロンプトについて複数の出力をサンプリングし、グループの平均報酬をアドバンテージ推定のベースラインとして用いる。これは PPO より安価で(価値モデルが不要)、正しさをプログラム的に検証できる推論タスクに適している。
| 手法 | 計算量 | 安定性 | データ要件 | 備考 |
|---|---|---|---|---|
| RLHF (PPO) | 非常に高い | 低い | 人間のランキング | 4モデルがメモリ上;報酬ハッキングのリスク |
| DPO | 低い | 高い | 嗜好ペア | 報酬モデルなし;よりシンプルなパイプライン |
| GRPO | 中程度 | 中程度 | ロールアウトサンプル | 参照モデルなし;推論に適する |
| SimPO | 低い | 高い | 嗜好ペア | 参照モデルなし;平均対数確率の報酬 |
知識蒸留は、小さな「生徒」モデルを大きな「教師」モデルを模倣するよう学習させる。重要な洞察は、教師が one-hot ラベルではなく語彙上のソフトな確率分布(logits)を提供することだ。これらのソフトターゲットははるかに多くの情報を符号化する — どの token が正解と意味的に類似しているかを明らかにし、生徒により豊かな学習信号を与える。
結合された損失:L = α × L_CE(ハードラベル) + (1 − α) × L_KL(生徒の logits ‖ 教師の logits)。温度スケーリング T > 1 は教師の分布を滑らかにし、確率質量をより多くの token に広げ、ソフトラベルをさらに情報量の多いものにする。
graph TB A["Large Teacher (70B)"] -->|"Generate on training data"| B[Soft Logits] C[Input Prompt] --> A C --> D["Small Student (7B)"] B -->|KL Loss| D E[Ground Truth] -->|CE Loss| D D -->|Both losses| F[Distilled Student]
生徒が教師の出力を模倣する — 教師の補完を生成し、それを再現するよう生徒を学習させる。DeepSeek-R1-Distill が推論トレースを転移するために使用。
教師と生徒の層の間で中間表現(隠れ状態、attention パターン)を一致させる。表面的な出力だけでなく、構造的な知識を転移する。
小さなドラフトモデルが token 列を提案し、大きなモデルがそれらを並列に検証する。品質を損なうことなく2〜4倍の推論高速化を達成する。
生徒が token を生成し、教師がそれを採点する。オフライン蒸留でよく見られる露出バイアス(学習と評価の分布のミスマッチ)を回避する。
モデルマージは、追加の学習を一切行わずに、複数のファインチューニング済みチェックポイントを単一のモデルに結合する。安価で高速、そして専門的なスキル — コード、数学、指示遵守 — を一つのデプロイ可能なモデルに統合するのに驚くほど効果的である。マージされたモデルは HuggingFace Open LLM Leaderboard の上位に頻繁に登場する。
重み空間における二つのモデルチェックポイント間の滑らかな補間。重みを超球面上の点として扱う。密接に関連した二つのモデルをブレンドするのに最適。
各ファインチューニング済みモデルについて ΔW = W_FT − W_base を計算し、差分を加算する。能力を合成したり、望ましくない振る舞いを減算したりできる。
モデル間の競合を解決する:大きさの小さいパラメータをトリミングし、各重みについて支配的な符号を選出し、その後マージする。3つ以上のモデルをきれいに扱う。
ファインチューニングの重み差分をランダムに(確率 p で)ドロップし、生き残ったものをリスケールしてノルムを保つ。モデル間の干渉を低減する。
# mergekit config.yaml
models:
- model: meta-llama/Llama-4-Scout-17B-16E
parameters:
weight: 0.4
- model: ./llama-4-scout-code-finetuned
parameters:
weight: 0.3
- model: ./llama-4-scout-math-finetuned
parameters:
weight: 0.3
merge_method: ties
base_model: meta-llama/Llama-4-Scout-17B-16E
parameters:
density: 0.7
normalize: truemergekit-yaml config.yaml ./merged-model --cuda
データセットの質は、ファインチューニングの成功における単一で最も重要な要因である — モデルアーキテクチャ、学習時間、オプティマイザの選択よりも重要だ。キュレーションが不十分なデータセットは、他のすべてに関わらず悪い結果を保証する。
専門家が執筆した例;最高の信号対雑音比。重要な振る舞いに使用される。
フロンティアモデルによる合成生成。ドメインのカバレッジを大規模に立ち上げるのに適する。
シード指示をより難しく多様なバリアントへと進化させる。WizardLM や OpenHermes で使用。
積極的な品質フィルタリングを要する:重複除去、長さフィルタ、パープレキシティフィルタ、安全性フィルタ。
{
"conversations": [
{"from": "system", "value": "You are an expert in EU AI regulation."},
{"from": "human", "value": "Explain the risk categories in the EU AI Act."},
{"from": "gpt", "value": "The EU AI Act categorizes AI systems into four risk levels..."}
]
}from openai import OpenAI # or use Mistral/Llama locally
client = OpenAI()
def generate_training_example(topic: str, difficulty: str) -> dict:
prompt = (
f"Generate a challenging {difficulty}-level question about {topic} "
"and a comprehensive expert answer."
)
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.8,
)
content = response.choices[0].message.content
# Parse and structure output (question/answer split)...
return {"instruction": topic, "response": content}ファインチューニングのループは:学習 → ホールドアウトでの評価 → 失敗モードの診断 → データの改善 → 再学習。良い評価こそが、試行錯誤を体系的な改善へと変えるものだ。
8カテゴリ(執筆、数学、コーディングなど)にわたる80問のマルチターンベンチマーク。GPT-4 が各応答を1〜10で採点する。
GPT-4o が判定する、参照モデル(GPT-4o)に対するモデルの勝率。指示遵守の品質の高速な自動評価。
検証可能な制約(例:「100語未満で応答する」)に対する指示遵守の精度。厳格版と緩和版の採点バリアントがある。
コード生成ベンチマーク。Pass@k 指標:k 回の試行で解決された問題の割合。グラウンドトゥルースの実行可能なテストケース。
import json
from openai import OpenAI
client = OpenAI()
def evaluate_response(question: str, answer: str, judge_model: str = "gpt-4o") -> dict:
prompt = f"""Rate the following AI assistant response on a scale of 1-10.
Question: {question}
Answer: {answer}
Evaluate: helpfulness (1-10), factuality (1-10), safety (1-10).
Return JSON: {{"helpfulness": N, "factuality": N, "safety": N, "rationale": "..."}}"""
response = client.chat.completions.create(
model=judge_model,
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
)
return json.loads(response.choices[0].message.content)| Run | ベースモデル | 手法 | データセット | MT-Bench | AlpacaEval Win% | 備考 |
|---|---|---|---|---|---|---|
| v1 | Llama-4-Scout | SFT | UltraChat 200K | 7.4 | 70% | ベースライン |
| v2 | Llama-4-Scout | SFT+DPO | + UltraFeedback | 8.0 | 76% | +DPO で安全性が向上 |
| v3 | Llama-4-Scout | SFT+DPO (r=16) | + UltraFeedback | 8.1 | 77% | LoRA r=16 vs フル FT |
ファインチューニングは強力だが、常に正しいツールとは限らない。決定は、何を変えようとしているか — 知識、振る舞い、形式、嗜好 — による。間違った選択は、数週間のエンジニアリングと計算資源を浪費する。
| シナリオ | 最良のアプローチ | 理由 |
|---|---|---|
| 社内文書に回答を根拠づける必要がある | RAG | 知識は変わりうる;FT は容易に更新できない |
| 一貫したトーン/スタイルが欲しい | SFT | トーンは形式であり、知識ではない |
| ドメイン固有の用語の使用 | SFT + 少量データ | デフォルトの振る舞いを安価に変更する |
| 特定の出力形式を扱う必要がある | SFT | スキーマ遵守は習得されるスキルである |
| 有害な出力を減らす | DPO / RLHF | 嗜好アライメントが直接これを狙う |
| 推論能力が必要 | GRPO または R1 から蒸留 | 推論パターンは学習可能である |
| 新しい事実知識を追加する | RAG(FT ではない) | FT は記憶するが、出典を引用できない |
| 大規模に API コストを削減する | 小さなモデルをファインチューニング | 狭いタスクで大規模モデルの品質に匹敵させる |
| プロトタイプ / 迅速な実験 | まずプロンプトエンジニアリング | 学習コストゼロ;まずコンセプトを検証する |
一番下から始めること。現在のレベルが本当に不十分なときにのみ登ること — 各段はコスト、複雑さ、レイテンシを加える。
ドメイン特化のアシスタント、嗜好に整合したモデル、蒸留された本番デプロイのいずれが必要でも — 私たちのチームはそれらを構築し出荷してきました。あなたのユースケースについて話しましょう。