Concepts / Tokenizing Text Using Byte Pair Encoding

Tokenizing Text Using Byte Pair Encoding

Tokenization converts input text into token IDs, using the tiktoken tokenizer and its encode method.

  • Programming
Interactive lab

Try it: Text Vectorization: Tokens to Vectors

The text-to-tensor pipeline: standardize, split into tokens, build a frequency-ranked vocabulary with padding and [UNK], map tokens to integer ids, pad or truncate, then one-hot or multi-hot encode and look the ids up in an embedding table.

How it works

  1. Standardize: lowercase and delete punctuation.
  2. Split on whitespace into tokens.
  3. Build the vocabulary: 0 = padding, 1 = [UNK], then words by frequency (ties: first appearance), capped at max tokens.
  4. Map each token to its id (1 if it did not make the vocabulary), then pad with 0 or truncate to the sequence length.
  5. Encode: one-hot rows per position or one multi-hot row per text; embed: id k selects row k of the embedding table.

Default run (18 steps): Raw text (59 characters): "The movie was great. The plot was great, the acting wasn't!". A model cannot read strings, so it is turned into numbers step by step. … Embedding lookup: id k selects row k of a fixed 8 x 3 table, giving a (8, 3) dense matrix instead of (8, 8) sparse one-hots. Row 0 (padding) is looked up too; a trained Embedding layer would learn these rows.

Simplified: Bounded ASCII text (up to 200 characters, 40 tokens), whitespace splitting only, and a small FIXED embedding table (a real Embedding layer learns its rows). The multi-hot vector keeps the padding slot (always 0) so its positions line up with the ids.

Educational simulation

Loading the simulation…

Why a Model Cannot Read Sentences

A GPT model cannot read the sentence Every effort moves you the way a person does. Its internal arithmetic operates on numbers, so every piece of text must be converted into numbers before the model sees it. This article follows that conversion for two short input texts, from the moment a string enters the pipeline to the moment the model receives a numerical input it can process.

The journey has two stages that are easy to blur together. The first stage turns text into token IDs, which are integers. The second stage turns those integers into numerical vectors called token embeddings. Keeping these two stages separate in your head is the most useful habit for debugging the pipeline, and the rest of this article is organized around that separation.

Tracing a Two-Text Batch

The program for this lesson builds a batch from two text inputs. It tokenizes each text with the tiktoken tokenizer, converts each result to a tensor, and stacks the tensors into a single batch. Before reading the explanation, trace the program from its first line to its last and keep track of what each variable holds after each line runs. Pay particular attention to the moment a list of integers becomes a tensor, and the moment two tensors become one.

What do you think happens?

Two texts each produce a list of four token IDs. After they are stacked into one batch, what is the shape of the resulting tensor?

  • 4 x 2

  • 2 x 4

  • 8

  • 2 x 4 x 768

Reveal answer
Answer:

2 x 4

Each text contributes one row of four token IDs, so the batch has two rows and four columns. In tensor shape notation this is $2 \times 4$, where the first number counts texts and the second counts tokens per text. The 2 x 4 x 768 option describes what happens later, after the embedding step, and is not the shape of the stacked token IDs.

Text 1 IDsfour token IDsRow 0first textBatch tensor2 x 4Text 2 IDsfour token IDsRow 1second textwrapped in tensorwrapped in tensortorch.stack, dim 0torch.stack, dim 0
When two texts each produce four token IDs, each text occupies one row of the stacked tensor, so the batch has two rows and four columns.

Each text is tokenized separately, and each resulting list of IDs is wrapped in a tensor. The two tensors are appended to a Python list named batch. The final step, torch.stack with dim set to 0, joins the two one-dimensional tensors into a single two-dimensional tensor. Dimension 0 is the batch dimension, so each text occupies one row of the result. The source output for this batch is a tensor with two rows of four token IDs each, which is the $2 \times 4$ shape. The first row corresponds to the first text and the second row to the second text, so reading the rows in the right order is what lets you connect each output back to its original input.

From Text to Token IDs

The call tokenizer.encode(txt) takes a single string and returns a sequence of integers. Each integer is a token ID that stands for one token in the vocabulary of the tokenizer. The output is therefore not a string and not a vector. It is an ordered list of whole numbers, with one number per token, in the same order as the tokens appear in the text.

Key point

Tokenization stops at integers. Nothing in the encode step produces vectors. If your output is a list of whole numbers, the tokenization stage has done its job, and any problem with vectors lies further down the pipeline.

