최신 트렌드

Karpathy nanochat 완벽 분석 - $100으로 만드는 나만의 ChatGPT 풀스택

백엔드 개발자 김승원 2026. 4. 16. 13:00

들어가며

AI 업계에서 Andrej Karpathy가 새 레포를 공개하면, 개발자들이 주말 일정을 취소하는 진풍경이 벌어집니다. 그가 만든 nanoGPT가 "GPT가 어떻게 학습되는가"를 단 몇백 줄 코드로 해부했다면, 이번에 공개된 nanochat은 한 걸음 더 나아가 ChatGPT 전체 파이프라인을 $100으로 재현할 수 있는 레퍼런스 구현입니다. Karpathy의 LLM Wiki 아이디어도 함께 확인하기

백엔드 개발자 입장에서 LLM은 오랫동안 "API로 호출해서 쓰는 블랙박스"였습니다. OpenAI, Anthropic이 몇천억 원을 쏟아 만든 거대 모델이니, 우리가 직접 학습하는 것은 현실적이지 않은 일이었죠. 그런데 nanochat은 그 장벽을 현실적인 높이로 내립니다. 8×H100 노드에서 4시간, 비용 약 $100이면 GPT-2 수준의 모델을 처음부터 끝까지 학습할 수 있고, 스팟 인스턴스를 쓰면 $15 수준까지 떨어집니다.

이 글에서는 nanochat의 구조와 파이프라인을 하나씩 뜯어봅니다. 토크나이저, 사전학습, 중간학습(midtraining), SFT, 강화학습(RL), 추론까지 — LLM이 만들어지는 전 과정을 코드 레벨에서 이해할 수 있도록 정리했습니다. AI 코딩·모델 4월 총정리가 "어떤 모델을 고를 것인가"에 대한 답이었다면, 이 글은 "모델이 어떻게 만들어지는가"에 대한 답입니다.

1. nanochat이란

nanochat은 Andrej Karpathy가 2026년 2월에 공개한 오픈소스 LLM 학습 프레임워크입니다. 한 줄로 요약하면 "단일 GPU 노드에서 돌아가는 ChatGPT 풀스택 파이프라인"입니다.

기존 프로젝트와의 차이

프로젝트 범위 특징
nanoGPT (2022) 사전학습만 GPT 아키텍처 이해용 최소 코드
nanochat (2026) 토크나이저 + 사전학습 + SFT + RL + 추론 UI ChatGPT를 처음부터 끝까지 재현
HuggingFace 스택 전 과정 생산 품질이지만 코드가 복잡함

핵심 설계 철학

  • 단일 복잡도 파라미터: --depth(트랜스포머 레이어 수) 하나만 정하면, 나머지 하이퍼파라미터(너비, 헤드 수, 학습률, 가중치 감쇠, 학습 기간)가 자동 계산됩니다.
  • 의존성 최소화: Python 토크나이저는 느리고 HuggingFace 토크나이저는 복잡하다는 이유로, Rust BPE 토크나이저를 직접 구현했습니다.
  • 해킹 가능성: 모든 단계의 코드가 읽을 수 있는 분량이고, 수정해서 실험하기 쉽도록 설계되었습니다.
  • MIT 라이선스: 자유롭게 사용, 수정, 재배포 가능.

2. 비용과 성능

가장 충격적인 수치는 역시 비용입니다.

항목 비교
GPT-2급 학습 비용 약 $48 (온디맨드) / $15 (스팟) 2019년 원본 GPT-2: $43,000
SFT까지 포함 약 $92.40 (3시간 51분) 약 ~900배 저렴
하드웨어 8×H100 GPU 노드 ($24/시간) Lambda, Paperspace, Modal 등에서 대여 가능
소요 시간 전체 파이프라인 ~3~4시간 사전학습 3시간 + SFT 8분 + midtraining 7분

d20 모델 성능 지표 (SFT 후)

벤치마크 Pretraining 후 SFT 후 개선폭
ARC-Easy 36.5% 38.8% ↑2.3%
ARC-Challenge 28.8% 28.1% -
MMLU 31.1% 31.5% ↑0.4%
GSM8K (수학) 2.5% 4.6% ↑2.1%
HumanEval (코딩) 6.7% 8.5% ↑1.8%
ChatCORE 7.3% 8.8% ↑1.5%

"GPT-4나 Claude Opus 4.6과 비교하면 초라한 수치 아닌가?" 싶겠지만, 핵심은 "$100으로 이 수치가 나온다"는 사실 자체입니다. 프론티어 모델 재현이 아니라 LLM 학습 파이프라인의 구조 이해가 nanochat의 목적입니다.

3. 전체 파이프라인 구조

nanochat은 6단계로 구성됩니다. 각 단계가 독립된 스크립트로 분리되어 있어, 원하는 지점부터 실험할 수 있습니다.

