› 01 · Embeddings › Token Embeddings
⚡ Visual Simulator
AI Journey · Understand Language

Token Embeddings

See how a token ID becomes a learned vector: the lookup that turns identifiers into numbers a transformer can compute with.

🔴 MUST 15 study phases Embeddings
🧙‍♂️ The Wise Scholar's Metaphor From Call Number to the Book
⏮️ 00 · Math & Foundations Hub →

Token Embeddings: The Book Behind the Call Number

A token ID is a library call number: it only tells you where to look. The embedding is the book you bring back — a long list of learned numbers. The transformer reads those books together to work out how each word is being used in the sentence.

01

IntroductionWhat is a token embedding?

Six-step diagram of how a question becomes vectors, paired with a librarian analogy
Your question → tokens → embedding lookup → input matrix → Transformer → next token, shown next to a librarian analogy. Click to open full size. Numbers are illustrative.
🤔 Layman Curiosity Hook

"Once my sentence has been turned into token IDs, does the AI finally know what I said?"

Not yet. After tokenization the model holds a list of integers — barcodes. It still has to turn each barcode into a vector before a transformer can compute anything with it.

💡 This is how it happens: the integer 3797 is only a name. The model uses it as a row number, reads that row of a big learned table, and gets back a list of numbers such as [0.21, -0.43, 0.87, …]. That list is the token embedding — the first thing the transformer can actually compute with.

A token embedding is the learned vector that a model assigns to one entry of its vocabulary. The model reads it from the embedding matrix by using the token ID as a row index.

STEP 1 Text "The cat is sleeping" STEP 2 Tokenization [464, 3797, 318, 10447] ← token IDs (illustrative) STEP 3 Embedding lookup 4 vectors, one per ID ← [0.21, -0.43, 0.87, ...] STEP 4 Transformer attention + other computation ← contextual representations Illustrative IDs: real IDs depend on the tokenizer.
Text→ Token IDs (integers)→ Embedding lookup→ Vectors (floats)→ Transformer

💡 Tokenization gives identifiers; embedding gives vectors. Token IDs tell the model which token it is looking at. Embeddings are what the transformer can meaningfully process.

02

WhyWhy can't the transformer work directly with token IDs?

A token ID is just an integer used to identify a token in the model's vocabulary. For example (illustrative IDs):

  • cat → token ID 3797
  • dog → token ID 8531

The numbers themselves don't inherently express meaning. The ID for dog being larger than the ID for cat does not mean a dog is more important, bigger, or more similar to a cat. The numbering follows the order in which the vocabulary was built — nothing more.

What goes wrong with raw IDs

  • Arithmetic on IDs has no meaning: 8531 − 3797 = 4734 describes nothing about cats or dogs.
  • A linear layer would treat ID 8531 as "bigger" than ID 3797, inventing a false ordering.
  • Nearby IDs are not related words; related words can have far-apart IDs.

What the transformer needs

  • Numbers that can take part in meaningful maths: dot products, sums, projections.
  • A geometry in which "similar" tokens can end up close together.
  • Values that training can adjust with gradients.
Insight: That is exactly what embeddings provide. Each token ID is used to look up a learned vector in an embedding matrix, and the vectors live in a space where distance and direction can carry meaning.
03

IntuitionFrom call number to the book itself

The Token IDs page used a library analogy: an ID is a call number. This page continues it.

  • Tokenization hands the model a slip of paper with call numbers: [464, 3797, 318, 10447].
  • Embedding lookup is the trip to the shelf. The call number is only used to find the right spot; what comes back is the book — a long learned vector.
  • The transformer is the scholar who reads those books together and works out how each one is being used in this particular sentence.
Call number (ID) → where to look (no meaning in the number) Embedding vector → what was learned there (meaning lives here) 3797 → E[3797] = [ 0.21, -0.43, 0.87, ... ] "cat" 8531 → E[8531] = [ 0.25, -0.40, 0.80, ... ] "dog" ← similar vector, far-apart ID 318 → E[318] = [ 0.05, 0.02, -0.04, ... ] "is" ← closer ID to "cat", unrelated vector

