파운데이션 모델 엔지니어링

10.3 Direct Preference Optimization (DPO)

Direct Preference Optimization (DPO)은 별도의 scalar reward model을 학습하거나 online rollout을 수행하지 않고 응답 pair로 policy를 학습합니다 [1]. Loss가 간결하다고 데이터 파이프라인도 간결한 것은 아닙니다. DPO 실패의 상당수는 잘못된 pair, 불일치 template, 길이 효과, 고정되지 않은 reference model에서 생깁니다.


목적함수

동일한 prompt xx에 preferred response ywy_w와 rejected response yly_l이 있다고 합시다. Policy πθ\pi_\theta, frozen reference πref\pi_{\text{ref}}, temperature와 비슷한 계수 β\beta에 대해

LDPO=logσ(β[logπθ(ywx)πref(ywx)logπθ(ylx)πref(ylx)]).\mathcal{L}_{\text{DPO}} = -\log\sigma\left( \beta\left[ \log\frac{\pi_\theta(y_w\mid x)}{\pi_{\text{ref}}(y_w\mid x)}- \log\frac{\pi_\theta(y_l\mid x)}{\pi_{\text{ref}}(y_l\mid x)} \right] \right).

대괄호 안은 암묵적 reward margin (implicit reward margin) 입니다. DPO는 rejected completion에 비해 preferred completion의 policy-reference 상대 점수를 높입니다. β\beta는 reference에서의 이탈이 preference logit으로 바뀌는 강도를 조절하지만 실제 효과는 데이터·optimizer·log-probability 규약에 따라 달라지므로 β\beta sweep을 수행합니다.


Pair와 Split 계약

각 record에는 하나의 prompt, chosen response, rejected response, preference strength 또는 tie/skip 상태, annotator/rubric provenance, stable ID가 들어갑니다. Rendering 후 chosen과 rejected는 byte와 token이 같은 prompt context를 공유해야 합니다. 서로 무관한 high-score와 low-score 답을 합쳐 pair를 만들면 안 됩니다.

학습 전에 prompt/conversation/entity 클러스터 단위로 분할(cluster split) 합니다. 두 completion, 모든 annotation, paraphrase, synthetic sibling을 같은 split에 둡니다. Annotation 화면 위치를 무작위화하고 평가자 일치도, tie, abstention, length/verbosity 차이를 기록합니다. Public/private evaluation, rubric, semantic neighbor, teacher-generated variant를 격리합니다.


Tokenization과 Log-Probability 계약

정확한 tokenizer artifact와 apply_chat_template로 양쪽을 rendering합니다. System message, role order, BOS/EOS, prompt truncation, add_generation_prompt 정책이 같아야 합니다. Completion에 의도한 EOS를 포함하고 completion token에만 log probability를 계산합니다.

def render_pair(tokenizer, prompt_messages, chosen, rejected):
    def render(answer):
        messages = [*prompt_messages, {"role": "assistant", "content": answer}]
        return tokenizer.apply_chat_template(
            messages,
            tokenize=True,
            add_generation_prompt=False,
        )
    return render(chosen), render(rejected)

# Collator는 각 side에 input_ids, attention_mask,
# completion_mask, labels(completion 밖은 -100)를 만들어야 합니다.

Decoded delimiter를 검색하지 말고 token-level boundary를 테스트합니다. Padding은 attention_mask로 제외하고 prompt와 special token은 completion mask에서 제외합니다. Variable-length batch는 의도한 token에 대해서만 normalize해야 합니다.

Sequence log probability는 보통 completion token log probability의 합(sum) 이며 derivation의 sequence likelihood와 맞지만 response-length pressure를 만들 수 있습니다. 평균(mean) 은 목적함수를 바꾸므로 중립적인 수정이 아닙니다. Chosen/rejected length를 기록하고 합과 length-normalized diagnostic을 함께 보고, 데이터의 verbosity를 통제하고, serving 목표에 맞는 정책을 명시합니다.

Truncation은 pair-coupled입니다. 양쪽에 같은 prompt budget을 적용하고 assistant boundary를 보존하며 결정적 span이나 EOS가 잘린 pair는 제거하거나 표시합니다. 한쪽만 더 많은 prompt context를 보게 하면 안 됩니다.


Reference와 PEFT 의미론

정확한 reference checkpoint 해시, tokenizer hash, template hash, precision, log-probability 구현을 고정하고 기록합니다. “같은 model name”으로 다시 불러온 reference는 재현 가능한 식별자가 아닙니다.

PEFT에서는 reference가 adapter를 끈 base인지, 별도로 frozen한 adapter snapshot인지, cached reference log probability인지 정의합니다. 고정 batch에서 동등성을 검사합니다. Reference-free variant는 다른 목적함수이므로 이름과 평가를 구분합니다.


실행 계약과 관측

유효한 응답을 이미 생성하는 SFT checkpoint에서 시작합니다. Pair manifest, code/container, optimizer, completion token 기준 batch, precision, max length, gradient accumulation, β\beta, seed를 고정합니다. Model/adapter, optimizer, scheduler, scaler, RNG, sampler, data cursor를 저장합니다.

Loss 외에도 다음을 관측합니다.

  • chosen/rejected policy log probability
  • chosen/rejected reference log probability
  • implicit reward margin과 preference accuracy
  • reference KL proxy, entropy, response length, EOS·truncation 비율
  • paired uncertainty가 있는 held-out win rate
  • domain, base-retention, safety, refusal, format/tool, latency, cost slice

Chosen과 rejected log probability가 함께 붕괴하거나, KL/length가 선언한 범위를 벗어나거나, held-out preference가 정체되면서 retention이 회귀하거나, nonfinite가 반복되거나, critical slice가 실패하면 중단합니다. Paired baseline comparison과 rollback rehearsal 후 complete artifact bundle만 배포합니다.


Quizzes

Quiz 1: Chosen과 rejected가 동일하게 rendering된 prompt를 사용해야 하는 이유는 무엇인가요? DPO는 likelihood 차이를 preference 때문이라고 해석합니다. System text, truncation, template token이 다르면 다른 원인이 섞여 학습 margin이 response preference를 분리하지 못합니다.

Quiz 2: Completion log probability의 합을 평균으로 바꾸는 것이 단순한 길이 보정이 아닌 이유는 무엇인가요? Derivation은 sequence likelihood를 사용하며 그 log는 합입니다. 평균은 목적함수를 바꿉니다. 길이 편향을 진단하고 verbosity를 큐레이션하며 length와 quality를 함께 평가해야 합니다.

Quiz 3: DPO reference policy를 식별하려면 무엇을 고정해야 하나요? 정확한 checkpoint와 tokenizer/template hash, precision, adapter 활성 상태 또는 cached log-prob artifact, log-probability 구현을 고정하고 검증해야 합니다.

Quiz 4: DPO loss가 내려가는데 모델이 나빠질 수 있는 이유는 무엇인가요? Length/style confound를 이용하거나, 양쪽 답 likelihood를 함께 낮추거나, reference에서 너무 멀어지거나, annotator bias를 overfit할 수 있습니다. Held-out win, margin, KL, length, retention, safety, format slice로 이를 발견합니다.


References

  1. Rafailov, R., et al. (2023). Direct Preference Optimization: Your Language Model is Secretly a Reward Model. arXiv:2305.18290.
  2. Hugging Face. DPO Trainer. TRL documentation.