mcpField
U
unsloth-training

unsloth-training

github.com/scientiacapital开发28117 次安装3 周前更新
代码仓库

关于 unsloth-training

unsloth-training 是面向使用 Unsloth 微调大模型的开发者指南,涵盖 GRPO、SFT 和视觉训练,也提供环境设置、故障排查以及模型导出和部署路径。

主要功能

  1. 01提供 GRPO 和 SFT 训练指导
  2. 02说明视觉模型微调方法
  3. 03配置 FP8 训练和数据打包
  4. 04排查训练问题并设计奖励函数
  5. 05将模型导出为 GGUF 等格式

适用场景

  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 指导大模型微调:
  1. GRPO - 使用奖励函数进行 RL(无需标注输出)
  2. SFT - 使用输入/输出对进行监督微调
  3. Vision - VLM 微调(Qwen3-VL、Gemma3、Llama 3.2 Vision)

主要功能:

  • FP8 Training - 显存占用减少 60%,速度提升 1.4 倍(RTX 40+、H100)
  • 3x Packing - 自动加速 2-5 倍,适用于长度混合的数据
  • Docker - 官方 unsloth/unsloth 镜像
  • Mobile - QAT → ExecuTorch → iOS/Android(约 40 tok/s)
  • Export - GGUF、Ollama、vLLM、LM Studio、SGLang

<quick_start> 使用 FP8 进行 GRPO(显存占用减少 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()

使用 Packing 进行 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”、“更少显存”
  • “视觉微调”、“VLM”、“图像训练”
  • “手机部署”、“移动端 LLM”、“ExecuTorch”
  • “docker 训练”、“容器”、“unsloth docker”
  • “packing”、“更快的训练”、“500k 上下文”
  • “导出 GGUF”、“Ollama”、“vLLM”、“SGLang” </activation_triggers>

<file_locations> 核心参考资料:

  • reference/reward-design.md - 奖励函数模式
  • reference/domain-examples.md - 语音 AI、销售 Agent 示例
  • reference/hyperparameters.md - GRPOConfig 参考
  • reference/troubleshooting.md - 常见问题修复方法

新功能参考资料:

  • reference/fp8-training.md - FP8 设置、显存节省
  • reference/deployment.md - Docker、vLLM、LoRA 热切换、SGLang
  • reference/export-formats.md - GGUF、Ollama、LM Studio、Dynamic 2.0
  • reference/advanced-training.md - 500K 上下文、packing、检查点
  • 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学习领域知识标注示例

模型选择

模型大小显存用途
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 的核心。对于每个补全内容,奖励函数都会返回一个浮点数列表。

模式 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_functions>

典型奖励组合
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 和 Support 模式请参阅 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",
)
导出为 GGUF 以用于 Ollama
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 训练: → 节省 60% VRAM、环境变量、预量化模型 → 参考: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 字段
  • 至少定义并测试了一个奖励函数
  • 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. 对于 Voice 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]"}

如果某些阶段失败但已生成结果,请使用状态 "partial"。只有在未生成任何输出时才使用 "error"。 </example_session>

评论

支持 Markdown