microgpt - 200줄 순수 파이썬으로 구현한 GPT 학습 및 추론 | GeekNews
Blog

microgpt - 200줄 순수 파이썬으로 구현한 GPT 학습 및 추론 | GeekNews

xguru
2026.02.20
·News·by 배레온/부산/개발자
#Autograd#GPT#LLM#Python#Transformer

핵심 포인트

  • 1microgpt는 Andrej Karpathy가 공개한 200줄의 순수 Python 스크립트로, 외부 의존성 없이 GPT의 학습 및 추론 알고리듬 전체를 구현한 최소형 프로젝트입니다.
  • 2이 프로젝트는 데이터셋, 토크나이저, Autograd 엔진, GPT-2 유사 Transformer 아키텍처, Adam 옵티마이저, 학습 및 추론 루프까지 포함하며, GPT의 본질적인 알고리듬을 이해하는 데 중점을 둡니다.
  • 3microgpt는 생산용 LLM과 수학적 핵심은 동일하나, 규모, 효율성(예: 텐서 기반 Autograd, GPU 사용), 그리고 후학습(SFT/RL) 과정에서 차이가 발생함을 명확히 보여줍니다.

microgpt는 karpathy.github.io에서 공개된 오픈 소스 프로젝트로, 200줄의 순수 Python 코드로 GPT 모델의 학습 및 추론 과정을 완벽하게 구현한 '아트 프로젝트'입니다. 이 프로젝트는 외부 의존성 없이 데이터셋, 토크나이저, autograd 엔진, GPT-2 유사 Transformer 아키텍처, Adam 옵티마이저, 학습 및 추론 루프를 모두 포함하며, 기존 micrograd, makemore, nanogpt 등의 작업을 집대성하여 GPT 알고리즘의 핵심을 '더 이상 단순화할 수 없는' 최소 형태로 압축했습니다. 목표는 이 코드를 통해 GPT의 알고리즘적 본질을 이해하는 것입니다.

