Build a tiny LLM
in your browser
Train a real language model right here in this tab. Watch it go from random noise to real words, with every number on display and every idea in plain English.
What is an LLM?
Before we build one, let's understand what Large Language Models actually are and how they work at a high level.
First: where do LLMs fit?
You hear "AI", "machine learning", and "LLM" used as if they mean the same thing. They don't - they nest inside each other. An LLM is one specific kind of machine learning, which is one specific kind of AI.
The whole rest of this page lives in the innermost circle. Everything you build - tokenization, embeddings, training, generation - is standard machine learning. LLMs just point that machinery at text, at a scale that makes it feel like magic.
How we got here: 70 years in six steps
The idea of a learning machine is old. It took decades of dead ends, two "AI winters", and a lot more computing power before it worked. The tiny network you're about to train is a direct descendant of step one.
Two halves, two eras. The trainer you're about to use is the 1958-1986 idea: one small network, learning by backpropagation. The Scale Up section at the end runs a real 2017-style transformer. Same lineage, sixty years apart.
The Big Picture
Large Language Models (LLMs) like ChatGPT, Claude, and Gemini are AI systems that can read and write text. But how do they actually work?
LLMs are prediction machines
At their core, LLMs do one simple thing: predict the next word (or character). Given some text, they calculate which word is most likely to come next. That's it. That's the whole trick.
For example, given "The cat sat on the...", an LLM might predict "mat" has a 30% chance, "floor" has 25%, "couch" has 15%, etc.
How do they learn?
LLMs learn by reading massive amounts of text - books, websites, articles, code - and learning patterns. They don't memorize the text; they learn statistical relationships between words.
Training: Show the model billions of examples of "context → next word" and adjust its internal numbers until it gets good at predicting.
Generation: To write text, repeatedly predict the next word, add it to the context, and repeat.
What we're building today
Real LLMs have billions of parameters and train on trillions of words. Our tiny model will have about 2,400 parameters and train on a few sentences - but it uses the exact same principles!
Finish the whole journey and you graduate: pass the Final Quiz at the end and you can print a shareable diploma with your name and grade on it. Extra Credit gets you honors.
We'll work with individual characters instead of words because it's the clearest way to see the mechanics. Real LLMs split text into sub-word chunks (like "under" + "stand" + "ing") - that's why their token counts never match word counts, and you'll compare both styles in the last section.
The 4-Step Process
Every LLM follows this pipeline:
1 Tokenization
Convert text into numbers that computers can process. Each character (or word) gets a unique ID.
2 Embedding
Convert each token ID into a rich numerical representation - a list of numbers that captures meaning and context.
3 Training
Show the model examples and adjust its internal numbers - called weights - until it learns to predict well.
4 Generation
Use the trained model to predict and generate new text, one token at a time.
Ready to see it in action? In the following sections, you'll go through each step hands-on, training a real (tiny) language model right in your browser!
Tokenization
Computers can't read. Step one is turning your text into numbers: every letter, space, and period gets its own ID. Type something and watch it happen live.
Why This Matters
Everything a language model does starts here. By the time your text reaches ChatGPT's neural network, it's already a list of token IDs - and common words arrive as whole chunks, not letters. This "translation step" is called tokenization, and once it clicks, the rest of the pipeline follows naturally.
Try It: Type Something!
Why do we need tokens?
Computers don't understand letters - they only understand numbers. So we give each character a unique ID number. Look at the tokens above - each character shows its ID below it! These IDs are assigned alphabetically based on characters in the training data.
See a red "unknown" token? That means you typed a character that isn't in the model's vocabulary. The model only knows characters from the training data below. Try typing "hello!" - the exclamation mark will be unknown because it's not in our training text. Unknown characters are simply skipped during training and generation.
Your Vocabulary
These are all the characters the model knows. The vocabulary is built automatically from the training data below:
What's a vocabulary?
The vocabulary is like the model's dictionary - it's the complete list of all characters the model can recognize and use. If a character isn't in the vocabulary, the model won't know what to do with it!
Want to add new characters? Edit the training data in Step 3 below! For example, add "hello!" to include the exclamation mark, or add "2+2=4" to include numbers and symbols. The vocabulary updates automatically when you change the training text.
Go deeper: tokenization causes real LLM failures
Ever seen a chatbot miscount the letters in a word? That's tokenization. Production models rarely see common words as letters: "strawberry" arrives as one or two sub-word chunks, so counting its r's means recalling a spelling the model never directly observed. The same stage is why early models were clumsy at arithmetic - "1234" might split into "12" + "34", and digit-by-digit carrying is hard when you can't see digits.
Your character-level model has none of these blind spots - it sees every letter. The price shows up in the Scale Up section: character sequences are several times longer than sub-word ones, and longer sequences cost more to process. Researchers keep exploring byte-level, tokenizer-free models to get the best of both; so far the efficiency of sub-words keeps winning. See it live: the Scale Up section tokenizes your own text both ways, side by side.
Think about it: your model sees every letter. ChatGPT doesn't. Who got the better deal?
There's a real trade-off. Character models can always spell, and no word is ever "unknown" - but a sentence becomes 4-5x more tokens, every prediction spans more steps, and long-range patterns get harder to hold onto. Sub-word models compress text so each prediction covers more meaning per step, at the price of letter-blindness. Efficiency won: every frontier model uses sub-words and accepts the strawberry problem.
Quick Check: Do you understand?
When text is tokenized, what do the numbers below each character represent?
Quick Check: Do you understand?
Why do chatbots famously miscount the letters in 'strawberry'?
What's Next?
Now we have numbers, but a single ID doesn't tell us much about how a character behaves. Next, we'll convert each ID into a richer representation called an embedding - giving each character its own "personality" in number form.
Embeddings
A bare ID number says nothing about how a character behaves. An embedding gives each one a list of numbers that works like a personality, and the model writes those personalities itself.
Why This Matters
One thing before you scroll: from here on, most numbers on this page are live. Every panel wearing a changes as you train badge shows values from your model - they start as random noise and move with every training step. If a number looks meaningless now, that's the point: train the model (the Train button lives in Step 3 below) and watch it become meaningful.
A single token ID (like the numbers you saw in the tokenizer) doesn't capture anything useful. Is one character similar to another? Do certain characters often appear together? To answer these questions, we need a richer representation. Embeddings are lists of numbers that encode these relationships - and the model learns them automatically during training!
Embedding Matrix changes as you train
Each row represents one character. The numbers in each row are that character's embedding - these values change as the model learns! You're not meant to read them individually; just watch them move once training starts. Click any character on the left to see which other characters ended up closest to it.
What are embeddings?
Instead of representing each character as just a single ID number, we represent it as a list of numbers like [0.12, -0.05, 0.33, ...]. This gives the model more information to work with when learning patterns.
The missing step: one-hot, then lookup
There's a hidden bridge between "token ID 7" and its embedding. A neural network can't do math on the raw number 7 - a bigger ID doesn't mean "more." So the token first becomes a one-hot vector: all zeros except a single 1 in position 7. Multiply that one-hot by the embedding table and you simply pluck out row 7 - which is exactly what the lookup above does. So the embedding matrix isn't a separate gadget; it's the weights that a one-hot input reads from. One-hot in, learned vector out.
Watch the colors: Blue means positive values, red means negative. As training progresses, you'll see these values change as the model learns which numbers best represent each character!
Why do similar characters cluster together?
During training, characters that appear in similar contexts (like vowels, or letters that follow "t") develop similar embeddings. The model discovers these patterns on its own - we don't tell it which characters are similar!
Go deeper: at scale, arithmetic works on meanings
Your characters learn tiny personalities. Scale the same mechanism to words and something startling happens: directions in the space start encoding relationships. The famous result from Mikolov et al.'s word2vec work (2013): take the vector for "king", subtract "man", add "woman" - the nearest word is "queen". Nobody programmed that; it fell out of next-word prediction, exactly the game your model is playing.
Modern LLM embeddings run to thousands of dimensions, and the same geometry carries tense, plurality, even country-to-capital. When people say models build a "semantic space", this is the concrete, measurable thing they mean.
Think about it: two characters never share a context. Can their embeddings still end up similar?
Yes - through transitivity. If "q" behaves like "z" around vowels, and "z" behaves like "x", pressure from the shared neighbor pulls "q" and "x" together even if they never co-occur. Embeddings aren't pairwise notes; they're positions in one shared space where every training example tugs on the whole geometry. This is why models generalize to combinations they've never seen.
Show the math: measuring similarity
"Similar" has a number: cosine similarity - the dot product of two embedding vectors divided by their lengths. +1 means pointing the same way, 0 unrelated, -1 opposite.
train the model, then come back - this fills in with your real embeddings
Try it yourself on any calculator
Two toy embeddings: a = (3, 4) and b = (4, 3).
- Dot product: 3 × 4 + 4 × 3 = 24
- Length of a: √(3² + 4²) = √25 = 5. Same for b: 5
- Divide: 24 / (5 × 5)
You should get 0.96 - very similar directions. Identical directions score 1, unrelated 0, opposite −1.
One honest caveat about the scatter plot below in the Generation section: it draws only dimensions 0 and 1 of each embedding, so it throws away the other 14. Cosine similarity uses all of them - trust the numbers over the picture.
Network Architecture changes as you train
This is the structure of our neural network. Watch how information flows from input to output:
Understanding the architecture
Input layer: Takes your context characters (e.g., "t", "h", "e")
Embedding layer: Converts each character to a rich numerical representation
Hidden layer: Combines embeddings and learns complex patterns
Output layer: Produces probability for each possible next character
This exact design - learned embeddings feeding a hidden layer that predicts the next token - is the classic neural language model of Bengio et al. (2003), the direct ancestor of today's LLMs.
Quick Check: Do you understand?
Two characters keep appearing in the same contexts. What happens to their embeddings during training?
What's Next?
We have our architecture ready - embeddings, hidden layer, and output layer. But right now, all the weights are random! The model will make terrible predictions. It's time to train the model by showing it examples and adjusting those weights until it learns patterns.
Training
The main event. Your model plays guess-the-next-character thousands of times, and every wrong guess nudges its weights a little closer to right.
Why This Matters
This is where learning happens. We'll show the model thousands of "context → next character" examples. Each time it guesses wrong, we calculate the error and adjust the weights slightly. Over many iterations (epochs), these tiny adjustments add up and the model starts recognizing patterns like "th" → "e" or word boundaries.
How machines learn - and why LLMs cheat
Before you press Train, it's worth knowing what kind of learning this is. Machine learning comes in three classic flavors, and LLMs use a clever fourth that gets the benefits of the first for free.
Every example comes with the right answer attached - a label. Show 10,000 photos tagged "cat" or "dog"; the model learns to match.
No labels at all. The model groups and clusters raw data on its own - like sorting a pile of photos into "similar-looking" stacks nobody named.
The model acts, gets a reward or penalty, and adjusts - like training a pet with treats, or an AI learning a game by its score.
So which one is this demo?
A twist on supervised learning called self-supervised learning - the trick behind every LLM. It needs labeled examples, but the labels are free, because the text labels itself. For any spot in the text, the "question" is the characters just before it, and the "answer" is simply the next character. Cover the next character, ask the model to guess, uncover it to grade. No human ever wrote a label.
This is why LLMs can train on the whole internet. Supervised learning needs armies of human labelers; self-supervised learning needs only raw text, because every next character (or word) is a ready-made label. That free-label trick is exactly what "pretraining" means - and it's what you're about to run.
Training Data SMALL
Dataset size matters! Try different sizes to see how it affects learning.
Names data from Karpathy's makemore (ssa.gov)
Train/Validation Split ⓘWe split data into training (to learn from) and validation (to test generalization). This prevents the model from just memorizing!
Try it: drop the training share to 50% and retrain. What changes?
Two opposite effects, both visible above. The validation curve gets smoother - more held-out examples means a steadier measurement. But the model has half as much to learn from, so training loss ends higher. Push it to 95% and it flips: more learning material, but the validation score turns noisy and less trustworthy. The split is a trade: data to LEARN from versus data to TRUST your score on. Real labs settle around 80-95% for exactly this reason.
Why hold data back?
Training loss answers "how well did you learn the flashcards?" Validation loss answers the question you actually care about: "can you handle cards you've never seen?" The model never trains on the held-out 10%, so its loss there measures generalization, not memory.
The gap between the two is the tell. Both falling: learning. Train falling while validation rises: memorizing - that's the overfitting warning below, caught live. Real LLM teams watch exactly this curve, just with billions of held-out tokens.
How does the model learn?
The model learns by playing a guessing game. We show it some characters and ask: "What comes next?" At first, it guesses randomly. But every time it's wrong, we adjust its internal numbers to make it a little more likely to guess correctly next time.
What is backpropagation?
When the model makes a wrong guess, we need to figure out which numbers to adjust and by how much. Backpropagation is the algorithm that calculates these adjustments by working backwards from the error. It's called "back" propagation because the error signal flows backward through the network layers. It was popularized for neural networks by Rumelhart, Hinton & Williams (1986) and is still how every major LLM is trained today.
Go deeper: this page is only stage one of ChatGPT's training
Everything you're doing here is pretraining: pure next-token prediction. A model with only this stage is an autocomplete engine - ask it a question and it may continue with three more questions, because that's what text often does.
Assistants get two more stages. Instruction tuning (supervised finetuning) trains on curated question-answer dialogues so the model learns the format of being helpful. Then preference training (RLHF or DPO) nudges it toward responses humans rate higher - the recipe from InstructGPT (Ouyang et al., 2022) that turned GPT-3 into something you could talk to. The SmolLM2 you can load below went through both: finetuning on the SmolTalk dialogue set, then DPO (SmolLM2 paper).
So when your tiny model babbles, remember: it's not a broken chatbot. It's an honest stage-one model - and stage one is where all the raw knowledge comes from.
Think about it: why do we shuffle the data every epoch?
Because order is a pattern too, and the model will learn any pattern you leave lying around. Feed examples in the same sequence every epoch and the updates arrive in the same rhythm - the model ends each epoch biased toward whatever came last. Shuffling (this page really does it, every epoch) makes each pass a fresh, decorrelated sample. Real training pipelines shuffle at massive scale for the same reason.
Try it: drag the learning rate slider (just below) to 0.5 and retrain. What happens, and why?
Make a prediction first, then test it. You'll likely see the loss fall, then bounce or even climb: each update now overshoots. Gradient descent is walking downhill in fog, and the learning rate is your stride length - small strides descend slowly but surely; huge strides step clean over the valley and land on the far slope. Real training schedules shrink the stride as the model converges (warmup then decay) - and so does this demo: the slider sets your STARTING stride, which decays to 10% of that by the last epoch. So drag it to 0.5 and the early epochs will do the overshooting for you.
Show the math
For softmax + cross-entropy, the output-layer gradient collapses to one beautiful line:
"Take the predicted probabilities, subtract 1 from the correct answer's slot." Then the chain rule walks it backwards:
Each symbol is a real layer above. See it on the diagram:
And every weight takes one small step downhill:
Reading the symbols: ∂ ("partial") means "how much L changes when this one thing changes"; η ("eta") is the learning rate - it starts at the slider value above and decays to 10% of it across the run; ⊗ is an outer product (every element of one vector times every element of the other).
Two honest simplifications versus industrial training: real runs compute the gradient over a batch of examples at once and average it (steadier steps, and batching is what keeps a GPU busy), and they use a smarter update rule called Adam that gives every weight its own adaptive step size instead of one global learning rate. Same idea - nudge weights downhill - just industrialized. Beyond that, this is the entire learning algorithm - the same one running in this page's Python equivalent and, at scale, in every frontier model.
Try it yourself on any calculator
Say the model predicted three characters at 0.7, 0.2, and 0.1, and the first one was correct.
- Gradient for the correct slot: 0.7 − 1 = −0.3 (negative = "push this probability UP")
- Gradients for the wrong slots: 0.2 − 0 = 0.2 and 0.1 − 0 = 0.1 (positive = "push these DOWN")
- Now update a weight - any weight; take one whose gradient came out +0.3 (not the −0.3 from step 1). With w = 0.5 and learning rate η = 0.1: type 0.5 − 0.1 × 0.3
You should get 0.47. That tiny nudge, times ~2,400 weights, times thousands of examples, is all training is.
What's a hidden layer?
Our model has a "hidden layer" between the input (character embeddings) and output (predictions). This middle layer allows the model to learn complex patterns that can't be captured by directly connecting input to output. The hidden layer combines and transforms the input information before making a prediction.
Activation Functions (ReLU)
After the hidden layer multiplies inputs by weights, we apply an "activation function" called ReLU (Rectified Linear Unit). It's incredibly simple: if the number is negative, make it zero; otherwise, keep it. Mathematically: ReLU(x) = max(0, x)
Why? Without activation functions, stacking layers would just be equivalent to one big linear transformation. ReLU introduces non-linearity, allowing the network to learn complex patterns like curves and conditional relationships. It became the default choice after Nair & Hinton (2010) showed it trains deep networks faster than older alternatives.
Context Window: The model looks at 3 characters to predict the next one:
Clean the Data (optional, but real)
Before a real LLM ever trains, its text goes through a massive cleaning pipeline - filtering junk, removing duplicates, normalizing characters. Garbage in, garbage out. Toggle a step and watch what it does to your vocabulary and character count. Nothing changes your text until you press Apply.
The built-in datasets are already tidy, so cleaning barely changes them. Real crawled text is a mess - and turn everything on to see cleaning do real work.
Go deeper: cleaning can matter more than the source
The teams behind the biggest models publish their recipes, and they're mostly about cleaning. Google's C4 dropped pages without enough real sentences and filtered obscenity. The Falcon team's RefinedWeb showed something surprising: carefully filtered and de-duplicated web text alone beat models trained on hand-curated "prestige" corpora. And Lee et al. (2021) found that removing duplicated passages cut memorization roughly tenfold and let models reach the same quality in fewer steps - one 61-word passage appeared over 60,000 times in the raw data before dedup.
Your toggles are toy versions of exactly those steps. Paste in some messy text - copy anything off the web - and watch how much of the "vocabulary" is really just stray invisible characters and one-off symbols.
Why vocabulary size is a real dial. Every character in the vocabulary adds a row to the embedding table and a slot to the output layer. Lowercasing English text often removes 30-40% of the vocabulary at once - a smaller, denser problem the model learns faster. That trade (lose capitalization, gain simplicity) is a real decision every tokenizer makes.
Where bias comes from
A model has no opinions and no experience of the world. It only ever knows what you fed it - so any lopsidedness in the data becomes lopsidedness in the model. That's not a bug you can patch; it's the whole mechanism. Here's a version you can see in one training run.
The demo: load a name list where every single name ends in the letter "a". Train, then generate. The model won't just prefer names ending in "a" - it will be nearly incapable of ending a name any other way, because it never saw one. It learned your skew perfectly.
Go deeper: why this is the serious problem in real AI
Our skew is obvious and harmless. Real ones aren't. A hiring model trained on a company's past resumes learns to prefer whoever got hired before, biases and all - Amazon scrapped exactly such a system in 2018 after it penalized resumes containing the word "women's". Speech recognizers trained mostly on one accent transcribe it best and everyone else worse. Face datasets skewed toward some skin tones misidentify others. In every case the math is what you're watching here: the model faithfully mirrors the distribution it was shown, including the parts nobody meant to teach it.
This is why "data curation" and "garbage in, garbage out" from the cleaning step above aren't just about quality - they're about fairness. What you leave out of the data, the model can't know. What you over-represent, it over-learns.
Choose Your Training Mode
Pick a preset or customize your own settings. These knobs - learning rate, epochs, context size, embedding size - are hyperparameters: the settings YOU choose before training. Everything the model learns on its own (its weights and biases) are its parameters.
These four dials are hyperparameters - you set them before training. The numbers they shape (the embedding table, the weight matrices) are the model's parameters, and the model learns those itself. Mixing up the two is the classic beginner slip.
What's an epoch?
An epoch is one complete pass through ALL the training data. If your training data has 100 examples, then after 1 epoch, the model has seen all 100 examples once. After 10 epochs, it has seen each example 10 times.
Training Progress changes as you train
Is my accuracy any good? How to judge these numbers
Train the model first - this fills in with your real numbers.
Judge accuracy against guessing, not against 100%. Language is genuinely uncertain: after "the ca", both "t" and "r" are legitimate futures, and no amount of training can know which one the author chose. Prediction quality has a ceiling built into the text itself - information theory calls that limit entropy. Frontier models with billions of parameters face the same wall; they're just closer to it.
Rule of thumb: scoring at chance means broken; 5-10x chance means it's learning; 20x chance and up is about as good as a model this size gets. The top-3 number tells the other half of the story - even when the #1 guess misses, the right answer is usually on the model's shortlist.
Why do the numbers jump around? This is completely normal! The model sees different examples in random order, and some are harder than others. What matters is the overall trend: loss should generally decrease and accuracy should generally increase over time.
Loss Over Time (lower is better)
Show the math: what the loss number means
The loss is cross-entropy: -ln of the probability the model gave the correct next character. Two facts turn it from an arbitrary score into something you can read:
random guessing over V characters → loss = ln(V)
That's why every fresh run starts near that number - untrained weights are as good as a coin flip over the whole vocabulary. And exponentiating the loss gives perplexity, the standard metric in language-model papers:
perplexity = e^loss (train the model to see yours)
Try it yourself on any calculator
Your default vocabulary has 17 characters.
- Random-guess loss: press ln(17) - you should see about 2.83. That's why every fresh run starts near that number.
- Now go the other way: press e2.83 (the eˣ button) - you get ~17 back. Loss and perplexity are the same fact in two units.
- After training, plug YOUR loss in: eˣ of 1.0 ≈ 2.7 - the model now effectively chooses between ~3 characters, not 17.
Perplexity reads as an "effective vocabulary": the number of equally-likely characters the model is effectively choosing between at each step (Jurafsky & Martin, Speech and Language Processing call it the weighted branching factor). GPT-class models are evaluated exactly this way, just over sub-word tokens.
The math, from the inside out (for the curious)
You just watched the loss fall. Here's the actual math making it fall - the same four ideas in Andrew Ng's Machine Learning Specialization and in every production training loop. Skip it if you like; it's here for when you want to see the engine, not just drive it.
1. The loss: how surprised were we by the right answer?
Every step, the model outputs a probability for each possible next character. The loss looks only at the one that was actually right and asks how much probability the model gave it. Give the correct character 90% and the loss is tiny (−ln 0.9 ≈ 0.11); give it 1% and the loss explodes (−ln 0.01 ≈ 4.6). This is cross-entropy, and it's the general form collapsed by the fact that the target is 1 for the right character and 0 everywhere else.
Why not just use squared error, like regression does?
Squared error () is the right loss for predicting a continuous number. Feed a softmax output into it and the cost surface turns wavy and non-convex, full of local dips that trap gradient descent - which is exactly why Ng switches to log-loss the moment he moves from regression to classification. Cross-entropy is the maximum-likelihood choice for a categorical output, and it stays well-behaved.
2. The update: take one step downhill
Picture the loss as a bowl and every weight as a position on its side. The slope points uphill, so we step the opposite way. The learning rate - the very slider you set in Step 3 - is how big that step is. Too small and you crawl; too large and you overshoot the bottom and the loss starts bouncing or blowing up. Near the minimum the slope flattens on its own, so the steps shrink automatically.
3. The gradient your code really computes
Here's the beautiful part. After softmax and cross-entropy, the error signal sent backward for each character is just predicted minus target: . For the correct character that's (negative, so its score gets pushed up); for every wrong character it's just (positive, pushed down, in proportion to how much probability it wrongly held). No calculus is visible in the running code - it's a single subtraction - but that subtraction is the calculus, already worked out.
Show the derivation (chain rule)
Softmax is and its Jacobian is . Chaining it with the log-loss derivative and summing over , the terms cancel and, because , everything collapses to . That cancellation is exactly why softmax and cross-entropy are always used together - the two "ugly" derivatives combine into something clean.
4. A layer is just matrix math
Every layer is the same two steps: a weighted sum of all its inputs (a matrix multiply plus a bias offset), then a squash through a nonlinearity. Your hidden layer uses ; your output layer uses softmax. Without that nonlinearity, stacking layers would collapse into one big linear map ( is still just a single matrix) - the squash is what lets the network learn shapes a straight line can't. The exact sizes of your and are in the "matrix shapes" panel above, live for your current model.
Matrix multiplication is the operation deep learning runs on. A forward pass, a backward pass, one layer or a hundred - it's all matrix multiplies: enormous grids of multiply-then-add, and crucially, each cell of the result is independent of the others. That independence is the whole game. A GPU has thousands of tiny cores that each do one multiply-add at the same instant, so it computes a giant matrix product in one parallel sweep where a CPU would grind through it cell by cell. That single fact - deep learning is matrix multiplication, and matrix multiplication parallelizes - is why GPUs power modern AI, why "more compute" is a real lever in the scaling laws, and why the Scale Up section below can run a 135-million-parameter model in your browser tab at all.
And the grids themselves have a name: tensors. There's a simple ladder - a single number is a scalar, a list of numbers is a vector (exactly one row of your embedding table), a grid is a matrix (one of your weight layers), and stacking matrices into three or more dimensions gives a tensor. A tensor is just an array of numbers with any number of dimensions, and it's the one data type deep-learning frameworks are built around - which is literally why one of them is called TensorFlow (and why PyTorch's core object is the tensor). Every live number on this page - each embedding, every weight matrix, the probability distribution - is a slice of some tensor, and training is a long chain of tensor multiplications.
And backward: the chain rule, layer by layer
Backpropagation hands that error backward through the network so every earlier weight learns its share of the blame. Output layer: . Hidden layer: multiply that error by , gate it by where ReLU was active, then . It's just the chain rule, computed once backward instead of re-derived for every weight - that efficiency is the whole reason deep networks are trainable. This is the "optional advanced" module even in Ng's course.
One thing Ng stresses that this tiny model doesn't need: regularization and the bias-variance trade-off (adding a penalty to fight overfitting). Our model is deliberately small and trained for a handful of epochs, so it's built to show underfitting turning into convergence, not to fight overfitting - which is why the train/validation gap above is the honest place to watch that story instead.
Go deeper: the knobs real trainers turn that this demo simplifies
To keep everything visible, this trainer makes a few simplifying choices a production run wouldn't. Knowing the real names closes the gap between the toy and the real thing:
Batch size. This demo updates the weights after every single example - "online" or batch-size-1 SGD. Real models average the gradient over a mini-batch of hundreds or thousands of examples per update. Bigger batches give smoother, less jumpy steps and, crucially, let a GPU process the whole batch in parallel. The tradeoff: too big and each step costs more memory and can generalize slightly worse.
The optimizer. Our update rule is plain SGD: step every weight against its gradient by a fixed learning rate. Almost every real model instead uses Adam (or AdamW), which keeps a running estimate of each weight's gradient and its variance, giving every weight its own adaptive step size plus momentum. It's why real training tolerates one global learning rate across millions of parameters that all need different-sized steps.
Dropout. Bigger networks randomly switch off a fraction of neurons on each step so the model can't over-rely on any single path - cheap insurance against overfitting. Ours is small enough that early stopping and a tiny model already do that job, so we leave it out.
Before vs After Training changes as you train
See how the model's predictions improve! Both boxes show what the model predicts when given "th" as input:
What to look for
Before training, the model is mashing the keyboard: every character is roughly equally likely. After, you should spot real fragments: "th", "at", spaces in sensible places, maybe even a whole word. Not copied - rebuilt, one probability at a time.
Early stopping: if validation loss stops improving for long enough, this trainer halts the run and keeps the best checkpoint - more epochs past that point only memorize. Real training pipelines do exactly the same thing.
Keep expectations realistic! This is a tiny model learning character-by-character with very limited training data. It won't write Shakespeare! But you should see it learn patterns like common letter combinations ("th", "at", "on") and maybe even short words. Real LLMs like ChatGPT have billions of parameters and train on trillions of words - our model has about 2,400 parameters at default settings!
Challenges: go beyond the tour
The tour showed you the mechanics. These turn the sandbox into a set of small experiments - each one earns a badge and drives home one real idea. They check off automatically as you do them.
Your Achievements
Curious Visitor0 / 32What-If Experiments
Make predictions about what will happen, then test them!
Live Forward Pass changes as you train
Watch what happens inside the model when it processes characters:
1 Input (Context)
The last few characters the model is looking at:
2 Look Up Embeddings
Get the embedding for each input character:
3 Compute Scores (Logits)
Calculate a raw score for each possible next character. Higher = more likely. These scores are called "logits" in ML:
4 Convert to Probabilities (Softmax)
Turn scores into probabilities using "softmax" - it exponentiates each score then divides by the sum, so they add up to 100%:
P(i) = e^(score[i]) / sum(e^(all scores))
Show the softmax stability trick
Softmax exponentiates scores - and eˣᵒᵒ overflows fast. In JavaScript, Math.exp(710) is already Infinity. Every real implementation (including this page's) subtracts the largest logit first:
Mathematically identical - the max cancels out - but now the biggest exponent is exactly 0, so nothing overflows. Look for "maxLogit" in this page's source: it's there for exactly this reason, and the same trick runs inside every production LLM.
Show the matrix shapes
And this is exactly why GPUs matter: every arrow in the forward pass - and every step of backprop - is a matrix multiplication: thousands of multiply-adds that don't depend on each other. A GPU does exactly that, thousands at once. That parallelism is why a CPU takes months where a GPU takes days, why training costs millions, and why "more compute" is a real dial in the scaling laws rather than a metaphor.
Every arrow is just a matrix multiply plus a bias. The numbers update when you change the embedding size, context size, or training data.
Next Character Predictions
The model's best guesses for what comes after the training example above. This is whatever context the model studied last - not your generation seed.
Quick Check: Do you understand?
You crank the learning rate way up and the loss starts bouncing wildly. Why?
What's Next?
Your model has learned patterns from the training data! Now comes the fun part - using it to generate new text. We'll give it a starting prompt and let it predict one character at a time, building up completely new text based on what it learned.
Text Generation
Your model has opinions now. Hand it a few letters and it will write one character at a time, exactly how ChatGPT does it. Just smaller.
Why This Matters
This is where everything comes together. Generation works by repeatedly asking: "Given this context, what's the most likely next character?" The model uses its learned patterns to predict, we add that character to the context, and repeat. This autoregressive process is exactly how ChatGPT and other LLMs generate text - just with words instead of characters!
Generate Text changes as you train
Watch temperature reshape the odds
Live probabilities for the character that would follow your starting text, computed at the temperature above. Drag the slider: the gaps change, the order never does. (Different context than the training panel above - that one shows the last example the model studied.)
What is temperature?
Temperature is a confidence dial, not a creativity dial. It reshapes the gaps between probabilities but never changes their order: the most likely character stays most likely at every temperature. It adds no new knowledge, and it only matters during generation - training never sees it. Mathematically, we divide the model's scores (logits) by the temperature before applying softmax: P(i) = e^(logit_i / T) / Σ e^(logit_j / T). The term comes from statistical physics via Hinton et al. (2015), and its effect on generated text is studied in Holtzman et al. (2020).
Low temperature (0.1-0.5): Makes differences between scores more extreme. The model almost always picks the highest-scoring character - which sounds safe, but often collapses into loops ("the cat sat on the cat sat on the...").
High temperature (1.5-2.0): Flattens the differences between scores. Lower-scoring characters become more likely. Output is more varied and creative but can be nonsensical.
Temperature = 1.0: Uses the model's original probabilities without modification.
Go deeper: the sampling zoo
Production systems rarely sample with temperature alone. The distribution's long tail is full of individually-unlikely-but-collectively-probable junk, so real decoders truncate before sampling: top-k keeps only the k most likely tokens; nucleus (top-p) keeps the smallest set whose probabilities sum to p - the fix proposed by Holtzman et al. (2020) after showing that pure sampling wanders and pure greedy loops. Add repetition penalties and you have roughly the decoder behind your chatbot conversations.
Every knob trades the same two failure modes you can produce with the slider above: too sharp repeats, too flat rambles.
Think about it: at temperature 0 your model can loop forever ("the cat sat on the cat sat on..."). Why can't it escape?
At T=0 generation is fully deterministic: the same 3-character context always produces the same top pick. The moment any context repeats, the future is locked - same input, same output, forever. With only 3 characters of memory, repeats come fast. Any temperature above zero breaks cycles by occasionally taking a different branch; production decoders also add explicit repetition penalties. This is also a first taste of why context-window size matters so much.
Show a worked example
Three characters with logits 2.0, 1.0, and 0.0. Divide by T, then softmax:
"a" "b" "c" T = 0.5: 86.7% 11.7% 1.6% (sharper) T = 1.0: 66.5% 24.5% 9.0% (raw) T = 2.0: 50.6% 30.7% 18.6% (flatter)
"a" wins at every temperature - the ranking is untouchable. Only the margins move.
Try it yourself on any calculator - reproduce the T = 1.0 row
The three logits behind that table are 2, 1, and 0.
- Exponentiate each (the eˣ button): e² ≈ 7.39, e¹ ≈ 2.72, e⁰ = 1
- Add them up: 7.39 + 2.72 + 1 = 11.11
- Divide each by the sum: 7.39 / 11.11, then 2.72 / 11.11, then 1 / 11.11
You should get 66.5%, 24.5%, and 9.0% - the exact T = 1.0 row. For the T = 0.5 row, divide the logits by 0.5 first (making them 4, 2, 0) and repeat.
See it side by side
Same trained model, same starting text - only the temperature changes. Generate both at once and watch one setting turn a careful, repetitive writer into a reckless, inventive one. This is the fastest way to feel what a single knob does.
Common Misconceptions
Let's clear up some common misunderstandings about how LLMs work:
| Myth | Reality |
|---|---|
| "AI understands what it's saying" | LLMs predict the most likely next character/word based on patterns. They don't have understanding or consciousness - they're very sophisticated pattern matchers. |
| "More epochs always = better results" | After a point, more training can cause "overfitting" - the model memorizes the training data instead of learning general patterns. There's a sweet spot! |
| "The model remembers specific examples" | The model stores patterns in its weights, not the actual text. It learns that "th" often comes before "e", not that it saw "the" 47 times. |
| "Higher temperature = smarter output" | Temperature only controls randomness. High temperature makes output more varied but often less coherent. Low temperature is more predictable but can be repetitive. |
| "Embeddings are hand-designed" | Embeddings are learned automatically during training! The model figures out the best numerical representation for each character on its own. |
| "ChatGPT learns from my conversations" | After training, the weights are frozen. Your chats don't change the model - it only "learns" if the company runs a whole new training run. What feels like memory is just the conversation being fed back in as context. |
| "It's just searching a giant database" | There's no lookup happening. The training text isn't stored anywhere in the model - just weights, like the ones you watched change above. That's why a 150MB download can "know" far more than 150MB of text. |
| "It only predicts the next word, so it can't really be smart" | The reverse myth! Predicting the next word WELL is brutally hard - it forces the model to encode grammar, facts, and reasoning patterns. Simple objective, sophisticated skill. You watched this happen in miniature today. |
| "If it sounds confident, it's correct" | The objective rewards PLAUSIBLE text, not true text. Fluent, confident, and wrong is a natural failure mode (hallucination) - which is why answers worth acting on deserve a second source. |
| "The model is neutral and objective" | A model learns whatever patterns live in its data - including the ugly ones. If the training text skews an association, the model reproduces it, not because it believes anything but because it predicts faithfully. The same objective that buys fluency buys bias; data curation and post-training correct it only imperfectly. |
| "The same prompt always gives the same answer" | Only at temperature 0. Normal generation samples from the probability distribution, so the same prompt legitimately produces different answers - you saw this with your own model's temperature slider. |
Embedding Visualization changes as you train
After training, characters that appear in similar contexts should cluster together. This shows the first 2 dimensions of each character's embedding:
What am I looking at?
Each dot is a character. Characters that are close together have similar embeddings, meaning the model thinks they behave similarly. For example, vowels might cluster together, or letters that often appear after "t" might be near each other.
Final Check: What did you learn?
Why does training for more epochs usually lead to better results?
Quick Check: Do you understand?
Which of these can CHANGE which character the model ranks first?
Quick Check: Do you understand?
The model just picked "e" as its next character. What happens next during generation?
Milestone: The Engine Works
You've built and trained a real language model - the hard part is behind you. While tiny compared to ChatGPT (a few thousand parameters vs. hundreds of billions), it uses the same core concepts:
- Tokenization: Converting text to numbers
- Embeddings: Learning rich representations
- Neural network: Forward pass, loss, backpropagation
- Training: Iterating over data to learn patterns
- Generation: Autoregressive prediction with temperature
The difference between this and a frontier model? Mostly scale - more layers, more parameters, more data, more compute - plus one architectural addition called attention that you'll meet in the next section. The fundamentals you learned here carry over directly.
Ready to see proof? In the next section, we'll load a REAL language model (135 million parameters!) right in your browser and compare it side-by-side with your tiny model.
Scale Up: A Real LLM
You trained about 2,400 parameters. Time to load 135,000,000 into this same tab and watch the identical math, with more zeros.
From your model to a chatbot: three stages
Your tiny model does exactly one thing: predict the next character. The SmolLM2 you're about to load can answer questions and hold a conversation. Same starting point - it just went through two more stages of training. This is the recipe behind every assistant, from ChatGPT to the model below.
Read a huge pile of text and play guess-the-next-token, billions of times. This is exactly what you just did, only bigger.
Show it thousands of example requests paired with good answers. Same next-token game, but now the text is curated question-and-answer dialogue.
People rank pairs of answers; the model shifts toward the ones humans prefer. This is the "reinforcement" flavor of learning from the Training section.
SmolLM2-135M-Instruct went through all three. Your tiny model is a faithful Stage 1 - and Stage 1 is where all the raw knowledge comes from. The two extra stages teach manners and format, not new facts. That's why the "Instruct" suffix matters: without it, even a giant model just autocompletes.
The Numbers That Matter
Here's how your tiny model compares to real LLMs. Same concepts, vastly different scale:
| Aspect | Your Tiny Model | SmolLM2-135M | SmolLM2-360M | Qwen3-0.6B | Llama 3.1 405B |
|---|---|---|---|---|---|
| Parameters | ~2,400 | 135,000,000 | 360,000,000 | 600,000,000 | 405,000,000,000 |
| Vocabulary | ~17 chars | 49,152 tokens | 49,152 tokens | 151,936 tokens | 128,256 tokens |
| Token Type | Characters | BPE subwords | BPE subwords | BPE subwords | BPE subwords |
| Embedding Size | 16 | 576 | 960 | 1,024 | 16,384 |
| Layers | 1 hidden | 30 | 32 | 28 | 126 |
| Training Data | ~250 characters | 2T tokens | 4T tokens | ~36T tokens (family) | ~15.6T tokens |
| Training Time | Seconds in your browser | Days on GPU clusters | Days on GPU clusters | Weeks on GPU clusters | ~54 days on 16,384 GPUs |
Sources: architecture numbers come from each model's published config.json on Hugging Face; training data from the SmolLM2 paper, the Qwen3 technical report (36T tokens across the family), and The Llama 3 Herd of Models (Meta, 2024). We compare against Llama 3.1 405B as the ceiling because its full specifications are published; commercial models like GPT-4 don't disclose theirs. Your tiny model's numbers reflect the default settings, and the three middle columns are the exact models you can load below.
Chinchilla's rule of thumb is about 20 training tokens per parameter (Hoffmann et al., 2022). By that math a 135M model "needs" ~3 billion tokens - SmolLM2 got roughly 2 trillion, deliberately overtrained so a small model runs cheaply and still holds its own, like it does right here in your tab.
Same Recipe, Different Scale
SmolLM2 uses the same core recipe you just learned: tokenization, embeddings, a forward pass, softmax, and temperature sampling. There is no secret ingredient in ChatGPT-class models - the recipe is public science. What changes at scale: more parameters let the model store more nuanced patterns, and more data shows it more examples of how language works.
One under-appreciated ingredient: data curation. Trillions of tokens aren't scooped up raw - the web crawl gets deduplicated, filtered for quality, and rebalanced, and researchers keep finding that data quality rivals sheer quantity. SmolLM2, the model you can load below, punches far above its size precisely because of unusually careful data curation.
One honest difference: attention
Real LLMs are transformers: on top of everything you learned, they stack layers of self-attention - a mechanism that lets the model decide, for every token, which earlier tokens matter most right now. Your tiny model weighs its 3 context characters with fixed learned weights; a transformer re-computes those relationships on the fly for thousands of tokens. That's the architecture leap from "Attention Is All You Need" (Vaswani et al., 2017). Everything else you built - embeddings, hidden layers, softmax, backprop, temperature - carries over unchanged.
And your hidden layer isn't left behind at scale - it IS half of every transformer block. Each block is attention (decide which earlier tokens matter) followed by a small neural network exactly like the one you built (process what attention gathered). Attention is the new half; your half is still there, thirty times over. (Before transformers, models read text one step at a time and couldn't parallelize - attention let the whole sequence be processed at once, which is why it took over.)
Go deeper: what's actually inside one transformer block
Attention is the headline, but a real block has a few more parts that solve problems your tiny model never hits. Together they're why a transformer can be stacked dozens deep and still train:
Positional encoding. Your model reads its context left to right, so order is baked in. A transformer looks at every token at once, which is fast but means it has no built-in sense of order. So position information has to be injected. The original 2017 recipe added a position signal to each token's embedding before the first block; most modern models, SmolLM2 included, instead use rotary position embeddings (RoPE), which rotate the query and key vectors inside every attention layer by an angle that depends on each token's position. Either way, without it the model couldn't tell "dog bites man" from "man bites dog".
Residual connections. Each sublayer adds its input back onto its output (a "skip"). That gives the signal - and its gradient during backprop - a clear path straight through the whole stack, which is what stops the vanishing-gradient problem that used to make deep networks untrainable.
Normalization (LayerNorm). Every block rescales its activations to a steady mean and spread so the numbers don't drift or explode as they pass through layer after layer. Your one-hidden-layer model is shallow enough to skip it; a 30-layer model would fall apart without it.
KV cache. When generating, the model saves each token's attention Key and Value vectors and reuses them, so producing token 100 doesn't re-process the first 99 from scratch. It's a big reason the SmolLM2 below can stream words at a readable pace in a browser tab.
Go deeper: how a big model gets adapted and shrunk to run here
A model like SmolLM2 wouldn't fit in a browser tab in its raw training form. Three techniques come up whenever a datacenter model gets adapted or shrunk - the third is the one actually at work on this page:
LoRA (low-rank adaptation). Fine-tuning a whole model means updating every weight - expensive. LoRA freezes the pretrained weights and trains a few small added matrices alongside them, capturing the new skill in a tiny fraction of the parameters. It's how people specialize big models on a single GPU.
Distillation. A small "student" model is trained to copy a big "teacher" model's outputs, packing much of the teacher's ability into far fewer parameters. Many small models are built this way, though not SmolLM2: its coherence comes from the careful data curation described above, not from copying a teacher.
Precision (fp16/bf16). Weights are stored in 16-bit floating point instead of 32-bit, roughly halving the download and memory for a little rounding error. Combined with 4-bit quantization, that's what turns a multi-gigabyte model into the ~150MB one you can load below - and the WebGPU path here runs the math in 16-bit.
Go deeper: scaling laws, and what's still unsolved
Scaling laws: loss doesn't improve randomly with size - it falls as a smooth, predictable power law in parameters, data, and compute (Kaplan et al., 2020). The Chinchilla paper (2022) refined it: compute-optimal training wants roughly 20 tokens per parameter. By that rule SmolLM2-135M "should" need about 3B tokens - it got 2 trillion, deliberately overtrained so a small model punches far above its weight when you run it (like on this page).
Honestly unsolved: why next-token predictors confabulate facts so fluently (hallucination is a natural failure mode of the objective you just trained - it optimizes for plausible text, not true text); why we can't fully explain why a model gave one specific answer (interpretability); and how models learn new tasks from a few examples in the prompt without any weight updates (in-context learning). The people building frontier systems argue about all three. You now know enough to follow those arguments.
Go deeper: the same stack runs far more than chat
The transformer you're comparing against isn't just a text machine. The identical architecture - embeddings, attention, softmax - powers speech-to-text (Whisper), translation, sentiment classifiers, image captioning, even protein folding. The only things that change are what gets tokenized (audio frames, pixels, amino acids) and what the output distribution ranges over.
The library running SmolLM2 on this page (Transformers.js) lists dozens of such tasks that run in a browser tab. We keep this page on one task - next-token text prediction - because that's the thread you can follow end to end. But when you hear "transformers ate machine learning", this is what it means: one architecture, every modality.
Go deeper: what modern LLM products add on top (the honest roundup)
Everything on this page is the engine. Products like ChatGPT bolt five more things onto it - know these and today's AI news makes sense:
Tool use & retrieval (RAG): the model can emit special tokens that call a search engine, calculator, or database, then weave the results into its answer. That's how chatbots cite yesterday's news despite frozen weights.
Multimodality: images and audio get their own tokenizers - a photo becomes a grid of patch tokens that flow through the same transformer as text. Frontier models are no longer text-only.
Reasoning models: newer models (o1/R1-style) are trained to generate thousands of hidden "thinking" tokens before answering. More forward passes per answer - literally buying accuracy with compute at answer time.
Prompt sensitivity: because everything is next-token prediction over your exact words, small wording changes shift which patterns activate. Rephrasing a question and getting a better answer isn't magic - it's conditioning.
Safety layers & their limits: post-training teaches refusals, but a model that predicts text can be steered by text - that's why jailbreaks and prompt injection exist, and why "the model got tricked" headlines keep appearing.
Think about it: your model hit 90% loss reduction on Shakespeare and still writes nonsense. What's actually missing?
All three dials at once. Not enough parameters (~2,400 can store letter patterns, not grammar). Not enough data (600 characters vs 2 trillion tokens). And the one people forget: not enough context - seeing 3 characters back means "to be or not to" is ancient history by the time it matters. The scaling laws above quantify how far each dial has to turn, and the answer is "orders of magnitude" - which is why SmolLM2 below feels like a different kind of thing while running the same algorithm. Your validation loss already told you which of your 90% was real learning versus memorization.
Show the attention math (with SmolLM2's real numbers)
Each token's embedding is projected into three vectors - a query Q, a key K, and a value V - and every token scores every earlier token:
Attention(Q, K, V) = softmax(QKⁿ / √d_k) V
That's your softmax again, just aimed at "which earlier tokens matter" instead of "which character comes next". The √d_k is the same kind of numerical-taming trick as temperature.
In the SmolLM2-135M you can load below (numbers from its published config): each of the 30 layers splits its 576-dimension embeddings into 9 attention heads of 64 dimensions each, with 3 shared key/value heads (grouped-query attention, a memory optimization). Every head learns its own notion of "what matters" - and that runs 30 times per token.
One subtlety attention creates: on its own, attention treats the input as a bag of tokens - "dog bites man" and "man bites dog" would look identical. Transformers fix this by injecting position information - SmolLM2 does it with rotary embeddings (RoPE), rotating each query and key vector by a position-dependent angle inside every attention layer. Your tiny model never had this problem: it reads its context characters in fixed slots, so order comes free. Attention trades that rigidity for reach, then has to buy order back.
And reach has a price: every token attends to every earlier token, so doubling the context roughly quadruples the work. That is why context limits exist, why long prompts cost more, and why "million-token context" is a headline feature instead of a default.
Load a Real LLM
Pick a size, then download and run it directly in your browser. These are real, production-quality language models from Hugging Face - bigger means smarter and a larger one-time download.
quiet watcher of the night,
the moon guides us home.
First time? The model downloads once and is cached by your browser. Return visits will load instantly!
Quick Check: Do you understand?
Your 2,400-parameter model and SmolLM2's 135 million parameters both spend their time doing the same core thing. What is it?
Final Quiz: Test Your Knowledge
Answer all 10 questions - this is the grade that goes on your diploma below. Get them all right to unlock the LLM Master achievement!
1. What is the main purpose of tokenization?
2. Why do we use embeddings instead of just token IDs?
3. What happens during one epoch of training?
4. What does "loss" measure during training?
5. What does backpropagation do?
6. What does high temperature do during text generation?
7. How does an LLM generate text?
8. What's the main difference between our tiny model and ChatGPT?
9. Training loss keeps falling but validation loss starts rising. What's happening?
10. Hallucination is best described as a natural consequence of:
Extra credit
Forty-eight more questions drawn from everything on this page - expanders included. Worth up to +10 points on your diploma grade, and getting 80% or more of them right earns you honors.
Claim Your Diploma
You did the work - get the paper. The grade is weighted like a real course: section checkpoints are worth 20 points, the Final Quiz 80, and Extra Credit adds up to 10 bonus points (and earns honors at 30+). Put your name on it and share it anywhere.
You Now Understand LLMs
Not approximately. Not metaphorically. The actual algorithm.
When someone asks "How does ChatGPT work?" - you can explain it. The fundamentals you learned with your tiny model are the same fundamentals powering the most advanced AI systems in the world.
Glossary
Every term this page uses, in plain language. Each entry points back to where you can play with the real thing.
- Accuracy
- The fraction of predictions where the model's top guess was the correct next character. Intuitive, but coarser than loss - a barely-right guess and a confident one count the same. Step 3
- Activation function
- The non-linear squeeze applied after each layer's multiply-and-add (this demo uses ReLU). Without one, stacked layers would collapse into a single linear transformation. Step 3
- Artificial intelligence (AI)
- Any technique that makes a machine do something we'd call smart - the broadest bucket, from hand-written rules to neural networks. Machine learning is one part of it. Intro
- Attention
- The transformer mechanism that lets a model decide, for each token, which earlier tokens matter most right now. The architectural leap this demo doesn't implement - see the honest-difference box. Scale Up
- Autoregressive generation
- Writing text one token at a time: predict, append, repeat. Every output token becomes input for the next prediction. Step 4
- Backpropagation
- The algorithm that traces a prediction error backwards through the network to compute how much each weight contributed - and therefore how to adjust it. Step 3
- Batch size
- How many training examples the model looks at before each weight update. This demo uses 1 (pure online SGD); real models average the gradient over hundreds or thousands at once - smoother updates, and far better use of a GPU. Step 3
- Bias
- The learnable "+b" each neuron adds after multiplying inputs by weights - a baseline offset that shifts when the neuron activates. This demo's hidden and output layers each have them. Step 3
- Bias-variance tradeoff
- The balance between a model too simple to fit the data (high bias, underfitting) and one that just memorizes it (high variance, overfitting). You read it right off the gap between training and validation loss. Step 3
- BPE (byte-pair encoding)
- How real LLMs tokenize: text splits into sub-word chunks ("under" + "stand" + "ing") learned from data. Efficient, but the model never sees individual letters. Scale Up
- Chain rule
- The calculus rule behind backpropagation: the influence of an early weight on the final loss is the product of every step's influence along the path. "Working backwards" is applying it layer by layer. Step 3
- Chain-of-thought
- Prompting or training a model to write out its reasoning step by step before the final answer, which improves accuracy on multi-step problems. The idea behind modern "reasoning" models. Scale Up
- Checkpoint
- A saved snapshot of the model's weights at a moment in training. This page's trainer keeps the checkpoint with the best validation loss and restores it if later epochs only made things worse. Step 3
- Context window
- How much preceding text the model can see when predicting. This demo: 3 characters. SmolLM2: 8,192 tokens. Frontier models: hundreds of thousands. Step 3
- Cosine similarity
- How aligned two embedding vectors are, ignoring their lengths: 1 means same direction, 0 unrelated, -1 opposite. The standard way to measure whether two tokens "behave alike". Step 2
- Cost function
- The single number training tries to make small - a measure of how wrong the model is. For our next-character classifier, the cost is the cross-entropy loss. Step 3
- Cross-entropy loss
- The training score: -ln of the probability the model assigned to the correct answer. Perfect confidence scores 0; random guessing over V options scores ln(V). Step 3
- Data annotation (human labeling)
- The human work of attaching the right answers to data - tagging images, writing example answers, or ranking a model's replies. Self-supervised pretraining needs none of it, but instruction tuning and RLHF depend on armies of human labelers. Step 3
- Data bias
- Any lopsidedness in the training data, which the model faithfully reproduces - it only knows what it was shown. The mechanism behind real-world fairness failures. Step 3
- Data cleaning
- Filtering, normalizing, and de-duplicating text before training. Real pipelines spend enormous effort here: garbage in, garbage out. Step 3
- Deduplication
- Removing repeated passages from the training data. It cuts memorization sharply and lets a model reach the same quality in fewer steps. Step 3
- Deep learning
- Machine learning built from many-layered neural networks that learn their own useful features. LLMs are one kind of deep learning. Intro
- Distillation
- Training a small "student" model to imitate a larger "teacher" model's outputs, compressing much of its ability into far fewer parameters. Part of why a small model can punch above its size. Scale Up
- Dropout
- Randomly switching off a fraction of neurons on each training step so the network can't lean on any single path - a common cure for overfitting. Not needed for a model this small. Step 3
- Early stopping
- Ending training when validation loss stops improving - the epochs after that point only memorize. This page's trainer does it automatically and keeps the best checkpoint. Step 3
- Embedding
- The learned list of numbers that represents a token. Tokens that behave similarly end up with similar embeddings - the model writes these "personalities" itself during training. Step 2
- Embedding layer
- The network's first stop: a lookup table that swaps each incoming token ID for that token's embedding vector. Its rows are exactly the embedding matrix you can watch changing above. Step 2
- Emergent abilities
- Skills that appear abruptly only past a certain model scale rather than improving smoothly - a big reason a giant model isn't just a bigger version of this one. Scale Up
- Epoch
- One full pass through all the training data. Fifteen epochs means the model studied every example fifteen times. Step 3
- Fine-tuning
- Continuing to train a pretrained model on curated data to specialize it - for example, instruction tuning that turns a raw base model into a helpful assistant. Scale Up
- Forward pass
- One trip through the network: embeddings in, hidden layer, logits out, softmax to probabilities. The Live Forward Pass card shows yours happening. Step 3
- Generalization
- Performing well on data the model never trained on - the actual goal. Measured here by validation loss; its failure mode is memorization. Step 3
- Gradient
- The direction and size of the adjustment that would most reduce the loss for one weight. Computed by backpropagation, applied by gradient descent. Step 3
- Gradient descent
- The learning loop: nudge every weight a small step against its gradient, over and over. The step size is the learning rate. Step 3
- Greedy decoding
- Always picking the single most likely next token (argmax) - what temperature 0 does. Deterministic, and prone to loops the moment any context repeats. Step 4
- Hidden layer
- A layer between input and output where the network combines features into more complex patterns. This demo has one; SmolLM2 stacks 30. Step 2
- Hallucination
- Fluent but false output. A natural failure mode of next-token training: the objective rewards plausible text, not true text. Scale Up
- In-context learning
- A model picking up a new task from examples in the prompt alone, with no weight updates - one of the honestly-unsolved puzzles of large models. Scale Up
- Inference
- Using a trained model (as opposed to training it). Everything after you hit Generate is inference. Step 4
- Input layer
- Where data enters the network - here, the IDs of your context characters, which immediately become embeddings. Step 2
- Instruction tuning / RLHF
- The post-training stages that turn a raw next-token predictor into an assistant: supervised finetuning on dialogues, then optimization toward human-preferred answers. This demo covers the stage before both. Step 3
- Interpretability
- The open research problem of explaining WHY a model produced a specific output. We can inspect every weight (you literally can, above) and still not have a satisfying answer. Scale Up
- Hyperparameters
- The settings YOU choose before training - learning rate, epochs, context size, embedding size. Distinct from parameters, which are the weights the model learns on its own. Step 3
- KV cache
- During generation, the stored Key and Value vectors from earlier tokens, reused so each new token doesn't recompute attention over the whole sequence. It's a big part of why token streaming is fast. Scale Up
- Learning rate
- How big a step each weight update takes. Too small learns slowly; too large overshoots and the loss bounces. Try 0.5 and watch. Step 3
- Learning-rate schedule
- Varying the step size over training: big exploratory steps early, careful small ones late. This demo does it too - your slider sets the starting rate, and it decays along a cosine curve to 10% of that by the final epoch. Step 3
- Logits
- The raw, unnormalized scores the model produces for every possible next token, before softmax turns them into probabilities. Step 3
- LoRA (low-rank adaptation)
- Fine-tuning by freezing the pretrained weights and training a few small added matrices instead, so a big model can be specialized cheaply on modest hardware. The most common parameter-efficient fine-tuning method. Scale Up
- Machine learning
- A kind of AI that learns patterns from examples instead of being programmed with explicit rules. Deep learning and LLMs are subfields of it. Intro
- Memorization
- Storing training examples instead of learning transferable patterns - what overfitting looks like from the inside. The train/validation gap is how you catch it. Step 3
- Model
- The whole learnable machine: all the weights plus the wiring between them. "Training the model" means adjusting those numbers until predictions improve. Introduction
- Neural network
- Layers of simple multiply-add-activate units whose stacked combination can learn remarkably complex patterns. Your ~2,400-parameter one and GPT-class models are the same species. Step 2
- Neuron
- One unit in a layer: it multiplies every input by a learned weight, adds its bias, and applies the activation function. This demo's hidden layer has 32 of them. Step 3
- Normalization (LayerNorm)
- Rescaling a layer's activations to a steady mean and spread so deep networks train stably. Transformers put a normalization step in every block; this shallow demo doesn't need one. Scale Up
- One-hot encoding
- Representing a category as a vector of all zeros with a single 1 marking which one it is. It's the raw input form of a token - the embedding layer is just a lookup that swaps each one-hot for a learned vector. Step 2
- ONNX
- An open, framework-neutral file format for trained models. A model trained in PyTorch gets exported to ONNX so anything - including your browser - can run it. Every model in the Scale Up section ships as ONNX. Scale Up
- Optimizer
- The rule that turns a gradient into an actual weight update. This demo uses plain SGD; almost every real model uses Adam, which adapts the step size per weight and adds momentum. Step 3
- Output layer
- The final layer, producing one raw score (logit) per vocabulary entry - softmax then turns those into next-character probabilities. Step 2
- Overfitting
- When a model memorizes its training data instead of learning patterns: training loss keeps falling while validation loss rises. Step 3
- Parameter
- One learnable number in the model - an embedding value, a connection weight, a bias. This demo: ~2,400. SmolLM2: 135 million. Llama 3.1: 405 billion. Step 1
- Perplexity
- e raised to the loss: the "effective vocabulary size" the model is choosing from at each step. Lower is better; the standard LM evaluation metric. Step 3
- Positional encoding
- How a transformer learns the order of its tokens - attention alone treats them as an unordered bag. The original recipe added a position signal to each embedding; modern models like SmolLM2 use RoPE, which rotates query and key vectors by a position-dependent angle inside each attention layer. Scale Up
- Precision (fp16/bf16)
- How many bits store each number. Running in 16-bit instead of 32-bit roughly halves memory and speeds up the matrix math, for a little rounding error. The demo's WebGPU path uses 16-bit weights. Scale Up
- Pretraining
- The next-token-prediction stage that builds all the raw knowledge - the only stage this demo performs, and the source of most of an LLM's capability. Step 3
- Probability distribution
- The full set of probabilities over every possible next character, summing to 1. Everything the model "thinks" lives in this list - generation just samples from it. Step 4
- Prompt
- The text you hand the model to continue from. Everything it generates is conditioned on this plus whatever it has generated so far. Step 4
- Quantization
- Shrinking a model by storing weights at lower precision - 4-bit integers instead of 16-bit floats. It's why SmolLM2-135M is a ~150MB download instead of the ~270MB its 16-bit weights would need, at a small accuracy cost. Scale Up
- Query, Key, Value (QKV)
- The three vectors attention projects from each token's embedding: the query asks "what am I looking for?", keys advertise "what I contain", values carry the payload. Scores between queries and keys decide what matters. Scale Up
- Reinforcement learning
- Learning from rewards and penalties rather than labeled answers - like training a pet with treats. The "RL" in RLHF, the final stage that aligns chatbots to human preferences. Scale Up
- ReLU
- The activation function in this demo's hidden layer: negative values become zero, positive pass through. It's what makes stacking layers more powerful than one big multiplication. Step 3
- Residual connection
- Adding a layer's input back onto its output so the original signal (and its gradient) can skip straight through. It's what lets transformers stack dozens of layers without the gradient fading away. Scale Up
- Retrieval (RAG)
- Retrieval-augmented generation: using embedding similarity to fetch relevant outside text and paste it into the prompt, so the model can answer from fresh or private data it never trained on. Scale Up
- Scaling laws
- The empirical finding that loss falls as a smooth, predictable power law in parameters, data, and compute - why bigger reliably works, and how labs budget training runs. Scale Up
- Sampling
- Picking the next character at random, weighted by the probability distribution - so a 79% option usually wins but a 9% option sometimes does. Temperature reshapes those weights first. Step 4
- Seed text
- The starting characters you give this demo's generator - its entire "prompt". With a 3-character context window, only the tail of it actually matters. Step 4
- Self-supervised learning
- Supervised learning where the labels come free from the data itself: predict the next character, and that next character IS the label. The trick that lets LLMs train on raw text with no human labeling. Step 3
- Shuffling
- Randomizing training-example order every epoch so the model can't learn the order itself as a pattern, and updates stay decorrelated. This page really does it each epoch. Step 3
- Softmax
- The function that turns logits into probabilities that sum to 1: exponentiate every score, divide by the total. Step 3
- Streaming
- Showing each token the moment its forward pass finishes instead of waiting for the whole answer. What you watch in the side-by-side comparison is the model's real computation speed. Scale Up
- Supervised learning
- Learning from examples that each come with the right answer attached (a label). Next-character prediction is a self-supervised twist on it, where the labels are free. Step 3
- Temperature
- A generation-time dial that sharpens (low) or flattens (high) the probability distribution before sampling. Changes the gaps, never the ranking. Step 4
- Tensor
- An array of numbers with any number of dimensions - the ladder goes scalar (one number), vector (a list, like one embedding), matrix (a grid, like a weight layer), tensor (three or more dimensions). The core data type of deep-learning frameworks; TensorFlow is named after it. Step 3
- Token
- The unit a model reads and writes. Characters in this demo; sub-word chunks in production models. Step 1
- Training data
- The text the model learns from - every "context → next character" example is carved out of it. Here it's editable; for production LLMs it's trillions of tokens of curated text. Step 3
- Top-k / top-p sampling
- Production decoding tricks that truncate the distribution's junk-filled tail before sampling: top-k keeps the k most likely tokens, top-p (nucleus) keeps the smallest set summing to probability p. Step 4
- Transformer
- The architecture behind every modern LLM: stacked layers of self-attention plus small neural networks. Vaswani et al., 2017. Scale Up
- Unsupervised learning
- Finding structure in data with no labels at all - grouping and clustering on its own. Contrast with the (self-)supervised learning this demo uses. Step 3
- Validation set
- Data held back from training and used only to measure generalization. This demo reserves 10%. Step 3
- Vanishing / exploding gradients
- When gradients shrink toward zero or blow up as they backpropagate through many layers, stalling or wrecking training. Residual connections and normalization are the standard fixes. Step 3
- Vocabulary
- The complete set of tokens a model knows. This demo builds it from your training text (~17 characters by default); SmolLM2 has 49,152 sub-words. Step 1
- Weight initialization
- The starting values before any training - random, but carefully scaled (Xavier-style here) so signals neither explode nor vanish as they pass through layers. Step 3
- WebAssembly (WASM)
- Near-native-speed code running safely in the browser - the CPU engine that runs the Scale Up models when no GPU is available. Scale Up
- WebGPU
- The browser's modern graphics-card API. When available, model math runs on your GPU - often an order of magnitude faster than WASM, and what the Qwen3 tier requires. Scale Up
- Weights
- The parameters connecting neurons - the numbers gradient descent adjusts. "The model learned" means "the weights changed". Step 3
References & Further Learning
Every technical claim on this page traces back to one of these. They're also the best next steps if you want to go deeper.
The papers behind what you just built
- Bengio, Ducharme, Vincent & Jauvin (2003). A Neural Probabilistic Language Model. JMLR. — The embedding + hidden-layer next-token architecture your tiny model uses.
- Rumelhart, Hinton & Williams (1986). Learning representations by back-propagating errors. Nature. — Backpropagation.
- Glorot & Bengio (2010). Understanding the difficulty of training deep feedforward neural networks. AISTATS. — The "Xavier" weight initialization.
- Nair & Hinton (2010). Rectified Linear Units Improve Restricted Boltzmann Machines. ICML. — ReLU.
- Sennrich, Haddow & Birch (2016). Neural Machine Translation of Rare Words with Subword Units. ACL. — Byte-pair encoding for tokenization.
- Vaswani et al. (2017). Attention Is All You Need. NeurIPS. — The transformer architecture behind every modern LLM.
- Hinton, Vinyals & Dean (2015). Distilling the Knowledge in a Neural Network. — Softmax temperature.
- Holtzman et al. (2020). The Curious Case of Neural Text Degeneration. ICLR. — How sampling choices shape generated text.
- Allal et al. (2025). SmolLM2: When Smol Goes Big. — The 135M-parameter model in the Scale Up section.
- Grattafiori et al. (2024). The Llama 3 Herd of Models. — Source for the 405B-scale comparison numbers.
- Mikolov et al. (2013). Efficient Estimation of Word Representations in Vector Space and Linguistic Regularities in Continuous Space Word Representations. — word2vec embeddings and the "king − man + woman ≈ queen" arithmetic.
- Ouyang et al. (2022). Training language models to follow instructions with human feedback. — RLHF, the stage-two recipe behind assistants.
- Kaplan et al. (2020). Scaling Laws for Neural Language Models · Hoffmann et al. (2022). Training Compute-Optimal Large Language Models. — Why bigger predictably works, and how much data it wants.
Keep learning (interactive)
- Neural Networks: Zero to Hero - Andrej Karpathy's free video course; makemore builds this page's exact model in Python.
- LLM Visualization - Brendan Bycroft's 3D walkthrough of a real GPT's internals.
- Transformer Explainer - live attention visualization of GPT-2 running in your browser.
- The Illustrated Transformer - Jay Alammar's classic visual essay.
- TensorFlow Playground - poke at a tiny neural network's decision boundaries.