Token IDs Become Embeddings

The second stage takes each integer token ID and selects a numerical vector for it. Token embeddings are typically 768-dimensional for the smallest GPT-2 model, which means each token is represented not by one number but by a vector of 768 numbers. The source figure for this step shows only the first two dimensions of such a vector for readability. The structural point is that the embedding step expands each single integer into a long vector, so the model's input becomes a richer numerical description of each token.

Token IDone integerRow 0768 valuesEmbedding vector768 numbersRow 1768 valuesRow 2768 valuesselects rowbecomes
A single integer token ID picks one row of the embedding table, and that row is the token's embedding vector. A list of IDs therefore becomes a list of vectors, one per token.

Following One Input Through the Model

The whole route for a single input runs in a fixed order. Text is tokenized into IDs, the IDs are converted into embeddings, the embeddings are fed into the GPT model, and the model returns output vectors that are postprocessed into output text. In the example the goal is to generate the next word, which is forward.

Input texta stringToken IDstokenizer.encodeToken embeddings768 numbers per tokenGPT modelone output vector per inputOutput vectorspostprocessedOutput textnext wordtokenizeembedfeed inreturnspostprocess
Raw text passes through tokenization, then embedding, then the GPT model, and finally postprocessing into output text. Each arrow marks a checkpoint where the output can be inspected.

Notice that the number of input tokens matches the number of output tokens. For this reason, the first token, Every, is not contained in the output. The model produces one output vector for each input position, and the continuation it is asked to generate follows from the sequence it was given. So if you count the tokens going in and find them unchanged coming out, that is expected behavior, not a sign of a fault.

In earlier code the token embedding was handled inside the GPT model itself. In a large language model, the embedded input dimension typically matches the output dimension, and the output embeddings represent the context vectors discussed in chapter 3. This means the model returns one output vector for each input token embedding.

Mistakes When Locating a Fault

  • Common mistake

    Treating the token IDs and the token embeddings as the same stage

    Why it fails

    The encode call returns integers, while the embedding step returns vectors of many numbers. If you blur them together, you cannot tell which stage produced a wrong value.

    Do this instead

    Inspect the IDs first. If they are correct integers for your text, the problem lies in the embedding step or later.

  • Common mistake

    Expecting the batch to have one row per token

    Why it fails

    Each text is tokenized separately and becomes one row. The number of rows counts texts, and the number of columns counts tokens per text.

    Do this instead

    For two texts of four tokens each, expect a $2 \times 4$ tensor, with the first row for the first text.

  • Common mistake

    Assuming the first input token must appear in the output

    Why it fails

    The model returns one output vector per input position, and the output is a continuation rather than a copy of the input.

    Do this instead

    Check the output counts and the generated continuation instead of looking for the input's first token.

  • Common mistake

    Guessing where a fault begins instead of checking in order

    Why it fails

    Guessing wastes time, and the fault may be upstream of where you are looking.

    Do this instead

    Inspect each checkpoint in order and stop at the first one whose contents differ from what you expected.

Locating the First Wrong Checkpoint

MEDIUM

A learner tokenizes two texts, each producing four token IDs, and stacks them into a batch. The token IDs look like valid integers for the text supplied. The final model output looks wrong. Which checkpoint should you check first, and why? Name the stage and say what its correct output looks like.

Hints
  • Work through the chain in order: text, token IDs, embeddings, model output, output text.
  • The source says that if the IDs are correct but the vectors seem wrong, the problem is in the embedding step.
  • Earlier checkpoints that look correct let you rule out the stages before them.

What do you think happens?

Before you look at the final output, what should the batch of two texts look like after the embedding step, assuming each token ID becomes a 768-dimensional vector?

Reveal answer
Answer:

2 x 4 x 768

The batch keeps its two rows and four token positions, and each position now holds a 768-number vector. This is a derived shape from the source's description of embeddings, so use it as a checkpoint to compare against rather than a value the source printed.

Key Takeaways

  • Tokenization turns a string into an ordered list of integer token IDs using tokenizer.encode, one ID per token.
  • Stacking two tokenized texts with torch.stack along dimension 0 gives one row per text, so two texts of four tokens each form a $2 \times 4$ tensor.
  • Token embeddings expand each integer into a vector, typically 768-dimensional for the smallest GPT-2 model, and the model returns one output vector per input token.
  • When output looks wrong, check the chain in order (text, token IDs, embeddings, model output, output text) and stop at the first checkpoint that differs from what you expected.

Related concepts

More concepts starting with T