Learning LabExplorable explanations
← All artifacts
Transformers

Inside an LLM

A real trained GPT, small enough to read, runs in your browser: watch a prompt become matrix math become the next character. Then corrupt a weight and see for yourself that the model is just a file of numbers.

transformersinferenceweightssamplingllm
LiveInteractive · drag, toggle, run it
Transformers

Inside an LLM

Every time you prompt a language model, a file of frozen numbers gets multiplied against your text until one more token falls out. No database of answers or any hidden reasoning module. Nothing learns while you chat. That claim is easy to repeat and strangely hard to believe, so this page ships an actual trained transformer, all 29,600 weights of it, and runs it in front of you. Type a prompt, step through the machine, read the numbers in flight, then break a weight and watch the consequences. It is the same kind of machine as the frontier models, shrunk a millionfold.

The model in front of you. A 2-block GPT with 32-dimensional vectors and a 65-character vocabulary, trained for 8,000 steps on Shakespeare's plays, then quantized to one byte per weight and pasted into this page's source code as a base64 string. Its output is toddler Shakespeare at best; quality is not the point. Its forward pass, the function that maps context to next-token scores, matches the PyTorch original to about four decimal places, so the machinery you are poking is real.
prompt
6 characters encoded. The corpus is Elizabethan drama, so speaker names and stage cues play to its strengths.
the machine
append the sampled char, run the whole thing againtokensOMEO:chars → idsembedid → vectorblock 1attention + MLPblock 2attention + MLPfinal normrescalelogits65 raw scoressoftmaxscores → probssample100%pick one char
Step through one forward pass, or run the loop and watch text accumulate. Click any stage to open its real numbers.
output0 generated · window sees last 6
ROMEO:

The only dice in the building

Everything left of the sampler is deterministic arithmetic. Whether the output varies between runs is decided entirely here, by one knob and one seed.

Applied at the softmax stage above, nowhere else. The logits never see it. In greedy mode it is ignored entirely.

Same weights, same prompt, same sampler settings: the output cannot differ, because nothing else in the pipeline has anywhere to hide state. When a hosted model gives you two different answers to one prompt, you are seeing the sampler's dice (plus some floating-point scheduling noise on parallel hardware), not a change of mind.

The model is a file

29,600
parameters
28
tensors
28.9 kB
int8 payload
40.8 kB
embedded blob
weights checksum 4c57de68 · recomputed this render, unchanged after 0 generated tokens

The weights are a const array baked in at build time. Generating ten tokens or ten thousand never writes a single byte back: the checksum above is recomputed from the live arrays on every render and only moves if you deliberately damage them below. Training, the process that does edit these numbers, finished before this page was built. When a vendor says a model "learned" something new, they shipped a different file.

Break the weights

If the constants are the model, damaging them should damage the behavior, on cue and reproducibly. Pick a tensor and find out.

The degradation is itself deterministic: greedy decoding over the damaged file gives the same broken text every time, because the text was never anywhere except in those numbers. Zeroing an embedding table usually lobotomizes it outright; noising one attention projection produces something eerier, a model that still spells but loses the plot. Restore puts the original constants back, and the checksum above returns to its old value.

Now scale it

modelparamsblocksvector dimcontextvocab
this page29.6 k23264 chars65
GPT-2 small (2019)124 M127681,02450,257
Llama 3 70B (2024)70 B808,1928,192+128,256

Every row is the same diagram you stepped through above: embed, attend, MLP, repeat, norm, score, sample, append. Frontier models differ by stacking the block forty times deeper, widening every vector a few hundredfold, and training on a few trillion times more text. More of the same machine, plus engineering to make it fast (the KV cache from the block inspector being the first such trick). Nothing in the loop changes kind on the way up.

go deeper, stage by stage
2-layer GPT, d=32, trained on tiny shakespeare · int8 weights decoded in your browser · forward pass parity-checked against the PyTorch original