순수 C/CUDA로 제로부터 구축한 GPT-2 규모 모델, NanoEuler
PyTorch나 자동 미분(autograd), 머신러닝 라이브러리 없이 순수 C/CUDA만으로 GPT-2 급의 언어 모델을 제로부터 구축한 프로젝트가 공개되었습니다. 순방향/역방향 패스부터 바이트 수준 BPE 토크나이저, CUDA 엔진, FlashAttention까지 전체 학습 파이프라인을 직접 손으로 작성 및 검증한 것이 특징입니다. 실사용 챗봇보다는 대형 언어 모델의 동작 원리와 엔지니어링 과정을 투명하게 이해하기 위한 교육 및 연구용으로 큰 의미가 있습니다.
nanoeuler는 PyTorch, 자동 미분(autograd), 머신러닝 라이브러리 없이 순수 C/CUDA만으로 제로부터 완전히 구축된 GPT-2 급 언어 모델입니다. 순방향 및 역방향 패스는 직접 손으로 작성하고 검증되었으며, 전체 학습 파이프라인이 이 저장소에 담겨 있습니다. 여기에는 직접 작성한 바이트 수준 BPE 토크나이저, 서적 및 웹 말뭉치를 활용한 사전 학습, 그리고 챗 모델로의 지도 미세조정(SFT) 과정이 포함되어 있습니다 (향후 RLHF/DPO 적용을 계획 중입니다).
이 모델은 작은 데모용 모델의 경우 CPU(libm + OpenMP)에서 실행되며, 완전히 제로부터 작성된 CUDA 엔진 — cuBLAS 행렬 곱셈, 직접 작성한 FlashAttention, CPU 참조 구현과 대비한 전체 모델 기울기 검증(gradient check) — 을 통해 단일 RTX 4070 GPU에서 약 1억 1,600만 개의 매개변수를 가진 모델을 학습합니다.
현재 상태 및 솔직한 평가: 이 프로젝트는 공개적으로 개발된 연구 및 교육용 결과물입니다. 단일 소비자용 GPU로 학습된 약 1억 1,600만 개 매개변수 모델은 GPT-2-small의 정신을 계승하는 텍스트 생성기로, 어느 정도 유창한 영어는 구사하지만 실제 세상의 지식은 없습니다. 이것은 유능한 어시스턴트가 아닙니다. 챗 모델은 사전 학습에서 SFT로 이어지는 파이프라인이 엔드투엔드로 작동한다는 것을 보여줄 뿐, 유용한 챗봇은 아닙니다. 이 프로젝트의 핵심은 제로부터 시작하는 엔지니어링과 완전하고 이해 가능한 학습 파이프라인을 구축하는 데 있습니다.
make check # 역방향 패스 검증 (기울기 확인, 배정밀도) make # 학습 바이너리 빌드 ./nanoeuler train # 작은 데모용 모델 학습 (약 0.76M 매개변수) ./nanoeuler train big # 더 큰 모델 학습 (약 10M 매개변수; GPU 전용) ./nanoeuler chat # REPL: 프롬프트를 입력하면 모델이 이어서 작성
왜 "Euler(오일러)"인가? 잔차 블록(residual block)은 x = x + f(x)를 계산합니다. 이를 수치 적분의 한 단계로 읽을 수 있습니다. 전진 오일러 방법(forward-Euler method)은 상미분 방정식 dx/dt = f(x)를 x(t+Δt) = x(t) + Δt · f(x(t))로 진행시킵니다. 여기에 스텝 크기 Δt = 1을 적용하면 이것은 정확히 잔차 업데이트와 같습니다. 따라서 심층 잔차 네트워크는 이산화된 ODE입니다. 즉, 깊이가 적분 시간이며, 각 레이어는 은닉 상태를 한 오일러 스텝씩 앞으로 적분합니다. 이는 신경망 ODE(Neural ODEs)와 같은 연구의 기반이 되는 관점입니다(ResNet은 연속 흐름의 오일러 이산화입니다). 이 프로젝트는 그 적분 방법을 제공한 레온하르트 오일러(Leonhard Euler)의 이름을 따서 명명되었습니다.
예시 출력 서적 + 웹 말뭉치에 대한 부분적인 사전 학습 실행 후 약 1억 1,600만 매개변수 모델의 샘플입니다 (프롬프트: Alessandro eat a ): "Alessandro eat a icing textile: the satisfied by the servants in order to keep your weight [Using to a heated, collaborated young people that attend the metric process where the rank is authorized and to contain the sedentary. Some state lawyers were able to insert ..." 내용 자체는 의미가 없지만, 모델이 스스로 학습한 점에 주목하세요. 실제 문법, 긴 절, 그리고 웹 데이터에서 얻은 백과사전적인 어조를 띠고 있습니다. 이것이 단일 GPU로 학습된 소규모 모델의 예상된 동작입니다. 유창한 형태는 갖추었지만 내용이 얕습니다. 추가 학습과 (훨씬 더 많은) 데이터는 유창성을 향상시킵니다. 반면 세상에 대한 지식은 이 프로젝트가 염두에 두지 않은 대규모 확장(scale)을 필요로 합니다.
아키텍처 현재 모델에서 사용되는 공통 빌딩 블록을 갖춘 디코더 전용(Decoder-only) 트랜스포머입니다:
- RMSNorm (사전 정규화, 편향 없음)
- 쿼리와 키에 적용된 회전 위치 임베딩 (RoPE)
- SwiGLU 피드포워드: down(silu(gate(x)) * up(x))
- 그룹화된 쿼리 어텐션 (GQA): 쿼리 헤드가 더 작은 키/값 헤드 세트를 공유
- 다중 토큰 예측 (MTP): K개의 출력 헤드가 다음 K개의 토큰을 예측합니다. 이 보조 헤드들은 학습된 표현을 개선하고 추측 디코딩(speculative decoding)을 가능하게 합니다. 텍스트 생성 시에는 헤드 0을 사용합니다.
- 어디에도 편향(Bias)을 사용하지 않습니다.
GPT-2 스타일의 사전 토큰화를 적용하여 직접 작성한 바이트 수준 BPE 토크나이저 (단일 선행 공백이 다음 단어에 결합되어, 공백이 독립적인 토큰으로 낭비되지 않도록 했습니다). 병합(merges)은 말뭉치 샘플에서 학습되며, GPU 모델은 4096 토큰 어휘를 사용합니다 (영어 기준 토큰당 약 3.4바이트).
각 블록은 x = x + attn(rmsnorm(x)) 이후에 x = x + swiglu(rmsnorm(x))가 따릅니다. 잔차 연결인 x = x + f(x)는 ODE dx/dt = f(x)에 대한 전진 오일러 방법의 한 단계입니다. 이것이 프로젝트 이름의 유래이며, 레온하르트 오일러에게 경의를 표하는 이유이기도 합니다.