cutaway ↖ LINCHPIN · AI Innovation Lab
Lesson 1 · How It Reads

It never sees letters.
Only numbers.

Before a model can learn a single thing, it has to turn your text into numbers, because numbers are all it can do math on. This is step one, and it shapes everything after it. You are about to watch your own words become the exact numbers this model reads.

Step 1 · Make a guess first

How does it hold onto your text?

Type a line below. Before you turn it into numbers, make a call: when this model takes in "hi there," how does it actually store it?

As the words themselves As one number per letter As a single number for the whole line

The line to turn into numbers (change it to anything you like):

Step 3 · There is more than one way to do this

Tiny vocabulary, or short text. Pick one.

This model takes the simplest path: one number per character, a vocabulary of just 65. That keeps the vocabulary tiny but makes every line long. The big models do it differently. They chop text into common chunks ("sub-words"), which keeps each line short but needs a vocabulary of around 50,000. Same job, opposite trade.

Real models group characters into tokens, short chunks; cutaway uses single characters so you can watch every step. Here is the same line, chopped both ways:

cutaway · one character at a time
Shakespearewrote
17 characters · vocabulary of 65
real models (GPT, Claude) · subword tokens
Shakespeare wrote
roughly 3 tokens · vocabulary near 50,000
Two ways to tokenize: character-level, used by nanoGPT, with a vocabulary of 65 and very long sequences; versus sub-word, used by OpenAI, with a vocabulary near 50,000 and short sequences. A balance scale weighs vocabulary size against sequence length.
Character-level (this model) vs. sub-word (GPT-class models): vocabulary size traded against text length.
See the real code, line by line
Tokenization From: data.py
Why it mattersIt is the bridge from human text to the numbers the model does all its math on. Nothing else can happen until this does.
Key conceptBuild a fixed table that maps every character to a number and back, then translate any text through it.
What to look for"stoi" turns characters into numbers; "itos" turns them back. Encoding and decoding are just those two tables, used in each direction.
def __init__(self, text):
chars = sorted(set(text))
self.vocab_size = len(chars)
self.stoi = {c: i for i, c in enumerate(chars)} # char → id
self.itos = {i: c for i, c in enumerate(chars)} # id → char
def encode(self, s):
return [self.stoi[c] for c in s]
def decode(self, IDs):
return "".join(self.itos[i] for i in IDs)
Hover or tap any line above. Its plain-English explanation appears right here.