DL/LLM

[LLM] 논문 리뷰 - LLM 강화학습 파인튜닝에서 BF16보다 FP16이 더 우수한 성능을 보일 수 있는 이유.

moonzoo 2026. 1. 1. 21:20

 

https://arxiv.org/abs/2510.26788

 

Defeating the Training-Inference Mismatch via FP16

Reinforcement learning (RL) fine-tuning of large language models (LLMs) often suffers from instability due to the numerical mismatch between the training and inference policies. While prior work has attempted to mitigate this issue through algorithmic corr

arxiv.org

 

 

1. 개요: Defeating the Training-Inference Mismatch via FP16 논문 리뷰

강화학습(RLHF/RLAIF)을 진행할 때, 엔지니어들이 흔히 겪는 현상이 있습니다. 모델이 학습 중에 보이는 행동과 실제 사용할 때의 행동이 다른 현상입니다. 이를 Distribution Shift 또는 Policy Mismatch라고 하며, 이로 인해 강화학습 파인튜닝 과정이 불안정해지는 문제가 발생합니다.

본 논문에서 다루는 연구는 이 문제의 원인을 복잡한 알고리즘이 아닌, 가장 기초적인 수치 정밀도(Numerical Precision) 에서 찾았습니다. 학습에서 사용하는 수치 표현 방식, 즉, 부동소수점 정밀도를 단순하게 최신의 포맷인 BF16에서 이전 세대의 포맷인 FP16으로 되돌리는 것만으로도 안정성과 일관성을 되찾을 수 있다는 사실을 발견했습니다.

 

결론적으로, LLM-RL-Finetuning에서 최신 포맷인 BF16 대신 이전 세대의 포맷인 FP16을 사용하는 것만으로도 학습의 안정성과 성능을 획기적으로 개선할 수 있음을 시사합니다.


2. 문제의 발단: 추론과 학습의 연산 불일치(Training-Inference Mismatch)

일반적인 사전학습(Pre-training) 단계에서는 BF16(Bfloat16) 이 표준으로 사용됩니다. 하지만 강화학습 단계에서는 BF16의 낮은 정밀도가 치명적인 오차를 유발할 수 있습니다.

 

 

온폴리시(On-Policy) 강화학습(예: PPO)의 파이프라인은 크게 두가지 단계로 나뉩니다.

 

  1. Generation (Inference): 현재 정책 $\pi_{old}$을 사용하여 응답을 생성(Rollout)하고 경험을 수집합니다.
  2. Training (Update): 수집된 데이터를 바탕으로 모델의 Logits을 다시 계산하고 Gradient를 업데이트합니다.

이론적으로 두 과정의 출력값은 동일해야 합니다. 하지만 비결정적(Non-deterministic) 연산 특성으로 인해 미세한 차이가 즉 Training-Inference Mismatch가 발생합니다. 원인은 다음과 같습니다. 

  • 병렬 연산의 순서 차이: GPU 분산 학습(Tensor Parallelism) 시 AllReduce 과정에서 덧셈 순서가 달라지면, 부동소수점의 결합법칙 성립 불가(Non-associativity) 특성으로 인해 결과값에 미세한 차이가 생깁니다. 즉, 부동소수점 반올림 오차가 누적되는 현상인 것이죠. 
  • 커널 구현의 차이: 추론용 커널과 학습용 커널의 반올림(Rounding) 처리 방식이 다를 수 있습니다.

문제는 BF16 포맷이 이 '미세한 차이'를 수용하지 못하고 오차로 키운다는 점입니다. 이로인해, 모델이 업데이트되지 않았음에도 불구하고, 마치 정책이 변한 것처럼(Fake KL Divergence) 인식하게 만들어 학습의 불안정성을 초래합니다.

 

이 Mismatch를 증폭시키는 주원인은 BF16 포맷의 구조적 한계에 있습니다.


3. 문제점 : BF16의 구조적 한계와 오차 증폭

3.1. 유효숫자 부족에 따른 정보 소실

