LLM 엔지니어링5장 · LoRA 파인튜닝과 DPO 정렬10 / 23← 이전목차다음 →MetaContents

5장. LoRA 파인튜닝과 DPO 정렬

선호 데이터

식당의 손님 의견 카드를 떠올려 보세요. "오늘의 요리 A 와 B 가운데 어느 쪽이 나았나요?"라고만 물으면 손님은 쉽게 답합니다. 맛을 점수로 매기라고 하면 사람마다 기준이 달라 어렵지만, 둘 중 하나를 고르는 것은 쉽고 일관됩니다. DPO 는 이런 "둘 중 고르기"를 모은 데이터로 배웁니다.

사람이 고르기, 규칙으로 만들기, 큰 모델에게 묻기의 세 가지 선호 데이터 만드는 길을 카드로 놓은 그림

선호 데이터를 만드는 길은 셋입니다. 사람이 두 답을 보고 고르는 방법이 가장 정확하지만 비쌉니다. 이 장의 데이터는 두 번째 길로, 정확하고 친절한 답을 고른 답으로, 정해진 흠(회피, 무뚝뚝, 두루뭉술)이 있는 답을 반대 답으로 만들었습니다. 큰 모델에게 심사를 맡기고 사람이 검토하는 방법도 많이 씁니다. 여기서 손님의 선택이 선호 데이터입니다.

DPO 라는 이름 풀기

DPO 는 Direct Preference Optimization 의 머리글자입니다. 우리말로는 "직접 선호 최적화"입니다.

글자영어뜻손님 의견 카드로
DDirect(직접)중간 단계를 거치지 않고 바로 한다. 아래의 보상 모델을 따로 만들지 않는다는 뜻이다카드를 점수로 바꾸지 않고 바로 반영한다
PPreference(선호)둘 가운데 더 마음에 드는 쪽. 선호 데이터의 "고른 답"이다손님이 고른 요리
OOptimization(최적화)어떤 값이 가장 좋아지도록 숫자를 고친다. 여기서는 DPO 손실을 줄인다다음 메뉴를 손님 입맛에 맞춘다

어디서 나왔나

DPO 가 나오기 전에는 4장에서 본 RLHF(Reinforcement Learning from Human Feedback, 사람 피드백을 받는 강화학습)가 정렬의 대표 방법이었습니다. 2022년 OpenAI 의 InstructGPT 가 이 방법으로 ChatGPT 의 바탕을 만들었습니다. RLHF 는 단계가 셋입니다. 사람의 선택으로 점수를 매기는 보상 모델(reward model)을 먼저 학습합니다. 그다음 그 점수가 높아지도록 PPO(Proximal Policy Optimization, 근접 정책 최적화)라는 강화학습으로 모델을 고칩니다. 이때 모델 여러 개를 함께 GPU 에 올려야 하고, 학습이 불안정해 설정을 맞추기 어렵습니다.

2023년 Stanford 대학의 연구진(Rafael Rafailov 등)이 논문 "Direct Preference Optimization: Your Language Model is Secretly a Reward Model" 을 냈습니다. 부제는 "언어모델이 사실은 보상 모델이다"라는 뜻입니다. 이 논문은 수식을 정리하면 보상 모델과 강화학습 없이 선호 쌍만으로 같은 목표를 학습할 수 있다는 것을 보였습니다. 그래서 이름에 "직접(Direct)"이 붙었습니다. 다루기 쉬워서 공개 모델의 정렬에 널리 쓰이게 되었습니다.

견줄 것RLHF(PPO)DPO
보상 모델따로 학습한다없다
학습 방법강화학습. 모델이 답을 만들어 보고 점수를 받는다보통의 지도 학습처럼 손실을 줄인다
GPU 에 올릴 모델학습 모델, 기준 모델, 보상 모델 등 여럿학습 모델과 기준 모델. LoRA 와 함께면 하나분
쓰는 데이터선호 데이터(보상 모델용)와 질문선호 데이터(prompt, chosen, rejected)

더 읽을 곳

무엇어디내용
원래 논문arXiv 2305.18290DPO 를 처음 낸 논문(영어)
trl 의 DPO 설명서huggingface.co/docs/trl이 장에서 쓰는 DPOTrainer 와 DPOConfig 의 설명서
이 교안4장 「정렬」정렬의 세 가지 방법과 RLHF 를 처음 소개한다
이 교안5장 「DPO 의 원리」, 5장 「DPO 지표 읽기」DPO 손실의 계산과 학습 기록 읽는 법

이 장의 선호 데이터: dpo_shop.jsonl

실습 5, 6에서 쓰는 선호 데이터는 data/dpo_shop.jsonl 입니다. tools/make_data.py 가 씨앗을 고정해 만든 연습용 가상 데이터이고, 크기는 24KB 쯤입니다.

