HuggingFace课程实践:使用Unsloth进行GRPO模型微调
引言
在自然语言处理领域,模型微调是提升预训练模型在特定任务上表现的关键技术。本文将介绍如何利用Unsloth库和GRPO(Group Relative Policy Optimization)技术对Gemma 3 1B模型进行高效微调,以提升其数学推理能力。
技术背景
GRPO简介
GRPO是一种强化学习优化方法,它通过定义多个奖励函数来引导模型学习特定行为模式。与传统的PPO(Proximal Policy Optimization)相比,GRPO能够更精细地控制模型的学习方向。
Unsloth优势
Unsloth是一个专注于加速大型语言模型微调的库,具有以下特点:
- 显著减少训练时间
- 降低显存消耗
- 无缝集成到现有训练流程中
环境准备
安装依赖
首先需要安装必要的Python库:
pip install unsloth vllm
pip install --upgrade pillow
模型加载与配置
加载Gemma 3 1B模型
使用Unsloth提供的FastLanguageModel类加载模型:
from unsloth import FastLanguageModel
import torch
max_seq_length = 1024 # 可根据需求调整
lora_rank = 32 # LoRA秩数,影响模型能力和速度
model, tokenizer = FastLanguageModel.from_pretrained(
model_name="google/gemma-3-1b-it",
max_seq_length=max_seq_length,
load_in_4bit=True, # 4位量化节省显存
fast_inference=True, # 启用vLLM快速推理
max_lora_rank=lora_rank,
gpu_memory_utilization=0.6, # 显存利用率
)
应用LoRA适配器
LoRA(Low-Rank Adaptation)是一种高效的微调技术:
model = FastLanguageModel.get_peft_model(
model,
r=lora_rank,
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",
],
lora_alpha=lora_rank,
use_gradient_checkpointing="unsloth", # 支持长上下文微调
random_state=3407,
)
数据准备
数据集选择
我们使用GSM8K数据集,包含小学数学问题及其解答:
from datasets import load_dataset
def get_gsm8k_questions(split="train"):
data = load_dataset("openai/gsm8k", "main")[split]
return data
数据格式化
定义系统提示和响应格式:
SYSTEM_PROMPT = """
Respond in the following format:
<reasoning>
...
</reasoning>
<answer>
...
</answer>
"""
XML_COT_FORMAT = """\
<reasoning>
{reasoning}
</reasoning>
<answer>
{answer}
</answer>
"""
奖励函数设计
GRPO的核心在于定义合适的奖励函数来引导模型学习:
正确性奖励
def correctness_reward_func(prompts, completions, answer, **kwargs):
# 提取模型响应中的答案
responses = [completion[0]["content"] for completion in completions]
extracted_responses = [extract_xml_answer(r) for r in responses]
# 对比正确答案给予奖励
return [2.0 if r == a else 0.0 for r, a in zip(extracted_responses, answer)]
格式奖励
def strict_format_reward_func(completions, **kwargs):
pattern = r"^<reasoning>\n.*?\n</reasoning>\n<answer>\n.*?\n</answer>\n$"
responses = [completion[0]["content"] for completion in completions]
matches = [re.match(pattern, r) for r in responses]
return [0.5 if match else 0.0 for match in matches]
数值答案奖励
def int_reward_func(completions, **kwargs):
responses = [completion[0]["content"] for completion in completions]
extracted_responses = [extract_xml_answer(r) for r in responses]
return [0.5 if r.isdigit() else 0.0 for r in extracted_responses]
训练配置
GRPO训练参数
from trl import GRPOConfig, GRPOTrainer
training_args = GRPOConfig(
learning_rate=5e-6,
adam_beta1=0.9,
adam_beta2=0.99,
weight_decay=0.1,
warmup_ratio=0.1,
lr_scheduler_type="cosine",
optim="paged_adamw_8bit",
per_device_train_batch_size=1,
gradient_accumulation_steps=1,
num_generations=6,
max_prompt_length=256,
max_completion_length=max_seq_length - 256,
max_steps=250,
save_steps=250,
max_grad_norm=0.1,
output_dir="outputs",
)
初始化训练器
trainer = GRPOTrainer(
model=model,
processing_class=tokenizer,
reward_funcs=[
xmlcount_reward_func,
soft_format_reward_func,
strict_format_reward_func,
int_reward_func,
correctness_reward_func,
],
args=training_args,
train_dataset=dataset,
)
模型训练与评估
启动训练
trainer.train()
模型测试
训练完成后,可以使用vLLM进行高效推理:
from vllm import SamplingParams
sampling_params = SamplingParams(
temperature=0.8,
top_p=0.95,
max_tokens=1024,
)
output = model.fast_generate(
prompt_text,
sampling_params=sampling_params,
lora_request=model.load_lora("grpo_saved_lora"),
)[0].outputs[0].text
模型保存与部署
保存模型权重
# 保存16位精度模型
model.save_pretrained_merged("model", tokenizer, save_method="merged_16bit")
导出为GGUF格式
model.push_to_hub_gguf(
"your-username/model-name",
tokenizer,
quantization_method=["q4_k_m", "q8_0", "q5_k_m"],
token="your-token",
)
总结与建议
通过本教程,我们完成了以下工作:
- 使用Unsloth高效加载和配置Gemma 3 1B模型
- 准备GSM8K数据集并设计合适的提示格式
- 实现多个奖励函数引导模型学习
- 配置GRPO训练参数并启动微调
- 评估模型性能并保存训练结果
训练建议:
- 初始阶段奖励可能不会立即提升,需要耐心等待150-200步
- 可以调整奖励函数的权重来平衡不同优化目标
- 对于复杂任务,可以增加训练步数和批次大小
这种结合Unsloth和GRPO的方法特别适合资源有限但需要高质量微调的场景,为开发者提供了强大的工具来定制语言模型行为。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