┌─────────────────────────────────────────────────────────┐
│                  nanochat Pipeline                        │
├─────────────────────────────────────────────────────────┤
│ 1. Tokenizer (Rust BPE)     → tokenizer.json            │
│    20억 문자 학습, 1분 소요, 65,536 vocab                  │
├─────────────────────────────────────────────────────────┤
│ 2. Pretraining (~3시간)      → base_model.pt            │
│    FineWeb-EDU 24GB, 112억 토큰                          │
│    최종 val BPB: 0.81, CORE: 0.22                        │
├─────────────────────────────────────────────────────────┤
│ 3. Midtraining (~8분)        → mid_model.pt             │
│    SmolTalk 460K + MMLU 100K + GSM8K 8K                  │
│    대화 형식 + 도구 사용 학습                              │
├─────────────────────────────────────────────────────────┤
│ 4. SFT (~7분)                → sft_model.pt             │
│    지도학습 파인튜닝, 대화 품질 향상                         │
├─────────────────────────────────────────────────────────┤
│ 5. RL (선택 사항)             → rl_model.pt              │
│    GRPO 단순화 버전, GSM8K 성능 향상                       │
├─────────────────────────────────────────────────────────┤
│ 6. Inference Engine          → chat_cli / chat_web      │
│    KV 캐시, prefill/decode, Python 인터프리터            │
└─────────────────────────────────────────────────────────┘

코드 구조

nanochat/
├── gpt.py              # GPT 트랜스포머 구현
├── dataloader.py       # 분산 데이터 로더
├── engine.py           # KV 캐시 기반 추론
├── optim.py            # AdamW + Muon 옵티마이저
└── core_eval.py        # DCLM CORE 평가

scripts/
├── base_train.py       # 사전학습
├── chat_sft.py         # 지도 파인튜닝
├── chat_rl.py          # 강화학습
├── chat_cli.py         # CLI 채팅
└── chat_web.py         # 웹 UI

runs/
└── speedrun.sh         # 전체 파이프라인 원샷 실행

4. Tokenizer - Rust BPE

Karpathy가 Python 토크나이저가 아닌 Rust 토크나이저를 직접 구현한 이유는 명확합니다. "Python은 너무 느리고, HuggingFace 토크나이저는 너무 복잡하다"는 것.

토크나이저 스펙

  • 알고리즘: Byte-level BPE (OpenAI GPT-2와 동일)
  • 어휘 크기: 2^16 = 65,536 토큰 (또는 2^15 = 32,768 옵션)
  • 학습 데이터: 20억 문자
  • 학습 시간: 약 1분
  • 압축률: 원본 대비 4.8:1 (GPT-2보다 우수)
  • 추론 형식: tiktoken 포맷으로 변환해 빠른 추론

왜 BPE인가

# 예시: "unbelievable" 토큰화

# 문자 단위 (너무 길음)
['u', 'n', 'b', 'e', 'l', 'i', 'e', 'v', 'a', 'b', 'l', 'e']

# 단어 단위 (미등록 단어 처리 불가)
['unbelievable']  # → OOV 발생 시 

# BPE (빈출 서브워드 단위)
['un', 'believ', 'able']  # 희귀 단어도 조합으로 표현 가능

BPE는 자주 등장하는 바이트 쌍을 반복적으로 병합해서 서브워드 단위 어휘를 만듭니다. "단어 단위의 짧은 시퀀스"와 "문자 단위의 OOV 대응"을 둘 다 얻는 절충점이죠.

5. Pretraining - 기초 능력 학습

모델이 언어의 통계적 패턴을 익히는 단계입니다. nanochat은 이 단계에서 FineWeb-EDU 데이터셋을 사용합니다.

데이터셋과 규모

  • FineWeb-EDU: CommonCrawl에서 교육적 가치가 높은 문서를 필터링한 오픈 데이터셋
  • 샤드: 100B 토큰 중 240개 샤드 사용 (~24GB)
  • 학습 토큰: 약 112억 개
  • 소요 시간: 8×H100에서 약 3시간
  • 최종 지표: val BPB 0.81, CORE 0.22 (GPT-2 Large 수준)

Chinchilla 스케일링 법칙 적용

nanochat은 파라미터 대비 20배 토큰이라는 Chinchilla 법칙에 따라 학습합니다.

# d20 모델 (560M 파라미터)
560M × 20 = 112억 토큰 학습
# → nanochat이 FineWeb-EDU에서 학습하는 분량과 정확히 일치

# d26 모델 (더 큼)
약 1B 파라미터 × 20 = 200억 토큰+ 필요
# → 더 많은 데이터/시간 요구

사전학습 실행

# 전체 파이프라인 한 번에 실행 (~3~4시간)
bash runs/speedrun.sh