핵심 방법론

  1. 데이터셋 및 토크나이저:
    • 데이터셋: 프로덕션 LLM이 수조 개의 인터넷 텍스트 토큰을 사용하는 반면, microgpt는 약 32,000개의 영문 이름 데이터를 한 줄씩 사용합니다. 각 이름은 하나의 '문서'로 취급되며, 모델은 데이터 내의 통계적 패턴을 학습하여 유사한 새 이름을 생성하는 것을 목표로 합니다.
    • 토크나이저: 신경망은 문자가 아닌 숫자로 작동하므로 텍스트를 정수 token ID 시퀀스로 변환하는 과정이 필요합니다. microgpt는 가장 단순한 형태인 문자 단위(char-level) 토크나이저를 사용합니다. 소문자 'a'부터 'z'까지 각각 ID를 할당하며, BOS (Beginning of Sequence) 특수 토큰을 추가하여 시퀀스의 시작과 끝을 알립니다. 예를 들어 "emma"는 [BOS, e, m, m, a, BOS]로 변환됩니다. 최종 어휘 크기는 소문자 26개와 BOS 1개를 포함해 총 27개입니다. 프로덕션 LLM은 BPE (Byte Pair Encoding)와 같은 서브워드 토크나이저를 사용하여 효율성을 높입니다.
  1. 자동 미분 (Autograd):
    • 신경망 학습에 필수적인 gradient 계산을 위해 autograd 엔진이 내장되어 있습니다. 이는 각 파라미터가 loss에 미치는 영향을 파악하여 업데이트 방향을 결정합니다.
    • Value 클래스: autogradValue라는 사용자 정의 클래스로 구현됩니다. 각 Value 객체는 단일 scalar 값(.data)을 래핑하며, 이 값이 어떻게 계산되었는지(_children)와 해당 연산의 국소 도함수(_local_grads)를 추적합니다. 예를 들어, 곱셈 __mul__ 연산은 (ab)/a=b\partial(a \cdot b)/\partial a = b(ab)/b=a\partial(a \cdot b)/\partial b = a를 기록합니다.
    • 역전파 (backward() 메소드): loss 노드에서 self.grad=1self.grad = 1로 시작하여 연산 그래프를 역위상 순서(reverse topological order)로 순회하며 미적분의 chain rule을 적용합니다. 각 단계에서 국소 gradient를 곱하여 경로를 따라 파라미터까지 전파합니다. 이때 +=+= 연산을 통해 gradient를 누적하는데, 이는 그래프가 분기될 때 각 분기에서 오는 gradient가 합산되어야 하는 다변수 chain rule의 결과입니다. 이는 PyTorch.backward()와 알고리즘적으로 동일하지만, tensor 대신 scalar 단위로 작동하여 훨씬 단순하지만 비효율적입니다. 프로덕션 LLM에서는 GPU/TPU에서 수십억 개의 부동소수점 연산을 병렬 처리하는 tensor 기반 autograd를 사용합니다.
  1. 모델 아키텍처:
    • microgpt는 GPT-2를 따르지만 RMSNorm ( LayerNorm 대신), bias 없음, ReLU (GeLU 대신) 등 일부 요소를 단순화한 Transformer 아키텍처를 사용합니다. nembd=16n_embd = 16, nhead=4n_head = 4, nlayer=1n_layer = 1, blocksize=16block_size = 16의 작은 하이퍼파라미터 설정을 가지며, 총 4,192개의 파라미터를 가집니다 ( GPT-2는 1.6억 개, 현대 LLM은 수천억 개).
    • 임베딩 (Embedding): token ID와 위치 ID는 각각의 임베딩 테이블(wte, wpe)에서 행을 참조하여 벡터로 변환됩니다. 이 두 벡터를 더하여 token이 무엇인지와 시퀀스에서 어디에 있는지 동시에 인코딩합니다.
    • 어텐션 블록 (Attention Block): 현재 tokenQ (Query), K (Key), V (Value) 세 벡터로 projection합니다. query는 "내가 찾는 것", key는 "내가 담고 있는 것", value는 "선택되면 제공하는 것"을 의미합니다. 각 어텐션 헤드는 query와 모든 cached key 사이의 내적( dhead\sqrt{d_{head}} 로 스케일링)을 계산하고 softmax를 통해 어텐션 가중치를 얻은 뒤 cached value의 가중 합을 계산합니다. 모든 헤드의 출력을 연결하여 attn_woprojection합니다. 어텐션은 token이 과거 token들을 "볼" 수 있는 유일한 통신 메커니즘입니다. KV cacheinference 시 이전 tokenkeyvalue를 저장하여 중복 계산을 피하고 sequential 처리 효율을 높입니다.
    • MLP 블록 (MLP Block): 2층 피드포워드 네트워크로, 임베딩 차원의 4배로 확장된 후 ReLU를 적용하고 다시 축소됩니다. 어텐션과 달리 시간 t에 완전히 local한 계산을 수행하며, position-wise "사고"의 대부분이 이루어지는 곳입니다.
    • 잔차 연결 (Residual Connection): 어텐션과 MLP 블록 모두 출력을 입력에 다시 더하여 gradient가 네트워크를 직접 통과하게 함으로써 깊은 모델의 학습을 가능하게 합니다.
    • 출력 (Output): 최종 은닉 상태를 lm_head로 어휘 크기(token 27개)에 projection하여 각 token에 대한 logits를 생성합니다. 높은 logit은 해당 token이 다음에 올 가능성이 높음을 의미합니다.
  1. 학습 루프 (Training Loop):
    • 학습 루프는 반복적으로 (1) 문서 선택 → (2) token에 대해 모델 순방향 실행 → (3) loss 계산 → (4) 역전파로 gradient 획득 → (5) 파라미터 업데이트 과정을 거칩니다.
    • 순방향 패스 및 손실: token을 한 번에 하나씩 모델에 공급하며 KV cache를 구축합니다. 각 위치에서 모델은 27개의 logits를 출력하고 softmax로 확률로 변환합니다. 각 위치의 loss는 올바른 다음 token의 음의 로그 확률 __INLINE_FORMULA_3__이며, 이를 cross-entropy loss라고 합니다. loss는 모델이 실제 결과에 얼마나 "놀랐는지"를 측정하며, 문서 전체의 position-wise loss를 평균하여 단일 scalar loss를 얻습니다.
    • 역방향 패스: loss.backward() 호출 한 번으로 전체 연산 그래프에 대해 역전파를 실행합니다. 이후 각 파라미터의 .grad 속성에 loss를 줄이기 위해 어떻게 변경해야 하는지에 대한 정보가 저장됩니다.
    • Adam 옵티마이저: 단순 gradientdescent(p.data=lrp.grad)gradient descent (p.data -= lr * p.grad) 대신 Adam 옵티마이저를 사용합니다. Adam은 파라미터당 두 개의 이동 평균(m: momentum, v: gradient 제곱의 평균)을 유지하며 bias correction을 적용합니다. 학습률은 학습 중 선형적으로 감소합니다. 프로덕션 LLM 학습에서는 bfloat16, fp8과 같은 혼합 정밀도와 GPU cluster에서의 학습, 정교한 학습률 스케줄링(워밍업/감쇠) 등 복잡한 최적화 기법이 사용됩니다.
  1. 추론 및 샘플링:
    • 학습 완료 후, 모델에서 새로운 이름을 sampling할 수 있습니다. sampling 과정은 파라미터를 고정한 채 순방향 패스를 루프로 실행하며, 각 생성된 token을 다음 입력으로 feed백하는 방식으로 진행됩니다.
    • sampleBOS token으로 시작하며, 모델이 27개 logits를 생성하면 이를 확률로 변환하여 해당 확률에 따라 무작위로 하나의 tokensample합니다. BOS token이 다시 생성되거나 최대 시퀀스 길이에 도달할 때까지 반복됩니다.
    • Temperature: softmax 전에 logitstemperature로 나누어 sampling의 다양성을 조절할 수 있습니다. temperature 1.0은 모델이 학습한 분포에서 직접 sampling하는 것이고, 낮은 temperature (예: 0.5)는 분포를 날카롭게 하여 모델이 더 보수적인 선택을 하게 하며, temperature 0에 가까우면 항상 가장 확률 높은 단일 token을 선택하는 greedy decoding이 됩니다. 높은 temperature는 분포를 평평하게 하여 더 다양하지만 덜 일관된 출력을 유도합니다.

