Navigation
📐 Foundations· 10 min read

Tokenization & Vocabulary

BPE, SentencePiece, tiktoken — how text becomes numbers, and why tokenization choices affect model quality, cost, and serving.

tokenizationbpesentencepiecetiktokenvocabularyembedding

Before any computation happens, text must be converted to numbers. Tokenization is the first and last step of every LLM pipeline — and its design choices ripple through the entire infrastructure stack.


1. What Is a Token?

A token is the atomic unit of text that the model processes. It’s not a word, not a character, but something in between:

"Tokenization is fun!" → ["Token", "ization", " is", " fun", "!"]
                          [  1234,     5678,   890,   2345,  33]
GranularityExampleVocabulary sizeSequence length
Characters['T','o','k','e','n','i','z','a','t','i','o','n']~100Very long
Words['Tokenization', 'is', 'fun']~100K+Short
Subwords['Token', 'ization', ' is', ' fun', '!']~32K-128KBalanced

Modern LLMs use subword tokenization — common words are single tokens, rare words are split into pieces. This balances vocabulary size against sequence length.


2. Byte Pair Encoding (BPE)

The dominant tokenization algorithm. BPE iteratively merges the most frequent pair of tokens:

Training

  1. Start with individual characters (or bytes) as tokens
  2. Count all adjacent token pairs in the corpus
  3. Merge the most frequent pair into a new token
  4. Repeat until vocabulary reaches target size
Corpus: "low lower lowest"

Step 0: ['l','o','w',' ','l','o','w','e','r',' ','l','o','w','e','s','t']
Step 1: Merge ('l','o') → 'lo':  ['lo','w',' ','lo','w','e','r',' ','lo','w','e','s','t']
Step 2: Merge ('lo','w') → 'low': ['low',' ','low','e','r',' ','low','e','s','t']
Step 3: Merge ('low','e') → 'lowe': ['lowe',' ','lowe','r',' ','lowe','s','t']
...

Encoding (Inference)

Apply the learned merge rules greedily to new text. The same text always produces the same tokens (deterministic).

Byte-Level BPE (GPT-2+)

Start from individual bytes (256 base tokens) instead of characters. This guarantees any text in any language can be tokenized — no “unknown token” problem.


3. Tokenizer Implementations

TokenizerUsed byVocabularyKey feature
SentencePieceLLaMA, Qwen, Mistral~32KLanguage-agnostic, treats text as bytes, no pre-tokenization
tiktokenGPT-3.5/4, Claude~100KFast (Rust), regex-based pre-tokenization for better splits
HuggingFace TokenizersMany open modelsVariesPython library wrapping multiple algorithms

tiktoken vs SentencePiece

The main difference is pre-tokenization: tiktoken uses regex patterns to split text into coarse chunks before BPE, resulting in more natural token boundaries (e.g., never merging across word boundaries). SentencePiece treats the raw byte stream directly.


4. Token Embedding

After tokenization, each token ID is mapped to a dense vector via the embedding table:

E∈RV×d\mathbf{E} \in \mathbb{R}^{V \times d}

Token ID ii → row E[i]\mathbf{E}[i], a dd-dimensional vector.

embedding = nn.Embedding(vocab_size, d_model)
x = embedding(token_ids)  # (B, S) → (B, S, d_model)

Memory cost: V×d×bytesV \times d \times \text{bytes}. For V=128K,d=4096V=128K, d=4096 in FP16: 128K×4096×2=1128K \times 4096 \times 2 = 1 GB.

Weight Tying

Many models tie the embedding and LM head weights — the same (V,d)(V, d) matrix is used for both input embedding and output projection. This saves memory (−1-1 GB for the example above) with minimal quality loss.


Special Tokens and Chat Templates

Beyond regular text tokens, LLMs use special tokens for control:

TokenPurposeExample
<BOS> / <s>Beginning of sequenceMarks sequence start
<EOS> / </s>End of sequenceSignals generation should stop
<PAD>PaddingFills shorter sequences in a batch
<UNK>Unknown tokenRare with byte-level BPE

Chat templates structure multi-turn conversations with role markers. Different models use different formats (ChatML, Llama-style, Mistral-style). The serving infrastructure must apply the correct template for each model — wrong templates produce garbled output.

Stopping criteria: Generation stops when the model outputs <EOS>, reaches max_tokens, or matches a stop string (e.g., "\nUser:" for chat). The serving engine must check all conditions after each token.


5. Infrastructure Impact

Token Count = Cost

LLM APIs charge per token. Efficient tokenization directly reduces cost:

  • GPT-4 tokenizer: “Tokenization” = 1 token
  • Poor tokenizer: “Token” + “ization” = 2 tokens

More efficient tokenization → shorter sequences → lower compute cost.

Vocabulary Size Tradeoffs

Larger vocabularySmaller vocabulary
✅ Shorter sequences (fewer tokens per text)✅ Smaller embedding table
✅ Better representation of rare words✅ Less memory
❌ Larger embedding table (V×dV \times d)❌ Longer sequences
❌ Sparser training signal per token❌ More compute per text

Sweet spot: 32K–128K tokens. LLaMA uses 32K, GPT-4 uses ~100K, Qwen-2.5 uses 152K.

Multilingual Considerations

Tokenizers trained primarily on English data may produce 2-3× more tokens for Chinese, Japanese, or Korean text — directly increasing cost and latency for non-English users. Modern tokenizers (Qwen, GPT-4) use larger vocabularies with better multilingual coverage.

Serving

Tokenization runs on CPU (not GPU) and happens before and after inference. For high-throughput serving:

  • Pre-tokenize inputs in parallel (tokenization is CPU-bound)
  • Use fast tokenizer implementations (tiktoken, HuggingFace’s Rust-based tokenizers)
  • Cache tokenized prompts for repeated system prompts

Self-Check

  • Explain BPE: how it trains and how it encodes new text
  • Explain the difference between SentencePiece and tiktoken
  • Calculate the memory cost of an embedding table for a given V and d
  • Explain weight tying and its memory savings
  • Explain why tokenizer efficiency affects serving cost
  • Explain why multilingual tokenization matters for infrastructure

References