# 단일 GPU에서 소규모 실험
torchrun -m scripts.base_train --depth=12

# 더 큰 모델 (GPT-2 XL 수준)
torchrun -m scripts.base_train --depth=26

6. Midtraining - 대화와 도구 사용 학습

nanochat에서 흥미로운 지점이 바로 midtraining입니다. 기존 ChatGPT 파이프라인(pretraining → SFT → RLHF)과 달리, 중간에 한 단계가 더 있습니다.

midtraining의 역할

데이터셋 목적
SmolTalk 460K rows 다중턴 대화 형식 습득
MMLU Aux 100K rows 지식 기반 QA 훈련
GSM8K 8K rows 수학 추론 + 도구 사용 태그

소요 시간은 약 8분에 불과하지만, 이 단계를 거치고 나면 모델이 단순 텍스트 완성기에서 대화형 어시스턴트의 기본 형태를 갖춥니다.

도구 사용 태그 학습

# GSM8K에 삽입되는 도구 호출 예시
"Jane has 3 apples. She buys 4 more. Then gives 2 to Bob.
 How many does she have?"

calc(3 + 4 - 2)
5

"Jane has 5 apples left."

이렇게 도구 호출 패턴을 midtraining 단계에서 미리 학습시키면, 이후 SFT/RL 단계에서 훨씬 안정적으로 계산기나 외부 API를 활용합니다. MCP로 AI 에이전트-도구 연결을 표준화하는 방법

7. SFT - 지도 파인튜닝

SFT(Supervised Fine-Tuning)는 "사람이 만든 좋은 답변 예시"로 모델의 대화 품질을 끌어올리는 단계입니다.

핵심 아이디어

  • midtraining 후 모델은 "대화 형식"은 알지만 답변 품질은 들쭉날쭉
  • SFT는 고품질 대화 쌍(질문-답변)으로 모델을 다시 학습
  • 테스트 시의 프롬프트 형식과 학습 시의 형식을 정확히 일치시킴
  • 소요 시간: 약 7분

SFT 성능 향상 (d20 기준)

앞서 본 표에서 주목할 점은 GSM8K와 HumanEval의 향상폭입니다. SFT 전 2.5% → 4.6%(수학), 6.7% → 8.5%(코딩). 7분의 추가 학습이 특정 작업에서 성능을 2배 가까이 끌어올립니다.

8. RL - 강화학습 (선택 사항)

마지막 단계는 RL(강화학습)입니다. nanochat은 단순화된 GRPO(Group Relative Policy Optimization)를 사용합니다. RLHF의 복잡성을 피하면서 특정 태스크 성능을 높이는 방법입니다.

GRPO 요약

# 기본 흐름
1. 같은 질문에 대해 여러 답변을 샘플링
2. 각 답변을 보상 함수로 평가 (GSM8K라면 정답 여부)
3. 그룹 내 상대적 순위로 어드밴티지 계산
4. 상위 답변의 확률을 높이는 방향으로 정책 업데이트

# RLHF와의 차이
- RLHF: 별도 보상 모델(Reward Model) 학습 필요
- GRPO: 규칙 기반 보상 사용 가능 (정답 일치 등)
→ 인프라 복잡도 급감

GSM8K 특화 강화학습

GSM8K는 정답 여부를 수학적으로 검증할 수 있으므로, 별도의 보상 모델 없이 "정답 = 보상 1, 오답 = 보상 0"의 간단한 규칙으로 RL을 돌립니다. 이 단계는 선택 사항이며, 돌릴 경우 GSM8K 정답률이 추가로 올라갑니다.

9. 추론 엔진과 채팅 UI

학습한 모델을 실제로 써보는 단계입니다. nanochat의 engine.pyKV 캐시prefill/decode 분리를 구현합니다.

KV 캐시의 중요성

# KV 캐시 없이 (매 토큰마다 전체 시퀀스 재계산)
토큰 100개 생성 → 100회 × O(N²) 연산 → 매우 느림

# KV 캐시 사용 (이전 K/V를 재사용)
토큰 100개 생성 → 1회 prefill + 99회 decode
→ 추론 속도 수십 배 향상

웹 UI 실행

# CLI 채팅
python -m scripts.chat_cli

# 웹 UI (ChatGPT처럼 생긴 인터페이스)
python -m scripts.chat_web
# → http://localhost:8000 에서 채팅 가능

$100짜리 모델이라도 "ChatGPT와 비슷한 UI에서 내 모델과 대화한다"는 경험은 독특합니다. 로컬에서 전부 돌아가므로 데이터가 외부로 나가지 않고, 완전히 커스터마이즈할 수 있습니다.

10. 백엔드 개발자가 nanochat으로 얻는 것

"GPT-4 대신 쓸 모델을 만드는 건 아닌데, 그럼 왜 배우나?"라는 질문에 대한 제 답입니다.

