Tokens and embeddings
From strings to integers to vectors
Chapter 5 of 21 · I. Foundations · about 30 minutes. Builds on: 4. Probability, softmax and next-token prediction.
Neural networks need numbers, not text
Section titled “Neural networks need numbers, not text”The network of Chapters 2–3 maps vectors to vectors. To use it on text you must first turn a string into a sequence of integers (tokenization) and then each integer into a vector (embedding).
Why not characters or words?
Section titled “Why not characters or words?”- Characters or bytes give a tiny vocabulary and no unknown inputs, but sequences become very long, and attention cost grows with the square of length.
- Whole words give short sequences, but the vocabulary is huge and open: names, typos, code, new words, other languages. Anything outside the list is “unknown”.
- Subwords sit between: frequent words are single tokens, rare words are split into familiar pieces, and any string can be represented. All current language models use some form of subword tokens.
Byte-pair encoding
Section titled “Byte-pair encoding”BPE was adapted to neural translation by . The training algorithm is short:
- Start with every word split into characters, with an end-of-word marker.
- Count how often each adjacent pair of symbols occurs across the corpus.
- Merge the most frequent pair into a new symbol, in every place it occurs.
- Repeat until the vocabulary reaches the desired size. The ordered list of merges is the tokenizer.
To encode new text, split it into characters and apply the merges in the order they were learned. Run it yourself, and watch frequent substrings such as “est” become single tokens:
Byte-level BPE starts from the 256 possible bytes instead of characters, so any text in any language, including emoji and binary data, can be encoded with no unknown tokens. SentencePiece is a widely used toolkit that treats text as a raw stream (spaces included) so no language-specific pre-splitting is needed.
Vocabulary size is a design choice
Section titled “Vocabulary size is a design choice”Larger vocabularies shorten sequences (fewer tokens per document) but increase the embedding and output matrices and give each rare token fewer training examples. Recent open models use between about 100K and 250K tokens: for example, Llama 3 has a 128K-token vocabulary (128,000 in the paper’s hyperparameter table, 128,256 entries in the released checkpoints) , gpt-oss uses a 201,088-token byte-pair tokenizer (o200k_harmony) , and DeepSeek-V3 has 129,280. The same sentence costs different numbers of tokens in different languages, which affects cost and context budget.
Special tokens and chat formats
Section titled “Special tokens and chat formats”Besides ordinary text pieces, the vocabulary contains reserved tokens for structure: start and end of text, and for chat models, markers for who is speaking. A conversation is flattened to one token sequence such as [system] … [user] … [assistant]. gpt-oss uses the “harmony” format, with roles system, developer, user, assistant and tool in a priority order, and separate channels for the model’s reasoning, tool calls and final answer . The model is trained to follow that format, but the format is only a convention in the token stream.
From token id to vector: embeddings
Section titled “From token id to vector: embeddings”An embedding table is a matrix with one row per vocabulary entry and columns. The vector for token is row . Equivalently, writing the token as a one-hot vector , the embedding is , a matrix product. is learned by gradient descent like any other weight; its size is (for example million parameters in Llama 3 8B).
Early work showed that such learned vectors place related words near each other and encode regularities as directions . In a transformer the embedding is only the starting point: layers will rewrite it using context, so the same token ends up with different vectors in different sentences.
At the output, the final vector is multiplied by another matrix to produce logits (the unembedding). Some models tie it to to save parameters; Llama 3, gpt-oss and DeepSeek-V3 keep them separate, so the vocabulary costs parameters.
Check yourself
Section titled “Check yourself”Run three merges by hand on "low low lower": which pair is merged first?
With end markers, the corpus is l o w _, l o w _, l o w e r _. The pair (l, o) occurs 3 times, (o, w) 3 times, (w, _) 2 times. Ties are broken by implementation; merging (l, o) → “lo”, then (lo, w) → “low”, then (low, ) → “low” gives a single token for the frequent word.
Why can byte-level BPE never produce an unknown token?
Every string is a sequence of bytes, and all 256 byte values are in the base vocabulary.
How many parameters are in a 201,088 × 2,880 embedding matrix?
million. gpt-oss has an input table and a separate output matrix, so about 1.16 billion in total.
Papers
Section titled “Papers”- BPE for neural models.
- SentencePiece.
- Learned word vectors and their geometry.
- Sections 2.3 and 2.5: tokenizer and harmony chat format.