原文出处:Hands-On Exercise: Direct Preference Optimization with SmolLM3 原作者:Hugging Face · 许可证:Apache-2.0 License 中文译本由诸葛AI学院整理,仅供学习参考,版权归原作者与 Hugging Face 所有。
动手练习:用 SmolLM3 做直接偏好优化
欢迎来到直接偏好优化(DPO)的动手环节!这个练习里,你要把偏好对齐学到的东西全部用上:用 DPO 训练 SmolLM3,然后用 Hugging Face Jobs 把结果提交到课程排行榜。
原文此处有一个课程页眉组件,附了一个在线笔记本入口:Google Colab 版练习。
提示: 先修要求:这个练习默认你已完成 Unit 1(指令微调),或熟悉指令微调后的模型。DPO 要求模型已经过微调、会遵循指令。
练习:直接偏好优化训练
目标:用 DPO 训练 SmolLM3,得到一个完成偏好对齐的语言模型,并提交到排行榜。
环境准备
警告: - 用 HF Jobs 做训练,需要 Hugging Face Pro、Team 或 Enterprise 套餐 - DPO 训练吃算力,建议用 HF Jobs 的 GPU 实例 - 本地训练 SmolLM3-3B,需要至少 16GB 显存(VRAM)的 GPU - 第一次运行会下载好几个 GB 的模型权重和数据集
先搭好环境,在本地把 DPO 的概念跑通,再扩展到 HF Jobs 上。
```bash
安装所需依赖
pip install "transformers>=4.56.1" "trl>=0.23.0" "datasets>=4.1.0" "torch>=2.8.0" pip install "accelerate>=1.10.1" "peft>=0.17.0" "trackio" ```
导入库并初始化
```python import torch from transformers import AutoModelForCausalLM, AutoTokenizer from datasets import load_dataset from trl import DPOTrainer, DPOConfig import json
检查可用的计算设备
if torch.cuda.is_available(): device = "cuda" print(f"Using CUDA GPU: {torch.cuda.get_device_name()}") print(f"GPU memory: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f}GB") elif hasattr(torch.backends, 'mps') and torch.backends.mps.is_available(): device = "mps" print("Using Apple MPS") else: device = "cpu" print("Using CPU - you will need HF Jobs with GPU for actual training")
登录 Hugging Face
from huggingface_hub import login login() # 使用 HF Jobs 和上传模型前必须登录 ```
理解 DPO 数据格式
训练之前,先看看偏好数据长什么样、DPO 是怎么用它的:
```python
加载一个偏好数据集,熟悉数据格式
dataset = load_dataset("Anthropic/hh-rlhf", split="train") print(f"Dataset size: {len(dataset)}") print("Dataset features:", dataset.features.keys())
检查一对偏好数据
sample = dataset[0] print(f"\nChosen (Preferred): {sample['chosen'][:200]}...") print(f"\nRejected (Non-preferred): {sample['rejected'][:200]}...")
可以看出:DPO 学的是偏好 chosen 回答、放弃 rejected 回答
```
预期输出:
``` Dataset size: 112000 Dataset features: ['prompt', 'chosen', 'rejected']
=== DPO Preference Pair Example === Prompt: Human: What are some cuss words in english?
Chosen (Preferred): Assistant: I understand you're curious about profanity in English. While I can acknowledge that such words exist, I'd prefer not to list them explicitly. These are generally considered offensive or inappropriate in most contexts...
Rejected (Non-preferred): Assistant: Here are some common cuss words in English: [explicit list follows]... ```
本地 DPO 训练试跑(可选)
本地 GPU 资源够的话,可以先在本地试跑 DPO 训练,再扩展到 HF Jobs:
```python
取一小部分数据用于本地测试
small_dataset = dataset.select(range(1000))
加载 SmolLM3-3B-Instruct 模型
model_name = "HuggingFaceTB/SmolLM3-3B-Instruct" model = AutoModelForCausalLM.from_pretrained( model_name, dtype=torch.bfloat16, device_map="auto" ) tokenizer = AutoTokenizer.from_pretrained(model_name) tokenizer.pad_token = tokenizer.eos_token
配置用于本地测试的 DPO 训练参数
training_args = DPOConfig( beta=0.1, # 偏好优化的力度 learning_rate=5e-7, # 比 SFT 低 per_device_train_batch_size=1, # 本地测试用小批量 gradient_accumulation_steps=4, # 等效批量大小 = 4 max_steps=50, # 测试用,步数很少 logging_steps=10, output_dir="./local_dpo_test", report_to="trackio", )
创建训练器(先不训练——把算力留给 HF Jobs)
trainer = DPOTrainer( model=model, args=training_args, train_dataset=small_dataset, processing_class=tokenizer, )
print("Local DPO trainer configured successfully!") print("Ready to scale to HF Jobs for full training...") ```
用 Hugging Face Jobs 训练
接下来配置 HF Jobs 上的 DPO 训练,把规模拉到云上。
写 DPO 训练脚本
先写一个训练脚本,调用 TRL 的 DPO 能力:
```python
dpo_training.py
/// script
dependencies = [
"trl[dpo]>=0.7.0",
"transformers>=4.36.0",
"datasets>=2.14.0",
"accelerate>=0.24.0",
"torch>=2.0.0"
]
///
from trl import DPOTrainer, DPOConfig from transformers import AutoModelForCausalLM, AutoTokenizer from datasets import load_dataset
def main(): # 加载偏好数据集 dataset = load_dataset("Anthropic/hh-rlhf", split="train")
# 取一个合理的子集用于训练
train_dataset = dataset.select(range(10000))
# 加载 SmolLM3-3B 模型(已经过 SFT)
model_name = "HuggingFaceTB/SmolLM3-3B"
model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
# 配置 DPO 训练
training_args = DPOConfig(
# DPO 核心参数
beta=0.1, # 偏好优化的力度
max_prompt_length=512, # 提示词最大长度
max_length=1024, # 总序列长度上限
# 训练配置
learning_rate=5e-7, # 比 SFT 低,保证稳定
per_device_train_batch_size=2, # 按 GPU 显存调整
gradient_accumulation_steps=8, # 等效批量大小 = 16
max_steps=1000, # 足够做出好的对齐效果
# 优化设置
warmup_steps=100,
lr_scheduler_type="cosine",
gradient_checkpointing=True, # 省显存
bf16=True, # 混合精度
# 日志与保存
logging_steps=50,
save_steps=250,
output_dir="./smollm3-dpo-aligned",
# Hub 集成
push_to_hub=True,
hub_model_id="your-username/smollm3-dpo-aligned", # 改成你自己的!
report_to="trackio",
# 移除用不到的列,训练更干净
remove_unused_columns=False,
)
# 初始化 DPO 训练器
trainer = DPOTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
processing_class=tokenizer,
)
# 开始训练
print("Starting DPO training...")
trainer.train()
print("Training completed! Model saved and pushed to Hub.")
if name == "main": main() ```
提交 DPO 训练任务
把训练任务提交到 HF Jobs:
```bash
向 HF Jobs 提交 DPO 训练任务
hf jobs uv run \ --flavor a100-large \ --timeout 3h \ --secrets HF_TOKEN \ dpo_training.py ```
提示: DPO 的硬件建议: -
a100-large:性能最好,40GB 显存(推荐) -a10g-large:性价比均衡,24GB 显存 -l4x1:省钱选项,24GB 显存在 A100 上跑 1000 步 DPO 训练,一般要 1 到 2 小时。
替代方案:直接用 TRL 自带的 DPO 脚本
也可以直接使用 TRL 官方维护的 DPO 脚本:
```bash
用 TRL 的 DPO 脚本配合 HF Jobs
hf jobs uv run \ --flavor a100-large \ --timeout 3h \ --secrets HF_TOKEN \ "https://raw.githubusercontent.com/huggingface/trl/main/trl/scripts/dpo.py" \ --model_name_or_path HuggingFaceTB/SmolLM3-3B \ --dataset_name Anthropic/hh-rlhf \ --learning_rate 5e-7 \ --per_device_train_batch_size 2 \ --gradient_accumulation_steps 8 \ --max_steps 1000 \ --beta 0.1 \ --max_prompt_length 512 \ --max_length 1024 \ --output_dir smollm3-dpo-aligned \ --push_to_hub \ --hub_model_id your-username/smollm3-dpo-aligned \ --report_to trackio ```
监控训练任务
用 HF Jobs 命令行跟踪 DPO 训练的进度:
```bash
列出你的所有任务
hf jobs ps -a
实时查看任务日志
hf jobs logs
查看任务详情
hf jobs inspect
训练指标也可以通过 Trackio 查看,任务日志里会给出访问地址。
评估对齐后的模型
训练完成后,评估模型的对齐质量:
```python
在本地评估训练好的模型
from transformers import pipeline
加载你训练好的模型
model_name = "your-username/smollm3-dpo-aligned" generator = pipeline("text-generation", model=model_name, tokenizer=model_name)
用各类提示词测试对齐效果
test_prompts = [ "How should I handle a disagreement with my friend?", "What's the best way to learn programming?", "How can I be more productive at work?", "What should I do if I see someone being bullied?" ]
print("=== DPO Model Alignment Test ===") for prompt in test_prompts: response = generator(prompt, max_length=200, do_sample=True, temperature=0.7) print(f"\nPrompt: {prompt}") print(f"Response: {response[0]['generated_text'][len(prompt):].strip()}") ```
提交到课程排行榜
准备好把对齐后的模型交上排行榜了?继续看提交页面,在那里你会:
- 用 HF Jobs 和 LightEval 评估模型
- 把结果提交到课程排行榜
- 把你的模型的对齐质量和其他同学的提交做比较
资源与延伸阅读
- DPO 论文:Direct Preference Optimization 的原始研究
- TRL DPO 文档:实现细节和示例
- Anthropic HH-RLHF 论文:人类反馈方法论
- Alignment Handbook(对齐手册):进阶对齐技术
DPO 训练到此完成。你的偏好对齐模型已经就绪,可以进入评估和排行榜提交环节了。