الدرس 19 من 24

المحاذاة مع DPO

DPOTrainer عملياً

3 دقيقة للقراءة

لننفذ تدريب DPO باستخدام DPOTrainer من TRL. سنمر على سكريبت تدريب كامل.

تدريب DPO الأساسي

from unsloth import FastLanguageModel
from trl import DPOTrainer, DPOConfig
from datasets import load_dataset

# ============================================
# 1. تحميل النموذج
# ============================================
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/Llama-3.2-3B-Instruct",
    max_seq_length=2048,
    load_in_4bit=True,
)

# أضف LoRA
model = FastLanguageModel.get_peft_model(
    model,
    r=16,
    lora_alpha=16,
    lora_dropout=0,
    target_modules=[
        "q_proj", "k_proj", "v_proj", "o_proj",
        "gate_proj", "up_proj", "down_proj"
    ],
    bias="none",
    use_gradient_checkpointing="unsloth",
)

# ============================================
# 2. تحميل مجموعة البيانات
# ============================================
dataset = load_dataset("HuggingFaceH4/ultrafeedback_binarized", split="train_prefs")
dataset = dataset.select(range(1000))  # مجموعة فرعية للاختبار

# ============================================
# 3. تكوين DPO
# ============================================
dpo_config = DPOConfig(
    output_dir="./outputs/dpo-model",
    beta=0.1,                              # معامل عقوبة KL
    learning_rate=5e-6,                    # أقل من SFT
    per_device_train_batch_size=2,
    gradient_accumulation_steps=4,
    num_train_epochs=1,
    warmup_ratio=0.1,
    logging_steps=10,
    save_steps=500,
    bf16=True,
    optim="adamw_8bit",
    max_length=1024,
    max_prompt_length=512,
)

# ============================================
# 4. تهيئة المدرّب
# ============================================
trainer = DPOTrainer(
    model=model,
    args=dpo_config,
    train_dataset=dataset,
    processing_class=tokenizer,
)

# ============================================
# 5. درّب
# ============================================
trainer.train()

# ============================================
# 6. احفظ
# ============================================
trainer.save_model("./outputs/dpo-model/final")

معاملات DPO الرئيسية

بيتا (β)

تتحكم في مقدار انحراف النموذج عن المرجع:

# محافظ (ابق قريباً من المرجع)
beta = 0.05

# متوازن (افتراضي)
beta = 0.1

# عدواني (انحراف أكثر مسموح)
beta = 0.5

معدل التعلم

DPO عادة يستخدم معدلات تعلم أقل من SFT:

# معدل تعلم SFT
sft_lr = 2e-4

# معدل تعلم DPO (10-100x أقل)
dpo_lr = 5e-6  # إلى 5e-7

الأطوال القصوى

# الطول الأقصى الكلي للمختار/المرفوض
max_length = 1024

# الطول الأقصى لجزء المحث
max_prompt_length = 512

التكوين المتقدم

dpo_config = DPOConfig(
    output_dir="./outputs/dpo-advanced",

    # خاص بـ DPO
    beta=0.1,
    loss_type="sigmoid",  # أو "hinge"، "ipo"

    # التدريب
    learning_rate=5e-6,
    per_device_train_batch_size=2,
    gradient_accumulation_steps=4,
    num_train_epochs=1,

    # الأطوال
    max_length=1024,
    max_prompt_length=512,
    truncation_mode="keep_start",

    # التحسين
    warmup_ratio=0.1,
    lr_scheduler_type="cosine",
    weight_decay=0.01,
    optim="adamw_8bit",
    bf16=True,

    # التسجيل
    logging_steps=10,
    eval_strategy="steps",
    eval_steps=100,
    save_steps=500,

    # التنظيم
    max_grad_norm=1.0,
)

أنواع الخسارة

DPO يدعم دوال خسارة مختلفة:

# خسارة sigmoid القياسية (افتراضي)
loss_type = "sigmoid"

# خسارة hinge
loss_type = "hinge"

# IPO (Identity Preference Optimization)
loss_type = "ipo"

مع نموذج مرجعي

لـ DPO صحيح، تحتاج نموذج مرجعي (نسخة مجمدة من نموذج SFT):

from trl import DPOTrainer, DPOConfig
from peft import PeftModel

# حمّل نموذج SFT كمرجع (مجمد)
ref_model = AutoModelForCausalLM.from_pretrained(
    "path/to/sft-model",
    torch_dtype=torch.bfloat16,
    device_map="auto"
)

# حمّل النموذج للتدريب
model = AutoModelForCausalLM.from_pretrained(
    "path/to/sft-model",
    torch_dtype=torch.bfloat16,
    device_map="auto"
)
model = get_peft_model(model, lora_config)

trainer = DPOTrainer(
    model=model,
    ref_model=ref_model,  # مرجع مجمد
    args=dpo_config,
    train_dataset=dataset,
    processing_class=tokenizer,
)

مراقبة التدريب

المقاييس الرئيسية

# سجلات التدريب ستُظهر:
# - loss: خسارة DPO (يجب أن تتناقص)
# - rewards/chosen: مكافأة الاستجابات المختارة (يجب أن تزيد)
# - rewards/rejected: مكافأة الاستجابات المرفوضة (يجب أن تتناقص)
# - rewards/margins: المختار - المرفوض (يجب أن يزيد)

علامات التدريب الجيد

المقياس الاتجاه الجيد
loss متناقص
rewards/margins متزايد
rewards/chosen مستقر أو متزايد
rewards/rejected متناقص

علامات التدريب السيء

  • الخسارة تنفجر ← قلل معدل التعلم
  • الهوامش تصبح سالبة ← تحقق من جودة البيانات
  • لا تحسن ← زد beta أو epochs

مثال كامل مع التقييم

from unsloth import FastLanguageModel
from trl import DPOTrainer, DPOConfig
from datasets import load_dataset

# حمّل النموذج
model, tokenizer = FastLanguageModel.from_pretrained(
    "unsloth/Llama-3.2-3B-Instruct",
    max_seq_length=2048,
    load_in_4bit=True,
)

model = FastLanguageModel.get_peft_model(
    model,
    r=16,
    lora_alpha=16,
    target_modules="all-linear",
    use_gradient_checkpointing="unsloth",
)

# حمّل وقسّم مجموعة البيانات
dataset = load_dataset("HuggingFaceH4/ultrafeedback_binarized")
train_dataset = dataset["train_prefs"].select(range(5000))
eval_dataset = dataset["test_prefs"].select(range(500))

# كوّن
dpo_config = DPOConfig(
    output_dir="./outputs/dpo-eval",
    beta=0.1,
    learning_rate=5e-6,
    per_device_train_batch_size=2,
    per_device_eval_batch_size=2,
    gradient_accumulation_steps=4,
    num_train_epochs=1,
    eval_strategy="steps",
    eval_steps=200,
    logging_steps=20,
    bf16=True,
    optim="adamw_8bit",
)

# درّب مع التقييم
trainer = DPOTrainer(
    model=model,
    args=dpo_config,
    train_dataset=train_dataset,
    eval_dataset=eval_dataset,
    processing_class=tokenizer,
)

trainer.train()
trainer.save_model("./outputs/dpo-eval/final")

نصيحة: ابدأ بـ beta صغير (0.1) وزده إذا لم يتعلم النموذج التفضيلات جيداً. راقب هوامش المكافأة للتأكد أن النموذج يفضل فعلاً المختار على المرفوض.

بعد ذلك، لنتعلم كيفية دمج SFT و DPO لخط أنابيب تدريب كامل. :::

اختبار

الوحدة 5: المحاذاة مع DPO

خذ الاختبار