Token Embeddings and Positional Information
Tokenization converts input text into token IDs, using the tiktoken tokenizer and its encode method.
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
- Standardize: lowercase and delete punctuation.
- Split on whitespace into tokens.
- Build the vocabulary: 0 = padding, 1 = [UNK], then words by frequency (ties: first appearance), capped at max tokens.
- Map each token to its id (1 if it did not make the vocabulary), then pad with 0 or truncate to the sequence length.
- 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.
Loading the simulation…
Why a Language Model Needs Numbers
A GPT model cannot read a sentence 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 the article is organized around that separation.
What do you think happens?
Before reading on: if you tokenize two texts, each of which produces four token IDs, and stack them into one batch, what shape do you expect the batch to have?
Reveal answer
2 by 4, meaning two rows (one per text) and four token IDs per row.
Each text contributes one row, and each row holds the four token IDs of that text. The batch therefore has two rows and four columns.
Tracing the Program Line by Line
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. As you read, keep track of what each variable holds after each line runs. The two moments that matter most are the moment a list of integers becomes a tensor, and the moment two tensors become one.
- 1Start with a plain Python string holding the first input text.
- 2Call tokenizer.encode on that string. The result is an ordered list of integers, one per token.
- 3Wrap that list of integers in a tensor. This is the first moment the data stops being a plain Python list.
- 4Append the tensor to a Python list named batch.
- 5Repeat the same steps for the second text, so that batch now holds two one-dimensional tensors.
- 6Call torch.stack with dim set to 0. This joins the two one-dimensional tensors into one two-dimensional tensor, the second moment the data changes shape.
What tokenizer.encode Returns
A token ID is an integer that stands for one token in the vocabulary of the tokenizer. Tokenization is the process of converting input text into token IDs using the tiktoken tokenizer and its encode method.
- txt holds a plain Python string, which is the only kind of input encode accepts here.
tokenizer.encode(txt)takes that single string and returns a sequence of integers.- The printed result is a list of whole numbers, not a string and not a vector.
The output of encode is therefore neither a string nor 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. Order matters: the first integer corresponds to the first token of the text, and so on. This is why you can later connect each output back to its original input.
Building a Batch of Two Texts
Tensors are the containers the model works with. Once each text has its own list of token IDs, each list is wrapped in a tensor. The two one-dimensional tensors are then appended to a Python list named batch. Finally, torch.stack with dim set to 0 joins them into one two-dimensional tensor. Dimension 0 is the batch dimension, so each text occupies exactly one row of the result.
Predicting the batch shape
Two texts are each tokenized into four token IDs. What is the shape of the batch tensor, and which row belongs to which text?
- 1Count the texts
There are two texts, so the batch has two rows. Dimension 0 counts texts.
- 2Count the tokens per text
Each text produces four token IDs, so each row has four entries. Dimension 1 counts tokens per text.
- 3Assign rows to inputs
The first row comes from the first text and the second row from the second text. Keeping this order lets you trace any output back to its input.
- 4Write the shape
The shape is $2 \times 4$: two texts by four tokens per text.
The batch tensor has shape $2 \times 4$, with the first row for the first text and the second row for the second text.
From Token IDs to Token Embeddings
Token IDs are single integers, but the model needs a richer description of each token. The second stage converts each integer into a token embedding, which is a numerical vector. In the smallest GPT-2 model, token embeddings are typically 768-dimensional. That means each token is represented not by one number but by a vector of 768 numbers.
The embedding step expands each single integer into a long vector. The source figure shows only the first two dimensions of such a vector for readability, but the important structural point is the expansion itself. Each ID is a single number going in and a 768-number vector coming out, so the model's input becomes a richer numerical description of each token. In the diagram above, each integer chooses one vector, which is why a sequence of IDs becomes a sequence of vectors in the same order.
Where the Embedding Step Sits in 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.
The model returns one output vector for each input token embedding, so the number of input tokens matches the number of output tokens. Because of this one-to-one correspondence, the first token, Every, does not appear 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.
Finding Where a Wrong Result Starts
When the final output looks wrong, the pipeline gives you a sequence of checkpoints. Each one can be inspected in order, and the first checkpoint whose contents differ from what you expected is where the problem begins. Because the stages are separate, you do not have to guess whether the fault lies in the text, the IDs, the embeddings, or the model.
Suppose the final output is wrong. Inspect the checkpoints in order. First, print the input string and confirm it is the text you intended. Second, print the list returned by encode and confirm it has one integer per token in the right order. Third, check the batch shape. If the IDs are correct but the embedding vectors seem wrong, the fault is in the embedding step, not in tokenization. If the IDs themselves look wrong for the text you supplied, go back to the encode call and its input string.
Mistakes Beginners Make with the Two Stages
Common mistake Treating token IDs as if they were embeddings
What it looks likeAssuming that the integer returned by encode already describes the meaning of a token.
Why it failsA token ID is one integer that only identifies a token in the vocabulary. The embedding stage is what expands it into a vector of numbers.
Do this insteadKeep the two stages separate: text becomes IDs, then IDs become embeddings.
Common mistake Expecting encode to return a string or a vector
What it looks likePrinting the result of encode and expecting readable text or a row of floats.
Why it failsThe output of encode is an ordered list of whole numbers, one per token.
Do this insteadRead the result as a list of integers and check that its length matches the token count.
Common mistake Reading the batch rows in the wrong order
What it looks likeSwapping the two rows of the stacked tensor when connecting outputs back to inputs.
Why it failsEach row corresponds to one text, in the order the texts were appended to batch.
Do this insteadKeep track of which text was appended first, and map row 0 back to it.
Common mistake Expecting the first input token to appear in the output
What it looks likeLooking for the word Every among the model's output for the input sentence.
Why it failsThe model returns one output vector per input token, and the continuation it generates follows from the given sequence rather than repeating the first token.
Do this insteadInterpret the output as the model's continuation, not as a copy of the input.
Practice: Predict Before You Run
Three texts are tokenized. The first produces four token IDs, the second produces four token IDs, and the third produces four token IDs. They are stacked with torch.stack along dim 0. Predict the shape of the resulting batch, and state which row holds the third text. Then describe the first checkpoint at which you would look if the final output seemed wrong.
Hints
- Dimension 0 counts texts, so count how many tensors were stacked.
- Dimension 1 counts token IDs per text, which the prompt gives directly.
- Rows are ordered by the order in which the tensors were appended to the batch list.
Explain, in your own words and without naming any specific model size, why an embedded batch carries more information per token than the raw batch of IDs.
Hints
- Compare what one integer carries with what one embedding vector carries.
- The source describes the embedding as a vector of numbers, not a single number.
Key Takeaways
- Tokenization turns input text into token IDs: an ordered list of integers, one per token, produced by the tokenizer.encode call of the tiktoken tokenizer.
- Each text is tokenized separately, wrapped in a tensor, and joined with torch.stack along dim 0, so two texts with four token IDs each form a $2 \times 4$ batch with one row per text.
- Token embeddings are the second stage: each integer ID selects a vector, typically 768-dimensional for the smallest GPT-2 model, and the model returns one output vector per input token.
- When output is wrong, inspect the checkpoints in order (text, IDs, batch, embeddings, model) and treat the first mismatch as the point where the problem begins.