Tokenization · Byte-pair encoding
Subword Tokenization
A learned subword vocabulary balances sequence length against vocabulary size while still giving the model a way to represent words it hasn't seen.
Evidence & limits
- What the further reading establishes
- Subword representations improve open-vocabulary neural translation, especially for rare words.
- What this lab runs
- You'll run the full BPE training and encoding algorithm on a fixed corpus and see every merge it learns.
- What it does not prove
- The toy trainer leaves out word-boundary markers, and its compression numbers don't measure translation quality.
Dataset
Morphology Set
- Source
- Course-authored synthetic corpus
- License
- Not separately licensed
- Size
- 6 lines · 24 words · fixed
Further reading
- Neural Machine Translation of Rare Words with Subword Units
Primary · Rico Sennrich · Barry Haddow · Alexandra Birch · 2016
Shows how byte-pair encoding handles rare and unseen words in neural sequence models.
- SentencePiece
Paper · Taku Kudo · John Richardson · 2018
Trains subword models straight from raw sentences, without language-specific tokenization rules.
- SentencePiece reference implementation
Implementation · Google · Current
Provides production-ready BPE and unigram tokenization with reproducible model files.
Lesson progressRestoring progress…
- CodeRestoring
- ExperimentRestoring
- CheckRestoring
Summary
Pick the right-sized pieces. A word vocabulary maps every unseen word to one unknown id. A character vocabulary can spell any word made from known base symbols, but even common words become long sequences. Subword tokenization lands in the middle, so the language model predicts reusable pieces instead of whole words or single characters.
How BPE trains. BPE starts each training word as a list of symbols: signaling becomes [s, i, g, n, a, l, i, n, g]. It counts every neighboring pair, picks the most common one, replaces every non-overlapping match, and then counts again. You have to recount because each merge creates new possible pairs.
Keep pairs distinct. A pair is two separate symbols, not just the spelling you get when you join them. If you made keys with plain string concatenation, [a, bc] and [ab, c] would both turn into abc. The code uses JSON array keys like ["s","i"] so those pairs stay separate and are easy to see while debugging.
Replay merges in order. What BPE learns is an ordered list of merges. To encode new text, start with the same base symbols and try each learned merge once in its training order. For abc, applying [a,b] before [ab,c] produces [abc]. Reverse the order, and you're left with [ab,c].
- 1Training words
s · i · g · n | s · i · g · n · a · l - 2Round 1 counts
[s,i]: 2 [i,g]: 2 [n,a]: 1 → select [s,i] - 3Merge 1
[s,i] → si then recount the modified words - 4Round 2 counts
[si,g]: 2 → next candidate
[a,b] → [ab,c]a · b · c → ab · c → abcReversed order[ab,c] → [a,b]a · b · c → a · b · c → ab · cThe system-wide tradeoff. A bigger merge budget usually makes encoded sequences shorter, but it also makes the model's embedding and output matrices larger. Tokenizer design changes context use, parameter count, serving cost, and the exact token ids the trained model expects. It's part of the model contract, not just a harmless preprocessing step.
Knowledge check
Implementation
Count the possible merges across the tokenized vocabulary.
- Signature
def count_pairs(words):- Inputs
- words list[list[str]]; one symbol list per vocabulary item
- Returns
- dict[str, int] keyed by JSON pairs
- Rule
slide over every adjacent pair and add one to its shared count- Example
[["s","i","g"], ["s","i"]] → {"[\"s\",\"i\"]": 2, …}
Reference solution
Approach Count the possible merges across the tokenized vocabulary.
import json def count_pairs(words): counts = {} for symbols in words: for index in range(len(symbols) - 1): pair = json.dumps( [symbols[index], symbols[index + 1]], separators=(",", ":"), ) counts[pair] = counts.get(pair, 0) + 1 return countsBuild the tokenizer in three separate Python cells. Pair counts use a visible key that can't confuse symbol boundaries: json.dumps(["s", "i"], separators=(",", ":")) returns the string ["s","i"]. The merge and encoder cells get each pair as a two-item list.
Saved results
Results created after your saved code passes its checks
Saved results
Results created after your saved code passes its checks
The replay is course data. The validation result is tied to the code you saved and checked.
Loading…