이 논문은 코드 생성을 "사전 계획이 아닌, 필요한 순간에 즉각 생각하는 과정"으로 바라본다 — 인간 개발자가 코드를 작성하다가 복잡한 부분에서 멈춰 생각하듯, LLM도 임의의 토큰 위치에서 온디맨드로 추론을 호출할 수 있어야 한다.
arXiv → GitHub →최근 LLM(대형 언어 모델)의 코드 생성 능력은 놀라운 수준으로 향상되었습니다. 이 발전의 핵심 동력은 업프론트 씽킹(upfront thinking)이라고 불리는 메커니즘입니다 — 코드를 생성하기 전에 먼저 <think>...</think> 블록 안에서 충분히 추론한 다음 코드를 출력하는 방식이죠.
Chain-of-Thought(CoT) 프롬프팅(Wei et al., 2022)을 시작으로, Self-Planning(Jiang et al., 2024), DeepSeek-R1, OpenAI o1, Kimi K2 등 최신 추론 최적화 모델들은 모두 이 패턴을 따릅니다. RL(강화학습)을 통해 추론 능력을 확장한 Skywork-OR1, OlympicCoder, CodeBoost, CodeRL+ 등의 포스트트레이닝 방법들도 마찬가지입니다.
"upfront thinking is often insufficient, as the full complexity of problems typically only reveals itself during implementation... upfront thinking cannot precisely allocate reasoning effort to the positions where it is needed."업프론트 씽킹은 종종 불충분합니다 — 문제의 전체 복잡성은 보통 구현 과정에서야 드러나기 때문입니다... 또한 추론 노력을 필요한 위치에 정확히 배분하지 못합니다.
보충 인간 개발자의 코딩 인지(coding cognition) 연구에 따르면, 개발자들은 코딩 전에만 생각하는 것이 아니라 구현 도중 복잡한 부분에서 멈추어 생각합니다. 이는 "필요한 순간에 생각하는" 방식이 더 자연스럽고 효율적임을 시사합니다. THINK-ANYWHERE는 이 관찰에서 출발합니다.
기존 Interleaved Thinking(Xie et al., 2025; Liang et al., 2025)은 각 서브스텝마다 추론을 강제하지만, 이는 불필요한 계산 오버헤드를 도입하고 가장 어려운 부분에 더 깊은 추론을 배분하는 유연성이 없습니다. 따라서 이 논문은 "임의의 토큰 위치에서 온디맨드로 추론을 호출할 수 있는" 메커니즘이 필요하다고 주장합니다.
핵심 통찰은 간단합니다: 추론이 코드 전체에 걸쳐 필요한 곳에 분산되어야 한다면, 추론 호출도 코드 어디서나 가능해야 한다.
대안으로 "모든 서브스텝마다 추론"(Interleaved Thinking)을 고려할 수 있습니다. 하지만 이 방식은 추론이 필요 없는 단순한 코드 라인에서도 추론을 강제하여 불필요한 계산 비용이 발생합니다. THINK-ANYWHERE는 반대로, 모델이 스스로 언제 추론이 필요한지를 학습하도록 설계되었습니다. 이를 통해 추론 자원을 복잡도가 실제로 높은 위치에 집중할 수 있습니다.
업프론트 씽킹과 THINK-ANYWHERE를 수식으로 비교해봅니다. x는 코딩 요구사항(requirement), c는 생성된 코드를 나타냅니다.
업프론트 씽킹의 생성 확률 분해:
| 변수 | 의미 | 비고 |
|---|---|---|
x | 코딩 요구사항 (입력 프롬프트) | – |
s | ⟨think⟩...⟨/think⟩ 블록 내 추론 트레이스 | 코드 생성 전에 완성 |
c | 생성된 최종 코드 | s에 조건부 |
직관적 해설
수학적 의미
THINK-ANYWHERE의 생성 시퀀스:
| 변수 | 의미 | 비고 |
|---|---|---|
y | 전체 혼합 시퀀스 (코드 + 인라인 추론) | – |
s | 초기 ⟨think⟩ 블록 (업프론트 추론, 짧아진 버전) | 선택적이지만 권장 |
c^(i) | i번째 코드 세그먼트 | – |
h^(i) | i번째 ⟨thinkanywhere⟩ 블록 (인라인 추론) | – |
M | 삽입된 thinkanywhere 블록의 수 | M ≥ 0, 모델이 동적으로 결정 |
직관적 해설
업프론트 씽킹과의 관계
THINK-ANYWHERE의 생성 확률 분해:
| 변수 | 의미 | 비고 |
|---|---|---|
y<c^(i) | c^(i) 이전의 모든 토큰 | 이전 코드 + 추론 블록 모두 포함 |
y<h^(i) | h^(i) 이전의 모든 토큰 | 이전 코드 + 추론 블록 모두 포함 |
직관적 해설
최종 코드 추출 방법
LLM은 코드 생성 중 자발적으로 추론 블록을 호출하지 않습니다 — 심지어 명시적인 프롬프트 지시도 이 동작을 신뢰성 있게 유도하지 못합니다. 따라서 먼저 모델에게 "어디서든 생각할 수 있다"는 기초 능력을 훈련으로 가르쳐야 합니다.
자동 데이터 구성: 강력한 추론 LLM(Google Gemini 2.5 Flash)에게 Table 1의 템플릿을 사용하여 코딩 문제를 풀게 합니다. 이때 모델이 코드 작성 중 숙고가 필요한 위치에 ⟨thinkanywhere⟩ 블록을 삽입하도록 유도합니다. 잘못된 형식(블록 경계 오류, 토큰 중첩 오류)을 가진 샘플은 필터링하지만, 코드 정확성과 무관하게 올바르게 포맷된 샘플은 모두 유지합니다(약 5,000개). 이는 올바른 풀이와 틀린 풀이 모두가 학습에 기여한다는 선행 연구(Li et al., 2025a)를 따릅니다.
LoRA 기반 SFT: 구성된 학습 데이터로 LoRA(Hu et al., 2022)를 사용한 지도학습 파인튜닝을 수행합니다. 전체 파라미터 SFT 대비 LoRA가 유사한 성능을 내면서도 강건성이 높고 계산 비용이 낮습니다.
기본 구현에서 <thinkanywhere>는 여러 일반 토큰으로 분리됩니다(예: "think", "any", "where"). 이는 두 가지 문제를 만듭니다: (1) 동일한 토큰이 어휘적 의미와 제어 신호로 이중 역할을 해 의미 모호성이 생기고, (2) 멀티토큰 구분자는 단일 제어 결정의 예측 경로를 길게 만들어 트리거 신뢰성이 낮아집니다.
해결책으로 새로운 단일 어휘 항목인 <ta>와 </ta> 토큰을 도입합니다. 문제는 무작위 초기화된 새 토큰을 효과적으로 학습하기 어렵다는 것입니다. 이를 위해 의미 인식 초기화(semantic-aware initialization) 전략을 제안합니다:
| 변수 | 의미 | 비고 |
|---|---|---|
e<ta> | 새 오프닝 특수 토큰 임베딩 | – |
e</ta> | 새 클로징 특수 토큰 임베딩 | – |
mean(e_think, e_any, e_where) | "think anywhere"의 의미적 내용 인코딩 | 0.5 가중치 |
e<im_start>, e<im_end> | 기존 구분자 토큰 (모드 전환 경계 역할) | 0.5 가중치 |
왜 이 초기화인가
2단계 콜드스타트 절차
콜드스타트 훈련은 모델에게 "어디서든 생각할 수 있다"는 기초 능력을 줍니다. 하지만 "어디서 생각해야 하는가"는 지도학습으로 가르치기 어렵습니다 — 이는 패턴 매칭을 넘어서는 적응적 판단을 요구합니다. 이를 위해 RLVR(Reinforcement Learning with Verifiable Rewards)을 적용합니다.
GRPO 알고리즘: Proximal Policy Optimization(PPO)과 달리 별도의 값 모델 없이 그룹 수준 통계에서 기준선(baseline)을 계산합니다. 각 입력 x에 대해 현재 정책 π_θ에서 G개의 후보 출력 {y₁, ..., y_G}를 샘플링합니다.
| 변수 | 의미 | 비고 |
|---|---|---|
Â_i | 그룹 정규화된 어드밴티지 | 그룹 평균 대비 상대적 성능 |
R(y_i) | 출력 y_i에 대한 보상 | 구조 보상 + 정확성 보상 |
G | 그룹 크기 (각 입력당 샘플 수) | 본 논문에서 G=8 |
직관적 해설
| 변수 | 의미 | 비고 |
|---|---|---|
ρ_i | 확률 비율 π_θ(y_i|x) / π_old(y_i|x) | 정책 업데이트 크기를 제어 |
ε | 클리핑 임계값 | 너무 큰 정책 업데이트 방지 |
β | KL 패널티 강도 | 참조 정책에서 너무 멀리 벗어나지 않도록 |
π_ref | 참조 정책 (일반적으로 초기 SFT 모델) | – |
직관적 해설
| 변수 | 의미 | 비고 |
|---|---|---|
α = 0.1 | 구조 보상 가중치 | 정확성 보상 대비 소규모 |
R_struct ∈ {0,1} | THINK-ANYWHERE 형식 준수 여부 | 초기 think 블록 + 최소 1개의 thinkanywhere 블록 필요 |
R_correct ∈ {0,1} | 테스트 케이스 통과 여부 | 코드 실행 결과 기반 |
왜 계층적인가
설계 의도
각 훈련 단계에서 <thinkanywhere> 블록의 평균 빈도(Avg.Freq)와 평균 길이(Avg.Len)를 분석합니다. 이는 콜드스타트 SFT와 RLVR의 기여를 명확히 보여줍니다.
| 데이터셋 | 모델 | Avg.Freq | Avg.Len (토큰) |
|---|---|---|---|
| HumanEval | Base Model | 0 | 0 |
| THINK-ANYWHERE (Prompting) | 0.24 | 113.5 | |
| THINK-ANYWHERE (SFT) | 6.69 | 31.9 | |
| THINK-ANYWHERE (Ours, RL) | 6.15 | 22.5 | |
| MBPP | Base Model | 0 | 0 |
| THINK-ANYWHERE (Prompting) | 0.53 | 66.4 | |
| THINK-ANYWHERE (SFT) | 5.76 | 33.4 | |
| THINK-ANYWHERE (Ours, RL) | 5.24 | 23.2 | |
| LeetCode | Base Model | 0 | 0 |
| THINK-ANYWHERE (Prompting) | 0.31 | 219.7 | |
| THINK-ANYWHERE (SFT) | 11.28 | 34.5 | |
| THINK-ANYWHERE (Ours, RL) | 11.26 | 22.9 |
이 데이터가 보여주는 핵심 패턴: RL 훈련 이후 블록 빈도는 SFT와 거의 동일하지만 블록 길이는 감소합니다 — RL이 추론 횟수가 아니라 추론의 질을 개선한다는 증거입니다. Prompting 단계의 비정상적으로 긴 블록 길이(219.7 토큰)는 모델이 패턴을 제대로 학습하지 못했음을 나타냅니다.
| 항목 | 설정값 |
|---|---|
| 베이스 모델 | Qwen2.5-Coder-7B-Instruct |
| RL 프레임워크 | VeRL (Sheng et al., 2024) |
| 콜드스타트 데이터 수 | ~5,000 샘플 |
| 콜드스타트 데이터 생성 | Google Gemini 2.5 Flash |
| RL 훈련 코퍼스 | Skywork 데이터셋 14K 문제 |
| 배치 크기 / 미니배치 | 128 / 64 |
| 학습률 | 1e-6 |
| 훈련 에포크 | 2 |
| 문제당 롤아웃 | 8 |
| 최대 토큰 길이 | 4096 |
| GPU | 8 × NVIDIA A100 (40G) |
| 평가 샘플링 | greedy (temperature=0) |
| LoRA 파인튜닝 | 전체 파라미터 SFT 대신 사용 (더 강건함) |
| 소스 코드 | github.com/jiangxxxue/Think-Anywhere |
| 방법 | LeetCode | LiveCodeBench | HumanEval | MBPP | 평균 |
|---|---|---|---|---|---|
| Base Model (Qwen2.5-Coder-7B) | 50.6 | 34.3 | 88.4 | 70.7 | 61.0 |
| Post-Training OlympicCoder | 45.3 | 30.9 | 75.6 | 61.0 | 58.0 |
| Post-Training OCR-Qwen-7B | 53.3 | 33.0 | 86.8 | 67.2 | 62.5 |
| Post-Training CodePRM | 52.8 | 34.8 | 88.4 | 58.9 | 60.2 |
| Post-Training CodeBoost | 53.3 | 34.6 | 87.2 | 73.9 | 65.7 |
| Post-Training CodeRL+ | 63.3 | 36.9 | 90.9 | 65.7 | 66.8 |
| Reasoning CoT | 53.9 | 30.9 | 86.6 | 77.7 | 62.3 |
| Reasoning Self-Planning | 49.2 | 31.1 | 86.9 | 77.9 | 61.3 |
| Reasoning Interleaved Thinking | 50.6 | 30.7 | 86.4 | 79.2 | 61.7 |
| Reasoning GRPO | 67.3 | 36.0 | 88.6 | 81.7 | 68.4 |
| Think-Anywhere (Prompting) | 41.1 | 34.4 | 84.8 | 67.4 | 56.9 |
| Think-Anywhere* (SFT) | 46.7 | 32.5 | 79.9 | 78.2 | 59.3 |
| Think-Anywhere* (Ours, 특수 토큰) | 68.9 | 36.7 | 90.2 | 84.5 | 70.0 |
| Think-Anywhere (SFT) | 47.9 | 32.3 | 82.9 | 79.4 | 60.6 |
| Ours Think-Anywhere (Ours) | 69.4 | 37.2 | 91.5 | 82.9 | 70.3 |
각 컴포넌트의 기여도를 LeetCode 벤치마크에서 분석합니다.
| 방법 변형 | LeetCode pass@1 | 베이스 대비 Δ | 의미 |
|---|---|---|---|
| Ours Think-Anywhere (완전체) | 69.4% | – | 콜드스타트 + RLVR 완전 파이프라인 |
| Only Cold Start (SFT만) | 47.9% | -21.5% | 지도학습만으로는 효과적인 사고 위치 학습 불가 |
| Only RLVR (콜드스타트 없이) | 63.4% | -6.0% | 콜드스타트 초기화가 RL 안정화에 중요 |
| Line-level Thinking | 67.2% | -2.2% | 라인 단위 제한이 최적 위치 선택을 방해 |
| No Upfront Thinking | 66.6% | -2.8% | 초기 think 블록 제거 시 소폭 하락 (thinkanywhere가 주 기여) |
| Padding Thinking | 67.6% | -1.8% | 추론 내용도 중요하나, 위치 선택 자체도 기여함 |
코드 생성 태스크만으로 훈련된 THINK-ANYWHERE를 수학 추론 벤치마크에 직접 평가합니다.
| 방법 | AIME 2024 | AIME 2025 | HMMT 2025 | ||||||
|---|---|---|---|---|---|---|---|---|---|
| pass@1 | pass@5 | pass@10 | pass@1 | pass@5 | pass@10 | pass@1 | pass@5 | pass@10 | |
| Base Model | 5.3 | 14.6 | 20.0 | 4.0 | 13.4 | 16.7 | 0.0 | 0.0 | 0.0 |
| GRPO | 6.0 | 16.8 | 23.3 | 4.7 | 17.2 | 26.7 | 0.3 | 1.7 | 3.3 |
| Ours THINK-ANYWHERE | 17.3 | 32.9 | 40.2 | 17.7 | 28.0 | 33.2 | 14.4 | 18.5 | 19.6 |
보충 AIME 2024 pass@1 기준 베이스 모델 5.3% → THINK-ANYWHERE 17.3%로 3배 이상 향상되었습니다. 코드 도메인에서 학습한 "온디맨드 추론" 능력이 수학 도메인으로 전이된다는 것을 보여줍니다. 이는 THINK-ANYWHERE가 특정 도메인에 과적합되지 않고 범용적인 추론 능력을 향상시킨다는 것을 시사합니다.
| 모델 | Base Model | + GRPO | + Think-Anywhere | 베이스 대비 향상 |
|---|---|---|---|---|
| Qwen2.5-Coder-7B-Instruct | 61.0 | 68.4 | 70.3 | +9.3% |
| Qwen2.5-Coder-1.5B-Instruct | 40.6 | 51.9 | 54.5 | +13.9% |
| LLaMA-3.1-8B-Instruct | 38.4 | 42.0 | 43.8 | +5.4% |
THINK-ANYWHERE가 "어디서" 추론을 호출하는지 분석합니다. 두 가지 관점에서 LeetCode 벤치마크의 생성된 솔루션을 분석했습니다.
토큰 엔트로피 분석: 모델이 <thinkanywhere>를 호출한 위치에서, thinkanywhere가 활성화된 경우와 비활성화된 경우의 엔트로피 차이를 계산합니다. 결과는 이 차이가 대부분 양수로 나타났습니다 — 즉, thinking이 비활성화될 때 해당 위치의 토큰 엔트로피가 더 높다는 것을 의미합니다. 이는 모델이 스스로 불확실성이 높다고 예측하는 위치에서 <thinkanywhere>를 호출한다는 것을 보여줍니다.
구문론적 컨텍스트 분석: AST 파서를 사용하여 <thinkanywhere>가 호출된 위치의 구문 범주를 식별했습니다. 가장 많이 호출되는 순서는 다음과 같습니다:
보충 이 분석은 THINK-ANYWHERE의 "해석 가능성(interpretability)" 기여를 보여줍니다. 모델이 어디서 어떤 이유로 추론을 호출하는지 관찰할 수 있어, 코드 생성의 의사결정 과정을 투명하게 이해할 수 있습니다.
THINK-ANYWHERE의 업프론트 씽킹 구간이 GRPO/CoT 대비 크게 단축되고, 추가되는 <thinkanywhere> 블록 비용은 작습니다 (HumanEval 기준: GRPO 309.4토큰 → THINK-ANYWHERE 업프론트 215.6 + thinkanywhere 22.5 = 238.1 토큰으로 net 감소).
THINK-ANYWHERE는 LLM의 추론 메커니즘에 대한 새로운 관점을 제시합니다. 업프론트 씽킹이 지배적인 현재 패러다임에서, 인라인 온디맨드 추론으로의 전환이 가능하고 더 효과적일 수 있음을 실증했습니다.
저자들이 제안한 향후 연구 방향:
논문에 수록된 원본 그림들입니다. 각 그림의 위치와 주요 포인트를 함께 설명합니다.