프로덕션 LLM과의 차이점

microgpt는 GPT 학습 및 실행의 완전한 알고리즘적 본질을 포함하지만, ChatGPT와 같은 프로덕션 LLM과의 차이는 핵심 알고리즘을 바꾸지 않으면서 규모에서 작동하게 하는 요소들에 있습니다.

  • 데이터: microgpt의 32K 짧은 이름 데이터셋 대신, 프로덕션 LLM은 수조 개의 internet text token (웹페이지, 책, 코드 등)을 사용하며, 데이터 deduplication, 품질 필터링, 도메인 간의 신중한 혼합 과정을 거칩니다.
  • 토크나이저: 단일 문자 대신 BPE 같은 subword tokenizer를 사용하여 약 100K의 token vocabulary를 가지며, position당 더 많은 content를 보므로 훨씬 효율적입니다.
  • 자동 미분: 순수 Python의 scalar Value 객체 대신 tensor (대규모 다차원 숫자 배열)를 사용하며, GPU/TPU에서 수십억 floating-point operations를 수행합니다. PyTorchtensor에 대한 autograd를 처리하며, FlashAttention 같은 CUDA kernel이 여러 연산을 융합합니다. 수학은 동일하지만 많은 scalar가 병렬 처리됩니다.
  • 아키텍처: microgpt는 4,192개의 파라미터인 반면, GPT-4급 모델은 수천억 개입니다. 전반적으로 매우 유사한 Transformer 신경망이나 훨씬 넓고(임베딩 차원 10,000+) 훨씬 깊습니다(100+ 레이어). RoPE, GQA (Grouped Query Attention), MoE (Mixture of Experts) 레이어 등 추가적인 lego block 유형과 순서 변경이 있을 수 있지만, 잔차 스트림 위에 attention (communication)MLP (computation)가 교차 배치되는 핵심 구조는 잘 보존됩니다.
  • 학습 최적화: microgpt는 Adam과 단순 선형 학습률 감소를 사용합니다. 대규모 LLM 학습은 bfloat16, fp8 등의 감소된 정밀도, 대규모 GPU cluster에서의 학습, 정교한 hyperparameter tuning (learning rate, weight decay, beta parameter, warmup/decay schedule)이 필요합니다. Chinchilla와 같은 scaling law는 고정된 computing budget에서 모델 크기와 학습 token 수 사이에 어떻게 할당할지 안내합니다.
  • 후학습 (Post-training): 학습에서 나온 기본 모델(pre-trained model)은 문서 완성기이지 챗봇이 아닙니다. ChatGPT로 만드는 과정은 두 단계로 이루어집니다: (1) SFT (Supervised Fine-Tuning): 문서를 curated conversation으로 교체하고 학습을 계속합니다. (2) RL (Reinforcement Learning): 모델이 응답을 생성하고 human 또는 '심판' 모델로부터 score를 받아 feedback으로 학습합니다.
  • 추론 (Inference): 수백만 사용자에게 모델을 serving하기 위해 request batching, KV cache managementpaging, speculative decoding, quantization (int8/int4), 여러 GPU에 모델 분산 등 복잡한 엔지니어링 스택이 필요합니다. 근본적으로는 여전히 시퀀스의 다음 token을 예측하지만, 이를 더 빠르게 만드는 데 많은 노력이 들어갑니다.

