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
관련 논문
레이어 하나면 충분한가? 단일 Transformer 레이어 학습이 전체 파라미터 RL 학습과 동등한 성능
LLM의 RL 후처리 학습(post-training)에서 성능 향상의 대부분이 중간 레이어 소수에 집중되며, 단 하나의 레이어만 학습해도 전체 파라미터 학습과 비슷하거나 더 나은 결과를 낼 수 있다는 연구 결과. 이는 RL 학습 비용을 대폭 줄일 수 있는 가능성을 시사한다.
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점 이상 수학 추론 성능이 오른다.