Exercises — Tokenization fundamentals
Two symbols we reuse everywhere, defined once in plain words:
Level 1 — Recognition
Exercise 1.1
Classify each unit as character, subword, or word token: "ing", "cat", "?", "un", "z".
Recall Solution
"ing"— subword (a suffix, not a standalone word)"cat"— word (a complete word)"?"— character (a single symbol)"un"— subword (a prefix)"z"— character (a single letter)
Why: a character is one symbol; a word stands alone with meaning; a subword is a meaningful chunk smaller than a word (prefix/suffix/stem fragment).
Exercise 1.2
The pipeline is . Name stages and , and say which one produces integers.
Recall Solution
- = Normalization + Pre-tokenization + Token Splitting (cleaning then splitting into token strings).
- = Numericalization — the dictionary lookup that turns token strings into integer IDs.
- Integers come from . Everything before is still text.
Level 2 — Application
Exercise 2.1
A sentence has 8 words and tokenizes into 11 tokens. Compute the fertility.
Recall Solution
Fertility is tokens per word: This sits inside the typical BPE range of –, so the tokenizer is behaving normally.
Exercise 2.2
A new document has 200 tokens, of which 3 are <unk> (unknown). Compute the coverage. Is it above the threshold?
Recall Solution
Known tokens . , so coverage is below the healthy threshold — too many unknowns, hinting the vocabulary is a poor fit for this document.
Exercise 2.3
A GPT-2-style vocabulary contains these entries:
"<pad>" : 0
"<unk>" : 1
"Hello" : 15496
"," : 11
"Ġworld" : 995
"!" : 50256
(The Ġ marks "a space came before this token".) Encode the text "Hello, world!" into token IDs, then decode those IDs back to the original string.
Recall Solution
Encode. Pre-tokenize with the space marker Ġ:
Look each token up in the vocabulary above:
Decode. Reverse-lookup each ID, concatenate, then swap every Ġ for a space:
The Ġ is what makes decoding reversible — it remembers the space belonged before world.
(Note: the parent note used a shortened toy ID list [15496, 11, 995, 0] where ! was written as 0. That 0 clashes with <pad>, so here ! gets its own distinct ID 50256 — every token needs a unique integer.)
Level 3 — Analysis

Exercise 3.1
Corpus (already split to characters; ␣ is a word-boundary marker — it sits between words and is never merged across):
l o w (×3)
l o w e r (×2)
n e w e s t (×2)
w i d e s t (×1)
Count these adjacent pairs across the whole corpus weighted by word frequency: l o, o w, e s, s t. Which merges first? Also explain why a pair like w ␣ or ␣ l is never counted.
Recall Solution
Multiply each in-word pair by that word's count:
l o: inlow(×3) +lower(×2)o w: inlow(×3) +lower(×2)e s: innewest(×2) +widest(×1)s t: innewest(×2) +widest(×1)
l o and o w tie at 5 (the maximum). BPE breaks ties by a fixed rule (e.g. first seen); the parent note merges l o first. Either choice is valid as long as it is deterministic.
Why pairs across ␣ are excluded: the space marker ␣ fences off each word. BPE only merges pairs inside a single word, so cross-boundary pairs like w ␣ (end of low) or ␣ l (start of next low) are never candidates. Why do this? If merges could cross word boundaries, the tokenizer would glue the end of one word to the start of the next (e.g. low + lower → a wl token), producing tokens that depend on random word order and never generalise. Fencing with ␣ keeps every learned token a genuine within-word chunk (prefix/stem/suffix).
Exercise 3.2
Continuing from Ex 3.1: after merging l o→lo, then lo w→low, what is the count of the pair e s now, and after merging it to es, what is the count of es t?
Recall Solution
Merging lo and low only touches the low… words — it does not change any e s or s t counts. So:
Merge e s→es. Now count es t:
newest→n e w es t: onees t, ×2 = 2widest→w i d es t: onees t, ×1 = 1 Soestbecomes a shared suffix for bothnewestandwidest. This is the whole point of BPE — the suffixestemerges purely from frequency and is now reusable.
Exercise 3.3
After the 4 merges (lo, low, es, est), how many entries has BPE added to the starting character vocabulary, and how does the vocabulary size change per merge?
Recall Solution
First, a notation we use here: let = the ==vocabulary after merges==, and = its size. So is the starting character vocabulary (zero merges done), after one merge, and so on.
Each merge adds exactly one new token, so:
After 4 merges that is tokens. If the character vocab started at (the set {l,o,w,e,r,n,s,t,i,d,␣}), then:
Level 4 — Synthesis
Exercise 4.1
Word-level model: corpus vocabulary is English words but you cap at , dropping the rarest to <unk>. Subword BPE instead reaches coverage with the same tokens. Explain in one causal chain why BPE avoids the OOV problem that word-level suffers, referencing the merge mechanics.
Recall Solution
Causal chain:
- Word-level treats each word as atomic → a rare word not in the top has no token → becomes
<unk>→ information lost. - BPE keeps all characters (or bytes) as base tokens in , and only adds merges on top.
- Therefore any string can always be spelled out from those base units, even one never seen in training (
"COVID-19"→C o v i d - 1 9or partial merges). - Result: no out-of-vocabulary word exists — the worst case is more tokens, never a missing one.
Trade-off: rare words get long token sequences (higher fertility), but they are never dropped.
Exercise 4.2
You must choose a vocabulary size. Character-level () gives average sequence length tokens per document; word-level () gives but <unk>. Transformer cost scales as in sequence length . For character vs word, compute the relative attention cost ratio and state the design tension.
Recall Solution
Squared (attention is quadratic in length):
Character-level costs about 31× more attention compute per document. But word-level pays with <unk> (lost meaning). Tension: shrink for speed (favours words) vs keep coverage high (favours characters). BPE sits in the middle — moderate , coverage — which is why it wins. See sequence length and the $O(n^2)$ attention.
Level 5 — Mastery
Exercise 5.1
Design task. You tokenize a -word test document. Two candidate tokenizers:
- A: fertility , coverage
- B: fertility , coverage
(a) How many tokens does each produce? (b) If attention cost , what is B's cost relative to A? (c) Which do you ship if the deployment is latency-bound but must keep coverage ? Justify.
Recall Solution
(a) Tokens = fertility × words: (b) Cost ratio: B costs about A's attention compute. (c) Both clear the coverage bar ( and ). Since it is latency-bound, pick the cheaper one → A. B's extra coverage buys almost nothing but costs more compute. Choose A.
Exercise 5.2
Two-language stress test. A multilingual tokenizer trained mostly on English has English fertility and, on an unseen script, fertility . If both documents have words, compute each token count and the fertility ratio. What real phenomenon does this expose?
Recall Solution
Fertility ratio: The under-represented script is shredded into more than 2× as many tokens per word — its words fall back toward characters/bytes because few merges cover it. This is the multilingual fairness / cost gap: the same content costs more tokens (hence more money and more sequence length) in low-resource languages. See multilingual tokenization.
Recall Quick self-test (cloze)
How to read this: the ::: marks a hidden answer — cover everything to the right of :::, recall it, then check.
Fertility is defined as ::: tokens divided by words.
Coverage must stay above ::: 99.5%.
Each BPE merge changes vocabulary size by ::: exactly +1.
Attention cost scales with sequence length (the number of tokens in the sequence) as ::: .
BPE avoids OOV because ::: characters/bytes remain in the base vocabulary, so any string can always be spelled out.
Related: 4.2.02-BPE-algorithm · 4.2.03-WordPiece-and-SentencePiece · 4.1.05-Vocabulary-and-OV · 4.3.01-Word-embedings