BF16과 FP16은 모두 16비트이지만, 비트 할당 전략이 다릅니다.

 

  • BF16 (1 Sign, 8 Exponent, 7 Mantissa):
     
    FP32와 동일한 지수부를 가져 Overflow 방지에는 유리합니다. 하지만 유효숫자 비트 수($p$)가 8비트(저장 7비트 + 숨은 비트 1비트)에 불과합니다. BF16의 기계 엡실론은 다음과 같이 계산됩니다. 즉, BF16 환경에서는 약 0.8% 수준의 상대 오차보다 작은 변화는 수치적으로 구분되지 않거나, 반올림 과정에서 왜곡될 수 있습니다.
    • $$\epsilon \approx 2^{-(8-1)} = 2^{-7} = \frac{1}{128} \approx 7.8 \times 10^{-3}$$
  • FP16 (1 Sign, 5 Exponent, 10 Mantissa):
    가수부가 10비트이므로 유효숫자 비트 수($p$)는 11비트가 됩니다.
    이는 BF16 대비 8배 더 정밀한 값을 표현할 수 있음을 의미합니다. 강화학습에서 확률 값의 변화가 미세하게 일어날 때, BF16의 0.8%라는 오차 한계는 무시할 수 없는 노이즈가 됩니다. 
    • $$\epsilon \approx 2^{-(11-1)} = 2^{-10} = \frac{1}{1024} \approx 9.7 \times 10^{-4}$$

3.2. PPO 알고리즘에서의 치명적 영향 (Importance Sampling)

이러한 정밀도 차이는 PPO(Proximal Policy Optimization) 알고리즘의 핵심 수식인 비율(Ratio) 계산에서 치명적으로 작용합니다.

$$r_t(\theta) = \frac{\pi_\theta(a_t|s_t)}{\pi_{old}(a_t|s_t)}$$

PPO는 현재 정책($\pi_\theta$)과 이전 정책($\pi_{old}$)의 확률 비율($r_t$)을 계산하여 업데이트 폭을 조절합니다.

  • BF16 사용 시: 추론 단계의 $\pi_{old}$ 값과, 학습 단계에서 재계산한 $\pi_{old}$ 값 사이에 수치적 오차가 발생합니다. 실제로는 모델이 업데이트되지 않았음에도, BF16의 정밀도 한계(약 0.8%)로 인해 $r_t$ 값이 1이 아닌 값으로 튀어버릴 수 있습니다.
  • 결과: 알고리즘은 이를 "정책이 급격히 변했다"고 오인하여 KL Penalty를 부과하거나, Clipping을 작동시킵니다. 이는 학습 초기에 허상의 KL Spike를 유발하고 학습 방향을 왜곡시킵니다.


LLM의 Logits 값은 매우 민감한 확률 분포를 나타내며, 특히 PPO에서는 log_prob의 미세한 차이가 KL Penalty와 Advantage 계산에 직접적인 영향을 미칩니다. BF16의 낮은 정밀도는 이 미세한 차이를 노이즈로 처리하지 못하고 오차로 누적시킵니다.


4. 해결책: 왜 RL Fine-tuning에서는 FP16인가?

연구 결과에 따르면, 모델의 가중치 포맷을 BF16에서 FP16으로 변경하는 것만으로 Training-Inference Mismatch 문제를 효과적으로 완화할 수 있습니다.

 

위에서 언급한 BF16, FP16의 구조를 보면 각각의 장 단점이 있습니다.

  • FP16 : 표현할 수 있는 값의 범위가 좁습니다. 숫자가 너무 크거나 작아지면 Overflow(값이 너무 커져버림) 또는 Underflow(0으로 사라짐)이 일어날 수 있습니다.
  • BF16 : 결과적으로 BF16은 극단적인 값에도 잘 버티지만, 정밀도가 거칠어지는(Format이 거친) 구조가 됩니다. ->잘 죽지는 않지만, 세밀한 차이는 흐릿하게 만들어버리는 셈입니다.

대규모의 사전학습 단계에서는 이런 정도의 트레이드오프는 합리적이었습니다. 모델이 다루는 값의 크기와 변화 폭이 워낙 크기 때문에, BF16의 넓은 값 범위가 매우 중요했습니다. 하지만, 강화학습 파인튜닝 단계에서는 상황이 역전됩니다. 

 

사전학습(Pre-training)과 달리, RL 파인튜닝 단계에서는 Dynamic Range(범위)보다 Precision(정밀도)이 훨씬 중요합니다.

 

Pre-training vs RL Fine-tuning

  • Pre-training (BF16 권장): 초기 학습 단계에서는 Gradient의 스케일이 매우 크고 변동 폭이 넓어, FP16의 좁은 지수부 범위로는 Overflow/Underflow가 발생하기 쉽습니다.
  • RL Fine-tuning (FP16 권장): SFT(Supervised Fine-tuning)가 완료된 모델은 가중치가 이미 안정적인 분포를 가집니다. 따라서 Dynamic Range에 여유가 생기며, 정밀도가 더 중요한 요소가 됩니다.

