179 lines
6.8 KiB
Markdown
179 lines
6.8 KiB
Markdown
# Preference Optimization 조사 보고서
|
||
|
||
**작성일:** 2026-02-26
|
||
**목적:** SFT 이후 반복 퇴화(repetition degeneration) 해결을 위한 Preference Optimization 방법론 조사
|
||
|
||
---
|
||
|
||
## 1. 현재 환경
|
||
|
||
| 패키지 | 버전 | 비고 |
|
||
|---------|------|------|
|
||
| transformers | 5.2.0 | ✅ 설치됨 |
|
||
| accelerate | - | 확인 필요 |
|
||
| peft | - | 확인 필요 |
|
||
| **trl** | **미설치** | ⚠️ `pip install trl` 필요 |
|
||
|
||
**인프라:** 8× B200 183GB
|
||
**모델:** 커스텀 1B 파라미터 (Llama 계열 아키텍처, FP8 지원)
|
||
**최신 체크포인트:**
|
||
- Pretrain: `checkpoints/korean_1b_fp8_run1/checkpoint-0034000`
|
||
- SFT: `checkpoints/korean_1b_sft/` (최종 체크포인트는 log 확인 필요)
|
||
|
||
**HF 변환:** `scripts/convert_to_hf.py` 존재 ✅ — LlamaForCausalLM 포맷으로 변환 가능
|
||
|
||
---
|
||
|
||
## 2. ORPO vs DPO vs SimPO 비교
|
||
|
||
### ORPO (Odds Ratio Preference Optimization)
|
||
- **논문:** Hong et al. 2024 (arXiv:2403.07691)
|
||
- **Reference model:** 불필요 ✅
|
||
- **핵심 아이디어:** SFT loss + odds ratio 기반 preference loss를 단일 모델로 동시 학습
|
||
- **메모리:** SFT와 동일 (1× 모델만 필요)
|
||
- **1B 모델 적용:** 8× B200에서 매우 여유 (단일 GPU로도 가능)
|
||
- **구현:** TRL `ORPOTrainer` (trl >= 0.8.0)
|
||
- **장점:** 가장 간단, 메모리 효율적, SFT+preference 한 번에
|
||
- **단점:** DPO 대비 안정성 검증 사례 적음
|
||
|
||
### DPO (Direct Preference Optimization)
|
||
- **논문:** Rafailov et al. 2023 (arXiv:2305.18290)
|
||
- **Reference model:** 필요 (frozen copy, 2× 메모리)
|
||
- **메모리:** 1B 모델 × 2 ≈ 4GB (BF16) — 여전히 여유
|
||
- **1B 모델 적용:** 문제없음
|
||
- **구현:** TRL `DPOTrainer`
|
||
- **장점:** 가장 잘 검증됨, 안정적, 논문/사례 풍부
|
||
- **단점:** reference model 관리 필요
|
||
|
||
### SimPO (Simple Preference Optimization)
|
||
- **논문:** Meng et al. 2024 (arXiv:2405.14734)
|
||
- **Reference model:** 불필요
|
||
- **핵심:** Length-normalized implicit reward, margin 기반
|
||
- **구현:** TRL에 별도 Trainer 없음 → DPOTrainer의 `loss_type="simpo"` 로 사용 가능 (trl >= 0.9.0)
|
||
- **장점:** ORPO보다 성능 우수하다는 보고, reference-free
|
||
- **단점:** 상대적으로 새로운 방법
|
||
|
||
### PPO (Proximal Policy Optimization) — 참고용
|
||
- Reward model 별도 학습 필요 → 복잡도 높음
|
||
- 1B 모델에는 과도한 오버헤드
|
||
- **추천하지 않음** (데이터/인프라 대비 비효율)
|
||
|
||
---
|
||
|
||
## 3. 추천: **ORPO → DPO 순서**
|
||
|
||
### 1순위: ORPO
|
||
- Reference model 없음 → 메모리/구현 최소
|
||
- SFT 체크포인트에서 바로 시작 가능
|
||
- 반복 퇴화용 preference 데이터 제작이 간단
|
||
|
||
### 2순위: DPO
|
||
- ORPO로 부족하면 DPO로 전환
|
||
- 1B 모델이라 reference model 부담 없음
|
||
- 더 안정적이고 검증된 방법
|
||
|
||
### 근거
|
||
1B 모델 + 8× B200 환경에서는 DPO의 2× 메모리도 문제없지만,
|
||
**구현 속도와 단순성** 면에서 ORPO가 먼저 시도할 가치가 있음.
|
||
|
||
---
|
||
|
||
## 4. 한국어 Preference 데이터셋
|
||
|
||
### ✅ 접근 가능 (DPO/ORPO 형식 호환)
|
||
|
||
| 데이터셋 | 형식 | Downloads | 적합도 |
|
||
|----------|------|-----------|--------|
|
||
| **kuotient/orca-math-korean-dpo-pairs** | `{system, question, chosen, rejected}` | 111 | ⭐⭐⭐ DPO/ORPO 즉시 사용 가능 |
|
||
| **ChuGyouk/argilla-distilabel-math-preference-dpo-korean** | DPO 형식 | 10 | ⭐⭐⭐ 수학 도메인 |
|
||
| **nayohan/preference-collection-ko-full** | `{response_A, response_B, orig_score_A, orig_score_B, orig_preference}` | 30 | ⭐⭐⭐ 변환 필요하지만 풍부 |
|
||
|
||
### ✅ 접근 가능 (SFT 형식, preference 변환 필요)
|
||
|
||
| 데이터셋 | 형식 | Downloads |
|
||
|----------|------|-----------|
|
||
| jojo0217/korean_rlhf_dataset | `{instruction, input, output}` | 54 |
|
||
| FreedomIntelligence/alpaca-gpt4-korean | SFT 형식 | 158 |
|
||
| nlpai-lab/kullm-v2 | SFT 형식 | 730 |
|
||
|
||
### ❌ 접근 불가
|
||
maywell/ko_Ultrafeedback, HAERAE-HUB/KoRA, heegyu/OpenOrca-ko, Bongseok/ko-DPO-v0.1 — 모두 404
|
||
|
||
### 💡 자체 Preference 데이터 생성 전략 (반복 퇴화 특화)
|
||
|
||
가장 효과적인 방법: **현재 모델의 반복 출력을 rejected로 활용**
|
||
|
||
```
|
||
{
|
||
"prompt": "서울의 유명한 관광지를 추천해주세요.",
|
||
"chosen": "서울의 대표적인 관광지로는 경복궁, 북촌한옥마을, 남산타워...",
|
||
"rejected": "서울의 관광지로는 경복궁이 있습니다. 경복궁이 있습니다. 경복궁이 있습니다..."
|
||
}
|
||
```
|
||
|
||
1. 현재 SFT 모델로 다양한 프롬프트에 대해 생성 (temperature 다양하게)
|
||
2. 반복이 발생한 응답 → rejected
|
||
3. 정상 응답 (또는 GPT-4로 생성) → chosen
|
||
4. 500~2000개만으로도 효과적
|
||
|
||
---
|
||
|
||
## 5. HF 변환
|
||
|
||
`scripts/convert_to_hf.py` 가 이미 존재하며 LlamaForCausalLM 포맷으로 변환:
|
||
- FP8 / BF16 체크포인트 모두 지원
|
||
- 출력: `config.json`, `model.safetensors`, `tokenizer.json` 등
|
||
|
||
**변환 명령:**
|
||
```bash
|
||
cd /PROJECT/0325120031_A/ghong/taketimes/llm-bang
|
||
python scripts/convert_to_hf.py \
|
||
--checkpoint checkpoints/korean_1b_sft/checkpoint-XXXXX \
|
||
--output outputs/hf_for_orpo \
|
||
--tokenizer tokenizer/korean_sp/tokenizer.json
|
||
```
|
||
|
||
변환 후 `AutoModelForCausalLM.from_pretrained("outputs/hf_for_orpo")` 로 로드 → TRL ORPOTrainer 사용 가능.
|
||
|
||
---
|
||
|
||
## 6. 반복 퇴화 해결에 ORPO가 효과적인 이유
|
||
|
||
### 메커니즘
|
||
ORPO의 odds ratio loss는 다음을 학습:
|
||
- **chosen 응답의 생성 확률 ↑** (정상적이고 다양한 응답)
|
||
- **rejected 응답의 생성 확률 ↓** (반복적인 응답)
|
||
|
||
반복 퇴화는 특정 토큰 시퀀스의 확률이 자기강화(self-reinforcing)되면서 발생.
|
||
ORPO는 이 패턴 자체를 직접적으로 페널티:
|
||
|
||
1. **반복 패턴 = rejected** → 모델이 반복 시퀀스에 높은 확률을 부여하는 것을 직접 억제
|
||
2. **다양한 정상 응답 = chosen** → 다양한 토큰 분포를 유도
|
||
3. **SFT loss와 동시 학습** → 일반 성능 유지하면서 반복 억제
|
||
|
||
### 왜 SFT만으로 부족한가
|
||
- SFT는 "좋은 응답을 따라하라"만 학습
|
||
- "나쁜 응답을 피하라"는 신호가 없음
|
||
- Preference optimization은 "이것은 하지 마라"를 명시적으로 학습
|
||
|
||
### 예상 효과
|
||
- 500~2000개의 반복-vs-정상 preference 쌍으로도 반복 퇴화 대폭 감소 가능
|
||
- repetition penalty 같은 디코딩 트릭보다 근본적 해결
|
||
- 일반 성능 저하 최소 (SFT loss가 함께 작용)
|
||
|
||
---
|
||
|
||
## 7. 실행 계획
|
||
|
||
```
|
||
1. TRL 설치: pip install trl --break-system-packages (또는 venv)
|
||
2. HF 변환: python scripts/convert_to_hf.py --checkpoint ... --output outputs/hf_for_orpo
|
||
3. Preference 데이터 준비:
|
||
a. kuotient/orca-math-korean-dpo-pairs 다운로드 (즉시 사용 가능)
|
||
b. 자체 반복 퇴화 데이터 생성 (eval/generate.py 활용)
|
||
4. ORPO 학습: python train/orpo.py (아래 스크립트)
|
||
5. 평가: 반복률 측정 + perplexity
|
||
```
|
||
|
||
ORPO 학습 스크립트: `train/orpo.py` 참조
|