Byte Pair Encoding Tokenizer
Train a real BPE tokenizer in your browser. Start from single characters, repeatedly merge the most frequent adjacent pair, and watch a subword vocabulary build itself from the data.
Train a real BPE tokenizer in your browser. Start from single characters, repeatedly merge the most frequent adjacent pair, and watch a subword vocabulary build itself from the data.
BPE lands in between: frequent words turn single tokens, rare words split into meaningful pieces, and nothing is ever out-of-vocabulary. The algorithm starts with the character-level vocabulary (plus a special end-of-word marker) and iteratively merges the most frequent next pair into a new token. Each merge reduces the total sequence length by the number of instances of that pair. After a fixed number of merges (the vocabulary size minus the initial character set), the vocabulary is complete. GPT-2 uses 50,257 tokens; GPT-4 uses around 100,000. A larger vocabulary means shorter sequences (fewer tokens per sentence, so faster inference and a longer effective context window) but a larger embedding table. The merge order is the tokenizer — at inference time, it applies the same merges in the same rank to any new text, greedily splitting unknown words into the longest known pieces. This page runs BPE step by step on a sample corpus, shows the merge table growing after each iteration, and covers the vocabulary-size tradeoff that decides how many merges to perform.
Train a real BPE tokenizer in your browser.
Before a language model sees a single word, a tokenizer must turn text into integers. Byte Pair Encoding is the algorithm most modern LLMs use, and it solves a problem that both word-level and character-level tokenizers get badly wrong.
BPE lands in between: frequent words turn single tokens, rare words split into meaningful pieces, and nothing is ever out-of-vocabulary. The algorithm starts with the character-level vocabulary (plus a special end-of-word marker) and iteratively merges the most frequent next pair into a new token. Each merge reduces the total sequence length by the number of instances of that pair. After a fixed number of merges (the vocabulary size minus the initial character set), the vocabulary is complete. GPT-2 uses 50,257 tokens; GPT-4 uses around 100,000. A larger vocabulary means shorter sequences (fewer tokens per sentence, so faster inference and a longer effective context window) but a larger embedding table. The merge order is the tokenizer — at inference time, it applies the same merges in the same rank to any new text, greedily splitting unknown words into the longest known pieces. This page runs BPE step by step on a sample corpus, shows the merge table growing after each iteration, and covers the vocabulary-size tradeoff that decides how many merges to perform.
That is the whole method. Vocabulary size is simply base characters plus the number of merges — which is why it is an exact dial. Rather than a thing you discover after the fact.
The merge list is ordered, and that order matters at encoding time. To tokenize a new word you replay the merges from rank 1 downward, applying each wherever it fits. The "How it got there" panel shows this replay step by step. The word starts as loose characters and step by step fuses.
Notice that the earliest merges are almost always very common fragments (e+s, t+h). While later merges assemble whole frequent words. The vocabulary discovers morphology — prefixes, suffixes, stems — without ever being told that such things exist.
Byte-pair encoding starts from single characters and repeatedly merges the most frequent next pair, recording each merge as a new vocabulary entry.
Worked through on a tiny corpus — the words "low", "lower", "newest", "widest", with the counts they appear:
l o w e r n s t i de + s → merge into eses + t → estl + o → lolo + w → lowContinue until the vocabulary reaches the target size — 30,000 or 100,000 entries in practice. The merges are recorded in order, and applying them in that same order is how new text is tokenised.
The outcome is a vocabulary that spends its budget where the text really is. Frequent words turn single tokens; rare words remain as fragments; and. This is because the single characters (or bytes) are always in the vocabulary, nothing is ever unrepresentable.
That last property is why the <UNK> token has in effect disappeared from modern models.
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("gpt2")
tok.tokenize("tokenization") # ['token', 'ization']
tok.tokenize("Tokenization") # ['Token', 'ization'] -- case matters
tok.tokenize("antidisestablishmentarianism")
# ['ant', 'id', 'ises', 't', 'ablish', 'ment', 'arian', 'ism']
tok.tokenize(" hello") # ['Ġhello'] -- Ġ marks a leading spaceThree observations from those lines.
Common words are single tokens. Long or rare ones fragment into pieces that were frequent in the training corpus.
Leading spaces are part of the token. GPT-style tokenisers treat " hello" and "hello" as other tokens. This is why a prompt ending in a space can change the output clearly.
Case matters. "Token" and "token" are other entries, so capitalisation consumes vocabulary and affects tokenisation.
Plain BPE over characters has a gap: a character never seen in training cannot be shown. With Unicode's 149,000+ code points, that gap is real.
Byte-level BPE runs on UTF-8 bytes rather than characters. There are only 256 doable bytes, all of which are in the base vocabulary. So any text in any script — plus emoji, plus binary noise — is representable.
The cost is speed for non-Latin scripts. A Chinese character is three UTF-8 bytes, so it costs at least one token and often more; the same sentence in Chinese and in English can differ severalfold in token count.
| Text | Approximate tokens |
|---|---|
| English prose | ~1.3 per word |
| Code | ~2 per word, more with symbols |
| Chinese / Japanese | ~1 per character |
| Cyrillic, Arabic | ~2–3 per word |
| Emoji | 1–4 each |
That table is a real cost and latency gap when calling an API. And it is why multilingual models often use larger vocabularies to compensate.
BPE starts from single characters and repeatedly merges whichever next pair is commonest, until the vocabulary is the size you asked for. This trains one on a small corpus, tokenises with it, and shows why token counts are the thing that really costs you money.
Building on the same setup, the next block shows the left cases.
The below block covers the left steps.
The next block goes on with the left demonstrations.
Building on the same setup, the next block shows the left cases.
The below block covers the left steps.
BPE is a compression algorithm repurposed as a vocabulary builder. Merge what is frequent, leave the rest in pieces. This lab runs the genuine training loop on any corpus you paste in. The merge table you see is the actual product of counting pairs, not a stored case. Real tokenizers add byte-level fallbacks and pre-tokenization rules, but the core loop is just this.
| Algorithm | Merge criterion | Used by |
|---|---|---|
| BPE | Most frequent adjacent pair | GPT-2, GPT-3, Llama |
| WordPiece | Pair that most increases corpus likelihood | BERT, DistilBERT |
| Unigram | Start large, prune the least useful tokens | T5, XLNet, mBART |
| SentencePiece | A wrapper implementing BPE or Unigram on raw text | T5, Llama, many multilingual models |
WordPiece differs from BPE only in the merge rule:. Rather than raw count, it picks the merge that most improves the likelihood of the corpus under a unigram model. In practice the vocabularies are close. It marks continuations with ## — "token", "##ization".
Unigram works backwards: begin with a large candidate vocabulary and iteratively remove the tokens whose loss hurts least. It can give a few valid segmentations of the same word with chances. This enables subword regularisation during training.
SentencePiece is worth grasp as a other kind of thing — not an algorithm but an implementation that treats input as a raw byte stream with no pre-tokenisation on whitespace. That matters for languages that do not separate words with spaces. And it makes detokenisation just reversible.
A few well-known model behaviours trace right back to this step.
Poor spelling and character counting. "strawberry" may be two or three tokens, none of which is a letter. Asking how many r's it holds asks the model to reason about a thing it cannot see.
Inconsistent arithmetic. "1234" might be one token or a few depending on the tokeniser and the nearby text. So digits are not always shown. Some newer models tokenise digits one by one to improve this.
Context limits in tokens, not words. A 128,000-token window is roughly 96,000 English words, and far fewer for code or other scripts.
Response to trailing spaces. Because the space is part of the token, a prompt ending with a space tokenises else from one that does not.
The tokeniser must ship with the model. Token id 1,547 means one thing in one vocabulary and a thing else in one more. A mismatch gives fluent nonsense rather than an error.
How large should the vocabulary be? 30,000–50,000 for a single language; 100,000–250,000 for multilingual models. Larger means shorter sequences and a bigger embedding table.
Can I train my own tokeniser? Yes, with tokenizers or SentencePiece. Worth it for a specialised domain or language. And it means the model must be trained or much adapted with it.
Why does my word split oddly? Because those fragments were the frequent merges in the training corpus. It looks arbitrary and is fully determined by corpus stats.
Is BPE reversible? Yes — concatenating the tokens reconstructs the first text just. This is why byte-level variants are careful about spaces.
Do I need to lowercase first? No, for a cased tokeniser. It was trained on cased text and lowercasing loses data.
How do I count tokens before an API call? With the model's own tokeniser — tiktoken for OpenAI models, the transformers tokeniser if not. Estimating from word count is unreliable.
Say the answer out loud before you reveal it — recalling it is what makes it stick, and rereading it is not.
What does this module say about “The Two Failure Modes It Avoids”?
What does this module say about “The Algorithm, in Four Lines”?
What does this module say about “Merge Order Is the Model”?
Merge the most frequent character pair, repeat, and build the subword vocabulary GPT-style models use to tokenise any text.