LLM 시스템을 블랙박스에서 꺼내기

  • 토크나이저가 뭘 하는지 → 프롬프트 비용 최적화의 근거
  • KV 캐시가 왜 중요한지 → LLM 서빙 인프라 설계 감각
  • SFT와 RLHF의 차이 → 파인튜닝 업체 선택 시 판단 근거
  • Chinchilla 법칙 → 파인튜닝에 필요한 데이터 규모 추정

파인튜닝 의사결정의 현실화

"우리 도메인 데이터로 파인튜닝할까요?"라는 질문이 나왔을 때, nanochat을 한 번 돌려본 개발자는 비용, 시간, 데이터 요구량을 구체적으로 추정할 수 있습니다. Spring AI로 LLM 애플리케이션을 구축하는 가이드가 "API 레벨"의 대응이라면, nanochat은 "학습 레벨"의 근력 훈련입니다.

실무 연결 포인트

nanochat 단계 실무 연결 지점
Tokenizer 프롬프트 토큰 수 계산, 비용 예측
Pretraining 파운데이션 모델 선정 근거, 데이터 큐레이션
Midtraining 도구 사용/MCP 학습 로직 이해
SFT 사내 데이터로 파인튜닝 시 설계
RL (GRPO) 규칙 기반 보상 적용 사례 탐색
Inference Engine LLM 서빙 최적화 (vLLM, TGI 등과 비교)

11. 시작하는 방법

단계별 추천

  1. 읽기부터: gpt.py, dataloader.py, engine.py를 먼저 정독. 단 300줄이면 GPT 구조를 파악할 수 있습니다.
  2. 단일 GPU 스몰 실험: torchrun -m scripts.base_train --depth=12로 작은 모델을 RTX 4090 같은 로컬 GPU에서 돌려봅니다.
  3. 클라우드 speedrun: Lambda, Paperspace, Modal에서 8×H100 노드를 대여해 bash runs/speedrun.sh. 약 $100, 4시간.
  4. 채팅 체험: python -m scripts.chat_web로 내가 학습한 모델과 대화.
  5. 변형 실험: 토크나이저 어휘 크기, depth, 데이터셋 등을 바꿔가며 성능 변화를 관찰.

주의 사항

  • GPU 대여 비용: $24/시간은 적은 돈이 아닙니다. 스팟 인스턴스 활용 권장.
  • 정밀도 관리: A100/H100은 bfloat16, V100/T4는 float32로 자동 설정됩니다. CPU/MPS에서는 float32만 가능.
  • 프로덕션이 아님: 말 그대로 학습·실험용 레퍼런스입니다. 실제 서비스는 Llama, Qwen 같은 오픈 모델을 파인튜닝하는 편이 현실적입니다. Meta Llama 4 완벽 정리

마치며

Karpathy의 nanochat이 개발자들에게 남긴 의미를 요약합니다.

  • LLM이 더 이상 신비의 영역이 아님: 토크나이저부터 추론 엔진까지, $100과 4시간이면 전체 파이프라인을 내 손으로 돌려볼 수 있습니다. 블랙박스의 문이 열렸다는 의미가 큽니다.
  • midtraining이라는 독립 단계의 재발견: 기존 "pretraining → SFT → RLHF" 공식에 "midtraining"을 끼워넣어, 대화 형식과 도구 사용을 먼저 학습시키는 접근법이 인상적입니다. 에이전트 시대의 학습 파이프라인은 이 방향으로 확장될 가능성이 높습니다.
  • 단순화된 GRPO의 실용성: RLHF의 복잡성을 피하면서 규칙 기반 보상으로 특정 태스크 성능을 끌어올리는 방식은, 국내 중소 조직이 사내 데이터로 "정답 검증 가능한 태스크"를 학습시킬 때 참고할 만한 템플릿입니다.
  • Chinchilla 법칙의 체감: 560M 파라미터 × 20 = 112억 토큰이라는 구체적 수치로, 파인튜닝·학습 프로젝트의 데이터 규모를 추정하는 근육이 생깁니다.
  • 엔지니어링 가독성의 표본: nanochat 코드는 "최소한의 추상화 + 최대한의 명료함"을 추구합니다. AI 엔지니어링 패러다임의 진화 AI 관련 오픈소스 설계에서 참고할 만한 레퍼런스입니다.

nanochat은 직접 쓰는 제품이라기보다 LLM 시대의 기초 체력을 쌓는 교재에 가깝습니다. API 사용에만 익숙해지면 놓치게 되는 "모델이 만들어지는 원리"를 손으로 익힐 수 있다는 점에서, 2026년 백엔드/AI 개발자에게 nanochat은 nanoGPT 이상으로 가치 있는 자료라고 생각합니다. 주말 4시간과 GPU 대여비 $100은 그 정도 투자 가치가 있습니다.