절대 포기하지 않기(Never Give Up): LLM RL에서 어려운 문제를 풀게 만드는 방법
Learning to solve hard problems in RL for LLMs by never giving up
TL;DR Highlight
쉬운 문제에 쓰는 연산을 줄이고 어려운 문제를 재시도했더니 어려운 문제 성능이 올랐다
Who Should Read
GRPO로 LLM을 RL 후학습하는데 평가 점수 평균만 보고 있어 어려운 문제가 안 풀려 고민인 ML 엔지니어
Core Mechanics
- 평균 점수가 어려운 문제의 정체를 가렸다
- Olmo 3.1 RL-Zero Math의 AIME 2025 평가에서 초기 모델 pass@32=0인 문제는 대부분 끝까지 pass@32=0이었다.
- 성능 향상 대부분은 쉬운 문제가 '어느 정도 풀림'에서 '거의 다 풀림'으로 가면서 나왔다.
- Matthew Effect: RL은 잘하는 문제만 더 잘하게 한다
- 저자는 RL 이득이 초기 모델의 능력에 비례한다는 현상을 Matthew Effect(부익부)라 부른다.
- 수학뿐 아니라 Deepcoder, DeepSWE 로그의 코드·에이전트 RL에서도 같은 경향을 확인했다.
- k를 키워도 해결이 안 된다
- Qwen 2.5 0.5B Instruct를 GSM8k platinum에서 GRPO로 학습한 실험에서 k=4(프롬프트 64개)가 k=32(프롬프트 8개)보다 어려운 문제를 더 잘 풀었다.
- k는 프롬프트당 샘플링하는 응답 수이고, 전부 틀리면 gradient가 없다는 signal loss 문제보다 쉬운 문제에 연산을 낭비하는 signal efficiency가 원인이라고 본다.
- k=32는 쉬운 문제의 드문 오답에 연산을 쓴다
- 약 200 step 전에는 k=32가 어려운 문제의 드문 정답을 더 잘 찾았다.
- 200 step 이후에는 k=4가 앞섰는데, k=4는 4/4 정답이면 필터링하지만 k=32는 32/32가 나와야 걸러서 쉬운 문제에 연산이 더 들어간다.
- NGU: 전부 틀리면 확률 p로 k개를 더 뽑는다
- 작은 k로 시작해서 k개 안에 풀면 학습에 쓰고, 전부 맞으면 바로 걸러낸다.
Community Reactions
- 메시지 속도를 Claude가 맞다고 확인해 줬지만 틀렸다는 경험
- 한 댓글 작성자가 WebSocket 초당 3,250,000건이라는 성능 측정치를 Claude가 맞다고 확인해 줬는데, 2주 뒤 틀린 값임을 알았다는 경험을 공유했다.
- 보정 후 초당 100,000건이었고, 큐 관리 개선으로 800,000건까지 올랐다고 한다.
- 원문 링크가 논문·코드가 아닌 같은 페이지로 연결된다는 지적
- 글 상단의 arxiv·github 링크가 둘 다 같은 페이지를 가리킨다는 의견이 있었다.
How to Apply
- 평가 세트를 초기 모델 pass@k로 난이도별로 쪼개 보기
- 기존 모델로 평가 문제를 여러 번 샘플링해 pass@32=0인 hard 구간과 나머지 구간으로 나눠라.
- 학습 전후로 구간별 정답률을 따로 찍어 평균이 어려운 문제를 가리는지 확인하라.
- 프롬프트별 샘플 수 k를 줄이고 프롬프트 수를 늘려 비교하기
- 배치 크기를 고정하고 k를 4, 8, 16, 32로 바꿔가며 어려운 구간 정답률을 비교하라.
- 쉬운 문제가 배치에서 차지하는 비중도 같이 기록하라.
- GRPO 샘플링에 NGU 재시도 루프 넣기
- 작은 k로 뽑아 전부 틀린 프롬프트는 확률 p로 생성기에 되돌리고 k개를 더 뽑아라.
- 정답이 나오면 누적된 응답 전체로 학습하고, 오래된 응답은 나이 임계값(원문에서는 T=4가 최고)으로 걸러라.
- 오래된 응답도 GRPO baseline 계산에는 포함하기
- 학습에서 뺀 stale 응답도 baseline에는 쓰고, 남은 음의 advantage를 재조정해 보상 합이 0이 되게 하라.
- 원문은 이 방식이 baseline을 무시하거나 재조정 없이 두는 것보다 낫다고 한다.
Try It
# Claude나 ChatGPT에 붙여넣기 (논문 방법의 간이 버전: 평가 결과를 난이도별로 쪼개 보는 분석)
나는 LLM 평가 결과를 갖고 있다. 평균 점수만 보면 개선처럼 보이는데 어려운 문제가 정말 나아졌는지 확인하고 싶다.
[초기 모델 결과]
{{문제별 초기 모델 pass@k 결과}}
[학습 후 모델 결과]
{{문제별 학습 후 모델 pass@k 결과}}
다음을 해줘:
1. 초기 모델에서 pass@32=0인 문제를 hard로, 나머지는 pass rate 기준으로 medium과 easy로 균등하게 나눠줘.
2. 구간별로 학습 전후 정답률 변화를 표로 정리해줘.
3. 평균 향상이 어느 구간에서 나왔는지, 어려운 문제가 실제로 나아졌는지 설명해줘.
이어서 해 볼 것: 결과가 쉬운 구간에 몰려 있다면 k를 줄이고 프롬프트 수를 늘린 설정을 비교하자고 제안해줘.Terminology
관련 논문
AI 글쓰기 버릇을 학습으로 뺀 Qwen3-4B (qwen3-4b-deslop)
Qwen3-4B를 LoRA로 증류했더니 AI 문체 점수가 121에서 12.5로 떨어졌다
Dust: 역전파 없이 Transformer를 사전학습하는 방법
활성값에 토큰별 노이즈를 줬더니 역전파 없이 Transformer 사전학습이 됐다
TurboGPT: 22KiB 트랜스포머를 13초 만에 학습시키는 CUDA 프로젝트
CUDA C++로 바이트 단위 tiny GPT를 1분 안에 학습하는 오픈소스
Gemini가 만든 라벨 $9로 자기 대체 모델 GLiNER 학습시키기
Gemini 라벨 $9로 GLiNER를 튜닝해 로컬에서 F1 0.83 달성
3.8B LLM을 $998로 학습해 CORE 0.384 달성하기
B200 8장으로 43시간, $998를 들여 3.8B 모델이 CORE 0.384를 기록했다
Paul Graham: "17살이면 LLM을 밑바닥부터 만들어 보겠다"
PG는 17살이면 창업 말고 LLM 밑바닥 구현부터 배우겠다고 했다
DeepSeek을 GPT-OSS에 증류해도 검열은 따라오지 않았다
DeepSeek V4 Flash로 금융 추론을 증류했더니 성능은 올랐고 검열은 안 따라왔다