항목내용
꼴JSON Lines. 한 줄에 선호 쌍 하나가 JSON 으로 들어 있다
줄 수72줄. 가상 쇼핑몰의 질문 의도 12가지(배송 기간, 교환, 환불 등)마다 6개
질문(prompt)4장의 sft_shop.jsonl 에서 학습용 질문만 가져왔다. 의도마다 시험용 질문 둘은 넣지 않아, 실습 6의 시험 질문 24개와 겹치지 않는다
고른 답(chosen)"안녕하세요, 고객님. (정확한 답) 감사합니다." 꼴. 답의 내용은 4장의 쇼핑몰 답과 같다
반대 답(rejected)흠이 있는 답 세 문장 가운데 하나를 씨앗으로 골랐다. 회피("저는 인공지능으로서…"), 무뚝뚝("직접 찾아보세요"), 두루뭉술("상황에 따라 다르기 때문에…")
의도질문의 종류. 학습에는 쓰지 않고 살펴볼 때만 쓴다

이 데이터는 사람이 고른 것이 아니라, 위의 세 길 가운데 두 번째인 "규칙으로 만들기"로 만들었습니다. 그래서 고른 답과 반대 답의 차이가 아주 뚜렷합니다. 모델이 DPO 로 무엇을 배우는지 눈으로 확인하기 좋도록 일부러 그렇게 만들었습니다. 파일을 다시 만드는 법과 열 설명은 실습 자료 쪽(data.md)에 있습니다.

한 줄의 생김새

열뜻dpo_shop.jsonl 의 예
prompt질문배송은 얼마나 걸리나요?
chosen고른 답안녕하세요, 고객님. 결제 후 1~3일 안에 도착합니다. … 감사합니다.
rejected반대 답그건 누리집에 다 나와 있어요. 직접 찾아보세요.

반대 답의 종류 세기

Python
import json
from collections import Counter

with open("dpo_shop.jsonl", encoding="utf-8") as f:
    pairs = [json.loads(line) for line in f]

print("쌍의 수:", len(pairs))
# 반대 답이 어떤 흠인지 앞 몇 글자로 묶어 센다
kinds = Counter(p["rejected"][:12] for p in pairs)
for text, n in kinds.most_common():
    print(n, text, "…")

72쌍의 반대 답은 세 가지 흠으로 나뉩니다. 앞 12글자로 묶으면 "상황에 따라 다르기 때"(두루뭉술) 27개, "그건 누리집에 다 나와"(무뚝뚝) 24개, "죄송합니다, 저는 인공"(회피) 21개입니다. 데이터를 학습에 쓰기 전에 이렇게 흠의 종류가 고루 섞였는지 봅니다.

코드에 나오는 함수

코드쉬운 뜻
open("dpo_shop.jsonl", encoding="utf-8")실습 자료 파일을 한글이 깨지지 않게 UTF-8 로 연다. jsonl 은 JSON Lines(한 줄에 JSON 하나)의 줄임말이다
json.loads(line)load string(글자에서 읽기)의 줄임말이다. JSON 꼴의 글 한 줄을 파이썬 사전으로 바꾼다
p["rejected"][:12]쌍 하나의 반대 답에서 앞 12글자만 잘라 낸다
Counter(...)collections 의 셈하는 도구다. 같은 값이 몇 번 나왔는지 센다
kinds.most_common()센 결과를 많이 나온 것부터 (값, 횟수) 꼴로 늘어놓는다

이 코드가 뜻하는 것

손님 의견 카드 72장을 받아 "아쉬웠던 요리" 칸만 훑어보고, 같은 요리끼리 쌓아 몇 장인지 세는 일과 같습니다. 여기서 카드 한 장이 선호 쌍 하나, "아쉬웠던 요리" 칸이 반대 답입니다.

줄하는 일쉽게 말하면
pairs = [json.loads(line) for line in f]파일의 줄마다 사전 하나로 바꿔 목록에 모은다카드 72장을 모두 꺼낸다
Counter(p["rejected"][:12] for p in pairs)반대 답의 앞부분이 같은 것끼리 센다같은 요리끼리 쌓는다
for text, n in kinds.most_common()많은 묶음부터 횟수와 앞부분을 찍는다높은 더미부터 장수를 읽는다

이 장의 반대 답은 세 가지 흠 문장 가운데 하나로 시작하도록 만들었기 때문에 앞 12글자만 봐도 흠의 종류가 갈립니다. 사람이 모은 데이터라면 반대 답이 제각각이라 이렇게 쉽게 묶이지 않습니다.

주의할 점

  • 고른 답과 반대 답이 너무 쉽게 갈리면(예: 반대 답이 늘 같은 문장) 모델은 그 문장만 피하는 법을 배웁니다. 실제로는 미묘하게 다른 두 답을 모으는 것이 좋습니다.
  • 사람이 고를 때는 기준(정확성 먼저, 그다음 친절함 등)을 미리 적어 두어야 사람마다 고르는 것이 일관됩니다.
← 이전 절5장 · 메모리 아끼는 기술다음 절 →5장 · DPO 의 원리