Concepts / Token IDs and the Vocabulary

Token IDs and the Vocabulary

Token IDs are zero-based row indices. The first row is row 0, so token ID 3 retrieves the fourth row, not the third.

  • 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…

From Words to Integers

Before a model learns anything, every token in a text has already been reduced to an integer. That integer is the token ID. It tells the model which entry of its vocabulary the token corresponds to, but on its own it carries no information about meaning. A token ID is only a label, the way a seat number tells you where a passenger sits without describing the passenger.

A neural network cannot do much with a bare label, so an embedding layer converts each token ID into a vector of numbers. The question this article answers is how that conversion happens. The short answer is that the layer does not perform a complicated calculation. It looks up a row. The rest of the article explains what that means, why the lookup returns exactly the vector you expect, and how it connects to a different way of writing the same operation.

Predict the Returned Row

Consider a small embedding matrix with five rows, one for each vocabulary entry. The rows are numbered 0 through 4. Suppose the token ID you pass in is 3. Before reading on, decide which row you think comes back, and whether the layer computes anything new to produce it.

What do you think happens?

Given token ID 3 and the five-row matrix described in the example below, which row does the embedding layer return?

  • Row 0, the first row

  • Row 2, the third row

  • Row 3, the fourth row

  • Row 4, the fifth row

  • A new vector computed from all five rows

Reveal answer
Answer:

Row 3, the fourth row, returned exactly as stored.

Token IDs are zero-based row indices, so token ID 3 retrieves the fourth row. The returned vector is not a fresh calculation. It is identical to the stored row, which is why the lookup gives an exact match rather than an approximation.

The Vocabulary as a Row Index

Definition

The embedding layer is a lookup operation: a token ID selects a row of the weight matrix by position. The token ID is used as a position, the layer moves to that position in the weight matrix, and it reads the row found there.

The weight matrix of an embedding layer has one row per vocabulary entry and one column per embedding dimension. Each token in the vocabulary therefore owns exactly one row. When the layer receives a token ID, it does not inspect the other rows for this lookup. It reads only the row whose position matches the ID.

Row 0the: 0.2, -0.5, 0.1Row 1cat: 0.7, 0.3, -0.2Row 2sat: -0.4, 0.8, 0.6Row 3on: 0.9, -0.1, 0.4Row 4mat: 0.0, 0.5, -0.7next positionnext positionnext positionnext position
Which exact row is pulled out for token ID 3, and how do the row positions line up with the token IDs?

The diagram shows a five-token vocabulary in which each row is labeled with its token and its three embedding values. Token ID 3 is the token 'on', and it selects the highlighted row at position 3. The values are illustrative numbers chosen for this example, not values from a trained model.

Key point

Token IDs are zero-based row indices. The first row is row 0, so token ID 3 retrieves the fourth row, not the third.

Tracing Token ID 3 Through the Matrix

Worked example

Looking up token ID 3 and verifying the result

The vocabulary is ['the', 'cat', 'sat', 'on', 'mat'] with token IDs 0 through 4. The embedding matrix has the rows shown in the earlier diagram. The layer receives token ID 3. What vector should it return, and how do you confirm the result?

  1. 1
    Identify the token

    Counting from zero, token ID 0 is 'the', 1 is 'cat', 2 is 'sat', 3 is 'on', and 4 is 'mat'. Token ID 3 therefore refers to 'on'.

  2. 2
    Convert the ID to a row position

    Because token IDs are zero-based row indices, the ID 3 is used directly as the row position. The row to read is the fourth row, which is the row at position 3.

  3. 3
    Read the stored row

    The fourth row of the matrix holds the values 0.9, -0.1, and 0.4. The layer copies this row as the output vector.

  4. 4
    Verify the match

    Compare the returned vector with the matrix entry at position 3. The values are identical, element by element. A match confirms that the lookup used the right index.

Result

The embedding layer returns [0.9, -0.1, 0.4]. This is exactly the fourth row of the matrix, not an approximation of it.

The verification step is the most useful habit to build. Because the returned vector is a copy of a stored row, you can check any embedding output against the matrix. If the values differ, the problem lies in the index that was used, not in some hidden calculation.

