Skip to content

Latest commit

Β 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🧠 miniGPT β€” A Decoder-Only Transformer Built From Scratch

An educational, from-scratch PyTorch implementation of a GPT-style language model.

Python PyTorch Tokenizer Dataset License

Built to understand GPT-style Transformers by implementing one from scratch β€” not a production model or a state-of-the-art system. Trained on modest data with modest compute; its purpose is to demonstrate a correct, working understanding of the architecture, training loop, and generation process end to end.


πŸ“– Overview

miniGPT is a compact, decoder-only Transformer implemented from scratch in PyTorch β€” no transformers library, no pretrained weights. Every component (attention, embeddings, normalization, the training loop, and inference-time sampling) is hand-written, so the mechanics of a GPT-style model are fully transparent β€” the same core ideas that power GPT-2 and GPT-3, scaled down.


πŸ›οΈ Architecture

flowchart TD
    A["Token IDs (B, T)"] --> B["Token Embedding"]
    A --> C["Positional Embedding"]
    B --> D["Sum"]
    C --> D
    D --> E["Transformer Block Γ— N"]

    subgraph Block["Pre-Norm Transformer Block"]
        direction TB
        E1["LayerNorm β†’ Self-Attention β†’ Residual Add"] --> E4["LayerNorm β†’ FeedForward (GELU) β†’ Residual Add"]
    end

    E --> F["Final LayerNorm"]
    F --> G["Linear Head β†’ Logits (vocab_size)"]
Loading

Self-attention, briefly: input is projected into Q/K/V, split across n_head heads, scored as (QΒ·Kα΅€)/√head_size, masked so no token can attend to future positions (causal masking β€” what makes the model autoregressive), softmaxed, and used to weight V. Heads are concatenated and projected back to n_embd.

File Responsibility
config.py GPTConfig β€” all hyperparameters
tokenizer.py GPT-2 BPE setup + dataset loading
model.py Attention, FeedForward, Block, GPTLanguageModel
utils.py Batching, loss estimation, LR schedule, checkpointing
train.py Training loop
generate.py Generation, decoding comparison, attention plots
Component notes (Token/Positional Embedding, LayerNorm, Residuals, Decoder Block)
  • Token Embedding β€” maps each token ID to a learnable dense vector; the model's first representation of meaning.
  • Positional Embedding β€” a learned vector per position, added to the token embedding, since attention has no inherent notion of order.
  • LayerNorm β€” normalizes each token's activations; used pre-sublayer (GPT-2 convention) for training stability.
  • Residual Connections β€” x = x + sublayer(x), giving gradients a direct path through deep stacks.
  • Decoder Block β€” x = x + Attn(LN(x)), then x = x + FFN(LN(x)), stacked n_layer times.

πŸ” Training

Self-supervised next-token prediction: the model predicts token t+1 from tokens 0..t at every position simultaneously.

flowchart LR
    A[Raw Text] --> B[BPE Tokenize] --> C["Input/Target Pairs (shift by 1)"]
    C --> D[Forward Pass] --> E[Cross-Entropy Loss] --> F[Backprop] --> G[AdamW Step]
    G --> H{Eval Interval?}
    H -- Yes --> I[Eval Loss + Sample + Checkpoint]
    H -- No --> C
    I --> C
Loading
  • Gradient accumulation simulates a larger batch than fits in memory.
  • Mixed precision (torch.amp) speeds up CUDA training.
  • LR schedule: linear warmup, then cosine decay to min_lr.
  • Every eval_interval steps: estimate train/val loss, generate a sample, save latest.pt and (if improved) best.pt.

🎲 Generation

Autoregressive: one token generated at a time, fed back in as input for the next step.

flowchart LR
    A[Prompt] --> B[Tokenize] --> C[Forward Pass] --> D["Logits Γ· Temperature"]
    D --> E["Top-k / Top-p Filter"] --> F[Softmax] --> G[Sample Token] --> H[Append] --> C
Loading

πŸ“Š Results

Aspect V2 β€” Character-Level V3 β€” GPT-2 BPE
Vocabulary size ~65 50,257
Final train / val loss 1.05 / 1.61 4.42 / 4.40
Overfitting? Yes (tiny dataset) No (103M tokens)
Tokens per word ~5 chars/token ~1.3 tokens/word

πŸ”§ Implementation Details

Hyperparameter Value
n_embd / n_layer / n_head 384 / 6 / 6
Context length (block_size) 256
Vocabulary size 50,257 (GPT-2 BPE)
Dropout 0.1
Batch size (effective) 16 Γ— 4 grad-accum = 64
Learning rate (peak β†’ min) 3e-4 β†’ 3e-5
Warmup / max iterations 200 / 5,000
Optimizer AdamW
Total parameters 49.38M (~49.4M)
Training hardware / time 1Γ— NVIDIA T4 GPU (Google Colab) / ~15 mins

Installation & Usage

git clone https://github.com/MohamedAbdelaiem/miniGPT.git
cd miniGPT
pip install -r requirements.txt

python train.py      # train (auto-resumes from checkpoints/latest.pt)
python generate.py   # generate text / compare decoding strategies
from config import GPTConfig
from model import GPTLanguageModel
from tokenizer import setup_tokenizer
from generate import generate_text
from utils import load_checkpoint
import torch

config = GPTConfig()
encode, decode, config.vocab_size = setup_tokenizer()
model = GPTLanguageModel(config).to(config.device)
optimizer = torch.optim.AdamW(model.parameters(), lr=config.learning_rate)
scaler = torch.amp.GradScaler('cuda', enabled=(config.device == 'cuda'))
load_checkpoint('checkpoints/best.pt', model, optimizer, scaler, config.device)

print(generate_text(model, encode, decode, config,
                     prompt="Once upon a time", max_new_tokens=200,
                     temperature=0.8, top_p=0.9))

Repository Structure

miniGPT/
β”œβ”€β”€ config.py         # Hyperparameters
β”œβ”€β”€ tokenizer.py       # GPT-2 BPE + dataset loading
β”œβ”€β”€ model.py            # Model definition
β”œβ”€β”€ utils.py              # Training helpers
β”œβ”€β”€ train.py                # Training loop
β”œβ”€β”€ generate.py               # Inference & sampling
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ checkpoints/               # latest.pt, best.pt
└── outputs/run_*/               # checkpoints, samples, losses.png

πŸ“„ License

MIT License

Built as a hands-on exploration of GPT-style Transformers β€” from tokenization to text generation, one component at a time.

About

A from-scratch implementation of a GPT-style language model in PyTorch, built to understand every component of modern decoder-only Transformers.

Resources

Stars

13 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages