首页 / 资料库 / Hugging Face · 小模型课

资料库13 分钟读完Apache-2.0DPO动手练习Hugging Face小模型课

动手练习:用 SmolLM3 做直接偏好优化

译自《Hands-On Exercise: Direct Preference Optimization with SmolLM3》 · 查看英文原文

原文出处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 --follow

查看任务详情

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()}") ```

提交到课程排行榜

准备好把对齐后的模型交上排行榜了?继续看提交页面,在那里你会:

  1. 用 HF Jobs 和 LightEval 评估模型
  2. 把结果提交到课程排行榜
  3. 把你的模型的对齐质量和其他同学的提交做比较

资源与延伸阅读

DPO 训练到此完成。你的偏好对齐模型已经就绪,可以进入评估和排行榜提交环节了。

这篇在讲什么,跟咱们的课怎么对?

资料库是大厂公开教材的中文译本,偏原理和工程做法。想看面向中小企业的白话版本,去入门课场景课