강화학습 파인튜닝에서는 수많은 확률 추정(Probability Estimate)이 연쇄적으로 이어지는 구조입니다. 이때 아주 작은 반올림 오차라도 있으면 시간이 지날수록 누적(Compound)되어서 정책이 점점 어긋나기 시작합니다. 즉 하나의 정밀도가 매우 소중한 상황입니다.

위에서 이야기한 것처럼, BF16은 가수부가 7비트이기 때문에 시간이 지날수록 오차가 점점 쌓이면서 훈련과 추론의 불일치가 커집니다. 반면에 FP16은 10비트를 사용하기 때문에 이 값들을 안정적으로 유지할 수 있는 것이죠. 수치적으로 보면 아래와 같이 8배의 정밀도 차이가 발생합니다.
FP16 : 2^10 -> 1024
BF16 : 2^7 -> 128

이 차이 덕분에 FP16은 훈련과 추론 사이의 일관성(Consistency)을 유지하고, 불안정성이 폭주(Instability Spiraling)하는 것을 막을 수 있습니다.

 

FP16의 이점은 다음과 같습니다.

 

4.1. SFT 모델의 가중치 안정성

Pre-training 초기에는 Gradient가 매우 크고 불안정하여 FP16의 좁은 지수부 범위($\sim 65,504$)를 넘어설 위험(Overflow)이 큽니다. 하지만 RL 파인튜닝은 이미 수렴된 SFT 모델을 기반으로 시작합니다. 가중치와 활성화 값의 분포가 안정적이므로, FP16의 좁은 범위 내에서도 충분히 표현 가능합니다.

 

4.2. 수치적 정합성 향상 : 노이즈 버퍼링 효과

FP16의 10비트 가수부는 추론-학습 엔진 간의 미세한 연산 차이를 '유효 숫자 범위 내'에서 흡수할 수 있습니다. 즉, 연산 순서가 달라져서 발생하는 하위 비트의 변동이 상위 비트(실제 확률값)에 영향을 주지 않도록 완충 작용을 합니다.

실제 실험 결과, FP16 적용 시 Training-Inference 간의 L2 Error Norm이 BF16 대비 약 24배 감소했습니다.

 

4.3 학습 안정성 (KL Spike 제거)

BF16 환경에서 PPO 학습 시, 초반에 KL Divergence가 급격히 치솟는 현상(KL Spike)이 자주 관측됩니다. 이는 실제 정책의 변화가 아니라 수치적 오차로 인한 허상의 변화입니다. FP16 환경에서는 초기 KL 값이 0에 가깝게 유지되며, 의도한 대로 정책 업데이트가 이루어집니다.


4. Reward 수렴 속도

수치적 노이즈가 제거되면서 Advantage Estimation이 정확해지고, 결과적으로 Reward 곡선이 더 빠르고 안정적으로 우상향하는 결과를 보입니다.

 


5. 실험 결과 : BF16에서 FP16으로 변환한 결과

연구팀은 이론적 가설을 검증하기 위해 다양한 모델 아키텍처와 학습 환경에서 광범위한 실험을 진행했습니다. 결과는 명확했습니다. FP16은 단순한 정밀도 변경 그 이상의 성능 향상을 가져왔습니다.

 

5.1. 오프라인 성능 점검: 24배의 차이

먼저 DeepSeek-R1-Distill-Qwen-1.5B 모델을 대상으로 기초 성능을 점검했습니다.

  • 추론 속도 (Raw Inference Performance): FP16, BF16, FP32 간에 유의미한 속도 차이는 없었습니다.
  • Mismatch 오차: 여기가 핵심입니다. FP16을 사용했을 때, 훈련-추론 간 불일치(Mismatch)가 BF16 대비 약 24배 감소했습니다.

이 극적인 오차 감소 덕분에 Rollout(시뮬레이션) 단계의 확률 분포와 훈련 단계의 확률 분포가 밀접하게 일치하게 되었고, 이는 곧 학습의 안정성으로 직결되었습니다.

 

5.2. Sanity Test: 수학 문제 해결 (MATH Dataset)

연구팀은 1,460개의 '풀 수 있지만 단순하지 않은' 수학 문제 집합을 사용하여 검증 실험을 수행했습니다. (통과 기준: 정확도 95% 이상)

 

[BF16 환경의 실패]

BF16 환경에서는 어떤 알고리즘을 써도 학습이 불안정했습니다.

  • Vanilla GRPO: 학습 초기에 즉시 붕괴(Collapse) 현상 발생.
  • Token-level TIS: 붕괴는 면했으나 안정적으로 수렴하지 못함.
  • Sequence-level MIS: 상대적으로 안정적이었으나, 학습 속도가 매우 느리고 정확도가 95% 수준에서 정체(Plateau) 됨.

