unsloth-training について
unsloth-trainingは、UnslothでLLMをファインチューニングする開発者向けの実践ガイドです。GRPO、SFT、ビジョンモデルの学習に加え、環境設定、トラブルシューティング、モデルのエクスポートとデプロイ方法を扱います。
主な機能
- 01GRPOとSFTのトレーニングガイド
- 02ビジョンモデルのファインチューニング手順
- 03FP8トレーニングとデータパッキングの設定
- 04報酬関数の設計と学習時の問題解決
- 05GGUFなどの形式へのモデル出力
活用シーン
- 01報酬関数を使ったモデルのファインチューニング
- 02入出力例を使ったモデルの学習
- 03視覚言語モデルのファインチューニング
- 04学習済みモデルのモバイル展開準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scientiacapital/ skills --skill unsloth-trainingインストール後、Claude Code で/unsloth-trainingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
config.jsonreference/advanced-training.mddeployment.mddomain-examples.mdexport-formats.mdfp8-training.mdhyperparameters.mdmobile-deployment.mdreward-design.mdtroubleshooting.mdvision-training.mdreference/grpo/basic_grpo.pyhyperparameters.pyreward_functions.pyreference/sft/generate_training_data.pysales_extractor_training.pyseed_examples.json詳細
- GRPO - 報酬関数を用いた RL(ラベル付き出力は不要)
- SFT - 入力/出力ペアを用いた教師ありファインチューニング
- Vision - VLM ファインチューニング(Qwen3-VL、Gemma3、Llama 3.2 Vision)
主な機能:
- FP8 トレーニング - VRAM 使用量を 60% 削減、1.4 倍高速(RTX 40+、H100)
- 3 倍パッキング - 長さが混在するデータで自動的に 2〜5 倍の高速化
- Docker - 公式の
unsloth/unslothイメージ - モバイル - QAT → ExecuTorch → iOS/Android(約 40 tok/s)
- エクスポート - GGUF、Ollama、vLLM、LM Studio、SGLang
<quick_start> FP8 による GRPO(VRAM 使用量を 60% 削減):
import os
os.environ['UNSLOTH_VLLM_STANDBY'] = "1" # Shared memory
from unsloth import FastLanguageModel
from trl import GRPOConfig, GRPOTrainer
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="unsloth/Qwen3-8B",
max_seq_length=2048, load_in_fp8=True, fast_inference=True,
)
model = FastLanguageModel.get_peft_model(
model, r=64,
target_modules=["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj"],
use_gradient_checkpointing="unsloth",
)
def correctness_reward(completions, answer, **kwargs):
return [2.0 if extract_answer(c) == a else 0.0
for c, a in zip(completions, answer)]
trainer = GRPOTrainer(
model=model,
args=GRPOConfig(num_generations=4, beta=0.04, learning_rate=5e-6),
train_dataset=dataset, reward_funcs=[correctness_reward],
)
trainer.train()
パッキングによる SFT(2〜5 倍高速):
from trl import SFTTrainer, SFTConfig
trainer = SFTTrainer(
model=model, train_dataset=dataset, processing_class=tokenizer,
args=SFTConfig(
per_device_train_batch_size=2, num_train_epochs=3,
learning_rate=2e-4, packing=True, # 2-5x speedup
),
)
trainer.train()
</quick_start>
<success_criteria> 以下の条件を満たすとき、トレーニング実行は成功です:
- モデルが OOM エラーなしで読み込まれる
- 報酬(GRPO)または損失(SFT)が改善傾向を示す
- 生成された出力が期待される形式に一致する
- モデルが目的の形式(LoRA、マージ済み、GGUF)にエクスポートされる
- テスト推論が妥当な出力を生成する </success_criteria>
<activation_triggers> 明示的なトリガー:
/unsloth grpo- GRPO(RL)トレーニング/unsloth sft- SFT トレーニング/unsloth fp8- FP8 トレーニングのセットアップ/unsloth vision- VLM ファインチューニング/unsloth mobile- スマートフォンへのデプロイ(QAT)/unsloth docker- Docker コンテナのセットアップ/unsloth troubleshoot- 問題のデバッグ
自然言語:
- 「GRPO でトレーニング」「ファインチューニング」「報酬関数」
- 「FP8 トレーニング」「fp8」「VRAM を減らす」
- 「vision ファインチューニング」「VLM」「画像トレーニング」
- 「スマートフォンへのデプロイ」「モバイル LLM」「ExecuTorch」
- 「docker トレーニング」「コンテナ」「unsloth docker」
- 「パッキング」「高速なトレーニング」「500k コンテキスト」
- 「GGUF をエクスポート」「Ollama」「vLLM」「SGLang」 </activation_triggers>
<file_locations> 主要リファレンス:
reference/reward-design.md- 報酬関数のパターンreference/domain-examples.md- Voice AI、Sales Agent の例reference/hyperparameters.md- GRPOConfig リファレンスreference/troubleshooting.md- 一般的な修正方法
新機能リファレンス:
reference/fp8-training.md- FP8 のセットアップ、VRAM 削減reference/deployment.md- Docker、vLLM、LoRA ホットスワップ、SGLangreference/export-formats.md- GGUF、Ollama、LM Studio、Dynamic 2.0reference/advanced-training.md- 500K コンテキスト、パッキング、チェックポイントreference/vision-training.md- VLM ファインチューニングreference/mobile-deployment.md- QAT、ExecuTorch、iOS/Android
コード例: reference/grpo/、reference/sft/
</file_locations>
<core_concepts>
GRPO と SFT の使い分け
| 手法 | 使用する状況 | 必要なデータ |
|---|---|---|
| GRPO | 推論品質を向上させたい | プロンプト + 検証可能な回答 |
| GRPO | 好みに合わせて動作を調整したい | 報酬関数 |
| GRPO | 正しさを検証できる場合 | 検証可能な出力 |
| SFT | 特定の出力形式を教えたい | 入力/出力ペア |
| SFT | 新しい指示に従わせたい | 会話の例 |
| SFT | ドメイン知識を学習させたい | ラベル付きの例 |
モデルの選択
| モデル | サイズ | VRAM | ユースケース |
|---|---|---|---|
unsloth/Qwen2.5-0.5B-Instruct | 0.5B | 5GB | モバイルへのデプロイ(約 200MB の GGUF) |
unsloth/Qwen2.5-1.5B-Instruct | 1.5B | 5GB | 学習/プロトタイピング |
Qwen/Qwen2.5-3B-Instruct | 3B | 8GB | バランスが良い(推奨の出発点) |
unsloth/Qwen2.5-7B-Instruct | 7B | 16GB | 本番品質 |
unsloth/Phi-4 | 14B | 20GB | 強力な推論 |
主要ハイパーパラメータ
GRPO(RL):
GRPOConfig(
num_generations=4, # Completions per prompt (2-8)
beta=0.04, # KL penalty (0.01-0.1)
learning_rate=5e-6, # 10x smaller than SFT!
max_completion_length=512,
max_steps=300, # Minimum for results
)
SFT:
TrainingArguments(
learning_rate=2e-4, # Standard SFT rate
num_train_epochs=3, # 2-4 typical
per_device_train_batch_size=2,
)
</core_concepts>
<reward_functions>
報酬関数の設計
報酬関数は GRPO の中核です。各完了に対して float のリストを返します。
パターン 1: 正確さ(主要シグナル)
def correctness_reward(completions, answer, **kwargs):
"""
+2.0 for correct answer, 0.0 otherwise.
This should be your highest-weighted reward.
"""
rewards = []
for completion, true_answer in zip(completions, answer):
extracted = extract_answer(completion)
try:
pred = float(extracted.replace(",", "").strip())
true = float(true_answer.replace(",", "").strip())
reward = 2.0 if abs(pred - true) < 0.01 else 0.0
except ValueError:
reward = 2.0 if extracted.strip() == str(true_answer).strip() else 0.0
rewards.append(reward)
return rewards
パターン 2: 形式の準拠
def format_reward(completions, **kwargs):
"""
+0.5 for proper XML structure with reasoning and answer tags.
"""
rewards = []
for completion in completions:
has_reasoning = bool(re.search(r"<reasoning>.*?</reasoning>", completion, re.DOTALL))
has_answer = bool(re.search(r"<answer>.*?</answer>", completion, re.DOTALL))
if has_reasoning and has_answer:
rewards.append(0.5)
elif has_answer:
rewards.append(0.2)
else:
rewards.append(0.0)
return rewards
パターン 3: 推論品質
def reasoning_length_reward(completions, **kwargs):
"""
+0.3 for substantive reasoning (30-200 words).
"""
rewards = []
for completion in completions:
reasoning = extract_reasoning(completion)
word_count = len(reasoning.split()) if reasoning else 0
if 30 <= word_count <= 200:
rewards.append(0.3)
elif 15 <= word_count < 30:
rewards.append(0.1)
else:
rewards.append(0.0)
return rewards
パターン 4: 負の制約
def no_hedging_reward(completions, **kwargs):
"""
-0.3 penalty for uncertainty language.
"""
hedging = ["i think", "maybe", "perhaps", "possibly", "i'm not sure"]
rewards = []
for completion in completions:
has_hedging = any(phrase in completion.lower() for phrase in hedging)
rewards.append(-0.3 if has_hedging else 0.0)
return rewards
典型的な報酬スタック
reward_funcs = [
correctness_reward, # +2.0 max (primary signal)
format_reward, # +0.5 max (structure)
reasoning_length_reward, # +0.3 max (quality)
no_hedging_reward, # -0.3 max (constraint)
]
# Total range: -0.3 to +2.8
ドメイン固有の報酬について: Voice AI、Sales Agent、サポートのパターンについては
reference/domain-examples.mdを参照してください。 </reward_functions>
<prompt_format>
プロンプト構造
XML タグ付きシステムプロンプト
SYSTEM_PROMPT = """You are a helpful assistant that thinks step-by-step.
Always respond in this exact format:
<reasoning>
[Your step-by-step thinking process]
</reasoning>
<answer>
[Your final answer - just the number or short response]
</answer>
"""
抽出ヘルパー
import re
def extract_answer(text: str) -> str:
"""Extract answer from XML tags"""
match = re.search(r"<answer>(.*?)</answer>", text, re.DOTALL)
return match.group(1).strip() if match else ""
def extract_reasoning(text: str) -> str:
"""Extract reasoning from XML tags"""
match = re.search(r"<reasoning>(.*?)</reasoning>", text, re.DOTALL)
return match.group(1).strip() if match else ""
データセット形式
GRPO (プロンプトのみ):
dataset = dataset.map(lambda ex: {
"prompt": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": ex["question"]}
],
"answer": ex["answer"] # Ground truth for verification
})
SFT (完全な会話):
dataset = dataset.map(lambda ex: {
"conversations": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": ex["input"]},
{"role": "assistant", "content": ex["output"]}
]
})
</prompt_format>
<model_export>
保存とデプロイ
LoRA のみを保存 (~100MB)
model.save_lora("grpo_lora")
マージして完全なモデルを保存
model.save_pretrained_merged(
"grpo_merged", tokenizer,
save_method="merged_16bit",
)
Ollama 用に GGUF へエクスポート
model.save_pretrained_gguf(
"grpo_gguf", tokenizer,
quantization_method="q4_k_m", # Options: q4_k_m, q8_0, q5_k_m
)
Ollama でテスト
# Create Modelfile
cat > Modelfile << EOF
FROM ./grpo_gguf/unsloth.Q4_K_M.gguf
TEMPLATE """{{ .System }}
User: {{ .Prompt }}
Assistant: """
PARAMETER temperature 0.7
EOF
ollama create my-model -f Modelfile
ollama run my-model "Solve: 15 + 27 = ?"
</model_export>
## リクエストルーティングGRPO トレーニング: → GRPOConfig、報酬関数、データセット準備
→ 参照: reference/grpo/basic_grpo.py
SFT トレーニング: → SFTTrainer、データセットのフォーマット
→ 参照: reference/sft/sales_extractor_training.py
報酬関数の設計: → 4 つのパターン (正確性、形式、品質、制約)
→ 参照: reference/reward-design.md、reference/domain-examples.md
FP8 トレーニング: → VRAM を 60% 節約、環境変数、事前量子化モデル
→ 参照: reference/fp8-training.md
Docker セットアップ: → 公式イメージ、ボリューム、Jupyter/SSH
→ 参照: reference/deployment.md
ビジョンファインチューニング: → FastVisionModel、VLM データ形式
→ 参照: reference/vision-training.md
モバイルデプロイ: → QAT、ExecuTorch、iOS/Android
→ 参照: reference/mobile-deployment.md
長いコンテキスト / パッキング: → 500K コンテキスト、2〜5 倍の高速化
→ 参照: reference/advanced-training.md
エクスポート形式: → GGUF の方法、Ollama、vLLM、SGLang
→ 参照: reference/export-formats.md
トレーニングの問題: → reference/troubleshooting.md
<troubleshooting_quick>
クイックトラブルシューティング
| 症状 | 対処 |
|---|---|
| 報酬が増加しない | 300 ステップ以上待ってから、learning_rate を 2 倍に増やす |
| 報酬が急変する/不安定 | learning_rate を 0.5 倍に減らし、beta を増やす |
| モデルが意味不明な出力をする | beta を 2〜4 倍に増やし、プロンプト形式を確認する |
| メモリ不足 | max_completion_length を減らす、num_generations=2 にする |
| 推論が現れない | 500 ステップ以上トレーニングする、モデル >= 1.5B を使用する |
詳細なトラブルシューティングについて:
reference/troubleshooting.mdを参照してください。 </troubleshooting_quick>
<training_checklist>
トレーニング前チェックリスト
GRPO:
- モデルが OOM なしでロードされる
- LoRA が
use_gradient_checkpointing="unsloth"で設定されている - データセットに
promptフィールドとanswerフィールドがある - 少なくとも 1 つの報酬関数が定義され、テストされている
-
num_generations >= 2 -
betaが設定されている (0.01〜0.1、0.04 から開始) -
learning_rateが設定されている (1e-6〜1e-5) - 少なくとも 300 ステップを計画している
SFT:
- モデルが OOM なしでロードされる
- データセットに会話またはテキストフィールドがある
- チャットテンプレートが正しく適用されている
-
learning_rate~2e-4 - 2〜4 エポックを計画している </training_checklist>
<cost_estimates>
コスト見積もり
トレーニングデータの生成:
- 50 シード x 10 バリエーション x 約 1000 トークン = 約 500K トークン
- Claude Sonnet: 約 $1.50
- GPT-4o-mini: 約 $0.30
トレーニングの計算リソース:
- Google Colab T4: 無料 (1000 例で 30〜60 分)
- RunPod A40 (48GB): 約 $0.79/時
実験あたりの合計: RunPod で約 $0.50〜$1.00 </cost_estimates>
<example_session>
セッション例
ユーザー: 「簡潔な音声応答を返すモデルをトレーニングしたいです」
Claude:
- まず、モデルをセットアップしましょう:
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="Qwen/Qwen2.5-3B-Instruct",
max_seq_length=1024, load_in_4bit=True,
)
- 音声 AI には、簡潔さの報酬が必要です。カスタムスタックはこちらです:
def brevity_reward(completions, **kwargs):
"""Voice responses under 50 words get +0.5"""
return [0.5 if len(c.split()) <= 50 else -0.3 for c in completions]
def speakable_reward(completions, **kwargs):
"""Penalize markdown that sounds bad spoken"""
bad = ["**", "- ", "```", "http"]
return [-0.2 * sum(1 for b in bad if b in c) for c in completions]
reward_funcs = [correctness_reward, brevity_reward, speakable_reward]
- 完全な Voice AI 報酬パターンについては
reference/domain-examples.mdを参照してください。
結果サイドカーの出力
最後のステップとして、~/.claude/skill-analytics/last-outcome-unsloth-training.json に書き込みます:
{"ts":"[UTC ISO8601]","skill":"unsloth-training","version":"1.0.0","variant":"default",
"status":"[success|partial|error]","runtime_ms":[estimated ms from start],
"metrics":{"models_trained":[n],"epochs_completed":[n],"exports_generated":[n]},
"error":null,"session_id":"[YYYY-MM-DD]"}
一部のステージが失敗しても結果が生成された場合は、status に "partial" を使用してください。出力がまったく生成されなかった場合にのみ "error" を使用してください。 </example_session>