HuggingFace课程实战:使用GRPO方法微调语言模型
course The Hugging Face course on Transformers 项目地址: https://gitcode.com/gh_mirrors/cou/course
前言
在自然语言处理领域,模型微调是提升预训练模型性能的关键技术。本文将基于HuggingFace课程内容,详细介绍如何使用GRPO(一种强化学习优化方法)来微调语言模型。通过本教程,您将掌握从环境配置到模型部署的完整流程。
环境准备
在开始之前,我们需要安装必要的依赖库:
pip install datasets transformers trl peft accelerate bitsandbytes wandb
pip install flash-attn --no-build-isolation
这些库包括:
datasets
:用于加载和处理数据集transformers
:HuggingFace的核心NLP库trl
:包含GRPO等强化学习训练方法peft
:参数高效微调工具accelerate
:分布式训练支持bitsandbytes
:量化工具wandb
:实验跟踪工具flash-attn
:高效的注意力机制实现
实验监控设置
为了更好跟踪训练过程,我们使用Weights & Biases(WandB)进行实验记录:
import wandb
wandb.login()
WandB提供了训练过程可视化、超参数记录和结果比较等功能,是机器学习实验管理的重要工具。
数据集加载
我们使用mlabonne/smoltldr
数据集,这是一个包含短篇故事的集合:
from datasets import load_dataset
dataset = load_dataset("mlabonne/smoltldr")
在实际应用中,您可以根据需求替换为任何文本数据集,确保数据格式符合模型输入要求。
模型选择与加载
考虑到硬件限制,我们选择SmolLM2-135M
模型,这是一个135M参数的小型语言模型:
from transformers import AutoModelForCausalLM, AutoTokenizer
model_id = "HuggingFaceTB/SmolLM-135M-Instruct"
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype="auto",
device_map="auto",
attn_implementation="flash_attention_2"
)
tokenizer = AutoTokenizer.from_pretrained(model_id)
关键参数说明:
torch_dtype="auto"
:自动选择最佳数据类型device_map="auto"
:自动分配设备attn_implementation="flash_attention_2"
:使用高效的注意力实现
参数高效微调(LoRA)
为了减少训练参数和内存占用,我们采用LoRA(Low-Rank Adaptation)技术:
from peft import LoraConfig, get_peft_model
lora_config = LoraConfig(
task_type="CAUSAL_LM",
r=16, # 低秩矩阵的秩
lora_alpha=32, # 缩放因子
target_modules="all-linear" # 应用于所有线性层
)
model = get_peft_model(model, lora_config)
LoRA通过引入低秩矩阵来调整模型权重,显著减少了可训练参数数量(本例中约为135M),同时保持模型性能。
奖励函数设计
GRPO方法需要定义奖励函数来指导模型优化。我们设计一个简单的长度奖励函数:
ideal_length = 50
def reward_len(completions, **kwargs):
return [-abs(ideal_length - len(completion)) for completion in completions]
这个函数鼓励模型生成接近50个token的文本。在实际应用中,您可以设计更复杂的奖励函数,如基于语法正确性、内容相关性等指标。
训练参数配置
使用GRPOConfig配置训练参数:
from trl import GRPOConfig
training_args = GRPOConfig(
output_dir="GRPO",
learning_rate=2e-5,
per_device_train_batch_size=8,
gradient_accumulation_steps=2,
max_prompt_length=512,
max_completion_length=96,
num_generations=8,
optim="adamw_8bit",
num_train_epochs=1,
bf16=True,
report_to=["wandb"],
remove_unused_columns=False,
logging_steps=1,
)
关键参数解析:
adamw_8bit
:8位量化的AdamW优化器,减少内存使用bf16=True
:使用bfloat16精度训练num_generations=8
:每次生成8个候选文本进行评估
训练过程
初始化训练器并开始训练:
from trl import GRPOTrainer
trainer = GRPOTrainer(
model=model,
reward_funcs=[reward_len],
args=training_args,
train_dataset=dataset["train"],
)
trainer.train()
在A10G GPU上,训练大约需要1小时。训练过程中,WandB会记录奖励值和损失函数的变化。
结果分析与解释
训练过程中有两个关键指标需要关注:
-
奖励值:随着训练进行,奖励值应逐渐接近0,表明模型生成的文本长度越来越接近理想值。
-
损失值:GRPO的损失函数可能呈现先上升后稳定的趋势,这与KL散度的变化有关,是算法预期的行为模式。
模型保存与部署
训练完成后,我们可以合并LoRA适配器并保存模型:
merged_model = trainer.model.merge_and_unload()
merged_model.push_to_hub(
"SmolGRPO-135M",
private=False,
tags=["GRPO", "Reasoning-Course"]
)
文本生成测试
使用训练好的模型生成文本:
from transformers import pipeline
generator = pipeline("text-generation", model="SmolGRPO-135M")
generate_kwargs = {
"max_new_tokens": 256,
"do_sample": True,
"temperature": 0.5,
"min_p": 0.1,
}
prompt = "# A long document about the Cat\nThe cat (Felis catus)..."
generated_text = generator(prompt, generate_kwargs=generate_kwargs)
print(generated_text)
生成参数说明:
temperature
:控制生成多样性min_p
:核采样参数,过滤低概率token
总结
通过本教程,我们完成了以下工作:
- 配置了GRPO微调环境
- 加载并预处理了数据集
- 使用LoRA技术进行参数高效微调
- 设计并实现了奖励函数
- 配置和运行了GRPO训练过程
- 分析了训练结果并部署了模型
GRPO方法结合了强化学习的优势,通过自定义奖励函数可以灵活地引导模型学习特定行为。这种方法特别适用于需要精细控制生成文本特性的应用场景。
对于希望进一步探索的读者,可以考虑:
- 尝试不同的奖励函数设计
- 调整LoRA参数观察对模型性能的影响
- 在更大规模的数据集和模型上实验GRPO方法
course The Hugging Face course on Transformers 项目地址: https://gitcode.com/gh_mirrors/cou/course
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考