이걸 왜 이제 알았을까? 단돈 10만 원으로 나만의 ChatGPT 만들기: NanoChat 솔직 분석 및 후기
“단돈 100달러로 살 수 있는 최고의 ChatGPT. 이제 누구나 바닥부터 LLM을 만들 수 있습니다.”
요즘 쏟아지는 수많은 AI 논문과 거대한 프레임워크 속에서 길을 잃은 기분이 들 때가 있지 않으신가요? 저도 그랬어요. 매주 새로운 ‘SOTA(State of the Art)’ 모델이 발표되고, 수천 줄짜리 복잡한 YAML 설정 파일과 거대한 라이브러리의 추상화 계층과 씨름하다 보면 ‘내가 지금 모델의 구조를 이해하고 있는 건지, 아니면 그냥 API 호출 기계가 된 건지’ 회의감이 들더라고요.
그러다 작년 10월, AI 씬의 록스타 안드레아 카파시(Andrej Karpathy) 형님이 무심한 듯 툭 던진 깃허브 레포지토리 하나를 발견하고는, 주말 내내 밥 먹는 것도 잊은 채 모니터 앞을 떠나지 못했습니다. 바로 오늘 소개해드릴 NanoChat 이야기예요.
이 프로젝트는 단순히 코드를 짜는 것을 넘어, 개발자로서의 본질적인 호기심을 자극하는 ‘진짜 물건’입니다. 오늘은 제가 동료 개발자로서 여러분과 커피 한잔하며 썰을 풀듯, 이 엄청난 프로젝트에 대해 깊이 파헤쳐볼까 해요.
💡 TL;DR (한 마디로?)
NanoChat은 토크나이저부터 사전 학습(Pre-training), 파인튜닝, 웹 UI까지 LLM 학습의 A to Z를 단 100달러(약 13만 원)와 4시간 만에 단일 GPU 노드에서 끝낼 수 있게 해주는 ‘초경량/초단순 순수 PyTorch 코드베이스’입니다.
🕵️♂️ Deep Dive: 기존 프레임워크와 무엇이 다를까?
사실 시중에 LLM 학습 프레임워크는 널리고 널렸잖아요? HuggingFace의 transformers, trl, datasets 등 정말 훌륭하고 강력한 도구들이 생태계를 꽉 잡고 있죠. 그런데 NanoChat은 이 생태계의 흐름을 정면으로 역행합니다. 제가 개발자로서 가장 열광했던, 그리고 여러분도 흥미로워할 포인트 세 가지를 짚어볼게요.
1. 의존성 제로, 순수 PyTorch가 주는 날것의 낭만 🎸
HuggingFace나 거대한 라이브러리를 쓰면 당장 구현하기엔 엄청 편합니다. 하지만 내부에서 대체 무슨 마법이 일어나고 있는지 알기 어렵다는 치명적인 단점이 있죠. NanoChat은 그 흔한 transformers 라이브러리조차 과감하게 걷어냈습니다. 모든 모델 아키텍처와 학습 루프가 투명한 하나의 PyTorch 파일에 담겨 있어요.
수많은 ‘If-then-else’ 지옥이나, 추상화된 거대한 팩토리(Factory) 패턴 없이 코드가 그냥 위에서 아래로 물 흐르듯 읽힙니다. 토크나이징부터 어텐션 메커니즘, 로스 계산까지 코드를 따라가다 보면, 그동안 블랙박스처럼 여겨졌던 LLM의 심장부가 적나라하게 드러납니다. 마치 복잡한 최신 자동차만 몰다가, 엔진 덮개를 열고 직접 부품을 조립해보는 짜릿함이랄까요? 진짜 ‘공부’가 되는 기분이에요.
2. 마법의 다이얼: --depth 하나로 끝나는 하이퍼파라미터 🎛️
LLM을 처음부터 학습시킬 때 우리를 가장 괴롭히는 게 뭘까요? 바로 하이퍼파라미터 튜닝입니다. 레이어 크기에 맞춰 학습률(Learning Rate)은 어떻게 조절해야 할지, 웜업(Warmup) 스텝은 얼마나 줘야 할지 골치가 아프죠. NanoChat은 이 복잡한 설정을 전부 수학적으로 해결해버렸습니다. 오직 --depth(트랜스포머의 레이어 수)라는 단 하나의 변수만 조작하면 됩니다.
| 파라미터 제어 방식 | 기존 거대 프레임워크 | NanoChat의 우아한 방식 |
|---|---|---|
| 모델 구조 크기 | hidden_size, num_heads 등 수동 계산 | --depth 하나로 비율 자동 조정 |
| 학습률 (Learning Rate) | 모델 크기마다 수동 스케줄링 | Depth에 맞춰 Compute-Optimal 자동 계산 |
| 설정 복잡도 | 수백 줄의 중첩된 JSON/YAML Config | 깔끔한 CLI 인자 하나면 끝 |
그냥 “나 GPT-2 수준의 성능을 내는 모델을 만들래!” 하면 --depth 26 정도로 맞추고 돌리면 그만이에요. 나머지는 코드 내부의 Compute-Optimal 공식이 알아서 최적화해줍니다. 이 철학을 보면서, 복잡성을 숨기는 가장 좋은 방법은 추상화 계층을 쌓는 게 아니라 ‘본질적인 규칙을 찾는 것’이라는 걸 다시금 깨달았습니다.
3. 혁명적인 Muon 옵티마이저의 도입 🚀
이 부분에서 저는 진짜 입을 다물지 못했어요. 보통 딥러닝 최적화 하면 Adam이나 AdamW를 국룰처럼 쓰잖아요? NanoChat은 최근 AI 씬에서 극찬받고 있는 Muon(뮤온) 옵티마이저를 은닉층(Hidden weights) 학습에 선구적으로 도입했습니다.
1
2
3
4
5
6
7
8
9
# NanoChat 아키텍처에서 영감을 받은 수도코드 (실제 코드는 더 정교합니다)
from muon import Muon
from torch.optim import AdamW
# 임베딩(Embeddings)과 분류기 헤드(Classifier heads)는 기존의 안정적인 AdamW 사용
optimizer_adam = AdamW(model.embeddings.parameters(), lr=1e-3)
# 트랜스포머 은닉층(Hidden layers)은 Muon을 사용하여 메모리 최적화!
optimizer_muon = Muon(model.hidden_layers.parameters(), lr=0.02)
이게 왜 대박이냐면요, Muon은 기존 Adam 대비 상태(State) 메모리를 절반만 차지하면서도 수렴 속도나 성능은 동급이거나 오히려 더 뛰어납니다. GPU VRAM 제한 때문에 늘 허덕이는 우리 같은 개발자들에게는 완전히 판을 바꾸는 기술(Game Changer)이죠. 이런 최신 연구 결과를 가장 미니멀한 형태로 바로 가져다 쓸 수 있다는 게 이 레포지토리의 진정한 가치라고 생각해요.
🛠️ Hands-on: 내 손으로 직접 구워본 챗봇 (실사용 경험)
사실 처음 깃허브를 봤을 땐 “진짜 4시간 만에 그럴싸한 채팅 모델이 나온다고? 장난감 수준 아닐까?” 의심했어요. 그래서 직접 팔을 걷어붙이고 클라우드 서비스(Modal이나 RunPod 등)에서 8xH100 인스턴스를 빌려 speedrun.sh 스크립트를 돌려봤습니다. (스팟 인스턴스로 잘 잡으면 20~30달러면 충분해요!)
전체 파이프라인이 돌아가는 과정은 한 편의 오케스트라 같았습니다.
- 초고속 토크나이저 학습: Rust로 래핑된 BPE 토크나이저가 FineWeb-edu 데이터의 100억 개 토큰을 눈 깜짝할 새에 분석해 맞춤형 사전을 만듭니다. (왜 굳이 Rust를 썼는지 속도를 보면 단번에 납득이 가더라고요.)
- 사전 학습 (Pre-training): 텅 빈 깡통 모델이 인터넷의 방대한 지식을 섭취하며 언어의 규칙을 깨우칩니다. W&B(Weights & Biases) 대시보드로 loss가 뚝뚝 떨어지는 걸 실시간으로 보는 쾌감은 정말 최고예요.
- 미드 트레이닝 (Mid-training & SFT): Smoltalk 데이터셋을 통해 이 똑똑해진 모델에게 “대화하는 법”과 “도구를 사용하는 법”을 가르칩니다.
- FastAPI 웹 UI 서빙: 모든 학습이 끝나면, ChatGPT와 똑같이 생긴 깔끔한 웹 인터페이스가 뙇! 하고 뜹니다.
매일 남이 만들어둔 거대한 LLM을 가져와서 LoRA로 껍데기만 살짝 파인튜닝하다가, 데이터 전처리부터 토크나이징, 베이스 학습, 채팅 정렬(Alignment)까지 내 손으로 직접 구워낸 녀석과 첫 대화를 나누는 기분은… 과장 조금 보태서 내 아이가 처음 말문이 터졌을 때의 감동과 비슷하더라고요.
특정 도메인의 코퍼스(Corpus)만 학습시켜 사내 스터디용으로 쓰거나, 외부 반출이 절대 불가한 극비 데이터를 다루는 ‘초프라이빗 온프레미스 소형 LLM’의 프로토타입을 구축할 때 이만한 도구가 없을 것 같습니다.
🤔 Honest Review: 공식 문서에는 없는 솔직한 장단점
물론 세상에 완벽한 은탄환은 없죠. 며칠간 코드를 뜯어보고 테스트하며 느낀 한계점도 가감 없이 털어놓겠습니다.
👍 극찬하고 싶은 점 (Pros):
- 압도적인 교육적 가치: 카파시의 LLM101n 코스 캡스톤 프로젝트답게, “LLM은 도대체 어떻게 동작하는가”를 근본적으로 이해하는 데 있어 현존 최고의 교보재입니다. 코드가 너무 아름다워서 계속 읽게 돼요.
- 혁명적인 가성비: 2019년 당시 4만 3천 달러(약 5천5백만 원)가 들었던 GPT-2급 모델 학습을, 단돈 100달러 컷으로 끊어버렸습니다. 컴퓨팅 자원의 민주화가 무엇인지 제대로 보여줬어요.
👎 조금 아쉬웠던 점 (Cons):
- 여전한 하드웨어 진입 장벽: ‘100달러’라는 타이틀이 자극적이긴 하지만, 이는 클라우드에서 ‘8xH100’이라는 괴물 같은 노드를 짧고 굵게 빌렸을 때의 이야기입니다. 집에 있는 맥북 M시리즈나 RTX 4090 한 대로는 학습 시간이 며칠 단위로 길어져서 사실상 ‘스피드런’의 기획 의도가 퇴색됩니다. 로컬 환경만 있는 분들에겐 여전히 그림의 떡일 수 있어요.
- 프로덕션 레벨의 확장성 부족: 이 레포지토리는 ‘교육’과 ‘강력한 베이스라인(Strong Baseline)’ 제공이 목적입니다. 만약 여러분이 이 코드를 기반으로 수십 개의 노드를 클러스터링해서 수천억 파라미터의 모델을 분산 학습시키려 한다면 지옥을 맛볼 수 있습니다. 최적화된 분산 처리나 모델 병렬화(Model Parallelism), 다양한 양자화(Quantization) 지원은 생략되어 있으니, 상용 서비스를 원한다면 학습 후 HuggingFace 생태계로 모델을 포팅(Porting)하는 과정이 필수적입니다.
- 유연성의 역설:
--depth다이얼 하나로 모든 걸 맞추는 건 아름답지만, 거꾸로 말하면 연구자가 완전히 새로운 커스텀 아키텍처 실험(예: 특정 레이어만 비대칭으로 키우기 등)을 하려면 내부의 Compute-Optimal 하드코딩 수식을 일일이 다 뜯어고쳐야 하는 수고로움이 동반됩니다.
☕ Conclusion: 일단 한 번 돌려보세요! 잃을 건 10만 원뿐입니다.
최근 해커뉴스나 레딧을 보면 LLM을 그저 ‘프롬프트 몇 줄 끄적이는 API’로만 대하는 분위기가 짙어지는 것 같아 개인적으로 아쉬움이 컸습니다. 마치 우리가 코드를 직접 짜지 않고 AI에게 모든 걸 맡기는 ‘바이브 코딩(Vibe Coding)’의 시대가 온 것처럼 말이죠.
하지만 NanoChat은 진짜 엔지니어들에게 “너도 바닥부터 챗봇을 조립할 수 있어! 원리는 생각보다 단순해!”라며 등을 떠밀어주는 유쾌하고 대담한 초대장 같습니다. 가끔은 편하게 포장된 블랙박스에서 벗어나 날것의 코드를 읽으며 본질을 탐구하는 시간이 개발자의 성장에 꼭 필요한 자양분이 되니까요.
이번 주말, 넷플릭스 볼 시간 조금 아끼고 치킨 몇 마리 덜 먹는 셈 치고 클라우드 인스턴스 하나 띄워보는 건 어떨까요? 여러분의 터미널에서, 여러분이 직접 학습시킨 작고 귀여운 챗봇이 첫인사를 건네는 순간, 잊고 있던 코딩의 순수한 즐거움을 다시 느끼실 수 있을 거라고 확신합니다.
저도 당분간은 이 NanoChat 코드를 가지고 로컬 RAG 시스템을 연동해보는 장난을 쳐볼 계획입니다. 다음에 또 심장을 뛰게 하는 재밌는 기술을 발견하면, 커피 한잔 챙겨서 썰 풀러 오겠습니다. 다들 즐거운 해킹 하세요! 🚀
References
- https://github.com/karpathy/nanochat
- https://huggingface.co/nanochat-students
- https://news.ycombinator.com/item?id=41865985
