DPO
Direct Preference Optimization
보상 모델 없이 직접 선호도를 최적화하는 학습 방법. RLHF의 단순화 버전.
Direct Preference Optimization
보상 모델 없이 직접 선호도를 최적화하는 학습 방법. RLHF의 단순화 버전.
DPO(Direct Preference Optimization)는 대규모 언어 모델(LLM)을 인간의 선호도에 맞게 정렬(align)하는 학습 방법입니다. 기존 RLHF(Reinforcement Learning from Human Feedback)의 복잡한 파이프라인을 단순화하여, 별도의 보상 모델(Reward Model) 없이 직접 선호도 데이터로 모델을 최적화합니다.
2023년 Stanford 연구팀(Rafael Rafailov 등)이 발표한 DPO는 "Your Language Model is Secretly a Reward Model"이라는 논문에서 소개되었습니다. RLHF의 수학적 목적 함수를 재정의하여, 강화학습 없이도 동일한 최적해를 찾을 수 있음을 증명했습니다.
DPO는 선호 데이터셋(prompt, chosen, rejected)을 사용합니다. 각 프롬프트에 대해 선호되는 응답(chosen)과 선호되지 않는 응답(rejected)의 로그 확률 차이를 최대화하는 방향으로 학습합니다. 이 과정에서 reference 모델과의 KL divergence를 통해 원래 모델에서 너무 멀어지지 않도록 제약합니다.
실무에서 DPO는 RLHF 대비 학습이 안정적이고, 하이퍼파라미터 튜닝이 적으며, 컴퓨팅 비용이 낮습니다. Llama 2, Zephyr, Mistral 등 최신 오픈소스 LLM의 alignment에 널리 사용되며, HuggingFace TRL 라이브러리로 쉽게 구현할 수 있습니다.
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOTrainer, DPOConfig
from datasets import load_dataset
# 모델 및 토크나이저 로드
model_name = "meta-llama/Llama-2-7b-hf"
model = AutoModelForCausalLM.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.pad_token = tokenizer.eos_token
# Reference 모델 (학습 중 고정)
ref_model = AutoModelForCausalLM.from_pretrained(model_name)
# DPO 데이터셋 로드 (prompt, chosen, rejected 컬럼 필요)
dataset = load_dataset("Anthropic/hh-rlhf", split="train[:1000]")
# DPO 학습 설정
training_args = DPOConfig(
output_dir="./dpo-llama",
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=5e-7, # DPO는 낮은 lr 권장
beta=0.1, # KL penalty 강도 (핵심 하이퍼파라미터)
max_length=512,
max_prompt_length=256,
num_train_epochs=1,
logging_steps=10,
bf16=True,
)
# DPO Trainer 초기화 및 학습
trainer = DPOTrainer(
model=model,
ref_model=ref_model,
args=training_args,
train_dataset=dataset,
tokenizer=tokenizer,
)
trainer.train()
trainer.save_model("./dpo-llama-final")
"이번 LLM alignment는 DPO로 진행하죠. RLHF보다 구현이 간단하고, PPO 학습의 불안정성 문제도 없습니다. 선호 데이터만 잘 구축하면 됩니다."
"DPO는 RLHF의 reward model과 RL 학습을 하나의 supervised loss로 통합한 방법입니다. beta 파라미터로 KL divergence 페널티를 조절하는데, 보통 0.1~0.5 사이에서 시작합니다."
"DPO가 간단하긴 한데, 선호 데이터의 품질에 민감해요. 노이즈 레이블이 많으면 성능이 급격히 떨어지니까, 데이터 필터링에 공을 들여야 합니다. 최근엔 IPO나 cDPO 같은 변형도 나왔어요."
Base 모델에 바로 DPO를 적용하면 성능이 저하됩니다. 먼저 SFT(Supervised Fine-Tuning)로 기본 응답 형식을 학습시킨 후 DPO를 적용하세요.
DPO는 일반 fine-tuning보다 훨씬 낮은 lr(1e-7 ~ 5e-6)을 사용해야 합니다. 높은 lr은 모델 붕괴(collapse)를 유발합니다.
SFT → DPO 순서로 진행하고, beta는 0.1에서 시작하여 조정하세요. Reference 모델은 SFT 체크포인트를 사용하고, 선호 데이터는 최소 1만 개 이상 확보하세요.