A hands-on, educational repository that teaches you how language models work by building one from scratch.
Learn the fundamentals that power GPT, LLaMA, and every modern language model — starting with the simplest possible model: the Bigram.
- What is a Bigram Model?
- Repository Structure
- How to Run
- Counting vs. Gradient-Based Approach
- Key Takeaway
- References & Further Reading
A Bigram Language Model predicts the next character (or word) based only on the immediately preceding one. It's the simplest non-trivial language model and the perfect starting point for understanding how all language models work.
"The probability of character $w_t$ given that the previous character was $w_{t-1}$."
For an entire sequence
This is called the Markov assumption — the future depends only on the present, not the past.
Given the training text "hello", the bigram counts are:
| Context ( |
Next ( |
Count | Probability |
|---|---|---|---|
h |
e |
1 | 1.00 |
e |
l |
1 | 1.00 |
l |
l |
1 | 0.50 |
l |
o |
1 | 0.50 |
After seeing l, the model assigns equal probability to l and o.
We measure how "surprised" the model is by a text using NLL:
- Lower NLL → the model finds the text plausible (good fit).
- Higher NLL → the model is "surprised" (poor fit).
biagram-models/
│
├── bigram_scratch.py # 🐍 Pure Python — Counting approach (no frameworks)
├── bigram_nn.py # 🔥 PyTorch — Neural network approach
└── README.md # 📖 You are here
| File | Approach | Dependencies | Key Concept |
|---|---|---|---|
bigram_scratch.py |
Counting & Normalisation | Python stdlib only | Maximum Likelihood Estimation |
bigram_nn.py |
Gradient Descent | PyTorch | Embeddings, Cross-Entropy Loss |
- Python 3.8+ (any recent version works)
- PyTorch (only for the neural network version)
# Install PyTorch (if you haven't already)
pip install torchpython bigram_scratch.pyThis will:
- Train the bigram model by counting character pairs
- Print the Negative Log-Likelihood (NLL) score
- Generate 200 characters of new "Shakespeare-like" text
- Display the learned probability distributions
python bigram_nn.pyThis will:
- Train a single-layer neural network for 200 epochs
- Print the loss decreasing over time
- Generate 200 characters of new text
- Compare the neural network's learned weights with the counting method
💡 No data files needed! Both scripts include a Shakespeare snippet directly in the code.
This repository implements the exact same model in two fundamentally different ways. Here's why that matters:
Text → Count Pairs → Normalise → Probability Table → Done!
- How: Scan the text, count every
(char_a, char_b)pair, divide by totals. - Pros: Fast, exact, easy to understand.
- Cons: Doesn't scale — you can't "count" your way to GPT.
Text → Neural Net → Loss → Backprop → Update Weights → Repeat → Done!
- How: A neural network starts with random weights and iteratively adjusts them to minimise CrossEntropyLoss (which is mathematically equivalent to NLL).
- Pros: Scales to billions of parameters (GPT, LLaMA, etc.).
- Cons: Slower, approximate (requires many iterations to converge).
| Aspect | Counting | Neural Network |
|---|---|---|
| Speed | ⚡ Instant | 🐢 Iterative (many epochs) |
| Accuracy | ✅ Exact MLE | ≈ Approximate (converges) |
| Scalability | ❌ Bigrams only | ✅ Scales to any model size |
| Interpretability | ✅ Direct counts | 🔍 Weights need softmax |
| Foundation for | Traditional NLP | Modern Deep Learning |
Gradient descent on CrossEntropyLoss discovers the same probability table that simple counting gives you.
This is the "Aha!" moment of the repository. Run both scripts and compare the outputs — the neural network's learned weights (after softmax) will closely match the counting model's probability table.
This means that when we scale up to GPT-sized models with billions of parameters, the training process is conceptually doing the same thing — just over much more complex patterns than simple bigrams.
| Resource | Description |
|---|---|
| Andrej Karpathy — "makemore" | The inspiration for this repository. Karpathy's brilliant series building language models from scratch. |
| PyTorch Documentation | Official docs for all the PyTorch modules used here. |
| The Illustrated Transformer | When you're ready to go beyond Bigrams and into modern Transformers. |
If this repo helped you understand language models, consider giving it a ⭐!
Made with ❤️ for the ML learning community.