FAQ 하이라이트

  • 모델이 "이해"하는가?: 철학적 질문이지만, 기계적으로는 모델은 입력 token을 다음 token에 대한 확률 분포로 mapping하는 큰 수학 함수입니다. 파라미터는 data의 통계적 규칙성(pattern)을 포착하도록 조정됩니다.
  • ChatGPT와 어떤 관련이 있는가?: ChatGPT는 microgpt와 동일한 핵심 루프(next token prediction, sampling, 반복)를 엄청나게 확장하고 대화형으로 만드는 후학습을 추가한 것입니다. ChatGPT의 대화도 token 시퀀스일 뿐이며, microgpt가 이름을 완성하는 것과 동일하게 token-by-token으로 문서를 완성합니다.
  • "환각 (Hallucination)"은 무엇인가?: 모델은 확률 분포에서 sample하여 token을 생성합니다. 진실 개념이 없으며 학습 데이터에 비추어 통계적으로 그럴듯한 시퀀스만 압니다. microgpt가 "karia" 같은 이름을 "환각"하는 것은 ChatGPT가 거짓 사실을 자신 있게 말하는 것과 동일한 현상입니다.
  • 왜 이렇게 느린가?: microgpt는 순수 Python에서 한 번에 하나의 scalar를 처리하므로 단일 학습 step에 수 초가 소요됩니다. GPU에서는 동일한 수학이 수백만 scalar를 병렬 처리하여 수 자릿수 더 빠르게 실행됩니다.
  • 더 좋은 이름을 생성하게 할 수 있는가?: num_steps를 증가시켜 더 오래 학습하거나, n_embd, n_layer, n_head 등을 증가시켜 모델 크기를 키우거나, 더 큰 데이터셋을 사용하면 됩니다. dataset을 변경하면 모델은 그 dataset의 패턴을 학습하여 해당 데이터를 생성하게 됩니다.