microgpt - 200 satırlık saf Python ile GPT eğitimi ve çıkarım
(karpathy.github.io)- karpathy’nin yayımladığı bir sanat projesi. Harici bağımlılık olmadan 200 satırlık tek bir dosyada GPT’nin tüm algoritmasını uygular
- Üretim ortamındaki LLM’lerden farkı yalnızca ölçek ve verimlilik; öz aynı. Bu kodu anlamak, GPT’nin algoritmik özünü anlamak demek
- Veri kümesi, tokenizer, autograd motoru, GPT-2 benzeri Transformer mimarisi, Adam optimizer, eğitim ve çıkarım döngüsünün tamamını içerir
- micrograd, makemore, nanogpt gibi önceki projelerle 10 yıllık LLM sadeleştirme çalışmalarının damıtılmış hali; artık daha fazla sadeleştirilemeyecek en küçük biçimde GPT’nin özünü taşır
- 32.000 isim verisiyle eğitilerek inandırıcı yeni isimler üretir ve tüm hesaplamaları skaler düzeyde autograd ile doğrudan yapar
- Eğitim süreci kayıp hesaplama → geri yayılım → Adam güncellemesi adımlarından oluşur ve yaklaşık 1 dakika içinde çalıştırılabilir
microgpt genel bakış
- microgpt, GPT modelinin eğitim ve çıkarım sürecini eksiksiz biçimde uygulayan 200 satırlık bir Python betiğidir
- Harici kütüphane olmadan veri kümesi, tokenizer, autograd, model, optimizer, eğitim döngüsü bileşenlerinin tümünü içerir
- micrograd, makemore, nanogpt gibi mevcut projeleri birleştirip tek dosyada toplar
- “Artık daha fazla sadeleştirilemez” düzeyinde, yalnızca algoritmik çekirdeği bırakan bir uygulama
- Kodun tamamı GitHub Gist, web sayfası ve Google Colab üzerinden sunuluyor
Veri kümesi yapısı
- Büyük dil modellerinin yakıtı metin veri akışıdır; üretim ortamında internet sayfaları kullanılırken microgpt’de satır başına bir ad içeren 32.000 isimlik basit bir örnek kullanılır
- Her isim birer "belge" olarak ele alınır ve modelin amacı veri içindeki istatistiksel örüntüleri öğrenip benzer yeni belgeler üretmektir
- Eğitim tamamlandığında model, "kamon", "karai", "vialan" gibi inandırıcı yeni isimler "halüsinasyon" olarak üretir
- ChatGPT açısından bakıldığında kullanıcıyla yapılan konuşma da yalnızca "tuhaf görünümlü bir belge"dir; belge prompt ile başlatılır ve modelin yanıtı istatistiksel belge tamamlama sayılır
Tokenizer
- Sinir ağları karakterlerle değil sayılarla çalıştığı için, metni tamsayı token ID dizilerine dönüştürmenin ve yeniden geri çevirmenin bir yolu gerekir
- tiktoken (GPT-4 tarafından kullanılır) gibi üretim tokenizer’ları verimlilik için karakter parçaları düzeyinde çalışır; ancak en basit tokenizer, veri kümesindeki her benzersiz karaktere bir tamsayı atar
- Küçük a-z harfleri sıralanır ve her karaktere indeks olarak bir ID verilir; tamsayı değerinin kendisi anlam taşımaz, her token ayrı bir ayrık semboldür
- BOS(Beginning of Sequence) özel token’ı eklenerek "yeni bir belgenin başladığı/bittiği" belirtilir; böylece "emma"
[BOS, e, m, m, a, BOS]olarak sarılır - Nihai sözlük boyutu 27’dir (26 küçük harf + 1 BOS)
Otomatik türev alma (Autograd)
- Sinir ağı eğitimi için gradyanlar gerekir: her parametre için "bu değeri biraz artırırsam kayıp artar mı, azalır mı, ne kadar?" sorusunun yanıtını bilmek gerekir
- Hesaplama grafiği çok sayıda girişe sahip olsa da tek bir skaler çıktı olan kayıp (loss) değerinde birleşir
- Geri yayılım (Backpropagation) çıktıdan başlayıp grafiği ters yönde izler ve kalkülüsün zincir kuralına dayanarak tüm girişler için kaybın gradyanını hesaplar
- Value sınıfı ile uygulanır: her Value, tek bir skaleri (
.data) sarar ve nasıl hesaplandığını izler- Toplama, çarpma gibi işlemlerde yeni Value, girişleri (
_children) ve ilgili işlemin yerel türevlerini (_local_grads) hatırlar - Örneğin
__mul__, ∂(a·b)/∂a=b ve ∂(a·b)/∂b=a değerlerini kaydeder
- Toplama, çarpma gibi işlemlerde yeni Value, girişleri (
- Desteklenen işlem blokları: toplama, çarpma, üs alma, log, exp, ReLU
backward()metodu grafiği ters topolojik sırayla dolaşır ve her adımda zincir kuralını uygular- Kayıp düğümünde
self.grad = 1ile başlar (∂L/∂L=1) - Yerel gradyanlar yol boyunca çarpılarak parametrelere kadar yayılır
- Kayıp düğümünde
- += ile biriktirme (atama değil): grafik dallandığında her daldan gradyan bağımsız biçimde akar ve toplanması gerekir (çok değişkenli zincir kuralının sonucu)
- PyTorch’un
.backward()yöntemiyle algoritmik olarak aynıdır; ancak tensörler yerine skaler düzeyde çalıştığı için çok daha basittir, ama verimliliği düşüktür
Parametre başlatma
- Parametreler modelin bilgisidir; rastgele başlar ve eğitim sırasında yinelemeli olarak optimize edilen büyük bir kayan noktalı sayı kümesinden oluşur
- Gaussian dağılımından gelen küçük rastgele değerlerle başlatılır
state_dictadı verilen matrislerden oluşur: embedding tablosu, attention ağırlıkları, MLP ağırlıkları, nihai çıktı projeksiyonu- Hiperparametre ayarları:
n_embd = 16: embedding boyutun_head = 4: attention head sayısın_layer = 1: katman sayısıblock_size = 16: maksimum dizi uzunluğu
- Küçük model için 4.192 parametre bulunur (GPT-2’de 1,6 milyar, modern LLM’lerde yüz milyarlarca)
Mimari
- Model mimarisi durumsuz bir fonksiyondur: tokenları, konumu, parametreleri ve önceki konumların önbelleğe alınmış anahtar/değerlerini alır, bir sonraki token için logitleri (puanları) döndürür
- GPT-2'yi takip eder ama biraz sadeleştirilmiştir: RMSNorm (LayerNorm yerine), bias yok, ReLU (GeLU yerine)
-
Yardımcı fonksiyonlar
- linear: matris-vektör çarpımıyla ağırlık matrisinin her satırı için bir iç çarpım hesaplar; sinir ağlarının temel yapı taşı olan öğrenilmiş doğrusal dönüşüm
- softmax: ham puanları (logitleri) bir olasılık dağılımına dönüştürür; tüm değerler [0,1] aralığına girer ve toplamları 1 olur; sayısal kararlılık için önce maksimum değer çıkarılır
- rmsnorm: vektörü birim karekök ortalama kare değerine sahip olacak şekilde yeniden ölçeklendirerek aktivasyonların ağ boyunca büyümesini ya da küçülmesini önler, eğitimi kararlı hale getirir
-
Model yapısı
- Embedding: token ID'leri ve konum ID'leri, ilgili embedding tablolarındaki (
wte,wpe) satırlara bakar; iki vektör toplanarak tokenın ne olduğu ve dizide nerede bulunduğu aynı anda kodlanır- Modern LLM'ler konum embedding'lerini atlayıp RoPE gibi göreli konumlandırma teknikleri kullanır
- Attention bloğu: mevcut tokenı Q (query), K (key), V (value) olmak üzere üç vektöre projekte eder
- Query: "Ne arıyorum?", key: "Ne içeriyorum?", value: "Seçilirsem ne sağlıyorum?"
- Örnek: "emma" içinde ikinci "m" bir sonrakini tahmin ederken "yakın zamanda hangi ünlü vardı?" gibi bir query öğrenebilir; önceki "e" bu query ile iyi eşleştiği için yüksek attention ağırlığı alır
- Key ve value'lar KV cache'e eklenir, böylece önceki konumlara başvurulabilir
- Her attention head, query ile önbelleğe alınmış tüm key'ler arasındaki iç çarpımı (√d_head ile ölçeklenmiş) hesaplar; softmax ile attention ağırlıkları elde edilir ve önbelleğe alınmış value'ların ağırlıklı toplamı hesaplanır
- Tüm head çıktıları birleştirilip
attn_woile projekte edilir - Attention bloğu, t konumundaki tokenın geçmişteki 0..t-1 tokenlarını "görebildiği" tek yerdir; attention bir token iletişim mekanizmasıdır
- MLP bloğu: 2 katmanlı bir feedforward ağ: embedding boyutunun 4 katına genişletme → ReLU uygulama → tekrar daraltma
- Konum başına "düşünmenin" büyük kısmı burada gerçekleşir
- Attention'dan farklı olarak t anında tamamen yerel bir hesaplamadır
- Transformer, iletişim (attention) ile hesaplamayı (MLP) ardışık olarak yerleştirir
- Residual bağlantılar: hem attention hem de MLP blokları çıktılarını yeniden girdiye ekler
- Bu, gradyanların ağdan doğrudan geçmesini sağlayarak derin modellerin eğitilebilir olmasını sağlar
- Çıktı: son gizli durum
lm_headile sözlük boyutuna projekte edilerek token başına bir logit üretilir (burada 27 sayı); yüksek logit = o tokenın sıradaki olma olasılığı daha yüksek - KV cache özelliği: eğitim sırasında KV cache kullanımı nadirdir, ancak microgpt her seferinde yalnızca bir token işlediği için açıkça oluşturulur; önbelleğe alınmış key ve value'lar, hesaplama grafiğinde geri yayılımın hedefi olan canlı Value düğümleridir
- Embedding: token ID'leri ve konum ID'leri, ilgili embedding tablolarındaki (
Eğitim döngüsü
- Eğitim döngüsü tekrarlı olarak şunları yapar: (1) belge seç → (2) tokenlar üzerinde model forward çalıştır → (3) kaybı hesapla → (4) backprop ile gradyanları elde et → (5) parametreleri güncelle
-
Tokenization
- Her eğitim adımında bir belge seçilir ve iki yanına BOS eklenir: "emma" →
[BOS, e, m, m, a, BOS] - Modelin hedefi, önceki tokenlar verildiğinde her bir sonraki tokenı tahmin etmektir
- Her eğitim adımında bir belge seçilir ve iki yanına BOS eklenir: "emma" →
-
Forward pass ve kayıp
- Tokenlar modele birer birer verilirken KV cache oluşturulur
- Her konumda model 27 logit üretir, bunlar softmax ile olasılığa dönüştürülür
- Her konumdaki kayıp, doğru bir sonraki tokenın negatif log olasılığıdır: −log p(target); buna cross-entropy loss denir
- Kayıp, modelin gerçekte gelecek olana ne kadar şaşırdığını ölçer: 1.0 olasılık atarsa kayıp 0, olasılık 0'a yakınsa kayıp +∞ olur
- Belgedeki tüm konumların kaybı ortalanarak tek bir skaler kayıp elde edilir
-
Backward pass
loss.backward()bir kez çağrılarak tüm hesaplama grafiği üzerinde geri yayılım çalıştırılır- Sonrasında her parametrenin
.graddeğeri, kaybı azaltmak için nasıl değişmesi gerektiğini gösterir
-
Adam optimizer
- Basit gradient descent (
p.data -= lr * p.grad) yerine Adam kullanılır - Parametre başına iki hareketli ortalama tutulur:
m: son gradyanların ortalaması (momentum)v: son gradyan karelerinin ortalaması (parametre başına öğrenme oranı uyarlaması)
m_hat,v_hat, sıfırdan başlatılan m ve v için bias düzeltmesidir- Öğrenme oranı eğitim boyunca doğrusal olarak azalır
- Güncellemeden sonra
.grad = 0ile sıfırlanır
- Basit gradient descent (
-
Eğitim sonucu
- 1.000 adım boyunca kayıp yaklaşık 3.3'ten (27 token arasında rastgele tahmin: −log(1/27)≈3.3) yaklaşık 2.37'ye düşer
- Daha düşük daha iyidir ve en düşük değer 0'dır (mükemmel tahmin); yani gelişme alanı olsa da modelin isimlerin istatistiksel örüntülerini öğrendiği açıktır
Çıkarım
- Eğitim tamamlandıktan sonra modelden yeni isimler örneklenebilir; parametreler sabitlenir, forward pass döngü içinde çalıştırılır ve üretilen her token bir sonraki girdi olarak geri beslenir
-
Örnekleme süreci
- Her örnek BOS tokenıyla başlar ("yeni isim başlat")
- Model 27 logit üretir → olasılığa dönüştürülür → bu olasılıklara göre rastgele bir token örneklenir
- Bu token bir sonraki girdi olarak geri beslenir; model tekrar BOS üretince ("bitti") veya maksimum dizi uzunluğuna ulaşılınca durur
-
Sıcaklık (Temperature)
- Softmax öncesinde logitler sıcaklığa bölünür
- Sıcaklık 1.0: modelin öğrendiği dağılımdan doğrudan örnekleme
- Düşük sıcaklık (örn. 0.5): dağılımı keskinleştirir, modelin daha temkinli davranıp üst sıralı seçimleri yapma olasılığını artırır
- Sıcaklık 0'a yakın: her zaman olasılığı en yüksek tek tokenı seçer (greedy decoding)
- Yüksek sıcaklık: dağılımı düzleştirir, daha çeşitli ama daha az tutarlı çıktılar üretir
Çalıştırma yöntemi
- Yalnızca Python gerekir (
pip installyok, bağımlılık yok):python train.py - MacBook'ta yaklaşık 1 dakika sürer
- Her adımda kayıp yazdırılır: ~3.3'ten (rastgele) ~2.37'ye düşer
- Eğitim tamamlandıktan sonra halüsinasyon ürünü yeni isimler üretir: "kamon", "ann", "karai" vb.
- Google Colab notebook'unda da çalıştırılabilir, Gemini'ye soru sorulabilir
- Başka veri kümeleri denenebilir,
num_stepsartırılarak daha uzun eğitim yapılabilir, model boyutu büyütülerek daha iyi sonuçlar alınabilir
Kodun ilerleme aşamaları
| Dosya | Eklenen içerik |
|---|---|
train0.py |
Bigram sayım tablosu — sinir ağı yok, gradyan yok |
train1.py |
MLP + manuel gradyanlar (sayısal ve analitik) + SGD |
train2.py |
Autograd (Value sınıfı) — manuel gradyanların yerini alır |
train3.py |
Konum embedding'leri + tek head attention + rmsnorm + residual |
train4.py |
Multi-head attention + layer döngüsü — tam GPT mimarisi |
train5.py |
Adam optimizer — bu dosya train.py |
- build_microgpt.py Gist'inin Revisions bölümünde tüm sürümler ve her adım arasındaki diff görülebilir
Prodüksiyon LLM'lerle farklar
- microgpt, GPT eğitimi ve çalıştırmanın tam algoritmik özünü içerir; ChatGPT gibi prodüksiyon LLM'lerden farkı çekirdek algoritmayı değiştirmez, bunu ölçekte çalıştıran unsurlardır
-
Veri
- 32K kısa isim yerine trilyonlarca internet metni token'ı (web sayfaları, kitaplar, kod vb.) ile eğitilir
- Veri tekilleştirme, kalite filtreleme ve alanlar arasında dikkatli harmanlama
-
Tokenizer
- Tek karakter yerine BPE (Byte Pair Encoding) gibi alt sözcük tokenizer'ları kullanılır
- Sık birlikte görülen karakter dizileri tek bir token'da birleştirilir; "the" gibi yaygın kelimeler tek token olurken nadir kelimeler parçalara ayrılır
- ~100K token sözlüğü ile konum başına daha fazla içerik görüldüğünden çok daha verimlidir
-
Autograd
- Saf Python'daki skaler Value nesneleri yerine tensor'lar (büyük çok boyutlu sayı dizileri) kullanılır ve saniyede milyarlarca kayan nokta işlemi yapan GPU/TPU üzerinde çalıştırılır
- PyTorch, tensor'lar için autograd işlemini yürütür; FlashAttention gibi CUDA kernel'leri birden fazla işlemi birleştirir
- Matematik aynıdır, sadece çok sayıda skaler paralel işlenir
-
Mimari
- microgpt: 4.192 parametre, GPT-4 sınıfı model: yüzlerce milyar
- Genel olarak çok benzer bir Transformer sinir ağıdır ama çok daha geniştir (embedding boyutu 10.000+) ve çok daha derindir (100+ katman)
- Ek Lego blok türleri ve sıralama değişiklikleri:
- RoPE (rotary positional embedding) — öğrenilmiş positional embedding yerine
- GQA (grouped query attention) — KV cache boyutunu azaltır
- Gated linear activation — ReLU yerine
- MoE (mixture of experts) katmanları
- Residual stream üzerinde attention (iletişim) ile MLP'nin (hesaplama) dönüşümlü olduğu çekirdek yapı büyük ölçüde korunur
-
Eğitim
- Her adımda tek bir belge yerine büyük batch'ler (adım başına milyonlarca token), gradient accumulation, mixed precision (float16/bfloat16) ve dikkatli hyperparameter ayarı kullanılır
- Frontier model eğitimi için binlerce GPU aylar boyunca çalıştırılır
-
Optimizasyon
- microgpt: Adam + basit doğrusal öğrenme oranı azaltımı
- Büyük ölçekte optimizasyon başlı başına ayrı bir alandır: düşürülmüş hassasiyet (bfloat16, fp8), büyük GPU kümelerinde eğitim
- Optimizer ayarlarının (öğrenme oranı, weight decay, beta parametreleri, warmup/decay schedule) hassas biçimde ayarlanması gerekir; doğru değerler model boyutuna, batch boyutuna ve veri kümesi bileşimine göre değişir
- Scaling laws (ör. Chinchilla), sabit hesaplama bütçesinin model boyutu ile eğitim token sayısı arasında nasıl dağıtılacağını yönlendirir
- Büyük ölçekte bu ayrıntıları yanlış yapmak milyonlarca dolarlık hesaplama israfına yol açabilir; ekipler tam eğitim çalıştırmasından önce kapsamlı küçük ölçekli deneyler yapar
-
Sonraki eğitim (Post-training)
- Eğitimden çıkan temel model ("ön eğitimli" model) bir belge tamamlayıcıdır, chatbot değildir
- Onu ChatGPT'ye dönüştürme süreci iki adımdır:
- SFT (supervised fine-tuning): belgeler, küratörlüğü yapılmış diyaloglarla değiştirilir ve eğitim sürdürülür; algoritmik olarak bir değişiklik yoktur
- RL (reinforcement learning): model yanıt üretir → puan verilir (insan, "hakem" model, algoritma) → geri bildirimle öğrenir
- Temelde hâlâ belgeler üzerinde eğitilir, ancak artık belge modelin kendisinden çıkan token'lar ile oluşur
-
Çıkarım
- Modeli milyonlarca kullanıcıya sunmak için ayrı bir mühendislik yığını gerekir: istek batch'leme, KV cache yönetimi ve paging (vLLM vb.), hız için speculative decoding, bellek azaltımı için quantization (int8/int4 ile çalıştırma), modeli birden fazla GPU'ya dağıtma
- Temelde hâlâ dizideki bir sonraki token'ı tahmin eder ama onu daha hızlı hâle getiren mühendisliğe büyük emek harcanır
SSS
-
Model bir şeyi "anlıyor" mu?
- Bu felsefi bir soru olabilir ama mekanik olarak bakarsak: ortada sihirli bir şey yok
- Model, giriş token'larını bir sonraki token için bir olasılık dağılımına eşleyen büyük bir matematik fonksiyonudur
- Eğitim sırasında parametreler, doğru sonraki token'ı daha olası kılacak şekilde ayarlanır
- Buna "anlama" denip denmeyeceği kişiye kalmıştır ama mekanizma tamamen bu 200 satırın içindedir
-
Neden çalışıyor?
- Modelde binlerce ayarlanabilir parametre vardır ve optimizer her adımda kaybı düşürecek şekilde bunları biraz hareket ettirir
- Çok sayıda adım boyunca parametreler, verinin istatistiksel düzenliliklerini yakalayan değerlere oturur
- İsimler için örneğin: çoğu ünsüzle başlar, "qu" birlikte görünme eğilimindedir, art arda üç ünsüz nadirdir vb.
- Model, açık kurallar değil bunları yansıtan olasılık dağılımlarını öğrenir
-
ChatGPT ile nasıl bir ilişkisi var?
- ChatGPT, bu aynı çekirdek döngüyü (sonraki token tahmini, örnekleme, tekrar) muazzam ölçekte genişletir ve buna diyaloğa uygun sonraki eğitim ekler
- Sohbet ederken sistem prompt'u, kullanıcı mesajı ve yanıtın hepsi sadece bir dizinin token'larıdır
- Model, microgpt'nin isim tamamlamasıyla aynı şekilde, bir belgeyi her seferinde bir token üreterek tamamlar
-
"Halüsinasyon" nedir?
- Model, token'ları bir olasılık dağılımından örnekleyerek üretir
- Doğruluk kavramına sahip değildir; sadece eğitim verisine göre istatistiksel olarak makul görünen dizileri bilir
- microgpt'nin "karia" gibi bir ismi "halüsinasyonla" üretmesi, ChatGPT'nin yanlış bir olguyu kendinden emin biçimde söylemesiyle aynı olgudur
- Her ikisi de gerçek olmak zorunda olmayan, sadece makul görünen tamamlamalardır
-
Neden bu kadar yavaş?
- microgpt saf Python'da aynı anda yalnızca bir skaler işler; tek bir eğitim adımı birkaç saniye sürer
- GPU'da aynı matematik milyonlarca skaleri paralel işler ve birkaç büyüklük mertebesi daha hızlı çalışır
-
Daha iyi isimler üretmesini sağlayabilir miyim?
- Evet: daha uzun eğitin (
num_stepsartırın), model boyutunu büyütün (n_embd,n_layer,n_head), daha büyük bir veri kümesi kullanın - Bunlar büyük ölçekte de önemli olan aynı kontrol düğmeleridir
- Evet: daha uzun eğitin (
-
Veri kümesini değiştirirsem ne olur?
- Model, veride bulunan her türlü deseni öğrenir
- Bunu şehir isimleri, Pokémon isimleri, İngilizce kelimeler veya kısa şiir dosyalarıyla değiştirirseniz bu kez onları üretmeyi öğrenir
- Kodun geri kalanını değiştirmeniz gerekmez
1 yorum
Güzel yazı için teşekkürler.