목차
메타 설명
SFT 모델과 Reward Model을 만들었다면 이제 어떻게 AI를 실제 강화학습시킬까요? Hugging Face TRL의 PPOTrainer를 이용해 Policy Model, Reference Model, Reward Model, Value Model, Rollout, KL Penalty, Advantage, GAE, PPO Clipping, RLHF Reward, LoRA까지 연결하여 생성형 AI를 보상 점수 기반으로 학습하는 전체 과정을 알아봅니다.
지난 시간에는 `RewardTrainer`를 이용해 AI 답변을 평가하는 Reward Model을 만들었습니다.
이제 우리에게는 두 종류의 AI가 있습니다.
생성 모델:
“제가 답변을 만들겠습니다.”
Reward Model:
“그 답변은 2.7점입니다.”그런데 여기서 질문이 하나 생깁니다.
생성 모델:
“2.7점인 건 알겠는데...
그래서 저는
어떻게 더 잘해야 하죠?”Reward Model은 시험 점수만 알려줍니다.
생성 모델의 파라미터를 직접 수정하지 않습니다.
그렇다면 Reward 점수가 높은 답변을 더 자주 생성하도록 생성 모델 자체를 다시 훈련해야 합니다.
오늘의 주인공이 바로 PPO입니다.
Prompt
↓
Policy Model
↓
Response 생성
↓
Reward Model
↓
Reward Score
↓
PPO
↓
Policy Model 업데이트드디어 지금까지 배웠던 조각들이 하나의 파이프라인으로 합쳐집니다.
#39 SFTTrainer
→ 답변하는 방법 교육
#41 RewardTrainer
→ 답변 채점관 교육
#42 PPOTrainer
→ 점수를 보고 생성 모델 개선AI 훈련장에 학생도 있고 심판도 있습니다.
이제 감독이 등장할 차례입니다. 🏟️🤖📈
먼저 꼭 알아둘 현재 TRL PPO의 중요한 변화
2026년 8월 14일 기준 PyPI의 최신 TRL 버전은 1.10.0이며, 2026년 8월 13일 공개되었습니다. Python 3.10 이상을 요구합니다.
그리고 현재 TRL에서 PPO는 일반 Stable Trainer 목록이 아니라 Experimental Online Trainer로 분류되어 있습니다. 현재 공식 API는 다음 위치에서 가져옵니다.
from trl.experimental.ppo import (
PPOConfig,
PPOTrainer
)예전 TRL 예제에서는 다음 패턴을 자주 발견할 수 있습니다.
ppo_trainer.generate(...)
ppo_trainer.step(...)하지만 현재 공식 PPO 구현은 구조가 크게 변경되었습니다.
현재 `PPOTrainer`에 Policy, Reference, Reward, Value Model과 Dataset을 전달한 뒤 다음처럼 실행합니다.
trainer.train()현재 공식 PPO 예제 역시 이 구조를 사용합니다.
따라서 오래된 PPO 강좌를 그대로 복사하면 현재 TRL에서 작동하지 않을 가능성이 높습니다.
2023년 PPO 강좌:
“step()을 호출하세요.”
2026년 TRL:
“어느 시대에서 오셨습니까?”이번 편에서는 TRL 1.10.x 계열의 현재 구조를 기준으로 설명합니다.
1. PPO란?
PPO는 다음 표현의 약자입니다.
Proximal Policy Optimization한국어로는 보통 다음처럼 표현합니다.
근접 정책 최적화2017년 John Schulman 등이 제안한 Policy Gradient 계열 강화학습 알고리즘입니다.
PPO의 핵심 아이디어는 좋은 행동의 확률을 높이되 Policy를 한 번에 너무 크게 바꾸지 않는 것입니다. 원 논문은 수집한 데이터를 이용해 여러 번의 Mini-batch 업데이트가 가능하면서도 지나치게 큰 Policy 변화를 억제하는 Surrogate Objective를 제안했습니다.
LLM에서는 행동(Action)이 무엇일까요?
로봇이라면:
왼쪽 이동
오른쪽 이동
점프LLM에서는:
다음 Token 선택입니다.
따라서 문장 전체는 수많은 Action의 연속입니다.
Python
→ 의
→ 리스트
→ 는
→ 여러
→ 값을
→ 저장합니다PPO는 높은 Reward를 받는 Token 선택의 확률을 높이는 방향으로 Language Model을 업데이트합니다.
2. 강화학습이란?
강화학습의 핵심 구조는 다음과 같습니다.
Agent
→ Action
→ Environment
→ Reward
→ Agent 학습게임으로 생각하면 쉽습니다.
게임 캐릭터:
동전 획득
→ +10
벽 충돌
→ -5
목적지 도착
→ +100캐릭터는 높은 Reward를 받는 행동을 더 자주 선택하도록 학습합니다.
LLM에서는 다음과 같이 바뀝니다.
Agent:
Policy Model
Action:
Token 생성
Environment:
Prompt와 생성 과정
Reward:
Reward Model의 점수3. RLHF란?
RLHF는 다음 표현의 약자입니다.
Reinforcement Learning
from Human Feedback즉:
사람의 피드백으로부터
학습하는 강화학습전통적인 RLHF 흐름을 단순화하면 다음과 같습니다.
Pre-trained Model
↓
SFT
↓
Preference Dataset
↓
Reward Model
↓
PPO
↓
Aligned Model지금까지 시리즈에서 이 구조를 거의 그대로 만들었습니다.
4. 지금까지의 전체 흐름
#39 SFTTrainer
Prompt
+
모범 답안
↓
Instruction Fine-tuning결과:
사용자의 질문에
답변하는 방법을 학습#40 DPOTrainer
Chosen
vs
Rejected
↓
Preference Optimization결과:
좋은 답변의 방향을
생성 모델에 직접 학습#41 RewardTrainer
Chosen
vs
Rejected
↓
Reward Model결과:
새로운 답변의 품질을
숫자로 평가 가능#42 PPOTrainer
Policy가 답변 생성
↓
Reward Model 채점
↓
PPO 업데이트결과:
높은 Reward를 받는 답변을
더 자주 생성하도록 Policy 개선5. PPO가 필요한 이유
Reward Model만 있다고 가정해 보겠습니다.
답변 A:
Reward = 3.8
답변 B:
Reward = 0.9Reward Model은 여기까지입니다.
Reward Model:
“A가 더 좋습니다.”그러나 생성 모델은 자동으로 바뀌지 않습니다.
PPO를 사용하면:
A 같은 답변
→ 생성 확률 증가
B 같은 답변
→ 생성 확률 감소하도록 Policy Model 자체를 업데이트할 수 있습니다.
6. Policy Model이란?
Policy Model은 실제 답변을 생성하는 모델입니다.
Prompt
↓
Policy Model
↓
Response강화학습에서는 보통 다음 기호를 사용합니다.
πθ`π`는 Policy입니다.
`θ`는 학습 가능한 모델 파라미터입니다.
LLM에서 Policy는 다음 확률을 의미한다고 볼 수 있습니다.
현재까지 생성한 Token을 보고
다음 Token을 무엇으로
선택할 확률인가?예:
Python의 리스트는
↓
여러 0.42
값을 0.21
변경 0.08
강아지 0.00001PPO는 좋은 결과로 이어지는 Token들의 확률을 조정합니다.
7. Reference Model이란?
PPO에서는 현재 Policy가 지나치게 빠르게 변하지 않도록 기준 모델을 둡니다.
이것이 Reference Model입니다.
Policy Model:
계속 학습
Reference Model:
기준점현재 TRL `PPOTrainer`는 `ref_model`을 KL Divergence 계산에 사용하며, `None`을 전달하면 Policy Model의 복사본을 Reference로 만들 수 있습니다.
개념적으로:
Reference:
“원래는 이렇게 답했어요.”
Policy:
“Reward를 높이기 위해
조금 바꾸겠습니다.”PPO에서는 `조금`이 매우 중요합니다.
8. Reward Model이란?
지난 편에서 만들었습니다.
Prompt
+
Response
↓
Reward Model
↓
Scalar Score현재 PPOTrainer API에서도 `reward_model`은 생성 응답의 Reward Score를 계산하는 필수 모델입니다.
예:
질문:
Python 리스트란 무엇인가요?
답변:
리스트는 여러 값을
순서대로 저장하는 자료형입니다.
Reward:
3.429. Value Model이란?
PPO에는 Reward Model 외에도 또 하나의 점수 모델이 등장합니다.
Value Model현재 TRL `PPOTrainer`에도 `value_model`이 별도의 필수 인자로 존재하며, 상태의 Value를 예측하는 역할을 합니다.
Reward Model은:
완성된 답변이 얼마나 좋은가?를 평가합니다.
Value Model은:
현재 생성 상태에서
앞으로 얼마나 좋은 Reward를
얻을 것으로 예상하는가?를 추정합니다.
예:
현재:
Python 리스트는 여러 값을...
Value Model:
“이 흐름이면 최종 Reward가
꽤 높을 것 같습니다.”Value Model은 PPO에서 Advantage를 계산하는 데 중요한 역할을 합니다.
10. PPO의 네 모델 구조
현재 TRL PPOTrainer의 핵심 모델은 다음 네 가지입니다.
┌──────────────────┐
│ Policy Model │
│ 답변 생성 │
└────────┬─────────┘
│
▼
Response
│
├──────────────────────┐
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ Reward Model │ │ Reference Model │
│ 답변 품질 점수 │ │ 기존 Policy 기준 │
└──────────────────┘ └──────────────────┘
│
│
▼
Reward
│
▼
┌──────────────────┐
│ Value Model │
│ 예상 Return │
└──────────────────┘한 줄로 정리하면:
Policy
→ 행동
Reference
→ 기준
Reward
→ 채점
Value
→ 미래 점수 예측11. Prompt Dataset이란?
SFT Dataset에는 정답이 필요했습니다.
Prompt
+
CompletionDPO Dataset에는 비교 답변이 필요했습니다.
Prompt
+
Chosen
+
RejectedPPO Dataset에는 기본적으로 Prompt만 있어도 됩니다.
Prompt왜냐하면 답변은 학습 과정에서 Policy가 직접 생성하기 때문입니다.
Prompt
↓
Policy
↓
새로운 Response
↓
Reward Model 평가이것이 Offline DPO와 Online PPO의 큰 차이입니다.
12. Episode란?
강화학습에서 하나의 학습 경험 단위를 Episode라고 부릅니다.
LLM PPO에서는 단순화하면 다음 과정 하나를 Episode라고 생각할 수 있습니다.
Prompt 하나
↓
Response 생성
↓
Reward 계산
↓
학습 데이터 생성현재 PPOConfig에는 전체 학습 Episode 수를 설정하는 `total_episodes`가 있습니다.
total_episodes=100013. Rollout이란?
Rollout은 현재 Policy를 이용해 실제 행동 결과를 생성하는 과정입니다.
LLM에서는:
Prompt
↓
현재 Policy
↓
Response Sampling입니다.
예:
Prompt:
리스트와 튜플 차이는?
Rollout 1:
리스트는 변경 가능하고...
Rollout 2:
두 자료형은...
Rollout 3:
Python에서 리스트는...PPO는 미리 저장된 답변만 보는 것이 아니라 현재 Policy가 실제로 생성한 답변을 이용해 학습합니다.
14. Reward Score 계산
Rollout이 생성되면 Reward Model이 평가합니다.
Prompt
+
Generated Response
↓
Reward Model
↓
Score예:
Response A:
3.8
Response B:
1.7
Response C:
-2.0하지만 PPO가 사용하는 최종 Reward는 Reward Model Score만으로 끝나지 않습니다.
15. KL Divergence란?
Policy가 Reference Model에서 얼마나 달라졌는지를 측정하기 위해 KL Divergence를 사용합니다.
직관적으로:
Policy와 Reference가 비슷함
→ KL 작음
Policy가 크게 달라짐
→ KL 큼예:
Reference:
“리스트는 여러 값을
저장하는 자료형입니다.”
Policy:
“리스트 리스트 리스트 리스트
최고 최고 최고 최고...”Reward Model의 허점을 이용해 Policy가 이상한 방향으로 움직였다면 Reference와의 차이가 커질 수 있습니다.
16. KL Penalty가 필요한 이유
Reward만 최대화하면 Policy가 Reward Model의 약점을 공략할 수 있습니다.
Reward Model:
“자세한 답변에 점수를 많이 줌”
Policy:
“그럼 무조건 5,000자 쓰겠습니다.”PPO에서는 Policy가 Reference에서 지나치게 멀어질 경우 Penalty를 줄 수 있습니다.
현재 TRL PPOConfig에서는 `kl_coef`가 KL Penalty의 계수를 조절하며 기본값은 `0.05`입니다.
kl_coef=0.0517. RLHF Reward 계산
현재 TRL PPO 로그에서는 다음 관계가 사용됩니다.
RLHF Reward
=
Reward Model Score
-
Non-score Reward여기서 Non-score Reward는 주로 KL Penalty에서 발생합니다. 공식 문서의 `objective/rlhf_reward`는 Reward Model의 Score에서 KL 관련 Non-score Reward를 뺀 값으로 설명됩니다.
예:
Reward Model Score:
4.2
KL Penalty:
0.8
RLHF Reward:
3.4다른 예:
Reward Model Score:
5.0
KL Penalty:
4.5
RLHF Reward:
0.5두 번째 답변은 Reward Model만 보면 좋지만 기존 Policy에서 너무 크게 벗어났습니다.
18. Return이란?
강화학습에서 Return은 앞으로 받을 Reward의 누적값입니다.
간단한 예:
현재 Token
↓
Reward:
0
↓
다음 Token
Reward:
0
↓
EOS
최종 Reward:
5LLM RLHF에서는 최종 응답 Score와 Token별 KL Penalty 등을 이용해 Return을 구성합니다.
19. Value란?
Value Model은 현재 상태에서 기대되는 Return을 추정합니다.
실제 Return:
4.2
Value Model 예상:
3.7좋은 Value Model은 Reward가 나오기 전에 다음과 같은 판단을 할 수 있게 도와줍니다.
“현재 생성 경로는
평균보다 좋은 결과로
이어질 가능성이 높습니다.”20. Advantage란?
Advantage는 현재 행동이 예상보다 얼마나 좋았는지 나타냅니다.
아주 단순하게 생각하면:
Advantage
≈
실제 결과
-
예상 결과예:
실제 Return:
5
Value 예상:
3
Advantage:
+2예상보다 좋은 결과입니다.
→ 해당 행동 확률을 높이는 방향반대로:
실제 Return:
1
Value 예상:
3
Advantage:
-2예상보다 나쁜 결과입니다.
→ 해당 행동 확률을 낮추는 방향21. GAE란?
PPO에서는 Advantage를 안정적으로 추정하기 위해 GAE가 널리 사용됩니다.
GAE는:
Generalized Advantage Estimation의 약자입니다.
GAE는 여러 시점의 Temporal Difference 정보를 조합해 Advantage 추정의 Bias와 Variance를 조절하는 방법입니다. 원 논문은 Value Function을 사용해 Policy Gradient 추정의 Variance를 낮추는 방법으로 GAE를 제안했습니다.
현재 PPOConfig에는 다음 두 설정이 있습니다.
gamma=1.0
lam=0.95`gamma`는 미래 Reward 할인에 관련됩니다.
`lam`은 GAE에서 장기 정보와 단기 정보의 균형을 조절합니다.
22. Policy Ratio란?
PPO는 Policy 업데이트 전후의 행동 확률을 비교합니다.
새 Policy 확률
÷
이전 Policy 확률이를 Policy Ratio라고 생각할 수 있습니다.
예:
이전 Policy:
Token "리스트"
확률 = 0.20
새 Policy:
Token "리스트"
확률 = 0.24
Ratio:
0.24 / 0.20
= 1.21에 가까우면 변화가 작습니다.
0.98
1.03
1.10너무 크거나 작으면 Policy가 급격하게 변한 것입니다.
0.1
3.0
10.023. PPO Clipping이란?
PPO가 유명한 이유 중 하나가 Clipped Objective입니다.
원 PPO 논문의 핵심 목적은 Policy 업데이트가 너무 커져 학습이 불안정해지는 것을 막으면서 한 번 수집한 데이터로 여러 Mini-batch 업데이트를 수행하는 것입니다.
현재 TRL PPOConfig의 기본 `cliprange`는 다음과 같습니다.
cliprange=0.2즉 Policy Ratio의 영향력을 대략:
1 - 0.2
~
1 + 0.2범위에서 제한하는 방식입니다.
0.8 ~ 1.224. Clip Range 이해하기
좋은 Action을 발견했다고 가정하겠습니다.
Advantage:
매우 높음모델이 흥분해서 다음처럼 움직일 수 있습니다.
기존 확률:
0.10
↓
한 번 업데이트
↓
새 확률:
0.90PPO:
“잠깐.
좋은 행동인 건 알겠는데
한 번에 그렇게까지 바꾸지는 맙시다.”Clipping은 이런 과도한 업데이트를 제한합니다.
25. Policy Loss
Policy Loss는 Advantage가 높은 행동의 확률은 높이고 낮은 행동의 확률은 낮추도록 Policy를 업데이트합니다.
Positive Advantage
→ 생성 확률 ↑
Negative Advantage
→ 생성 확률 ↓하지만 PPO Clipping 때문에 변화 폭에는 제한이 있습니다.
26. Value Loss
Value Model도 학습해야 합니다.
Value Prediction
vs
실제 Return차이를 줄입니다.
현재 PPOConfig에는 Policy와 함께 Value Function 학습 강도를 조절하는 `vf_coef`가 있으며 기본값은 `0.1`입니다. Value Function 자체의 Clipping 범위인 `cliprange_value` 기본값은 `0.2`입니다.
vf_coef=0.1
cliprange_value=0.227. PPO 전체 Loss 구조
개념적으로 PPO 학습에는 여러 신호가 함께 존재합니다.
Policy Loss
+
Value Loss
+
KL 관련 제약
+
기타 Regularization각 요소가 서로 다른 문제를 막습니다.
Policy Loss:
좋은 행동 학습
Value Loss:
미래 Reward 예측
PPO Clipping:
Policy 급변 방지
KL Penalty:
Reference에서 과도한 이탈 방지28. PPO 학습 전체 과정
전체 흐름을 연결해 보겠습니다.
① Prompt Batch
↓
② Policy가 Response 생성
↓
③ Reward Model이 Score 계산
↓
④ Reference와 Policy KL 계산
↓
⑤ KL Penalty 적용
↓
⑥ RLHF Reward 계산
↓
⑦ Value Model이 Value 추정
↓
⑧ Advantage 계산
↓
⑨ PPO Clipped Policy Loss
↓
⑩ Value Loss
↓
⑪ Gradient Update
↓
⑫ 다시 RolloutPPO는 학습할 때마다 현재 Policy의 새로운 응답을 관찰합니다.
이 점이 Offline Preference 학습인 DPO와 크게 다릅니다.
29. 현재 PPOTrainer 구조
2026년 현재 PPOTrainer 생성자는 다음 주요 객체를 받습니다.
trainer = PPOTrainer(
args=ppo_config,
processing_class=tokenizer,
model=policy_model,
ref_model=reference_model,
reward_model=reward_model,
value_model=value_model,
train_dataset=train_dataset,
eval_dataset=eval_dataset
)LoRA를 사용할 경우:
trainer = PPOTrainer(
...,
peft_config=lora_config
)현재 `PPOTrainer`는 Policy Model에 PEFT Adapter를 적용할 수 있는 `peft_config` 인자를 제공합니다.
30. PPOConfig 핵심 옵션
from trl.experimental.ppo import (
PPOConfig
)
ppo_config = PPOConfig(
output_dir=(
"outputs/"
"python-tutor-ppo"
),
learning_rate=3e-6,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
total_episodes=200,
response_length=128,
temperature=0.7,
num_ppo_epochs=2,
num_mini_batches=1,
kl_coef=0.05,
cliprange=0.2,
vf_coef=0.1,
cliprange_value=0.2,
gamma=1.0,
lam=0.95,
stop_token="eos",
missing_eos_penalty=1.0,
logging_steps=10,
report_to="none"
)현재 PPOConfig의 기본 Learning Rate는 `3e-6`, `num_ppo_epochs`는 4, `cliprange`는 0.2, `kl_coef`는 0.05, `gamma`는 1.0, `lam`은 0.95입니다.
31. Learning Rate
PPO는 일반 Fine-tuning보다 작은 Learning Rate를 사용하는 경우가 많습니다.
현재 PPOConfig 기본값:
learning_rate=3e-6왜 작을까요?
Policy는 이미 SFT된 모델입니다.
SFT:
이미 어느 정도 잘 답함PPO의 목적은:
모델을 새로 만드는 것
이 아니라
선호 방향으로 조금씩 조정하는 것입니다.
32. total_episodes
total_episodes=1000전체 Rollout Episode 수입니다.
현재 PPOConfig가 제공하는 핵심 Online RL 설정입니다.
데이터가 100개 Prompt라도 여러 Episode 동안 반복 Sampling할 수 있습니다.
Prompt Dataset:
100개
total_episodes:
10,000모델은 같은 Prompt에서도 Sampling에 따라 다양한 Response를 생성할 수 있습니다.
33. response_length
response_length=128현재 PPOConfig는 생성 Response 길이를 `response_length`로 지정하며 기본값은 53입니다.
너무 작으면:
답변 중간에서 잘림너무 크면:
GPU 메모리 증가
Rollout 시간 증가
불필요한 장문 가능34. Temperature
temperature=0.7현재 PPOConfig의 기본 Temperature도 0.7입니다.
낮으면:
안정적
비슷한 답변 반복높으면:
다양한 탐색
품질 변동 증가PPO 학습에는 어느 정도 Exploration이 필요합니다.
항상 같은 답변
→ 새로운 좋은 행동을
발견하기 어려움35. num_ppo_epochs
Rollout Batch 하나를 이용해 몇 번 PPO 업데이트할지 결정합니다.
num_ppo_epochs=4현재 기본값은 4입니다.
PPO 원 논문의 장점 중 하나도 수집한 Sample을 여러 Epoch의 Mini-batch 업데이트에 재사용하는 것입니다.
너무 높으면:
현재 Rollout Batch에 과적합할 수 있습니다.
36. Mini Batch
PPO는 하나의 Rollout Batch를 다시 작은 Mini Batch로 나누어 업데이트할 수 있습니다.
num_mini_batches=1현재 PPOConfig는 `num_mini_batches`, `mini_batch_size`, `local_mini_batch_size` 같은 관련 설정을 제공합니다.
GPU 메모리가 충분하지 않다면 작은 Batch와 Gradient Accumulation을 사용할 수 있습니다.
37. KL Coefficient
kl_coef=0.05값이 크면:
Reference Model에서
멀리 움직이기 어려움값이 작으면:
Reward 최적화를 위해
더 많이 변화할 수 있음현재 기본값은 0.05입니다.
38. Gamma와 Lambda
현재 기본값:
gamma=1.0
lam=0.95`gamma`:
미래 Reward 할인 정도`lam`:
GAE Advantage 추정의
Bias와 Variance 균형LLM PPO에서는 Episode가 일반적인 로봇 환경보다 비교적 짧은 Text Generation이기 때문에 `gamma=1.0` 같은 설정이 사용될 수 있습니다.
39. Missing EOS Penalty
Response가 최대 길이까지 생성되었는데 EOS가 나오지 않았다면 완결되지 않은 답변일 수 있습니다.
현재 PPOConfig는:
missing_eos_penalty=1.0
stop_token="eos"같은 설정을 제공합니다. 공식 TRL PPO 문서도 EOS로 끝나지 않은 Completion에 고정 Penalty를 주는 방식을 권장 팁으로 소개합니다.
모델:
“Python의 리스트란 무엇인지
설명하기 위해 우선 컴퓨터의 역사를...”
128 Token 종료
EOS 없음
PPO:
“-1점.”말을 끝내는 것도 실력입니다.
40. PPO 로그 읽기
PPO는 일반 Fine-tuning보다 로그를 꼼꼼하게 봐야 합니다.
현재 TRL 공식 PPO 문서는 다음과 같은 주요 지표를 제공합니다.
objective/scores
objective/rlhf_reward
objective/kl
objective/non_score_reward
policy/approxkl_avg
policy/clipfrac_avg
loss/policy_avg
loss/value_avg
policy/entropy_avg
val/ratio
val/ratio_var
val/num_eos_tokens
eps하나씩 살펴보겠습니다.
41. objective/scores
objective/scoresReward Model이 Response에 부여한 평균 Score입니다.
예:
Step 100:
1.2
Step 500:
2.1
Step 1000:
2.7증가한다면 Reward Model 관점에서는 답변 품질이 향상되고 있다는 신호입니다.
하지만 Reward Hacking 때문에 이것만 보면 안 됩니다.
42. objective/rlhf_reward
현재 TRL 공식 문서는 이 값을 PPO RLHF 학습의 핵심 Objective로 설명합니다. Reward Model Score에서 KL 기반 Non-score Reward를 반영한 값입니다.
Reward Score
-
KL Penalty
=
RLHF Reward공식 문서는 학습이 정상적으로 진행된다면 `objective/rlhf_reward`가 상승하는지 확인하라고 안내합니다.
43. objective/kl
현재 Policy와 Reference Policy의 평균 KL Divergence입니다.
너무 작음:
Policy 변화 거의 없음
적당함:
Reward 방향으로 점진적 변화
급격하게 증가:
Policy가 Reference에서 빠르게 이탈Reward가 올라가면서 KL까지 폭발한다면 주의해야 합니다.
44. Policy Ratio와 Clip Fraction
val/ratio
이전 Policy와 현재 Policy의 Probability Ratio입니다.
TRL 공식 문서는 이 값이 대체로 1.0 근처에 있어야 하며 지나치게 2, 1000 또는 0.1 같은 값으로 움직이면 업데이트가 너무 큰 원인을 조사하라고 안내합니다.
1.02
0.98
1.06
→ 비교적 안정12.7
→ 매우 위험policy/clipfrac_avg
PPO Update 중 Clipping이 적용된 비율입니다.
값이 너무 높다면 Policy Update가 자주 Clip 범위를 넘고 있다는 의미일 수 있습니다.
45. Value Loss
loss/value_avgValue Model이 실제 Return을 얼마나 잘 예측하는지와 관련된 Loss입니다.
너무 높다면:
Value Model:
“예상 Reward 5점입니다.”
실제 Reward:
-2점같은 상태일 수 있습니다.
Advantage가 불안정해지고 PPO 학습도 흔들릴 수 있습니다.
46. 메모리 사용량이 큰 이유
PPO가 부담스러운 이유가 이제 보입니다.
최소한 다음 모델이 필요합니다.
Policy Model
Reference Model
Reward Model
Value Model그리고 Rollout 중에는:
Prompt Batch
Response Token
Log Probability
Reference Log Probability
Value
Reward
Advantage
Gradient
Optimizer State까지 관리합니다.
GPU:
“모델 한 개 Fine-tuning한다고 하셨죠?”
PPO:
“네.
참고로 네 모델입니다.”
GPU:
“...”그래서 PPO는 DPO보다 구현과 인프라 부담이 큰 편입니다.
47. LoRA와 PPO
현재 PPOTrainer는 `peft_config`를 직접 지원합니다.
from peft import (
LoraConfig,
TaskType
)
lora_config = LoraConfig(
task_type=TaskType.CAUSAL_LM,
r=16,
lora_alpha=32,
lora_dropout=0.05,
target_modules=[
"q_proj",
"k_proj",
"v_proj",
"o_proj"
],
bias="none"
)PPOTrainer:
trainer = PPOTrainer(
...,
peft_config=lora_config
)Policy 전체를 업데이트하지 않고 LoRA Adapter를 PPO로 학습할 수 있습니다.
공식 현재 PPO 예제에서도 PEFT 설정이 있으면 별도 Reference Policy 객체를 만들지 않고 `ref_policy=None`으로 구성하는 패턴을 사용합니다.
48. QLoRA와 PPO
TRL 전체 라이브러리는 PEFT와 Quantization 통합을 제공합니다.
PPO 공식 스크립트도 Model Config에서 Quantization 설정을 읽어 모델 로딩 옵션에 전달하는 구조를 사용합니다.
다만 PPO는 여러 모델을 동시에 다루므로 QLoRA 구성은 SFT보다 복잡합니다.
Policy
Reference
Reward
Value모델마다 Quantization과 Device 배치를 고려해야 합니다.
초보자라면 다음 순서를 권장합니다.
작은 모델 PPO
↓
LoRA PPO
↓
Multi-GPU PPO
↓
필요하면 Quantization처음부터 7B QLoRA PPO로 시작하면 디버깅이 AI 공부보다 GPU 메모리 퍼즐에 가까워질 수 있습니다.
49. Prompt Dataset 준비
현재 공식 PPO 예제는 Dataset의 Prompt를 학습 전에 Tokenization하고 `input_ids`와 길이 정보만 남기는 구조를 사용합니다.
대화 모델용 Prompt를 만들어 보겠습니다.
from datasets import Dataset
SYSTEM_MESSAGE = (
"당신은 Python 입문자를 위한 "
"친절하고 정확한 교관입니다. "
"핵심부터 설명하고 필요한 경우 "
"짧은 예제를 제공합니다."
)
QUESTIONS = [
"Python 변수란 무엇인가요?",
"리스트와 튜플의 차이는 무엇인가요?",
"for 반복문을 설명해 주세요.",
"while 반복문은 언제 사용하나요?",
"함수의 return은 무엇인가요?",
"딕셔너리는 어떤 자료형인가요?",
"try-except는 왜 사용하나요?",
"None은 어떻게 비교하나요?",
"가상환경은 왜 필요한가요?",
"with 문은 언제 사용하나요?"
]Chat Template:
def build_prompt(
tokenizer,
question: str
) -> str:
messages = [
{
"role": "system",
"content": SYSTEM_MESSAGE
},
{
"role": "user",
"content": question
}
]
return tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)Dataset:
dataset = Dataset.from_dict({
"question": QUESTIONS
})50. Reward Model 준비
PPO에 사용할 Reward Model은 지난 편에서 만든 Sequence Classification Reward Model입니다.
PPO의 현재 공식 예제에서는 Reward Model과 Value Model을 모두 `AutoModelForSequenceClassification`으로 불러오고 `num_labels=1`을 사용합니다.
from transformers import (
AutoModelForSequenceClassification
)
reward_model = (
AutoModelForSequenceClassification
.from_pretrained(
REWARD_MODEL_PATH,
num_labels=1
)
)
value_model = (
AutoModelForSequenceClassification
.from_pretrained(
REWARD_MODEL_PATH,
num_labels=1
)
)둘은 초기 가중치 경로가 같더라도 PPO 안에서 역할이 다릅니다.
Reward Model:
Response 품질 채점
Value Model:
현재 상태에서
예상 Return 추정지난 편의 LoRA Reward Model을 사용할 경우
#41에서 Adapter만 저장했다면 먼저 전체 Reward Model로 병합해 두는 편이 실습하기 쉽습니다.
from peft import (
AutoPeftModelForSequenceClassification
)
reward_model = (
AutoPeftModelForSequenceClassification
.from_pretrained(
"models/python-reward-model-lora"
)
)
merged_reward_model = (
reward_model.merge_and_unload(
safe_merge=True
)
)
merged_reward_model.save_pretrained(
"models/python-reward-model-merged"
)그 뒤:
REWARD_MODEL_PATH = (
"models/"
"python-reward-model-merged"
)를 PPO 프로젝트에서 사용합니다.
51. 실전 PPO 프로젝트
중요
아래 코드는 현재 TRL PPO 구조를 학습하기 위한 프로젝트 템플릿입니다.
`REWARD_MODEL_PATH`에는 #41에서 실제 학습해 저장한 Reward Model이 있어야 의미 있는 PPO 학습이 됩니다.
Reward Head가 무작위인 모델을 연결하면 PPO는 무작위 심사위원의 점수를 성실하게 최적화하게 됩니다.
그것은 강화학습이라기보다 AI 복불복 대회입니다.
`train_ppo.py`:
from pathlib import Path
import torch
from accelerate import PartialState
from datasets import Dataset
from peft import (
LoraConfig,
TaskType
)
from transformers import (
AutoModelForCausalLM,
AutoModelForSequenceClassification,
AutoTokenizer,
set_seed
)
from trl.experimental.ppo import (
PPOConfig,
PPOTrainer
)
SFT_MODEL_PATH = (
"Qwen/"
"Qwen2.5-0.5B-Instruct"
)
REWARD_MODEL_PATH = (
"models/"
"python-reward-model-merged"
)
OUTPUT_DIR = Path(
"outputs/"
"python-tutor-ppo"
)
SEED = 2026
SYSTEM_MESSAGE = (
"당신은 Python 입문자를 위한 "
"친절하고 정확한 교관입니다. "
"핵심부터 설명하고 필요한 경우 "
"짧은 코드 예제를 제공합니다. "
"확실하지 않은 내용은 추측하지 않습니다."
)
QUESTIONS = [
"Python 변수란 무엇인가요?",
"리스트와 튜플의 차이를 설명해 주세요.",
"for 반복문은 언제 사용하나요?",
"while 반복문을 사용할 때 주의할 점은 무엇인가요?",
"함수의 return은 어떤 역할을 하나요?",
"딕셔너리는 어떤 자료형인가요?",
"try-except는 언제 사용하나요?",
"None을 비교하는 방법을 알려 주세요.",
"클래스와 객체의 차이를 설명해 주세요.",
"가상환경은 왜 필요한가요?",
"파일을 안전하게 열고 닫는 방법을 알려 주세요.",
"set 자료형의 특징을 알려 주세요.",
"enumerate 함수는 언제 사용하나요?",
"리스트에서 중복 값을 제거하는 방법을 알려 주세요.",
"문자열을 정수로 변환하는 방법을 알려 주세요.",
"함수의 매개변수와 인자의 차이는 무엇인가요?",
"Python에서 들여쓰기가 중요한 이유는 무엇인가요?",
"모듈을 사용하는 이유는 무엇인가요?",
"Boolean 자료형을 예제로 설명해 주세요.",
"리스트 컴프리헨션을 초보자에게 설명해 주세요."
]
def build_prompt(
tokenizer,
question: str
) -> str:
messages = [
{
"role": "system",
"content": SYSTEM_MESSAGE
},
{
"role": "user",
"content": question
}
]
return tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
def prepare_dataset(
dataset,
tokenizer,
dataset_num_proc=None
):
def tokenize(
example
):
prompt = build_prompt(
tokenizer,
example["question"]
)
input_ids = tokenizer(
prompt,
padding=False,
truncation=False
)["input_ids"]
return {
"input_ids": input_ids,
"lengths": len(
input_ids
)
}
return dataset.map(
tokenize,
remove_columns=(
dataset.column_names
),
num_proc=dataset_num_proc
)
def select_dtype():
if not torch.cuda.is_available():
return torch.float32
if torch.cuda.is_bf16_supported():
return torch.bfloat16
return torch.float16
def main():
set_seed(
SEED
)
OUTPUT_DIR.mkdir(
parents=True,
exist_ok=True
)
dtype = select_dtype()
print(
"[1/8] Tokenizer 로딩"
)
tokenizer = (
AutoTokenizer
.from_pretrained(
SFT_MODEL_PATH,
padding_side="left"
)
)
if tokenizer.pad_token is None:
tokenizer.add_special_tokens({
"pad_token": "[PAD]"
})
print(
"[2/8] PPOConfig 생성"
)
ppo_config = PPOConfig(
output_dir=str(
OUTPUT_DIR
),
learning_rate=3e-6,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
total_episodes=200,
num_ppo_epochs=2,
num_mini_batches=1,
local_rollout_forward_batch_size=2,
response_length=128,
temperature=0.7,
stop_token="eos",
missing_eos_penalty=1.0,
kl_coef=0.05,
kl_estimator="k1",
cliprange=0.2,
vf_coef=0.1,
cliprange_value=0.2,
gamma=1.0,
lam=0.95,
logging_steps=10,
num_sample_generations=5,
save_strategy="steps",
save_steps=50,
save_total_limit=2,
gradient_checkpointing=True,
report_to="none",
seed=SEED,
sft_model_path=(
SFT_MODEL_PATH
),
reward_model_path=(
REWARD_MODEL_PATH
)
)
print(
"[3/8] Policy Model 로딩"
)
policy_model = (
AutoModelForCausalLM
.from_pretrained(
SFT_MODEL_PATH,
dtype=dtype
)
)
policy_model.resize_token_embeddings(
len(tokenizer)
)
print(
"[4/8] Reference Model 로딩"
)
reference_model = (
AutoModelForCausalLM
.from_pretrained(
SFT_MODEL_PATH,
dtype=dtype
)
)
reference_model.resize_token_embeddings(
len(tokenizer)
)
print(
"[5/8] Reward·Value Model 로딩"
)
reward_model = (
AutoModelForSequenceClassification
.from_pretrained(
REWARD_MODEL_PATH,
num_labels=1,
dtype=dtype
)
)
value_model = (
AutoModelForSequenceClassification
.from_pretrained(
REWARD_MODEL_PATH,
num_labels=1,
dtype=dtype
)
)
print(
"[6/8] Prompt Dataset 준비"
)
raw_dataset = (
Dataset.from_dict({
"question": QUESTIONS
})
)
split_dataset = (
raw_dataset
.train_test_split(
test_size=0.2,
seed=SEED,
shuffle=True
)
)
with (
PartialState()
.local_main_process_first()
):
train_dataset = (
prepare_dataset(
split_dataset[
"train"
],
tokenizer,
ppo_config.dataset_num_proc
)
)
eval_dataset = (
prepare_dataset(
split_dataset[
"test"
],
tokenizer,
ppo_config.dataset_num_proc
)
)
train_dataset = (
train_dataset.filter(
lambda item: (
item["lengths"]
<= 512
)
)
)
eval_dataset = (
eval_dataset.filter(
lambda item: (
item["lengths"]
<= 512
)
)
)
if (
train_dataset[0][
"input_ids"
][-1]
== tokenizer.eos_token_id
):
raise ValueError(
"PPO Prompt의 마지막 Token이 "
"EOS입니다. "
"add_generation_prompt=True를 "
"확인하세요."
)
print(
f"Train Prompt: "
f"{len(train_dataset)}"
)
print(
f"Eval Prompt: "
f"{len(eval_dataset)}"
)
print(
"[7/8] PPOTrainer 생성"
)
lora_config = LoraConfig(
task_type=(
TaskType.CAUSAL_LM
),
r=16,
lora_alpha=32,
lora_dropout=0.05,
target_modules=[
"q_proj",
"k_proj",
"v_proj",
"o_proj"
],
bias="none"
)
trainer = PPOTrainer(
args=ppo_config,
processing_class=(
tokenizer
),
model=policy_model,
ref_model=(
reference_model
),
reward_model=(
reward_model
),
value_model=(
value_model
),
train_dataset=(
train_dataset
),
eval_dataset=(
eval_dataset
),
peft_config=(
lora_config
)
)
print(
"[8/8] PPO 강화학습 시작"
)
trainer.train()
trainer.save_model(
str(
OUTPUT_DIR
)
)
tokenizer.save_pretrained(
OUTPUT_DIR
)
print(
"PPO 학습이 완료되었습니다."
)
print(
f"저장 위치: "
f"{OUTPUT_DIR.resolve()}"
)
if __name__ == "__main__":
main()현재 공식 TRL PPO 스크립트 역시 Policy를 `AutoModelForCausalLM`, Reward와 Value를 `AutoModelForSequenceClassification(num_labels=1)`로 불러오고, Prompt를 미리 Tokenization한 뒤 `PPOTrainer(...).train()`을 호출하는 흐름을 사용합니다.
52. 학습 결과 저장
현재 PPOTrainer는 다음 메서드를 제공합니다.
trainer.save_model(
"models/python-tutor-ppo"
)Hub:
trainer.push_to_hub()LoRA를 사용하는 경우 저장 결과가 Adapter 중심인지 전체 Policy인지 실제 `peft_config`와 저장 구조를 확인해야 합니다.
운영 환경에서는 다음을 반드시 함께 기록하는 것이 좋습니다.
SFT Model ID
SFT Model Revision
Reward Model ID
Reward Model Revision
TRL Version
Transformers Version
PEFT Version
PPOConfig
Prompt Dataset Version
Random Seed53. 학습 전후 비교
PPO 학습에서 가장 중요한 평가입니다.
같은 Prompt에 대해 SFT Model과 PPO Model을 비교합니다.
질문:
Python의 리스트와 튜플 차이를
초보자에게 설명해 주세요.SFT Model
답변 APPO Model
답변 B평가:
| 항목 | SFT | PPO |
|---|---|---|
| ------------ | --: | --: |
| 정확성 | 평가 | 평가 |
| 설명 충분성 | 평가 | 평가 |
| 코드 정확성 | 평가 | 평가 |
| 관련성 | 평가 | 평가 |
| 장황함 | 평가 | 평가 |
| Reward Score | 측정 | 측정 |
| 사람 선호도 | 측정 | 측정 |
PPO의 Reward가 높아졌다고 끝이 아닙니다.
54. PPO 실패 패턴
Reward는 상승하지만 답변 품질 하락
objective/scores:
계속 상승
사람 평가:
계속 하락Reward Hacking 가능성이 있습니다.
KL 폭발
objective/kl:
급격히 상승Policy가 Reference에서 지나치게 멀어지고 있을 수 있습니다.
Ratio 폭발
val/ratio:
7.2업데이트가 너무 큽니다.
TRL 공식 PPO 문서도 `val/ratio`가 1.0 근처에서 지나치게 벗어나는 경우 업데이트가 너무 큰 원인을 조사하도록 안내합니다.
Value Loss 폭발
Value Model이 Return을 제대로 예측하지 못합니다.
EOS 감소
모델이 답변을 끝내지 않습니다.
val/num_eos_tokens
감소55. Reward Hacking
지난 편에서도 등장했습니다.
PPO에서는 더욱 중요합니다.
Reward Model이 다음 규칙을 잘못 학습했다고 가정합니다.
코드 블록이 있으면
Reward +2Policy는 결국 다음을 발견할 수 있습니다.
````text질문:
안녕하세요?
PPO Model:
print("안녕하세요")
````
````
왜 그랬을까요?Policy:
“코드 블록 넣으면점수가 올라가는데요?”````
모델 입장에서는 정확한 최적화입니다.
우리가 잘못된 시험지를 만든 것입니다.
56. PPO 안정화 방법
PPO가 불안정하다면 다음 순서로 확인합니다.
Learning Rate 감소
learning_rate=1e-6KL Coefficient 증가
kl_coef=0.1PPO Epoch 감소
num_ppo_epochs=1Clip Range 확인
cliprange=0.2Response Length 감소
response_length=64Batch Size 조정
per_device_train_batch_size=1
gradient_accumulation_steps=8Reward Model 검증
가장 중요합니다.
PPO 문제라고 생각했는데
사실 Reward Model 문제일 수 있습니다.
57. DPO와 PPO 차이
이제 두 기술을 명확히 비교할 수 있습니다.
| 구분 | DPO | PPO |
|---|---|---|
| 학습 방식 | Offline Preference | Online RL |
| 입력 | Prompt·Chosen·Rejected | Prompt |
| 학습 중 Response 생성 | 필수 아님 | 필수 |
| Reward Model | 불필요 | 필요 |
| Value Model | 불필요 | 필요 |
| Reference Model | 사용 | 사용 |
| Rollout | 없음 | 있음 |
| 구현 복잡도 | 비교적 낮음 | 높음 |
| GPU 메모리 | 상대적으로 적음 | 많음 |
| Reward Hacking | 상대적으로 낮음 | 중요 |
| Online Exploration | 없음 | 있음 |
DPO:
사람이 이미 만들어둔
좋고 나쁜 답안으로 공부PPO:
직접 답변을 만들어 보고
심사위원 점수를 받은 뒤
다시 행동 수정58. PPO와 GRPO 차이
현재 TRL은 PPO를 Experimental Online Trainer로 분류하는 반면 GRPOTrainer는 현재 핵심 Online Method 중 하나로 제공하고 있습니다.
PPO의 구조:
Policy
Reference
Reward
Value ModelGRPO는 여러 Completion의 상대적인 Reward를 이용해 Advantage를 구성할 수 있기 때문에 PPO에서 사용하던 별도의 Value Model이 필요하지 않은 구조로 유명합니다.
PPO:
Value Model 필요
GRPO:
그룹 내 Reward 비교를 이용따라서 대형 추론 모델 학습에서는 GRPO 계열 방법도 매우 중요한 선택지가 되었습니다.
다음 편에서 이 구조를 자세히 다루겠습니다.
59. 자주 발생하는 오류
오류 1. PPOTrainer import 실패
오래된 코드:
from trl import PPOTrainer현재 PPO는 Experimental API입니다.
현재 방식:
from trl.experimental.ppo import (
PPOConfig,
PPOTrainer
)오류 2. `step()`이 없음
오래된 예제:
ppo_trainer.step(
queries,
responses,
rewards
)현재 공식 PPO 구조는 Trainer에 Model과 Dataset을 전달하고:
trainer.train()을 사용합니다.
오류 3. value_model이 필요함
현재 PPOTrainer 생성자에는 `value_model`이 별도 인자로 존재합니다.
value_model = (
AutoModelForSequenceClassification
.from_pretrained(
REWARD_MODEL_PATH,
num_labels=1
)
)오류 4. reward_model이 필요함
reward_model은 현재 PPOTrainer의 필수 구성 요소입니다.
Reward Head가 실제로 학습되어 있어야 합니다.
오류 5. Reward Model이 무작위 Head
Some weights were newly initializedReward Model을 실제 Preference Dataset으로 학습하지 않았다면 PPO에 사용하면 안 됩니다.
먼저 #41 RewardTrainer 단계를 수행합니다.
오류 6. Prompt가 EOS로 끝남
현재 공식 PPO 예제는 Tokenized Prompt의 마지막 Token이 EOS가 아니어야 한다고 확인합니다. Policy가 그 뒤에 Response를 생성해야 하기 때문입니다.
Chat Template에서는:
add_generation_prompt=True를 확인합니다.
오류 7. Padding Token 없음
if tokenizer.pad_token is None:
tokenizer.add_special_tokens({
"pad_token": "[PAD]"
})모델 Embedding도 함께 확장해야 합니다.
policy_model.resize_token_embeddings(
len(tokenizer)
)Reference Model도 동일하게 적용합니다.
오류 8. CUDA Out of Memory
PPO는 여러 모델 때문에 메모리 사용량이 큽니다.
우선:
Batch Size 감소
Gradient Accumulation 증가
작은 모델
LoRA
Response Length 감소
DeepSpeed를 검토합니다.
현재 공식 PPO 문서도 Batch Size 감소와 Gradient Accumulation 증가를 기본 메모리 절약 방법으로 안내하며, Multi-GPU에서는 DeepSpeed ZeRO-3를 사용할 수 있다고 설명합니다.
오류 9. Reward는 증가하지만 답변이 이상함
Reward Hacking을 의심합니다.
확인:
Reward Dataset
길이 편향
특정 문구 편향
특정 Format 편향
Reward Model Test Accuracy오류 10. objective/kl이 급상승
해결 후보:
Learning Rate 감소
kl_coef 증가
num_ppo_epochs 감소
Reward Scale 확인오류 11. val/ratio가 1에서 크게 벗어남
공식 문서가 특별히 강조하는 PPO 디버깅 지표입니다.
예:
0.98
1.04
→ 정상 범위에 가까움10.2
→ 업데이트 과도 가능오류 12. EOS가 거의 생성되지 않음
stop_token="eos"
missing_eos_penalty=1.0를 검토합니다.
Response Length도 너무 짧지 않은지 확인합니다.
오류 13. Reward Model과 Tokenizer가 다름
SFT Policy와 Reward Model이 서로 다른 Tokenizer를 요구하는 경우 별도의 전처리가 필요할 수 있습니다.
처음 실습에서는 동일한 Base Model Family에서 Policy와 Reward Model을 만드는 것이 단순합니다.
오류 14. Policy 성능이 갑자기 붕괴함
Learning Rate 과다
KL 제약 부족
Reward Scale 이상
PPO Epoch 과다
잘못된 Reward Model을 확인합니다.
오류 15. fp16에서 NaN
지원 GPU라면 BF16을 검토합니다.
bf16=True
fp16=False또는 Learning Rate를 낮춥니다.
오류 16. 작은 Dataset에서 성능이 이상함
PPO는 Online Rollout을 반복하므로 아주 작은 Prompt Dataset에서는 같은 Prompt를 지나치게 반복할 수 있습니다.
10개 Prompt
× 수천 Episode
→ Prompt 과적합실제 프로젝트에서는 다양한 Prompt 분포가 중요합니다.
오류 17. LoRA를 썼는데 Reference Model까지 복사함
현재 공식 PPO 예제는 PEFT 설정이 있으면 `ref_policy=None`으로 구성하는 패턴을 사용합니다.
메모리가 부족하다면 이 구조를 참고합니다.
다만 실제 사용 중인 TRL 버전과 Adapter 구성을 반드시 확인합니다.
오류 18. 최신 PPO 문서와 예제가 다름
PPO는 현재 TRL의 Experimental 영역입니다.
즉:
Minor Version Update
↓
API 변화 가능운영 프로젝트라면 버전을 고정합니다.
trl==1.10.0그리고 해당 버전에서 검증한 코드를 유지합니다.
60. 연습 문제
문제 1
Policy Model과 Reference Model의 차이를 설명하세요.
문제 2
Reward Model과 Value Model의 차이를 설명하세요.
문제 3
다음 PPO 파이프라인의 빈칸을 채우세요.
Prompt
↓
( )
↓
Response
↓
( )
↓
Reward
↓
PPO Update문제 4
Reward Score가 5.0이고 KL Penalty가 1.2라면 단순화한 RLHF Reward는 얼마인가요?
3.8문제 5
실제 Return이 4이고 Value Prediction이 2라고 단순화하면 Advantage의 방향은 양수인가요, 음수인가요?
양수문제 6
Policy Ratio가 다음일 때 어떤 상태인지 설명하세요.
1.02
5.70
0.12문제 7
다음 PPOConfig를 작성하세요.
Learning Rate:
3e-6
Clip Range:
0.2
KL Coefficient:
0.05
Gamma:
1.0
Lambda:
0.95문제 8
Response Length를 64, 128, 256으로 변경해 GPU 메모리와 Reward를 비교하세요.
문제 9
Temperature를 다음 값으로 비교하세요.
0.3
0.7
1.0문제 10
Missing EOS Penalty를 사용했을 때 EOS 생성 비율을 비교하세요.
문제 11
다음 로그를 그래프로 기록하세요.
objective/scores
objective/rlhf_reward
objective/kl
val/ratio
loss/value_avg문제 12
Policy에 LoRA를 적용하세요.
r:
16
alpha:
32
target:
q_proj
k_proj
v_proj
o_proj문제 13
PPO 학습 전과 후에 같은 20개 Prompt를 생성하고 Reward 평균을 비교하세요.
문제 14
Reward Model이 긴 답변을 편향적으로 선호하는지 검사하세요.
문제 15
Human Evaluation으로 PPO Model과 SFT Model의 Blind Win Rate를 계산하세요.
문제 16
다음 조건에서 PPO를 안정화하세요.
objective/kl 급상승
val/ratio = 8
Reward 증가
사람 평가 하락문제 17
`num_ppo_epochs=1`, `2`, `4`를 비교하세요.
문제 18
`kl_coef=0.01`, `0.05`, `0.1`을 비교하세요.
문제 19
Reward Hacking이 발생한 Candidate를 자동 저장하는 로직을 추가하세요.
문제 20
다음 전체 RLHF 평가표를 만드세요.
SFT Model
Reward Model
PPO Model
평균 Reward
KL
사람 승률
평균 답변 길이
EOS 비율
GPU 메모리
학습 시간61. 핵심 요약
현재 PPO Import
from trl.experimental.ppo import (
PPOConfig,
PPOTrainer
)Policy Model
policy = (
AutoModelForCausalLM
.from_pretrained(
SFT_MODEL_PATH
)
)Reference Model
reference = (
AutoModelForCausalLM
.from_pretrained(
SFT_MODEL_PATH
)
)Reward Model
reward_model = (
AutoModelForSequenceClassification
.from_pretrained(
REWARD_MODEL_PATH,
num_labels=1
)
)Value Model
value_model = (
AutoModelForSequenceClassification
.from_pretrained(
REWARD_MODEL_PATH,
num_labels=1
)
)PPOConfig
ppo_config = PPOConfig(
output_dir="outputs/ppo",
learning_rate=3e-6,
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
total_episodes=1000,
response_length=128,
temperature=0.7,
num_ppo_epochs=4,
kl_coef=0.05,
cliprange=0.2,
vf_coef=0.1,
gamma=1.0,
lam=0.95,
stop_token="eos",
missing_eos_penalty=1.0
)PPOTrainer
trainer = PPOTrainer(
args=ppo_config,
processing_class=tokenizer,
model=policy,
ref_model=reference,
reward_model=reward_model,
value_model=value_model,
train_dataset=train_dataset
)학습
trainer.train()저장
trainer.save_model(
"models/ppo-model"
)62. 마무리
이번 시간에는 Hugging Face TRL의 PPOTrainer를 이용해 Reward Model의 점수로 생성형 AI를 강화학습시키는 전체 구조를 알아보았습니다.
지금까지의 시리즈가 드디어 하나의 RLHF 파이프라인으로 연결되었습니다.
SFTTrainer
↓
질문에 답하는 기본 능력
RewardTrainer
↓
답변 품질 평가 능력
PPOTrainer
↓
Reward를 높이는 방향으로
생성 모델 학습PPO에는 네 명의 핵심 등장인물이 있습니다.
Policy Model
→ 선수
Reference Model
→ 경기 전 기준 기록
Reward Model
→ 심판
Value Model
→ 경기 흐름을 예측하는 분석가Policy가 새로운 답변을 생성합니다.
Reward Model이 채점합니다.
Value Model은 예상 Reward를 계산합니다.
Reference Model은 Policy가 너무 멀리 도망가지 않는지 감시합니다.
그리고 PPO가 이 모든 정보를 모읍니다.
“이 행동은 예상보다 좋았군.”
→ 확률 조금 증가
“이 행동은 예상보다 나빴군.”
→ 확률 조금 감소
“잠깐, 너무 많이 바뀌고 있어.”
→ Clip
“기존 모델에서 너무 멀어졌다.”
→ KL Penalty이것이 PPO의 핵심입니다.
좋은 행동을 강화하되 한 번에 모델을 너무 크게 바꾸지 않는다.
PPO를 이해하면 왜 생성형 AI 강화학습이 단순 Fine-tuning보다 복잡한지도 명확해집니다.
SFT:
정답을 보고 공부
DPO:
좋은 답변과 나쁜 답변을 비교
PPO:
직접 답변 생성
→ 채점
→ 결과 분석
→ 행동 수정
→ 다시 생성즉 PPO부터는 모델이 훈련 데이터에 적힌 답변만 보는 것이 아닙니다.
현재 자신의 행동으로 새로운 학습 데이터를 만들어 냅니다.
Policy:
“이번에는 이렇게 답해 보겠습니다.”
Reward Model:
“2.1점.”
Policy:
“그럼 조금 바꿔보죠.”
Reward Model:
“3.8점.”
PPO:
“좋습니다.
그 방향의 확률을 조금 높이겠습니다.”하지만 PPO의 가장 큰 함정도 바로 여기에 있습니다.
Reward가 높다
≠
사람이 정말 만족한다Reward Model이 잘못된 기준을 가지고 있다면 PPO는 그 잘못된 기준을 매우 열심히 최적화합니다.
잘못된 Reward Model
+
강력한 PPO
=
잘못된 행동을
매우 잘하는 모델따라서 RLHF에서 가장 중요한 것은 PPO 알고리즘 하나가 아닙니다.
좋은 SFT Model
+
정확한 Reward Model
+
다양한 Prompt
+
안정적인 PPO 설정
+
독립적인 사람 평가이 모든 것이 함께 필요합니다.
그리고 현재 생성형 AI 강화학습 분야에서는 PPO의 Value Model과 복잡한 RLHF 구조를 줄이는 새로운 방법들도 활발하게 사용되고 있습니다.
그 대표적인 방법이 다음 편의 주인공입니다.
다음 편 예고
[Python 완전정복 시리즈 #43] GRPOTrainer 완벽 이해하기 | Value Model 없이 여러 답변을 비교해 추론형 AI를 강화학습하는 방법
다음 시간에는 PPO보다 구조를 단순화하면서 최근 추론형 AI 학습에서 매우 중요해진 GRPO, Group Relative Policy Optimization을 알아봅니다.
하나의 Prompt
↓
답변 A
답변 B
답변 C
답변 D
↓
각 답변 Reward 계산
↓
그룹 평균과 비교
↓
상대적으로 좋은 답변 강화PPO에서는 필요했던:
Value Model을 제거하고 같은 Prompt에서 생성된 여러 답변의 상대적인 Reward를 이용해 Advantage를 계산하는 방법을 살펴봅니다.
다음 편에서는 다음 내용까지 연결합니다.
GRPO 개념
Group Sampling
Reward Function
Reward Model
Advantage Normalization
KL Penalty
Accuracy Reward
Format Reward
Multiple Reward Functions
LoRA
QLoRA
Reasoning Model 학습
TRL GRPOTrainer
실전 수학·코딩 추론 프로젝트PPO에서 네 명이 필요했던 훈련장에 새로운 감독이 들어옵니다.
GRPO:
“Value Model이요?
이번 경기에는
벤치에서 쉬셔도 됩니다.”추론형 AI 강화학습의 세계로 넘어가 보겠습니다. 🧠🤖🏆
#Python #파이썬 #Python강좌 #HuggingFace #TRL #PPO #PPOTrainer #ProximalPolicyOptimization #RLHF #강화학습 #ReinforcementLearning #PolicyModel #ReferenceModel #RewardModel #ValueModel #Advantage #GAE #KLDivergence #KLPenalty #PPOClipping #RewardHacking #LoRA #QLoRA #PEFT #Transformers #생성형AI #LLM #AI정렬 #PostTraining #FineTuning #GRPO #PyTorch #코딩공부 #프로그래밍