[FP16 환경의 성공]

반면, Rollout과 Training을 모두 FP16으로 전환하자 놀라운 변화가 일어났습니다.

  • 학습이 빠르고 안정적으로 수렴했습니다.
  • 일부 케이스에서는 정확도가 약 99%에 도달했습니다.
  • 핵심 : FP16 환경에서는 복잡한 보정 기법(TIS, MIS 등)을 적용하지 않은 단순한 기본 알고리즘(Vanilla Policy Gradient)이 BF16 기반의 복잡한 알고리즘보다 더 우수한 성능을 보였습니다.

5.3. 다양한 모델 아키텍처에서의 검증

이 현상은 특정 모델에 국한되지 않고 다양한 세팅에서 일관되게 관찰되었습니다.

실험 모델 및 환경 BF16 결과 FP16 결과
MoE (Qwen3-30B-A3B) 보상(Reward) 상승 폭이 제한적임 더 높은 보상 달성 및 안정적 학습 곡선 유지
LoRA Fine-tuning 600 Step 이후 학습 붕괴(Collapse) 전체 과정에서 붕괴 없이 안정적 유지
Dense (Qwen3-14B) 수렴 속도가 느림 빠른 수렴 속도 및 더 높은 최종 정확도 달성
OctoThinker (Llama-3.2) 150 Step 부터 반올림 오차 누적으로 불안정화 전체 학습 구간 내내 안정적

 

FP16은 단순히 정밀도를 조금 높인 것뿐인데도, 모델이 훨씬 일관되고 예측 가능한 방식으로 학습할 수 있게 되었습니다. 

 

5.4. 심층 분석: 편향-분산 트레이드오프 (Bias-Variance Tradeoff)

FP16의 우수성은 통계적 관점인 '편향과 분산'에서도 설명됩니다.

  • BF16의 딜레마:
    • GRPO나 Token-level IS 같은 방식을 쓰면 분산은 낮지만 편향이 높아 모델이 붕괴합니다.
    • 반대로 Seq-IS 방식을 쓰면 편향은 낮지만 분산이 높아 학습이 너무 느립니다.
    • 즉, BF16에서는 안정성과 속도 중 하나를 포기해야 합니다.
  • FP16의 해결책:
    • 높은 정밀도가 훈련-추론 불일치로 인한 편향(Bias) 을 제거합니다.
    • 동시에 Importance Sampling 과정의 분산(Variance) 까지 안정화시킵니다.
    • 결과적으로 트레이드오프가 사라져, 단순한 알고리즘으로도 빠르고 안정적인 학습이 가능해집니다.

5.5. 정밀도 조합에 따른 비교 (Ablation Study)

연구팀은 BF16 훈련 + FP32 추론 조합도 테스트했습니다.

  • BF16 Train + FP32 Inference: 훈련 안정성은 개선되나, 추론 속도가 약 3배 느려짐.
  • FP16 Train + FP16 Inference: 안정성, 속도, 정확도(거의 100% 근접) 등 모든 지표에서 가장 균형 잡힌 최고 성능을 기록.

6. 결론: 가장 기본부터 되짚어보자.

딥러닝 엔지니어링에서 "최신 기술 = 최적의 솔루션"이라는 공식은 항상 성립하지 않습니다. BF16은 거대 모델의 사전학습을 가능하게 한 혁신적인 포맷이지만, 미세한 확률 제어가 필요한 강화학습 단계에서는 독이 될 수 있다는 연구 결과를 확인할 수 있습니다.

 

이 논문의 연구 결과를 실제로 적용한 많은 연구자들도 특정 케이스에선 FP16이 훨씬 더 좋은 성능이 나온다고 합니다.

이 글을 읽는 분들 중 현재 LLM 강화학습(PPO/GRPO 등)을 수행 중이거나 계획 중이라면, 모델 로딩 및 학습 설정을 bfloat16에서 float16으로 변경하여 테스트해봐도 좋을 것 같습니다. 코드 몇 줄의 수정만으로 학습의 불안정성을 제거하고 수렴 속도를 높일 수 있는 가장 확실한 방법일 수 있습니다.

 

그러나, FP16을 사용할 때는 Gradient Underflow를 방지하기 위해 Loss Scaling이 필수적입니다. 요즘 프레임워크에서는 이를 모두 지원하고 있고, 자동 적용되기도 하니 한번 확인해보시고 적용해보시면 좋겠습니다.