Mistakes With Zero-Based Rows

  • Common mistake

    Treating the first row as row 1

    What it looks like

    Reading token ID 3 as the third row because the rows seem to start at 1.

    Why it fails

    Token IDs are zero-based row indices. Token ID 0 maps to the first row, so token ID 3 maps to the fourth row.

    Do this instead

    Count rows from 0. Position 3 is the fourth row in the matrix.

  • Common mistake

    Expecting the output to be newly computed

    What it looks like

    Assuming the layer calculates a fresh vector each time token ID 3 appears.

    Why it fails

    The returned vector is identical to the stored row. The layer copies that row rather than approximating it.

    Do this instead

    Compare the output directly with the matching row of the matrix.

  • Common mistake

    Assuming the token ID carries meaning

    What it looks like

    Believing that token ID 3 is numerically close to token ID 2 because the numbers are close.

    Why it fails

    A token ID is only a label that identifies a vocabulary entry. Adjacent IDs do not imply related meanings.

    Do this instead

    Treat the ID as a position. The learned meaning, if any, lives in the values of the row.

  • Common mistake

    Mixing up the vocabulary size with the number of embedding dimensions

Lookup Versus One-Hot Multiplication

Readers who know one-hot encoding may recognize the lookup as a shortcut. One-hot encoding represents a token ID as a vector whose length equals the vocabulary size. That vector holds a single 1 at the position of the token and 0 everywhere else. The one-hot vector is then multiplied by a weight matrix in a fully connected layer.

For the five-token vocabulary, the one-hot vector for token ID 3 has a 1 in position 3 and zeros in the other four positions. Written as a row vector, it is multiplied by the matrix as follows.

Formula

Here $\mathbf{x}$ is the one-hot vector, $W$ is the weight matrix, and $W_{3,:}$ is the row at index 3. Each entry of the product is a sum of terms, and every term except one is multiplied by zero. Only the term that multiplies the 1 survives, so the product reproduces the row at index 3. This is the same row the embedding layer would have returned directly.

One-hot vector0, 0, 0, 1, 0Token ID 3used as a positionMultiply by matrixfive rows summed, fourzeroedRead row 3only one row touchedRow 3 vector0.9, -0.1, 0.4Row 3 vector0.9, -0.1, 0.4matrix productresultindex readresult
How does multiplying a one-hot vector by the matrix give the same result as reading the row at the token ID, and where does the extra work go?

The two paths produce the same output. The one-hot path does extra work: it builds a vector of vocabulary length, multiplies it against every row, and adds up terms that are mostly zero. The lookup path skips all of that and reads one row. This is why the source describes the embedding layer as the more efficient implementation of the same operation.

Locating Where a Lookup Goes Wrong

When an embedding output does not match what you expected, follow the path from token string to token ID to matrix row to returned vector. The mismatch appears at exactly one step, and checking each step in order will find it. The returned vector is a copy of a stored row, so a wrong output almost always means the wrong row was read.

Token string 'on'Token ID 3Row index 3Fourth row returnedRow index 4 usedFifth row returnedvocabulary lookupzero-based positionmatches stored rowoff-by-one errorwrong row
At which step in the path from token string to returned vector does the output stop matching the expected row?
Debugging

Suppose the output for 'on' is [0.0, 0.5, -0.7] instead of [0.9, -0.1, 0.4]. The token string and the token ID are both correct, since 'on' is ID 3. The output matches the fifth row, which is row 4. The error therefore sits in the step that converts the ID to a row position: an off-by-one index was applied, so the lookup moved one position too far. Fixing that index restores the expected vector.

This procedure works because each step has a checkable output. You can confirm the token ID against the vocabulary, the position against the zero-based count, and the returned values against the matrix row. The step where the check fails is the step that diverges.

Check Your Lookup

EASY

Using the five-token vocabulary ['the', 'cat', 'sat', 'on', 'mat'] and the matrix rows 0 through 4 from the earlier diagram, a learner gets the vector [0.7, 0.3, -0.2] for the token 'cat'. Is this correct? If not, identify the row that should have been returned and explain which step went wrong.

Hints
  • Find the token ID for 'cat' by counting from zero.
  • Compare the returned vector with each row of the matrix, not only the one you expect.
  • Check whether the error is in the token-to-ID step or the ID-to-row step.

Key Takeaways

  • The embedding layer is a lookup: a token ID is used as a zero-based position, and the layer returns the row of the weight matrix found there.
  • The returned vector is an exact copy of a stored row, so you can verify any embedding output by comparing it with the matching matrix row.
  • Looking up a row gives the same result as multiplying a one-hot vector by the weight matrix, but the lookup avoids the extra computation over mostly zero terms.
  • When an output is unexpected, check the token-to-ID step, the ID-to-row step, and the returned values in that order to find where the path diverges.

Related concepts

More concepts starting with T