Skip to content

DPO / KTO Dataset Engineering: The Engineering of Chosen/Rejected Triplet Generation

DPO and KTO need 'chosen' (good) and 'rejected' (bad) response pairs. Generation methods: AI Feedback Loop (RLAIF), regex-graded pairs (math/code), human-in-the-loop, hard-negative mining, length-controlled pairs. UltraFeedback analysis, TR DPO dataset build, KTO's unpaired advantage.

Şükrü Yusuf KAYA
30 min read
Advanced
DPO / KTO Dataset Engineering: Chosen/Rejected Triplet Üretiminin Mühendisliği
🎯 Bu derste
DPO/KTO matematiği Part XI'de — bu ders dataset hazırlığı. Aynı prompt için iki cevap: chosen (iyi) + rejected (kötü). Bu çifti kalitedinli üretmek alignment'ın en zor kısmı.

1. 5 Üretim Stratejisi#

StratejiKaliteMaliyetUse case
Human-annotateden yüksek$$$$en iyi (Anthropic HH-RLHF)
AI feedback (RLAIF)yüksek$$scalable
Regex-gradedyüksek (verifiable domain)$math, code
Length-controldüşük (proxy)$quick start
Hard-negative miningyüksek$$edge-case coverage
Cookbook'un kuralı: AI feedback (RLAIF) + verifiable regex karması.
python
# === RLAIF — AI Feedback ile chosen/rejected üretimi ===
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
 
# Generator (student) — 8B
gen_model = AutoModelForCausalLM.from_pretrained("...8B-Instruct", torch_dtype="bfloat16", device_map="cuda")
gen_tok = AutoTokenizer.from_pretrained("...8B-Instruct")
 
# Judge (teacher) — 70B veya cloud API
# Cookbook'un kuralı: judge ≠ generator (yoksa self-bias)
def judge(prompt, response_a, response_b, judge_model="...-70B-Instruct"):
judge_prompt = f"""İki cevabı karşılaştır. Hangisi daha iyi cevap?
 
Soru: {prompt}
 
Cevap A: {response_a}
 
Cevap B: {response_b}
 
Daha iyi cevap (A veya B):"""
# Judge ile generate
out = run_judge(judge_prompt)
return "A" if "A" in out[:5] else "B"
 
# Her prompt için 2 cevap üret, judge'la sırala
preference_pairs = []
for prompt in prompts:
# 2 ayrı temperature/seed ile generate
resp_a = generate(prompt, temperature=0.7, seed=42)
resp_b = generate(prompt, temperature=0.9, seed=43)
 
winner = judge(prompt, resp_a, resp_b)
chosen, rejected = (resp_a, resp_b) if winner == "A" else (resp_b, resp_a)
 
preference_pairs.append({
"prompt": prompt,
"chosen": chosen,
"rejected": rejected,
})
RLAIF preference pair generation

2. Regex-Graded Pairs (Verifiable Domain)#

Math, code, structured output için objective grading:
def grade_math(question, response): """Math problem'ın doğru cevabını regex ile yakala.""" correct = solve_math(question) # SymPy ile match = re.search(r"sonu(c|ç).*?(\\d+)", response, re.I) if match and int(match.group(2)) == correct: return "correct" return "incorrect" # Aynı prompt'a N farklı temperature ile cevap üret, birini chosen birini rejected correct_responses = [] incorrect_responses = [] for _ in range(5): r = generate(question, temperature=0.7) if grade_math(question, r) == "correct": correct_responses.append(r) else: incorrect_responses.append(r) if correct_responses and incorrect_responses: pair = {"prompt": question, "chosen": correct_responses[0], "rejected": incorrect_responses[0]}

3. Length Bias Trap#

DPO modelleri uzun cevap = daha iyi cevap ezberlemeye eğilimli (UltraFeedback bias).
Çözümler:
  • Length-controlled DPO: chosen ve rejected'i benzer uzunlukta seç
  • Length-aware reward: judge'a "uzunluk dikkate alma" instruction'ı
def filter_length_control(pair, max_ratio=1.5): """Chosen / rejected uzunluk oranı 1.5x'i geçmesin.""" l_c, l_r = len(pair["chosen"]), len(pair["rejected"]) if max(l_c, l_r) / min(l_c, l_r) > max_ratio: return None return pair balanced = [p for p in pairs if filter_length_control(p)]

4. KTO — Tek-Yönlü Preference#

KTO (Kahneman-Tversky Optimization, Ethayarajh et al. 2024): pair gerek değil, sadece "iyi" veya "kötü" label.
{ "prompt": "Ankara'nın nüfusu nedir?", "completion": "Yaklaşık 5.6 milyon (2024).", "label": true // veya false }
KTO avantajı: Production'da çok daha kolay toplanır — sadece thumbs-up/down. Pair üretmek yerine sigle-label.
Cookbook'un kuralı: Production deploy'dan thumbs-up/down feedback topla → KTO ile periodically retrain.
🐛 FMD — 'DPO eğittim ama model artık eski capability'yi kaybetti'
Hipotez: DPO çok agresif (β düşük) → reference model'den çok uzaklaştı. Çözüm: β = 0.1-0.3 sweet spot. Ayrıca SFT mix DPO'ya ekle (RPO/CPO yöntemleri). Drill: β=0.05, 0.1, 0.3, 1.0 sweep ve baseline benchmark karşılaştır.
✅ Part II tamamlandı
  1. 1000 prompt için RLAIF ile preference pair üret. 2) Length-control filter ile dengele. 3) Sonraki Part: Part III — Small Open Models (1B-8B) Reçeteleri. Llama 3.x, Qwen, Mistral, Gemma 3, Phi-4, SmolLM, DeepSeek-R1-Distill — her biri RTX 4090'da QLoRA reçetesiyle.

Yorumlar & Soru-Cevap

(0)
Yorum yazmak için giriş yap.
Yorumlar yükleniyor...

Related Content