Two tables, one ID

A token ID works like a row ID. The same number is used as the key into two different tables. (Small IDs below are illustrative.)

Table 1 — Vocabulary (tokenizer)

Token IDToken
0the
1cat
2dog
3bank
4river

Maps token ↔ ID. Text the cat becomes [0, 1].

Table 2 — Embedding matrix E (model)

RowVector (illustrative)
0[ 0.2, 0.5, −0.1, …]
1[ 0.8, −0.3, 0.4, …]
2[−0.2, 0.7, 0.1, …]
3[ 0.1, 0.6, −0.5, …]
4[ 0.0, 0.4, −0.6, …]

Maps ID → learned vector. ID 1 selects row 1: the vector for cat.

Text "the cat"→ Token IDs [0, 1]→ Rows E[0], E[1]→ Vectors→ Transformer
  • The vocabulary is a dictionary-like mapping ("cat" → 1), usually a hash map, and often supports ID → token as well.
  • The embedding matrix is not a dictionary. It is a dense array indexed by position, E[1]. It stores no token strings.
  • They are aligned only by the shared number. Row i of E belongs to token i because training used that alignment. Change the tokenizer and every ID points at the wrong row.
  • Row count vs vocabulary size: usually one row per vocabulary entry, though some models pad E with extra rows.

Does a token ID contain the vector numbers?

No. The ID only says which row to read. Take token ID 1 (cat) from the tables above, with a 4-number row (illustrative values):

Token ID 1 ← identifies the row for "cat" Embedding row E[1] = [ 0.80, −0.30, 0.40, 0.15 ] ← these four numbers are the vector for "cat"

The ID 1 is not the vector [0.80, −0.30, 0.40, 0.15]. It is the address used to retrieve it.

Where do the vector numbers come from?

  • Start: the embedding values are typically initialized with a numerical initialization scheme, so at first they carry no useful meaning.
  • Training: the model adjusts them through optimization and backpropagation (see phase 04).
  • Result: over time the values become useful for the model's language-processing task. A real LLM stores hundreds or thousands of numbers per token.

Remember: token ID = which row?  Vector = the learned numbers stored in that row.

💡 The ID is the key; the vector is the content. Think of a token ID as a database row index, not as the meaning of the word.

💡 Critical mental model: before the lookup the model "knows" nothing about the words. After the lookup it holds learned numbers. After the transformer layers it holds numbers that also reflect the surrounding words.

04

TheoryWhat does the model know at each stage?

It is tempting to say "the model learns the meaning at the embedding step". That is not quite right. The embedding step only reads parameters that were already learned during training.

StageWhat existsWhat it can express
After tokenizationDiscrete token IDsIdentifies tokens. The integers themselves carry no usable numeric geometry.
After embeddingOne learned vector per tokenA numeric representation the transformer can process. It is the same vector for a token wherever it appears.
After transformer layersContext-updated vectorsHow each word is being used in this sentence (see Contextual Embeddings).

Where the knowledge actually lives

  • The embedding matrix and the transformer weights were established during training.
  • At inference the model uses those fixed parameters to process your input. It does not suddenly acquire knowledge at the embedding stage.
  • The embedding matrix typically starts with random values and is adjusted by backpropagation until related tokens end up with useful vectors.
One-line summary: Text → Token IDs → Embedding vectors → Transformer computations → Contextual representations.
05

How It WorksThe four-step pipeline, with a lookup in the middle

Follow "The cat is sleeping" through the pipeline:

Step 1
Text. The cat is sleeping
Step 2
Tokenization. The tokenizer splits the text and maps each piece to an integer: [464, 3797, 318, 10447]. Illustrative IDs; actual IDs depend on the tokenizer.
Step 3
Embedding lookup. Each ID retrieves one row of the embedding matrix. Four IDs give four vectors, for example [0.21, -0.43, 0.87, ...] for cat.
Step 4
Transformer. Attention and other computations turn these vectors into contextual representations.
graph LR
    A["Text: The cat is sleeping"] --> B["Token IDs: 464, 3797, 318, 10447"]
    B -->|"row lookup in E"| C["4 vectors, each D numbers"]
    C --> D["Transformer layers"]
    D --> E["Contextual representations"]

    style A fill:#3b82f6,stroke:#1d4ed8,color:#fff
    style B fill:#10b981,stroke:#047857,color:#fff
    style C fill:#8b5cf6,stroke:#6d28d9,color:#fff
    style E fill:#f59e0b,stroke:#b45309,color:#fff
    
