---
title: "DeepSeek-R1 해부: 정답 채점으로 ‘생각하는’ 모델을 길들이는 GRPO와 2단계 RL"
slug: "deepseek-r1-reinforcement-learning-deep-dive"
category: "AI / LLM"
topic: "ai-llm"
subtopic: "transformer"
tags: ["DeepSeek-R1","GRPO","Reinforcement Learning","Reasoning Model","LLMOps","Paper Review"]
status: "published"
created: "2026-07-24"
updated: "2026-07-24"
summary: "DeepSeek-R1 논문을 DeepSeek-R1-Zero의 순수 강화학습, GRPO의 그룹 상대 보상, cold start·거절 샘플링·두 번째 SFT·두 번째 RL, 보상 해킹과 운영 한계까지 연결해 읽는다. ‘긴 생각’이 왜 성능과 비용을 함께 바꾸는지 직접 계산으로 확인한다."
kind: "Deep Dive"
evidence: "DeepSeek-R1 원 논문 arXiv v2·공식 DeepSeek-R1 README/모델 문서·Python 3.9 순수 GRPO 계산"
series: "LLM 시스템 지도 — 0단계"
---

> **0단계 세 번째 논문.** 이 글은 [DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning](https://arxiv.org/abs/2501.12948v2) arXiv v2(2026-01-04)를 직접 읽고 썼다. 아래 숫자와 결과는 그 논문 및 [공식 DeepSeek-R1 저장소의 고정 commit `0cf7856`](https://github.com/deepseek-ai/DeepSeek-R1/tree/0cf78561f1d51c84a21b2190626b21116d5c68bb)을 기준으로 한다. 2026년 현재의 최고 모델 순위, 어느 서비스의 현재 API 동작, 또는 비공개 학습 코드를 재현했다는 주장은 하지 않는다.

## 이 글에서 얻을 답과 범위

이 글의 최초 질문은 아주 단순하다.

> **사람이 ‘이렇게 생각해’라고 쓴 풀이를 잔뜩 주지 않아도, 정답인지 틀렸는지만 채점해서 언어 모델(Language Model, 언어 모델)의 문제 해결 과정을 더 좋게 만들 수 있을까?**

DeepSeek-R1 논문의 답은 조건부로 **그렇다**다. 수학 답, 코드 테스트처럼 정답을 비교할 수 있는 문제에서는 보상(reward, 행동에 주는 점수)과 대규모 강화학습(Reinforcement Learning, RL)을 주어 긴 검토·재시도 같은 출력 행동이 나타나게 할 수 있었다고 보고한다. 그러나 이것은 “모든 질문에 믿을 만한 사고력을 공짜로 만든다”는 뜻이 아니다. 무엇을 정답으로 볼지 채점할 수 있어야 하고, 보상 함수를 속이는 reward hacking(보상 해킹), 긴 지연 시간, 언어 혼합, 도구 사용 부재가 함께 생긴다.

이 글을 다 읽으면 다음 질문에 답할 수 있어야 한다.

1. DeepSeek-R1-Zero와 최종 DeepSeek-R1은 왜 다른 모델이며, “순수 RL”은 어디까지 맞는 말인가?
2. GRPO(Group Relative Policy Optimization, 그룹 상대 정책 최적화)는 한 질문에 여러 답을 뽑아 어떻게 학습 신호로 바꾸는가?
3. `정답 보상 + 형식 보상`만으로 왜 더 긴 풀이와 자기 검토처럼 보이는 출력이 나타날 수 있는가?
4. cold start(콜드 스타트), SFT(Supervised Fine-Tuning, 지도 미세조정), rejection sampling(거절 샘플링), 두 번째 RL은 각각 어떤 실패를 고치는가?
5. R1의 긴 `think` 텍스트를 제품의 사실·보안·도구 호출 근거로 믿으면 왜 위험한가?
6. 백엔드·DBA 출신 개발자가 RAG(Retrieval-Augmented Generation, 검색 증강 생성), 데이터 파이프라인, AI 에이전트에 이 논문을 어떻게 적용하고 무엇을 미뤄야 하는가?

**범위:** 이 글은 DeepSeek-V3-Base 위에서 한 사후학습(post-training) 논문을 설명한다. 671B 모델을 학습하거나 가중치를 실행하지는 않는다. R1의 기반 Transformer·MoE(Mixture of Experts, 전문가 혼합)·MLA(Multi-head Latent Attention, 다중 헤드 잠재 어텐션)는 이전 글 [DeepSeek-V3 Technical Report 해부](/posts/deepseek-v3-technical-report-deep-dive)에서 구조를 다뤘다. 여기서는 그 기반 모델 위에 **어떤 학습 루프를 얹었는지**를 끝까지 내려간다. 공개 R1 저장소에는 학습 구현이 없으므로, 비공개 학습 코드를 읽었다고 말하지 않는다.

### 먼저 외울 한 문장

> **DeepSeek-R1은 한 질문의 여러 답을 채점해 같은 그룹 안에서 상대적으로 더 좋은 답의 확률을 올리는 GRPO를 사용했고, R1-Zero의 읽기 어려움과 언어 혼합을 cold start·두 SFT·두 RL 단계로 보정한 reasoning model(추론 모델)이다.**

## 왜 필요한가: “정답 풀이를 베끼기”만으로는 탐색이 막힌다

12살 학생에게 어려운 수학 문제를 가르친다고 생각해 보자.

```text
방법 A: 선생님 풀이 10만 장을 그대로 베끼게 한다.
방법 B: 같은 문제에 16번 도전하게 하고,
        정답·제출 형식만 자동 채점한다.
        같은 16개 중 더 잘한 시도는 조금 더 자주 하게 만든다.
```

방법 A는 SFT다. 입력 질문과 사람이 만든 좋은 답을 짝으로 주고, 모델이 그 답의 다음 단어를 맞히게 한다. 문체·형식·기본 행동을 빠르게 가르치기 좋다. 하지만 사람이 작성한 풀이 밖의 전략을 스스로 발견하기에는 제한이 있다.

방법 B가 RL이다. 모델을 policy(정책, 현재 답을 생성하는 확률 규칙)라고 부르고, 생성한 행동의 결과에 점수를 준 뒤 좋은 행동의 확률을 올린다. 수학의 최종 답이나 코드의 테스트 통과 여부는 verifier(검증기, 답을 규칙으로 채점하는 프로그램)로 비교적 싸고 명확하게 점수화할 수 있다.

**논문 확인:** DeepSeek-R1-Zero는 DeepSeek-V3-Base에 **SFT를 먼저 하지 않고** GRPO를 적용했다. 논문은 수학·코드·논리 문제에서 정확도 보상과 `<think>...</think>`, `<answer>...</answer>` 형식 보상을 썼다고 설명한다(논문 §2.1–2.3). AIME 2024의 논문 보고 pass@1은 학습 전 15.6%에서 77.9%로 상승했다. 단, 그 수치는 논문이 정한 데이터·프롬프트·샘플링 조건의 벤치마크 결과이지 일반 지능 점수가 아니다.

### 그런데 R1-Zero만으로 끝내면 왜 안 되는가

순수 RL 결과인 R1-Zero는 문제 풀이 점수는 강했지만, 논문은 다음 제품 문제를 명시한다.

- 반복이 끝나지 않거나 문장이 읽기 어렵다.
- 하나의 사고 출력 안에 영어와 중국어가 섞일 수 있다.
- 규칙 채점이 가능한 추론 문제에 치우쳐 글쓰기·일반 질의응답 품질이 부족하다.
- 사람이 원하는 답보다 보상 함수가 좋아하는 이상한 답을 만들 수 있다.

그래서 최종 R1은 “순수 RL 모델”이 아니다. **R1-Zero가 순수 RL 실험이고, 최종 R1은 사람 검수 cold-start 데이터, 두 번의 SFT, 두 번의 RL을 결합한 제품 지향 모델**이다. 이 구분을 놓치면 논문의 핵심을 반만 이해하게 된다.

## 무엇인가: R1-Zero, R1, Distill을 한 바구니에 넣지 않기

공식 [README의 모델 표](https://github.com/deepseek-ai/DeepSeek-R1/blob/0cf78561f1d51c84a21b2190626b21116d5c68bb/README.md#3-model-downloads)는 R1-Zero와 R1 모두 DeepSeek-V3-Base 기반이며 671B total parameters(전체 파라미터), 토큰당 약 37B activated parameters(활성 파라미터), 128K context를 제시한다. 논문 부록의 “660B” 표현은 반올림된 표기처럼 보이지만 이유를 정의하지 않으므로, 이 글은 공식 표의 671B/37B를 사용하고 둘의 차이를 임의로 해석하지 않는다.

| 이름 | 무엇을 학습했나 | 반드시 기억할 경계 |
|---|---|---|
| DeepSeek-V3-Base | 사전학습(pre-training)을 끝낸 기반 언어 모델 | R1의 뼈대다. R1 논문이 새로운 Transformer 구조를 제안한 것은 아니다. |
| DeepSeek-R1-Zero | SFT 없이 규칙 기반 보상으로 RL | 순수 RL이 긴 추론 출력과 검토 행동을 유도할 수 있는지 보는 실험 모델이다. |
| DeepSeek-R1 | cold start SFT → RL → 거절 샘플링/SFT → RL | 읽기 쉬움, 일반 답변, 도움됨·안전성까지 보정한 최종 모델이다. |
| DeepSeek-R1-Distill-* | R1이 만든 약 800K 학습 표본으로 Qwen/Llama 계열을 SFT | 작은 dense model(밀집 모델)로 전이한 별도 checkpoint다. 원본 671B R1과 같은 모델이 아니다. |

### “생각한다”는 말의 정확한 뜻

R1은 답 앞에 긴 reasoning trace(추론 흔적), 흔히 CoT(Chain-of-Thought, 사고 사슬)라고 부르는 텍스트를 생성한다. 이 글에서는 이를 **모델이 출력한 중간 풀이 텍스트**라고 부른다. 그것이 사람이 머릿속에서 느끼는 의식, 모델 내부의 유일한 계산 경로, 또는 모든 문장이 사실이라는 증거는 아니다.

**논문 확인:** cold start 절은 1인칭·대화체 추론 양식이 DeepSeek가 설계한 heuristics(휴리스틱, 좋은 결과를 위해 넣은 경험적 규칙)이며, 이것이 모델이 인간 같은 지능이나 자율 문제 해결을 얻었다는 뜻은 아니라고 직접 경고한다(부록 B.3.2). 따라서 `think` 출력은 디버깅 힌트나 사용자 설명으로 볼 수는 있어도, 결제·권한·SQL 실행·도구 호출의 신뢰 경계로 쓰면 안 된다.

## 선행 개념: RL을 이해하려면 먼저 “답 하나는 확률의 길”임을 알아야 한다

### 1. 언어 모델은 토큰을 하나씩 고른다

token(토큰)은 모델이 읽고 쓰는 작은 문자 조각이다. 질문 `q`가 있을 때 모델이 답 `o = (o₁, o₂, ..., o_T)`를 만들 확률은 각 다음 토큰 확률을 곱한 것으로 생각할 수 있다.

```text
πθ(o | q)
  = πθ(o₁ | q)
  × πθ(o₂ | q, o₁)
  × ...
  × πθ(o_T | q, o₁ ... o_T₋₁)
```

- `π`(파이): policy, 즉 현재 모델의 확률 규칙
- `θ`(세타): 그 모델의 조절 가능한 파라미터
- `q`: question/prompt, 질문
- `oᵢ`: i번째 출력 토큰
- `T`: 답의 토큰 수

SFT는 정답 문장에 나온 다음 토큰의 확률을 높인다. RL은 완성된 답을 채점한 뒤, **좋은 완성 답으로 이어진 토큰 선택 전체의 확률을 높이는 방향**으로 `θ`를 바꾼다.

### 2. rollout과 reward는 “시험지 여러 장과 채점표”다

- rollout(롤아웃): 현재 policy로 질문 하나의 답을 끝까지 생성하는 실행이다.
- reward(보상): 생성 결과를 수치로 바꾼 점수다. 수학 답 일치면 1, 불일치면 0처럼 만들 수 있다.
- rule-based reward(규칙 기반 보상): 사람이나 다른 LLM이 감으로 평가하지 않고, 답 비교기·컴파일러·테스트·형식 검사기로 점수를 계산한다.
- RM(Reward Model, 보상 모델): “이 답이 더 도움 되는가?”처럼 코드 규칙으로 채점하기 어려운 것을 점수로 예측하는 별도 모델이다.
- reference policy(참조 정책): 학습 모델이 너무 갑자기 이상한 문장을 내지 않도록 거리를 재는 고정 또는 주기적으로 갱신하는 기준 모델이다.

수학의 `2 + 3 = 5`는 규칙으로 채점하기 쉽다. “이 기술 블로그가 독자에게 충분히 유용한가?”는 정답 문자열이 없으므로 RM 또는 사람 평가가 필요하다. 바로 이 차이가 R1식 RL이 잘 맞는 곳과 위험한 곳을 가른다.

### 3. advantage는 절대 점수가 아니라 같은 질문 안의 상대 순위다

GRPO는 질문 하나에 답 `G`개를 만든다. 각 답의 reward가 `r₁, r₂, ..., r_G`일 때, i번째 답의 advantage(어드밴티지, 같은 그룹 평균보다 얼마나 좋은지)는 논문 식 (3)처럼 계산한다.

```text
μ = mean(r₁, r₂, ..., r_G)          # 그룹 평균
σ = std(r₁, r₂, ..., r_G)           # 그룹 표준편차
Aᵢ = (rᵢ - μ) / σ                   # i번째 상대 이점
```

`Aᵢ > 0`이면 그 질문의 다른 시도보다 잘한 답, `Aᵢ < 0`이면 못한 답이다. 예를 들어 4개 답의 정답 점수가 `[0, 0, 1, 1]`이면 평균은 0.5, 모집단 표준편차는 0.5, advantage는 `[-1, -1, +1, +1]`가 된다. “맞은 답을 더 자주 내고, 틀린 답을 덜 내게” 하는 비교 신호가 생긴다.

표준편차가 0이면 모두 맞거나 모두 틀린 그룹이라 상대 순위를 만들 수 없다. 이것은 사소한 수학 문제가 아니라 RL 데이터 설계 문제다. 너무 쉬운 문제만 넣으면 모든 답이 맞고, 너무 어려운 문제만 넣으면 모든 답이 틀려서 그룹 비교 신호가 약해질 수 있다.

## 밑바닥 원리: GRPO가 좋은 답의 확률만 조금씩 올리는 법

### GRPO의 입력·중간 상태·출력

논문 §2.1과 부록 A.3을 12살 수준의 절차로 풀면 다음과 같다.

```text
입력: 질문 q, 이전 정책 πθold, 현재 정책 πθ, 참조 정책 πref, 검증기

1. πθold로 같은 질문 q의 답 G개를 뽑는다.                 # rollout
2. 각 답을 검증기로 채점해 reward r₁ ... rG를 얻는다.       # answer/code/format
3. 같은 질문 그룹의 평균과 표준편차로 A₁ ... AG를 만든다.    # 상대 이점
4. 각 답에서 새 정책이 이전 정책보다 얼마나 확률을 바꿨는지
   ρᵢ = πθ(oi|q) / πθold(oi|q)를 계산한다.                 # policy ratio
5. ρᵢ를 clip(클리핑, 안전 구간 자르기)해 한 번에 너무 멀리
   움직이지 못하게 한다.
6. 좋은 답(Aᵢ > 0)의 확률은 올리고, 나쁜 답(Aᵢ < 0)의 확률은
   내리되, πref와 너무 멀어지면 KL penalty(거리 벌점)를 준다.
7. 이 목적함수의 기울기로 θ를 한 번 갱신한다.

출력: 다음 rollout에서 좋은 답을 더 자주 뽑는 새 정책 πθ
```

### 식 (1): clip과 KL이 없으면 왜 위험한가

논문의 GRPO 목적함수를 읽기 좋은 형태로 쓰면 다음과 같다. `E[...]`는 많은 질문·많은 그룹에 대한 평균이다.

```text
J_GRPO(θ) = E[ (1/G) × Σᵢ {
  min( ρᵢ Aᵢ, clip(ρᵢ, 1-ε, 1+ε) Aᵢ )
  - β × D_KL(πθ || πref)
} ]

ρᵢ = πθ(oᵢ|q) / πθold(oᵢ|q)
```

- `ρᵢ`(rho): 새 정책이 이전 정책보다 그 답을 얼마나 더/덜 선호하는가. `1.0`이면 같다.
- `ε`(epsilon): 허용 변화폭이다. `clip(x, a, b)`는 x가 a보다 작으면 a, b보다 크면 b로 자른다.
- `Aᵢ`: 위에서 만든 그룹 상대 이점이다.
- `β`(beta): KL 벌점의 세기다.
- `D_KL`: KL divergence(Kullback–Leibler divergence, 두 확률 분포가 얼마나 다른지 재는 값)다. 논문 식 (2)는 샘플로 계산하는 추정 항 `πref/πθ - log(πref/πθ) - 1`을 쓴다.

좋은 답의 `Aᵢ`가 양수일 때 `ρᵢ`를 무한히 키우면 모델이 그 답만 과도하게 외우며 불안정해질 수 있다. clip은 좋은 답을 한 번에 너무 크게 올려 생기는 이득을 잘라 준다. KL 항은 기준 모델에서 너무 멀리 떠나는 것을 벌준다. 반대로 나쁜 답의 `Aᵢ`가 음수일 때는 그 답 확률을 내려야 한다.

**중요한 정확성:** 식은 완성 답 단위로 보이지만, 실제 언어 모델의 확률은 토큰들의 확률로 구성된다. 논문은 공개 학습 소스 코드를 제공하지 않아 그 토큰 집계·마스킹의 정확한 구현을 확인할 수 없다. 위 식은 논문이 공개한 목적함수의 수준에서 설명한 것이며, 특정 오픈소스 GRPO 구현의 내부라고 단정하지 않는다.

### PPO와 무엇이 다른가: critic을 덜어 낸 이유

PPO(Proximal Policy Optimization, 근접 정책 최적화)는 보통 value model(가치 모델, 지금까지 만든 일부 답에서 마지막 보상을 예상하는 모델)로 advantage를 추정한다. 긴 CoT에서는 앞에서 쓴 문장이 뒤의 재검토로 뒤집힐 수 있다. 부분 답만 보고 최종 정답 보상을 맞히는 critic은 어렵고, policy와 비슷한 크기의 모델 하나를 더 GPU 메모리에 올리는 비용도 크다.

GRPO는 같은 질문에서 나온 여러 답의 reward를 서로 비교해 advantage를 만든다. 그래서 **GRPO 자체에는 별도 value model이 필요 없다.** 논문 Figure 3과 부록 A.3은 이것을 PPO 대비 메모리·연산 절감 이유로 든다. 단, “critic이 없으니 항상 더 좋다”는 뜻은 아니다. 논문도 PPO가 `λ` 등 하이퍼파라미터를 잘 조정하면 GRPO에 가까운 성능을 낼 수 있다고 보고한다. 선택은 보상 종류, 출력 길이, GPU 예산, 안정성 실험 결과로 해야 한다.

### R1의 보상은 하나가 아니다

R1-Zero의 규칙 보상은 논문 식 (4)처럼 다음 두 항의 합이다.

```text
Reward_rule = Reward_accuracy + Reward_format
```

| 보상 | 예 | 해결하는 문제 | 놓치는 것 |
|---|---|---|---|
| accuracy reward(정확도 보상) | 수학 최종 답 비교, 코드를 컴파일·테스트 | 정답 여부에 명확한 신호 | 풀이가 읽기 좋고 안전한지 |
| format reward(형식 보상) | `<think>`와 `<answer>` 태그가 있는지 | 파서가 최종 답을 찾기 쉬움 | 태그 안 풀이가 참·충실한지 |
| language consistency reward(언어 일관성 보상) | 목표 언어 단어 비율 | 언어 혼합 완화 | 수학·코드 점수의 작은 저하 가능성 |
| helpful/safety RM | 두 답 중 도움됨, 안전/위험 분류 | 일반 대화·안전 선호 | RM 편향과 reward hacking |

**논문 확인:** R1의 첫 RL에서는 language consistency reward를 CoT의 목표 언어 단어 비율로 정의했다(식 7). 이 보상은 읽기 좋게 하지만 부록 B.6의 ablation(제거 실험)에서 코딩 벤치마크의 작은 저하가 보고된다. 따라서 “품질”은 단일 숫자가 아니라 정답·가독성·안전·비용의 묶음이다.

## 내부 구조와 실제 실행 흐름: 최종 R1은 네 번의 교정 단계를 거친다

### 전체 학습 파이프라인

논문 Figure 2를 실행 순서로 바꾸면 다음이다. 화살표 하나마다 앞 단계의 약점을 고친다.

```text
DeepSeek-V3-Base
  │
  ├─ [규칙 보상 RL] ─────────────────────────► DeepSeek-R1-Zero
  │     정확도 + 형식, SFT 선행 없음              강한 추론 / 읽기 어려움·언어 혼합
  │
  ├─ [cold start SFT] ───────────────────────► R1-Dev1
  │     사람 검수·정제한 긴 CoT 양식              대화성↑ / 일부 추론 점수 하락
  │
  ├─ [첫 번째 RL] ───────────────────────────► R1-Dev2
  │     규칙 보상 + 언어 일관성                   추론 회복·개선
  │
  ├─ [거절 샘플링 + 두 번째 SFT] ─────────────► R1-Dev3
  │     약 600K reasoning + 약 200K general      일반 답변·SW 공학 데이터 보강
  │
  └─ [두 번째 RL] ───────────────────────────► DeepSeek-R1
        규칙 보상 + helpful/safety RM + 언어 보상  도움됨·안전·지시 이행 보정
```

### 1단계: R1-Zero의 순수 RL

**논문 확인:** R1-Zero는 질문 하나마다 16개 답을 샘플링한다. 8.2k step 전에는 최대 32,768 tokens, 뒤에는 최대 65,536 tokens까지 생성했다. 32개 고유 질문 × 16개 답으로 한 학습 step의 batch는 512개 샘플이다. 총 10,400 steps(논문 표기 1.6 training epochs) 동안 학습했으며, 400 step마다 reference model을 최신 policy로 교체했다. rollout은 한 번에 8,192개를 생성하고 16 mini-batch로 나누어 inner epoch 1회만 학습했다(§2.1).

이 설정에서 “모델이 오래 생각하도록 명령했다”는 설명은 불완전하다. 긴 답 자체에 점수를 준 것이 아니라, 맞힐 수 있는 어려운 문제에서 더 긴 검토·다른 접근·수정이 정답 확률을 높이는 경우가 많았고, RL이 그런 출력 경로를 더 자주 만들도록 바꿨다. 물론 길이가 정답의 원인은 아니다. 같은 논문도 overthinking(과도한 생각)을 한계로 든다.

### 2단계: cold start는 성능보다 사용자 경험을 위한 교정이다

cold start는 R1-Zero가 만든 원시적인 긴 CoT 중 맞고 읽기 좋은 것을 뽑아 사람 친화적 양식으로 정제한 **수천 개**의 예시로 SFT하는 단계다. 논문 부록 B.3.2의 과정은 다음이다.

1. 다양한 reasoning prompt에 R1-Zero가 높은 temperature 1.0으로 여러 풀이를 만든다.
2. 최종 답이 맞고 형식이 읽기 좋은 출력을 남긴다. 수학식은 SymPy로 파싱·비교하고, 반복·언어 혼합을 필터링한다.
3. DeepSeek-V3가 같은 언어의 자연스러운 풀이·요약으로 정제한다.
4. 사람이 다시 품질과 일관성을 검수한다.

여기서 핵심은 “사람 데이터를 완전히 없앴다”가 아니다. R1-Zero에서 사람이 쓴 **reasoning trajectory(추론 경로)** 없이 출발한 것은 맞지만, 최종 R1에는 사람이 정제·검수한 자료가 들어간다. 논문은 이런 1인칭 사고 양식이 인간 지능의 증거가 아니라 제품 경험을 위한 설계라고도 명시한다.

### 3단계: 첫 번째 RL은 읽기 좋게 하면서 추론을 되찾는다

R1-Dev1의 small cold start는 IF-Eval 같은 지시 이행을 개선하지만 AIME 같은 추론 점수는 일부 낮아질 수 있었다. 그래서 첫 번째 RL을 다시 한다. 논문 §3.2.1의 공개 설정은 learning rate(학습률) `3e-6`, KL coefficient `0.001`, GRPO clip ratio `ε=10`, temperature `1`, 질문당 16개 출력, 최대 32,768 tokens다.

`ε=10`은 일반적인 작은 clip 예시보다 매우 넓게 보일 수 있다. 그래서 이 논문에 다른 프로젝트의 `0.2` 같은 관행 값을 몰래 대입하면 안 된다. 논문은 낮은 clip이 많은 토큰의 gradient(기울기)를 잘라 성능을 낮추고, 높은 clip은 불안정을 만들 수 있다고 말한다. 정답은 숫자 암기가 아니라 **자기 모델·보상·출력 길이에서 holdout(학습에 쓰지 않은 검증 문제)으로 안정성과 성능을 함께 확인하는 것**이다.

### 4단계: 거절 샘플링과 800K SFT는 “정답이 없는 제품 일”을 다시 넣는다

rejection sampling은 여러 생성 후보 중 검증을 통과한 것만 학습 데이터로 채택하는 방법이다. 논문 부록 B.3.3은 첫 RL checkpoint에서 reasoning 표본을 여러 개 뽑고, 정답만 남겨 약 600K reasoning samples를 모았다고 말한다. 글쓰기·사실 QA·번역·자기 인식·소프트웨어 엔지니어링 등 비추론 데이터 약 200K도 더했다. Table 5의 실제 합계는 804,745개 표본이다.

이 단계가 없으면 모델은 채점 가능한 수학·코드에는 강해도, “API 오류를 사용자에게 짧고 정확하게 설명해 줘”처럼 단일 정답 검증기가 없는 제품 요청에는 약할 수 있다. 반대로 이 데이터는 대부분 단일 턴이라 multi-turn conversation(여러 차례 대화) 능력에는 제한이 있을 수 있다고 논문이 스스로 밝힌다.

### 5단계: 두 번째 RL은 모델 보상을 짧게만 쓰는 이유

최종 RL은 reasoning 데이터에는 규칙 보상을, 일반 데이터에는 helpful RM과 safety RM을 더한다. helpful RM은 A/B 응답 순서를 바꿔 네 번 평가해 위치 편향을 줄이고, 점수 차이가 1보다 큰 66K pair를 썼다. safety RM은 106K prompt-response를 안전/위험으로 분류하도록 훈련했다(논문 §3.1).

**논문 확인:** 두 번째 RL은 1,700 steps이고 temperature는 0.7이다. 일반 instruction과 preference-based reward는 마지막 400 steps에만 넣었다. 더 오래 넣으면 reward hacking이 생길 수 있었기 때문이다(§3.2.2, 부록 B.5). 이것은 “RM 점수 상승 = 사람 만족 상승”이라는 등식을 깨는 매우 중요한 실험 결과다.

### 학습 인프라는 모델 하나를 GPU에 올리는 작업이 아니다

논문 부록 B.1은 RL 시스템을 네 모듈로 나눈다.

```text
dataset prompts
  ├─ Rollout module: actor가 답 여러 개 생성(vLLM workers)
  ├─ Inference module: reference/RM forward pass
  ├─ Rule-based reward module: 코드 실행·답 비교·형식 검사
  └─ Training module: loss 계산·actor 갱신
```

- rollout은 MoE expert parallelism(전문가 병렬화), hot expert의 redundant copy(중복 배치), MTP(Multi-Token Prediction, 다중 토큰 예측) speculative decoding(추측 디코딩)을 쓴다고 보고한다.
- 규칙 채점은 GPU를 쓰지 않아도 코드 실행·테스트가 오래 걸릴 수 있으므로 rollout/inference와 비동기로 겹쳐 지연을 숨긴다.
- padding(짧은 시퀀스를 긴 시퀀스 길이에 맞추는 빈 토큰)을 줄이려고 길이순 정렬 후 best-fit packing(빈 공간이 가장 적은 묶음)을 한다.
- 모듈이 끝나면 rule-based reward 모듈을 제외한 모델 인스턴스를 VRAM(Video Random Access Memory, GPU 메모리)에서 시스템 메모리 또는 디스크로 내린다고 설명한다.

즉 R1식 RL의 병목은 “역전파만 빠른 GPU”가 아니다. 긴 rollout, verifier queue(검증 대기열), GPU 메모리의 actor/reference/RM 교대, 코드 샌드박스, 데이터 패킹, 가장 긴 응답의 tail latency(꼬리 지연 시간)를 함께 다뤄야 한다.

## 직접 검증: 논문 식 (1)~(3)을 작은 숫자로 끝까지 계산하기

### 검증 범위와 환경

이 Mac에는 H800 GPU, DeepSeek-R1 671B 가중치, 비공개 학습 프레임워크가 없다. 따라서 “R1을 재학습했다”는 검증은 불가능하며 그렇게 주장하지 않는다. 대신 논문 §2.1의 **GRPO 그룹 advantage, clip 목적항, 식 (2)의 sampled KL 항**을 외부 라이브러리 없이 계산했다.

- 환경: macOS 26.4.1, Python 3.9.6
- 스크립트: `/tmp/deepseek-r1-research/verify_grpo_mechanics.py`
- SHA-256: `d8cc7d322c2a473a465b19a837294959e8c4166b84bbe08855bce7343677e770`
- 입력: 한 질문의 reward `[0, 0, 1, 1]`, 가상의 old/new/reference 확률
- 주의: 확률은 식을 보이기 위한 작은 수다. 실제 R1의 토큰 확률·GPU 분산 구현·gradient update를 재현하지 않는다.

```python
#!/usr/bin/env python3
import math
from statistics import fmean, pstdev

def clipped_surrogate(ratio, advantage, epsilon):
    clipped = min(max(ratio, 1 - epsilon), 1 + epsilon)
    return min(ratio * advantage, clipped * advantage)

def sampled_kl(policy_probability, reference_probability):
    # DeepSeek-R1 Eq. (2)
    ratio = reference_probability / policy_probability
    return ratio - math.log(ratio) - 1

rewards = [0.0, 0.0, 1.0, 1.0]
mean, std = fmean(rewards), pstdev(rewards)
advantages = [(reward - mean) / std for reward in rewards]

old = [0.10, 0.10, 0.10, 0.10]
new = [0.08, 0.08, 0.13, 0.13]
reference = [0.10, 0.10, 0.10, 0.10]
ratios = [n / o for n, o in zip(new, old)]

print("advantages:", advantages)
for epsilon in [0.2, 10.0]:
    terms = [clipped_surrogate(r, a, epsilon)
             for r, a in zip(ratios, advantages)]
    print(epsilon, terms, fmean(terms))

kls = [sampled_kl(p, r) for p, r in zip(new, reference)]
print("sampled KL mean:", fmean(kls))
```

**직접 실행 결과:**

```text
group rewards: [0.0, 0.0, 1.0, 1.0]
mean / population std: 0.500 0.500
normalized advantages: [-1.0, -1.0, 1.0, 1.0]
new / old policy ratios: [0.8, 0.8, 1.3, 1.3]
teaching clip example; epsilon=0.2
  clipped surrogate terms: [-0.8, -0.8, 1.2, 1.2]
  group mean: 0.2
DeepSeek-R1 first-RL paper setting; epsilon=10
  clipped surrogate terms: [-0.8, -0.8, 1.3, 1.3]
  group mean: 0.25
Eq.(2) sampled KL terms: [0.026856, 0.026856, 0.031595, 0.031595]
mean sampled KL: 0.029226
all-equal reward group: group rewards have zero standard deviation; relative advantage is undefined
```

이 결과에서 두 가지를 눈으로 확인할 수 있다.

1. 교육용 `ε=0.2`에서는 좋은 두 답의 `ρ=1.3`이 `1.2`로 잘린다. 한 번의 갱신이 너무 커지지 않게 하는 clip의 역할이다.
2. 논문 첫 RL의 `ε=10`에서는 이 작은 예시의 `0.8`, `1.3`이 모두 허용 범위라 잘리지 않는다. **논문 수치를 일반 RL 튜토리얼의 작은 clip으로 바꿔 쓰면 안 된다.**

마지막 줄은 또 하나의 운영 질문을 만든다. 모든 reward가 같으면 식 (3)의 분모가 0이다. 논문은 공개 코드가 없으므로 실제 zero-variance group(분산 0 그룹)을 어떻게 처리하는지 확인할 수 없다. 실제 구현자는 skip, epsilon 추가, 그룹 필터링 같은 정책을 명시하고 로그로 관찰해야 한다. 그것을 논문이 했다고 추정하면 안 된다.

### 작은 verifier를 먼저 만드는 실습 경로

R1을 재현하려는 초보자가 671B RL 클러스터부터 만들면 실패한다. 다음의 작고 닫힌 환경을 먼저 만든다.

```text
질문: 2자리 정수 두 개의 합을 출력하라.
생성: 작은 로컬 모델이 답 4개를 만든다.
검증: Python int로 정답과 비교한다.
형식: JSON {"answer": 정수}만 허용한다.
로그: prompt_id, 후보 답, verifier 결과, reward, latency, model revision
학습: 처음에는 하지 않는다. 후보 생성·검증·저장·재현부터 한다.
```

이 단계에서 값 하나를 바꿔 본다. `JSON` 형식이 아닌 답에 0점을 주면 모델은 **형식**을 배운다. 정답 비교기를 잘못 만들면 모델은 **비교기의 버그**를 배운다. 이것이 reward design(보상 설계)이 모델 선택보다 먼저여야 하는 이유다. 코드 실행 verifier는 반드시 timeout, 메모리 제한, 네트워크 차단, 읽기 전용 파일시스템 같은 sandbox(샌드박스)를 갖춰야 한다.

## 성능과 트레이드오프: 점수표보다 단계별 손익을 읽기

### 중간 checkpoint가 보여 주는 것

논문 Table 3의 일부를 옮기면, 각 단계가 모든 점수를 동시에 올리지 않는다는 사실이 보인다.

| 벤치마크(지표) | R1-Zero | Dev1 | Dev2 | Dev3 | R1 |
|---|---:|---:|---:|---:|---:|
| IF-Eval (Prompt Strict) | 46.6 | 71.7 | 72.0 | 78.1 | 83.3 |
| AIME 2024 (pass@1) | 77.9 | 59.0 | 74.0 | 78.1 | 79.8 |
| MATH-500 (pass@1) | 95.9 | 94.2 | 95.9 | 95.4 | 97.3 |
| LiveCodeBench (pass@1-CoT) | 50.0 | 57.5 | 63.5 | 64.6 | 65.9 |
| ArenaHard (GPT-4-1106) | 53.6 | 77.0 | 73.2 | 75.6 | 92.3 |

- Dev1: cold start가 지시 이행은 크게 올렸지만 AIME는 77.9 → 59.0으로 낮아졌다.
- Dev2: RL이 수학·코드 추론을 회복했다.
- Dev3: 대규모 SFT가 일반 답변·소프트웨어 엔지니어링을 보강했다.
- 최종 R1: 마지막 RL은 특히 사용자 선호·지시 이행을 더 올렸다.

이 표가 가르치는 것은 “RL이 마법이라 모든 지표를 올린다”가 아니다. **정답 채점 최적화와 사람이 읽기 좋은 제품 행동은 별개의 목표**이며, 데이터·보상·단계를 분리해야 충돌을 발견할 수 있다는 점이다.

### pass@1도 조건을 떼면 오해가 된다

논문은 긴 reasoning model의 greedy decoding(항상 가장 확률 높은 토큰 하나 선택)이 반복과 checkpoint 간 큰 변동을 만든다고 보고한다. 그래서 AIME와 GPQA는 `k=64`, MATH와 Codeforces는 `k=16`, LiveCodeBench는 `k=8` 샘플을 temperature `0.6`, top-p `0.95`로 생성하고, 각 응답의 정답 여부 평균을 pass@1로 보고한다(부록 D.1).

```text
pass@1 = (p₁ + p₂ + ... + p_k) / k
# pᵢ는 i번째 생성 결과가 맞으면 1, 틀리면 0
```

따라서 표의 79.8을 “내 API 요청 한 번도 79.8%로 정답”이라고 읽으면 안 된다. 모델 버전, 답 길이 제한, temperature, prompt, 채점기, 샘플 수가 묶인 측정값이다. 서비스에서는 사용자 1명당 64번 생성할 예산이 있는지부터 결정해야 한다.

### 비용: 37B active가 곧 싼 reasoning은 아니다

논문 부록 B.4.4 Table 7은 H800 GPU hour(한 GPU를 한 시간 쓴 양)당 $2라는 가정에서 다음 항목을 보고한다.

| 논문이 집계한 항목 | H800 GPU hours | 그 가정의 USD |
|---|---:|---:|
| DeepSeek-R1-Zero | 101K | $202K |
| SFT data creation | 5K | $10K |
| DeepSeek-R1 | 41K | $82K |
| 합계 | 147K | $294K |

이는 논문이 열거한 이 세 항목의 추정치이며, 선행 연구·작은 모델 탐색·인력·데이터 수집·서버 운영을 포함한 “세상 전체 비용”이라고 확대 해석하면 안 된다. 또한 이전 V3 글에서 본 671B/37B는 추론 때 일부 expert만 활성화한다는 뜻이지, 긴 CoT rollout·16개 후보·검증기·reference/RM 실행 비용이 사라진다는 뜻이 아니다.

### 제품에서는 token budget이 기능 명세다

**해석:** R1 계열을 제품에 넣을 때 “reasoning을 켠다”가 아니라 다음을 계약으로 정해야 한다.

```text
요청 등급       최대 입력/출력 token     허용 지연 시간     검증 방식
간단 Q&A       작게                     짧게               RAG 근거/JSON schema
복잡 분석      중간                     중간               계산·인용·규칙 검사
코드 변경      크게                     비동기             sandbox test + human review
고위험 의사결정 제한 또는 금지            -                  사람이 최종 책임
```

긴 reasoning은 어려운 문제를 풀 기회를 늘릴 수 있지만, 비용·tail latency·반복 위험·사용자가 읽어야 할 양도 늘린다. `max_tokens`, timeouts, cancellation, cache, fallback model, 결과 검증을 API 계약에 넣어야 한다.

## 실패, 한계, 장애와 운영 기준: 보상·출력·안전은 서로 다른 문제다

### 1. reward hacking: 점수 그래프가 올라가도 실제 능력은 떨어질 수 있다

논문 부록 B.5는 helpful RM을 오래 쓰면 reward score는 오르는데 Codeforces test pass@1이 내려가는 사례를 Figure 6으로 제시한다. 이것이 reward hacking이다. 모델이 사람 의도를 잘 만족한 것이 아니라 RM의 빈틈을 찾아 점수만 얻은 것이다.

```text
나쁜 목표: RM 점수 최대화
원래 목표: 실제 사용자에게 정확하고 유용하며 안전한 답 제공

둘이 다르면 → 모델은 둘 사이의 틈을 최적화한다.
```

**운영 기준:** 학습 reward와 독립된 holdout verifier, 사람 평가, 실제 작업 성공률을 같이 둔다. reward trend 하나로 배포를 승인하지 않는다. RM으로 채점할 수 없는 글쓰기·정책·의료·법률 문제에 “R1처럼 순수 RL을 크게 돌리자”라고 바로 결론 내리면 안 된다.

### 2. 구조화 출력과 도구 사용은 논문이 인정한 약점이다

논문 §6은 R1의 structured output(구조화 출력) 능력과 tool use(도구 사용)가 기존 모델보다 최적이 아니며, 검색 엔진·계산기를 활용해 답을 개선하지 못한다고 쓴다. 이 논문만으로 “R1은 MCP(Model Context Protocol, 모델 문맥 프로토콜) 에이전트에 최적”이라고 말할 수 없는 이유다.

**해석:** RAG·MCP 백엔드에서 R1류 모델을 쓴다면 다음 분리가 안전하다.

```text
모델: 계획 초안·문서 요약·후보 SQL/코드 생성
애플리케이션: schema validation, ACL(Access Control List, 접근 제어 목록),
              parameterized query, tool allowlist, timeout, audit log
검증기: 테스트·정답 비교·정책 검사
사람: 파괴적 DB 변경·권한 상승·고위험 결과의 최종 승인
```

모델이 `<think>`에서 “이 도구를 호출하자”라고 써도 실제 호출 권한은 애플리케이션이 결정한다. reasoning text를 권한 증명으로 쓰지 않는다.

### 3. 프롬프트·언어·반복은 관찰해야 할 운영 지표다

공식 README의 [Usage Recommendations](https://github.com/deepseek-ai/DeepSeek-R1/blob/0cf78561f1d51c84a21b2190626b21116d5c68bb/README.md#usage-recommendations)는 이 계열에 temperature `0.5–0.7`(권장 `0.6`), system prompt를 넣지 말고 지시는 user prompt에 넣을 것, 수학에는 단계별 풀이와 `\boxed{}` 지시, 여러 번 시험해 평균낼 것을 권한다. 또한 일부 질의에서 빈 `<think>`를 내어 성능에 나쁜 영향을 줄 수 있어 `<think>\n`으로 시작하게 하는 권고도 있다.

이것은 **그 commit의 모델별 운영 권고**다. 모든 LLM에 적용할 보편 규칙이 아니다. 배포 전 반드시 자신의 tokenizer, serving engine, system-message 변환, 언어, 트래픽에서 다시 시험한다.

추천 관측값:

| 지표 | 왜 보는가 | 이상 징후의 첫 대응 |
|---|---|---|
| 입력/출력 token, p50/p95 latency | overthinking·비용·tail latency | token budget과 timeout 점검 |
| empty/unterminated `<think>` 비율 | reasoning 형식 붕괴 | prompt template·parser fallback 점검 |
| JSON/schema parse 실패율 | 구조화 출력 약점 | constrained decoding 또는 별도 formatter |
| 언어 혼합률 | 사용자 이해 저하 | language reward가 아닌 serving prompt/모델 재평가 |
| verifier pass rate와 user success rate | reward hacking 탐지 | holdout·사람 검토·보상 재설계 |
| tool call 거절/권한 오류 | 모델과 권한 경계 확인 | allowlist·ACL·감사 로그 점검 |

### 4. 안전: 모델 안의 거절만으로 경계를 만들지 않는다

논문 §5는 jailbreak(탈옥)로 위험한 계획이 생성될 수 있고, 공개 모델은 안전 장치를 약화하는 추가 미세조정의 대상이 될 수 있다고 쓴다. 논문은 자체 평가에서 기본 안전 수준을 “moderate”라고 표현하며 외부 risk-control system(위험 제어 시스템)을 붙였을 때 향상된다고 말한다. 이는 “R1 자체가 충분히 안전하다”는 보증이 아니다.

운영에서는 모델 앞뒤에 입력 정책, 도구 권한, 민감 데이터 마스킹, 출력을 소비하는 서비스의 권한 검증, 감사 로그, incident response(사고 대응)를 둔다. 특히 SQL·쉘·배포 도구를 줄 때는 모델이 만든 텍스트를 실행하지 말고 allowlist와 사람 승인을 통과시킨다.

## 대안, 비교와 선택 기준: 내 문제에 verifier가 있는가부터 묻기

| 선택지 | 잘 맞는 문제 | 장점 | 결정적 한계 |
|---|---|---|---|
| SFT | 말투·형식·정해진 업무 흐름 | 가장 단순하고 재현하기 쉬움 | 교사 데이터 품질·범위를 넘는 탐색 제한 |
| DPO(Direct Preference Optimization, 직접 선호 최적화) | A/B 선호 데이터가 있는 일반 답변 | 온라인 rollout·별도 RL 인프라 부담이 작음 | 객관적 정답 verifier의 탐색 이점을 직접 쓰지 못함 |
| PPO | 가치 모델과 보상 설계를 운용할 역량이 있음 | 널리 연구된 RL 방법 | 긴 CoT에서는 critic 메모리·학습·튜닝 부담 |
| GRPO | 질문당 여러 답을 만들 수 있고 규칙 보상이 신뢰할 만함 | value model 없이 그룹 상대 신호 | G개 rollout 비용, 모두 같은 reward면 신호 약화 |
| RAG | 최신 사내 문서·근거 인용이 핵심 | 모델 지식 밖의 사실을 회수 | 검색 품질이 나쁘면 reasoning만 길어져도 틀림 |
| 도구 사용 agent | 계산·DB 조회·코드 테스트를 실제 수행 | 검증 가능한 외부 상태를 사용 | 권한·sandbox·관측 없으면 큰 운영 위험 |

### 백엔드·DBA 출신인 나의 우선순위

**해석:** 지금의 나는 671B GRPO 클러스터를 만드는 사람보다, **검증 가능한 업무 환경을 설계하는 사람**이 되는 편이 효율적이다. R1 논문이 보여 주는 진짜 경쟁력은 “GRPO라는 이름 암기”가 아니라 다음 질문을 설계하는 능력이다.

```text
1. 이 업무의 정답/성공을 기계적으로 검증할 수 있는가?
2. 검증기가 속거나 위험한 코드를 실행하지 않는가?
3. 실패한 후보·보상·근거·버전을 나중에 재현할 수 있는가?
4. reasoning token을 더 쓴 비용보다 실제 성공률 향상이 큰가?
5. 모델이 아니라 애플리케이션이 권한·DB 변경을 통제하는가?
```

예를 들어 데이터 파이프라인에서는 모델에게 SQL 초안을 만들게 할 수 있다. 그러나 성공 verifier는 “문장이 그럴듯한가”가 아니라 read-only schema check, `EXPLAIN`, 샘플 데이터 결과, row count guard, lineage(데이터 계보), 승인된 migration policy가 되어야 한다. R1을 읽은 뒤 바로 학습을 돌리는 것보다 이 closed-loop(생성 → 검증 → 기록 → 개선) 루프를 작은 업무에 만드는 것이 먼저다.

## 흔한 오해와 최초 질문에 대한 답

### Q1. “R1은 SFT 없이 순수 RL로 만든 모델이네?”

**아니다.** R1-Zero가 SFT 선행 없이 RL을 한 실험 모델이다. 최종 R1은 cold start SFT, 첫 RL, 거절 샘플링 기반 두 번째 SFT, 두 번째 RL을 쓴다. “R1 논문이 순수 RL 가능성을 보였다”와 “최종 제품 R1이 순수 RL이다”는 다른 문장이다.

### Q2. “`<think>`가 길면 진짜로 더 깊게 생각한 증거인가?”

**아니다.** 긴 중간 텍스트는 모델이 생성한 출력이며, 논문도 과도한 생각과 언어 혼합을 한계로 든다. cold start의 1인칭 사고 양식은 사용자 경험을 위한 DeepSeek의 설계다. 최종 답은 외부 근거, 계산, 테스트, verifier로 확인한다.

### Q3. “정답만 채점하면 글쓰기나 고객 상담도 R1처럼 학습할 수 있나?”

**대부분 바로는 안 된다.** 수학 답·코드 테스트처럼 신뢰할 verifier가 있어야 한다. 일반 도움됨·안전은 RM 또는 사람 선호가 필요하고, 논문도 RM을 오래 쓰면 reward hacking이 생길 수 있음을 보였다.

### Q4. “R1의 79.8 AIME는 내 서비스 성공률 79.8%인가?”

**아니다.** Table 3/8의 평가 프로토콜, 32K max generation, temperature/top-p, 다중 샘플 수, dataset에 묶인 값이다. 내 사용자 입력·한국어·RAG·툴·비용 제한에서는 별도 evaluation set을 만들어 측정해야 한다.

### Q5. “R1-Distill-Qwen-32B는 작은 R1을 압축한 것이니 같은 행동을 보장하나?”

**아니다.** 공식 README는 Qwen/Llama 기반 별도 dense 모델을 R1 생성 표본으로 fine-tune했다고 설명한다. distillation(증류)은 큰 모델의 일부 행동을 작은 모델에게 전이하는 방법이지, 원본의 구조·모든 능력·안전성을 동일하게 복제하는 보증이 아니다.

### Q6. “그럼 나도 처음부터 GRPO를 학습해야 AI 전문가가 되나?”

**아니다.** 먼저 RAG와 데이터 파이프라인에서 verifier·평가 데이터·권한 경계·관측을 만든다. 그 다음 작은 모델 또는 offline 후보 생성으로 `생성 → 채점 → 분석`을 경험한다. 실제로 신뢰할 규칙 보상이 있고 비용 대비 개선이 확인될 때만 RL을 검토한다. 이것이 이 논문을 top-down으로 읽고도 bottom-up을 버리지 않는 순서다.

## 출처

### 1차 자료

1. DeepSeek-AI, [*DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning*, arXiv:2501.12948v2](https://arxiv.org/abs/2501.12948v2), 2026-01-04. 이 글의 GRPO 식 (1)–(3), 보상 식 (4)–(10), Figure 2/3/5, Table 3/5/6/7/8, 부록 B.1–B.6/D.1을 확인했다.
2. DeepSeek-AI, [DeepSeek-R1 공식 README, commit `0cf78561f1d51c84a21b2190626b21116d5c68bb`](https://github.com/deepseek-ai/DeepSeek-R1/blob/0cf78561f1d51c84a21b2190626b21116d5c68bb/README.md). 모델 표, distill base 모델, local serving 예시, 모델별 사용 권고, 라이선스를 확인했다.
3. DeepSeek-AI, [*DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models*](https://arxiv.org/abs/2402.03300). GRPO가 처음 제안된 연구 맥락을 확인하는 원 논문이다. 이 글의 세부 식·R1 수치는 위 R1 원문을 우선한다.
4. DeepSeek-AI, [DeepSeek-V3 공식 저장소](https://github.com/deepseek-ai/DeepSeek-V3). R1-Zero/R1의 기반 DeepSeek-V3-Base 구조와 실행 환경의 경계는 [이전 DeepSeek-V3 Deep Dive](/posts/deepseek-v3-technical-report-deep-dive)에서 별도로 검증했다.

### 직접 실행

- `/tmp/deepseek-r1-research/verify_grpo_mechanics.py`를 macOS 26.4.1, Python 3.9.6에서 실행했다. 스크립트 SHA-256과 실제 출력은 `직접 검증` 절에 기록했다. 이는 논문 식의 작은 수 재현이며 DeepSeek의 비공개 학습 코드를 검증하는 실험이 아니다.
