NanoEuler – 순수 C/CUDA로 처음부터 만든 GPT-2 규모 언어 모델
Show HN: NanoEuler – GPT-2 scale model in pure C/CUDA from scratch
TL;DR Highlight
PyTorch나 autograd 없이 C와 CUDA만으로 GPT-2 수준의 LLM을 처음부터 구현한 교육용 프로젝트로, 역전파·BPE 토크나이저·FlashAttention까지 직접 손으로 작성했다.
Who Should Read
딥러닝 프레임워크 내부 동작 원리를 C/CUDA 수준에서 직접 이해하고 싶은 ML 엔지니어나 시스템 프로그래머. 특히 역전파·어텐션 메커니즘을 코드로 깊게 파고들고 싶은 개발자에게 적합하다.
Core Mechanics
- PyTorch, autograd, 어떤 ML 라이브러리도 쓰지 않고 순수 C와 CUDA만으로 GPT-2 스타일의 LLM 전체 학습 파이프라인을 구현했다. 이 프로젝트의 핵심 목표는 '동작하는 결과물'이 아니라 '모든 것을 직접 만들어보는 엔지니어링 경험'이다.
- 순전파(forward pass)와 역전파(backward pass, 즉 gradient를 계산해서 가중치를 업데이트하는 과정)를 모두 손으로 작성했고, CPU 기반 reference 구현과 전체 모델 gradient check로 정확성을 검증했다. double precision(배정밀도) 모드로 수치 검증까지 완료했다.
- BPE(Byte Pair Encoding, 자주 등장하는 문자 쌍을 반복적으로 합쳐서 어휘를 구성하는 토크나이징 방법) 토크나이저도 직접 구현했다. byte-level BPE 방식이라 어떤 언어나 특수문자도 처리할 수 있다.
- CUDA 엔진에는 cuBLAS(NVIDIA의 행렬 연산 라이브러리)로 행렬 곱셈을 처리하고, FlashAttention(메모리 효율적인 어텐션 알고리즘)도 직접 손으로 구현했다. CPU 버전은 libm과 OpenMP로 병렬처리를 지원한다.
- 소규모 모델(약 76만 파라미터)은 CPU에서, 약 1억 1600만(116M) 파라미터짜리 대형 모델은 RTX 4070 단일 GPU에서 학습할 수 있도록 설계했다.
- 사전학습(pretraining)은 책과 웹 코퍼스를 사용했고, 이후 SFT(Supervised Fine-Tuning, 정답 예시를 보여주며 지도학습하는 파인튜닝)까지 연결되는 전체 파이프라인이 완성되어 있다. RLHF/DPO는 추후 계획 단계다.
- 프로젝트 이름 'Euler'는 수학적 의미에서 따온 것으로, 잔차 블록(residual block)의 x = x + f(x) 연산이 수치해석의 forward-Euler 방법(미분방정식을 단계적으로 적분하는 기법)과 구조적으로 동일하기 때문이다. 즉 깊은 신경망은 '이산화된 ODE(상미분방정식)'로 볼 수 있다.
- 프로젝트 자체적으로 '이것은 유용한 챗봇이 아니다'라고 명시하고 있다. 116M 파라미터를 단일 소비자 GPU로 학습한 수준이라 자연스러운 영어 생성 정도는 되지만, 실제 지식이나 추론 능력은 없다. 학습/엔지니어링 목적의 교육용 결과물이다.
Evidence
- CUDA 부분의 실제 동작 여부에 의문을 제기하는 댓글이 있었다. CUDA 소스 코드 내부에 LLM이 남긴 것으로 보이는 'untested(테스트 안 됨)'라는 주석이 발견됐다는 지적이 있었고, 실제로 CUDA 코드가 제대로 동작하는지 묻는 질문이 이어졌다.
- README가 AI(LLM)로 작성된 것으로 보인다는 지적이 나왔다. em-dash(—) 사용 패턴이 AI 글쓰기 특유의 스타일이라는 이유였고, 프로젝트 자체가 얼마나 직접 작성된 것인지(vibe-coding인지) 궁금하다는 반응이 여럿 있었다.
- Neural ODE 언급이 맥락상 맞지 않는다는 기술적 반론도 있었다. Transformer의 residual connection은 모든 구현체에 공통적으로 사용되는 것이지, 이것이 곧 Neural ODE를 학습한다는 의미는 아니라는 지적이었다.
- 코딩 스타일이 매우 독특하다는 댓글도 있었다. C 코드에 `astyle --style=python` 포맷터를 적용한 듯한 스타일이라는 표현으로, Python 스타일의 들여쓰기·포맷이 C 코드에 적용된 것이 어색하다는 의견이었다.
- 학습에 얼마나 걸렸는지, 몇 토큰을 학습했는지, CUDA 행렬 곱셈 최적화를 어떻게 했는지, PyTorch 대비 학습 속도 차이가 얼마나 되는지 같은 구체적인 벤치마크 질문들이 많았지만, 원문이나 저자 답변에 수치가 명시되어 있지 않다.
How to Apply
- 딥러닝 프레임워크 없이 역전파 원리를 코드 수준에서 이해하고 싶다면, `make check` 명령어로 gradient check부터 실행해보면서 각 레이어의 역전파 구현 코드를 직접 읽어볼 수 있다. 수식과 코드를 1:1로 대조하기 좋은 구조다.
- 소규모 모델(76만 파라미터)은 CPU에서도 학습이 가능하므로, GPU가 없는 환경에서도 `./nanoeuler train` 명령어로 전체 학습 파이프라인(토크나이징 → 사전학습 → 채팅 REPL)을 처음부터 끝까지 직접 돌려볼 수 있다.
- FlashAttention을 직접 구현한 CUDA 코드가 포함되어 있으므로, CUDA 커널 작성 방법이나 FlashAttention 알고리즘 내부 구조를 학습하려면 `cuda/` 디렉토리의 코드를 CPU reference 구현과 비교하면서 읽어보면 된다.
- 사전학습 후 SFT(지도 파인튜닝)까지 연결되는 전체 파이프라인이 단일 레포에 있으므로, 커스텀 데이터셋으로 처음부터 학습하는 minimal한 LLM 파이프라인 레퍼런스가 필요할 때 이 코드를 템플릿으로 참고할 수 있다.
Code Example
# gradient check (역전파 정확성 검증)
make check
# 학습 바이너리 빌드
make
# 소규모 모델 학습 (~0.76M 파라미터, CPU 가능)
./nanoeuler train
# 대형 모델 학습 (~10M 파라미터, GPU 권장)
./nanoeuler train big
# 채팅 REPL 실행 (프롬프트 입력 → 모델이 이어서 생성)
./nanoeuler chatTerminology
관련 논문
Black-Box LLM에서 지식 증류하기: Proxy-KD 기법 (2024)
GPT-4 같은 내부 구조에 접근할 수 없는 독점 LLM에서 작은 모델로 지식을 효과적으로 전달하는 Proxy-KD 기법을 소개하는 논문으로, 전통적인 White-Box 방식보다 성능이 높다는 점에서 주목할 만하다.
Neural Particle Automata: 자기조직화 파티클 시스템을 학습하는 신경망 모델
고정된 격자 대신 움직이는 파티클 위에서 동작하는 Neural Cellular Automata의 확장 버전으로, 형태 생성·포인트 클라우드 분류·텍스처 합성 등 다양한 작업에서 자기조직화 동작을 학습할 수 있다.
PyTorch Training Loop 완전 해부: 각 줄이 하는 일과 순서를 바꾸면 생기는 문제
PyTorch 학습 루프의 각 코드 줄이 왜 그 위치에 있어야 하는지, 순서를 바꾸거나 빠뜨렸을 때 어떤 문제가 생기는지를 단계별로 설명한 심층 가이드다.
좋은 Verifier도 망가질 수 있다: Self-Improving VLM이 새로운 태스크에서 오히려 퇴보하는 현상
VLM 자가학습 루프에서 verifier가 특정 태스크에 맞지 않으면 학습할수록 오히려 성능이 떨어지는데, DPO 손실값은 멀쩡히 내려가서 눈치채기도 어렵다.
Self-Distillation에서 Feedback Alignment의 역할
LLM이 스스로를 가르칠 때, 피드백을 모델의 추론 흐름에 단계별로 맞추면 GRPO보다 16점 이상 수학 추론 성능이 오른다.
작고 수정 가능한 CUDA 기반 Language Model 직접 구현체
CUDA로 작성된 GPT(Generative Pretrained Transformer) 미니멀 구현체로, 텍스트뿐 아니라 모든 바이트 스트림을 학습할 수 있어 LLM 내부 구조를 직접 뜯어보고 싶은 개발자에게 유용하다.
Stanford CS336: Language Modeling from Scratch - LLM을 처음부터 직접 만드는 강의