Fig 1. The lookup is the bridge between the discrete world (IDs) and the continuous world (vectors).
06

CalculateManual lookup with a tiny 4-dimensional matrix

Real models use hundreds or thousands of dimensions. Here we use 4 so every number fits on the page. The vectors are invented for teaching; they are not from a trained model.

Step 1
Embedding matrix rows we need (indexed by ID):
E[464]  = [ 0.10, −0.05, 0.02, 0.30]  "The"
E[3797] = [ 0.21, −0.43, 0.87, 0.15]  "cat"
E[318]  = [ 0.05, 0.02, −0.04, 0.22]  "is"
E[10447]= [−0.30, 0.55, 0.40, −0.10]  "sleeping"
E[8531] = [ 0.25, −0.40, 0.80, 0.10]  "dog"
Step 2
Look up the sentence: IDs [464, 3797, 318, 10447] select four rows, producing a 4 × 4 matrix (sequence length × embedding dimension).
Step 3
Compare IDs: |3797 − 8531| = 4734 and |3797 − 318| = 3479. By ID distance, "cat" looks closer to "is" than to "dog".
Step 4
Compare vectors with cosine similarity:
cos(cat, dog) = 0.997  — nearly the same direction
cos(cat, is) = 0.000  — unrelated direction
Lesson: the ID distances point the wrong way. The relationship between "cat" and "dog" is visible only in the vectors.

What does "dimension" mean?

Dimension is how many numbers are inside one token's vector. Using cat from Step 1 (illustrative values):

Token ID 3797 → E[3797] = [ 0.21, −0.43, 0.87, 0.15 ] dim 1 dim 2 dim 3 dim 4 4 numbers = a 4-dimensional vector

Each dimension is one position in the vector. Together the numbers form the token's learned numerical representation. Language has many patterns and relationships, and a single number would give the model very little capacity to represent them.

A human analogy

Describing a person

  • Height: 175 cm
  • Age: 30 years
  • Weight: 70 kg
  • Shoe size: 9

[175, 30, 70, 9] → 4 measurements = 4 dimensions.

Describing the token "cat"

  • Dim 1: 0.21
  • Dim 2: −0.43
  • Dim 3: 0.87
  • Dim 4: 0.15

[0.21, −0.43, 0.87, 0.15] → 4 learned numbers = 4 dimensions.

  • Person → the thing being represented (here: the token).
  • Measurements → the individual dimensions.
  • List of measurements → the vector.
  • Number of measurements → the dimensionality.
Where the analogy stops: height and age are human-readable. Embedding dimensions usually are not. Dimension 1 does not necessarily mean "animal-ness" and dimension 2 does not necessarily mean "size"; information is distributed across the whole learned vector, and the values are learned in training rather than assigned by hand.

How big are vectors in real models?

