Supervised Fine-Tuning(SFT)과 Direct Preference Optimization(DPO), RLHF(Reinforcement Learning from Human Feedback) 비교
Supervised Fine-Tuning(SFT) Direct Preference Optimization(DPO), RLHF(Reinforcement Learning from Human Feedback) 비교
SFT, DPO, RLHF 비교: 목적과 개념
구분SFT (Supervised Fine-Tuning)DPO (Direct Preference Optimization)RLHF (Reinforcement Learning from Human Feedback)
| 구분 | SFT | DPO | RLHF |
|---|---|---|---|
| 목적 | 명확한 정답(task/문제)에 맞춘 1차 파인튜닝 | 인간 선호에 직접 맞추는 미세조정 | 인간 피드백을 바탕으로 RL로 정책(=모델) 미세조정 |
| 핵심 아이디어 | 정해진 레이블(정답) 데이터로 지도학습 | "좋은/나쁜" 선택 쌍 기반, 선호응답 확률 ↑ | 인간 랭킹/선호 → 보상모델 △ → RL(PPO 등)로 미세조정 |
| 주요 활용 | Q&A, 요약, 코드 생성 등 | human alignment, 답변 품질/안전성 등 | ChatGPT, Claude 등 상용 LLM alignment |
| 장점 | 품질, 형식의 통제 용이 | 구현 간편(보상모델 불필요)/학습 안정적 | 창의성, 안전성 등에서 강력/서비스급 튜닝 |
| 단점 | 주관적 선호 반영 한계 | (보상 기반 RL 대비) 극한의 fine-tuning 어려움 | 구현 복잡/데이터 구축 비용 높음/보상 해킹 가능 |
각 과정에서 사용하는 주요 소스 코드 구조 및 데이터 형태
1. Supervised Fine-Tuning (SFT)
데이터:
Prompt & 정답(Response) 쌍의 리스트
예:[ {"input": "기후변화란?", "output": "기후변화는 ..."}, {"input": "파이썬 리스트 예제", "output": "예: my_list = [1,2,3]"} ]
파이썬 기반 주요 코드 구조 예시
(Hugging Face Transformers 활용)python
from transformers import Trainer, TrainingArguments, AutoModelForCausalLM, AutoTokenizer
데이터셋 로딩 및 토크나이징
tokenizer = AutoTokenizer.from_pretrained('base-model')
def preprocess(example):
tokens = tokenizer(example['input'] + tokenizer.eos_token + example['output'], padding="max_length", truncation=True)
return tokens
Trainer를 통한 fine-tuning
model = AutoModelForCausalLM.from_pretrained('base-model')
training_args = TrainingArguments(output_dir="output", ...)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=processed_train_data,
eval_dataset=processed_eval_data,
)
trainer.train()
```2. Direct Preference Optimization (DPO)
데이터:
동일한 prompt에 대해 좋은(good), 나쁜(bad) 응답 쌍으로 구성
예:json
[ { "prompt": "고양이와 강아지 차이?", "chosen": "고양이는 독립적, 강아지는 ...", "rejected": "저는 잘 모르겠네요." } ]
주요 코드 뼈대:
- DPO Loss는 CrossEntropy 느낌의 logit ratio 방식
- 공개 라이브러리: trl (https://github.com/huggingface/trl/tree/main/examples/research_projects/dpo)
python
# 의사코드, 실제 사용시 dpo loss 구현 필요 from trl import DPOTrainer
model = AutoModelForCausalLM.from_pretrained('sft-checkpoint')
tokenizer = AutoTokenizer.from_pretrained('sft-checkpoint')
DPOTrainer에서 학습 (데이터: prompt, chosen, rejected)
trainer = DPOTrainer(
model=model,
args=TrainingArguments(output_dir="output", ...),
train_dataset=paired_preference_data,
eval_dataset=paired_preference_data_eval,
tokenizer=tokenizer
)
trainer.train()
```3. RLHF (Reward Model + RL(PPO 등))
데이터:
① SFT와 동일: prompt–정답 쌍
② 인간 피드백: 동일 prompt 여러 답변(A, B 등) → 랭킹/선호 표시
예:json
[ { "prompt": "기후변화 원인?", "responses": ["기후변화는 ...", "기후변화는 대기오염..."], "ranking": [0, 1] // 0이 더 선호됨 } ]
주요 코드 뼈대:
- 보상모델 학습
python
# RM은 보통 LLM의 마지막 레이어(head)를 회귀로 수정 model = RewardModel(...) reward_trainer = Trainer(model=..., ...) reward_trainer.train()- 정책(PPO 등) 미세조정
python
from trl import PPOTrainer
ppo_trainer = PPOTrainer(
model=policy_model,
ref_model=ref_model, # SFT로 학습됨
reward_model=trained_rm,
...
)
ppo_trainer.train()
```
정리
- 요약:
- SFT: task 정답 데이터 → CrossEntropy 학습
- DPO: (좋은, 나쁜) 쌍 데이터 → logit ratio 기반 loss, 보상모델 없이
- RLHF: 인간 피드백 랭킹 → 보상모델(RM) → PPO 등 RL로 Policy fine-tuning
- 소스와 데이터:
- Hugging Face transformers, trl, OpenAI baselines, DeepSpeed 등 다양한 프레임워크에서 코드가 공개되어 있음.
- 데이터 형식은 SFT는 prompt-정답, DPO는 prompt+쌍, RLHF는 prompt+랭킹/점수.
- 실제 구현은 코드와 데이터 품질, trainer 세팅, 데이터 양에 크게 좌우됩니다.
실제 코드는 작업 환경, 프레임워크 변동에 따라 달라질 수 있으므로 공식 문서와 레포지토리(readme, 예제 코드)를 참고하여 적용하면 됩니다.