mcpField
U
unsloth-training

unsloth-training

github.com/scientiacapital開発28117 回インストール3 週間前に更新
リポジトリ

unsloth-training について

unsloth-trainingは、UnslothでLLMをファインチューニングする開発者向けの実践ガイドです。GRPO、SFT、ビジョンモデルの学習に加え、環境設定、トラブルシューティング、モデルのエクスポートとデプロイ方法を扱います。

主な機能

  1. 01GRPOとSFTのトレーニングガイド
  2. 02ビジョンモデルのファインチューニング手順
  3. 03FP8トレーニングとデータパッキングの設定
  4. 04報酬関数の設計と学習時の問題解決
  5. 05GGUFなどの形式へのモデル出力

活用シーン

  1. 01報酬関数を使ったモデルのファインチューニング
  2. 02入出力例を使ったモデルの学習
  3. 03視覚言語モデルのファインチューニング
  4. 04学習済みモデルのモバイル展開準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/scientiacapital/skills --skill unsloth-training

インストール後、Claude Code で/unsloth-trainingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

config.json
reference/
advanced-training.md
deployment.md
domain-examples.md
export-formats.md
fp8-training.md
hyperparameters.md
mobile-deployment.md
reward-design.md
troubleshooting.md
vision-training.md
reference/grpo/
basic_grpo.py
hyperparameters.py
reward_functions.py
reference/sft/
generate_training_data.py
sales_extractor_training.py
seed_examples.json

詳細

Unsloth を使用した LLM ファインチューニングのガイド:
  1. GRPO - 報酬関数を用いた RL(ラベル付き出力は不要)
  2. SFT - 入力/出力ペアを用いた教師ありファインチューニング
  3. 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 ホットスワップ、SGLang
  • reference/export-formats.md - GGUF、Ollama、LM Studio、Dynamic 2.0
  • reference/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-Instruct0.5B5GBモバイルへのデプロイ(約 200MB の GGUF)
unsloth/Qwen2.5-1.5B-Instruct1.5B5GB学習/プロトタイピング
Qwen/Qwen2.5-3B-Instruct3B8GBバランスが良い(推奨の出発点)
unsloth/Qwen2.5-7B-Instruct7B16GB本番品質
unsloth/Phi-414B20GB強力な推論

主要ハイパーパラメータ

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:

  1. まず、モデルをセットアップしましょう:
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="Qwen/Qwen2.5-3B-Instruct",
    max_seq_length=1024, load_in_4bit=True,
)
  1. 音声 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]
  1. 完全な 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>

コメント