Example embedding dimensionNumbers per token
4 (this page's toy example)4
128128
768768
4,0964,096
12,28812,288

These are example sizes; actual models vary. With 4,096-dimensional embeddings, each token ID retrieves a vector of 4,096 numbers. For a matrix with 50,000 tokens and 4,096 dimensions, the shape is 50,000 × 4,096: 50,000 rows, each containing 4,096 numbers.

A more detailed person description can capture more detail, and likewise more dimensions can represent more. But more dimensions alone do not guarantee a better model; architecture, training and the learned parameters matter too.

07

MathematicsThe lookup as row selection

Let $V$ be the vocabulary size and $D$ the embedding dimension. The embedding matrix is

$$\mathbf{E} \in \mathbb{R}^{V \times D}$$

For a token ID $i$, its embedding is row $i$:

$$\mathbf{e}_i = \mathbf{E}[i, :] \in \mathbb{R}^{D}$$

For a sequence of $L$ token IDs, the transformer receives:

$$\mathbf{X} = \mathbf{E}[[i_1, \ldots, i_L]] \in \mathbb{R}^{L \times D}$$

Same thing as a one-hot matrix product

If $\mathbf{o}_i \in \{0,1\}^{V}$ is the one-hot vector with a 1 at position $i$, then

$$\mathbf{o}_i^{\top}\,\mathbf{E} = \mathbf{E}[i, :]$$

So the lookup is mathematically a matrix product, but frameworks implement it as direct row indexing because multiplying by a mostly-zero vector would waste work.

Size

GPT-2 small : V = 50,257, D = 768 → 50,257 × 768 = 38,597,376 parameters BERT-base : V = 30,522, D = 768 → 30,522 × 768 = 23,440,896 parameters
Training: the entries of $\mathbf{E}$ are ordinary learned parameters. Only the rows of tokens present in a batch receive gradient, which is why rarely seen tokens end up with less-trained vectors.
08

VisualizeDiagram and live ID-vs-vector comparison

Pick any two words. The lab compares what the IDs say with what the vectors say, using the toy 4-dimensional matrix from the Calculate phase.

🗄️ Live Lab: ID gap vs cosine similarity
09

CodeEmbedding lookup from scratch, then PyTorch

Part A — pure Python:

Python — Toy embedding lookup
import math

vocab = {"The": 464, "cat": 3797, "is": 318, "sleeping": 10447, "dog": 8531}  # illustrative IDs

E = {   # toy 4-d "embedding matrix", keyed by token ID
    464:   [ 0.10, -0.05,  0.02,  0.30],
    3797:  [ 0.21, -0.43,  0.87,  0.15],
    318:   [ 0.05,  0.02, -0.04,  0.22],
    10447: [-0.30,  0.55,  0.40, -0.10],
    8531:  [ 0.25, -0.40,  0.80,  0.10],
}

def cosine(a, b):
    dot = sum(x * y for x, y in zip(a, b))
    return dot / (math.sqrt(sum(x * x for x in a)) * math.sqrt(sum(y * y for y in b)))

ids = [vocab[w] for w in ["The", "cat", "is", "sleeping"]]
print(ids)                       # [464, 3797, 318, 10447]

vectors = [E[i] for i in ids]    # the embedding lookup
print(vectors[1])                # [0.21, -0.43, 0.87, 0.15]

print(abs(vocab["cat"] - vocab["dog"]))            # 4734  (ID gap)
print(abs(vocab["cat"] - vocab["is"]))             # 3479  (ID gap)
print(round(cosine(E[3797], E[8531]), 3))          # 0.997 (cat vs dog)
print(round(cosine(E[3797], E[318]), 3))           # 0.0   (cat vs is)

Part B — PyTorch nn.Embedding:

Python — PyTorch
import torch
import torch.nn as nn

emb = nn.Embedding(num_embeddings=50257, embedding_dim=768)   # E has shape [50257, 768]

ids = torch.tensor([[464, 3797, 318, 10447]])   # shape [batch=1, seq_len=4]
x = emb(ids)                                     # row lookup: weight[ids]
print(x.shape)                                   # torch.Size([1, 4, 768])

print(emb.weight.requires_grad)                  # True  -> the rows are learned parameters
print(emb.weight.numel())                        # 38597376
Note: a freshly created nn.Embedding holds random numbers. The useful geometry appears only after training (or by loading a trained model's weights).
10

ExperimentProbe a real model's embedding matrix

Try these with a real tokenizer and model (for example gpt2 from HuggingFace):

11

CompareToken ID vs one-hot vs embedding vs contextual vector

PropertyToken IDOne-hotToken embeddingContextual vector
TypeIntegerSparse vector, length VDense vector, length DDense vector, length D
Learned?No (fixed by vocabulary)NoYes (rows of E)Yes (produced by learned layers)
Depends on neighbours?NoNoNoYes
Similar tokens close together?NoNo (all equally far apart)Can be, after trainingYes, and context-aware
Where it appearsTokenizer outputConceptual / math viewTransformer inputEvery layer after the first
12

ApplyWhere token embeddings show up in real models

  • First layer of every language model: an integer tensor [B, L] becomes a float tensor [B, L, D].
  • Position is added separately. The lookup says nothing about word order; models add positional information (for example GPT-2 adds learned position embeddings) before the first transformer layer.
  • Weight tying: many models, including GPT-2, reuse the input embedding matrix as the output projection that scores the next token.
  • Vocabulary changes: when you add tokens during fine-tuning, you must resize the embedding matrix (for example model.resize_token_embeddings(len(tokenizer))) so each new ID has a row.
  • Memory: for small models the embedding matrix can be a large share of all parameters.
13

LimitationsCommon mistakes and traps

Trap 1 — "The embedding step is where the model learns meaning." No. Meaning was learned during training and is stored in the weights. The embedding step reads one slice of them.
Trap 2 — "One token, one meaning." A token embedding is the same vector wherever the token appears. bank gets one input vector whether it means a river bank or a financial bank. Disambiguation happens in the transformer layers.
Trap 3 — IDs and matrices must match. An ID only means something with the tokenizer and embedding matrix it was created for. Swapping either breaks the model.
Trap 4 — Illustrative IDs. The IDs on this page (464, 3797, …) are for teaching. Look up real IDs with your own tokenizer.

Mistakes to avoid

  • Doing arithmetic on token IDs
  • Believing a freshly built embedding layer already "knows" words
  • Expecting the input embedding alone to capture sentence meaning

Correct mental models

  • ID = address; embedding = learned content at that address
  • Lookup = reading learned parameters, not learning
  • Context is added by the transformer, not by the lookup
14

ExplainFeynman Challenge: why can't the AI use token IDs directly?

Feynman Challenge — Explain It Simply

Token IDs are like call numbers on library books. The number 3797 tells you which shelf to visit, but it says nothing about the book. The embedding is the book you bring back: a long list of numbers the model has learned that describes how the token behaves.

Try explaining this to someone right now: "Why can't a transformer work directly with token IDs, and what exactly happens between tokenization and the first transformer layer?"

🚫 Common Misconceptions to Correct

  • Misconception: a bigger ID means a more important word.
    Reality: IDs are labels. Importance or similarity is expressed, if at all, by the vectors.
  • Misconception: the embedding lookup does computation.
    Reality: It is a constant-time row read. The learning happened earlier, during training.
  • Misconception: after tokenization the model already understands the sentence.
    Reality: After tokenization it has identifiers; after embedding it has vectors; only after the transformer layers does it have context-aware representations.
15

BuildMini-project and summary

🎯 Four Things to Build for Mastery

1 — Lookup layer

Implement class Embedding with a random [V, D] list-of-lists and a forward(ids) that returns rows. Compare with nn.Embedding shapes.

2 — ID-vs-vector report

For 20 word pairs, print ID gap and cosine similarity side by side for a real model. Compute the correlation between the two columns.

3 — Nearest neighbours

Write nearest(word, k) that returns the k tokens whose embedding rows have the highest cosine similarity to a word.

4 — Resize experiment

Add two new tokens to a tokenizer, resize the model's embeddings, and inspect the new rows. What values do they start with?

📌 Summary — Everything in Six Bullets

  • IDs identify, vectors represent. Tokenization yields integers; the transformer needs numeric vectors.
  • Lookup, not computation. Token ID i selects row i of the embedding matrix E of shape [V, D].
  • IDs carry no usable geometry. The size of an ID or the gap between two IDs means nothing.
  • Knowledge lives in learned weights. The embedding matrix and transformer weights come from training; the lookup merely reads them.
  • Token embeddings are context-free. The same token gives the same input vector in every sentence.
  • Pipeline: Text → Token IDs → Embedding vectors → Transformer computations → Contextual representations.
This page 0:00
This session 0:00
Total (all pages) 0:00
Today 0:00
▶ Running
📊 View all study stats →
0:00 studying