Skip to the lesson
FixTheRobot Explore Robotics / LLM / LM3 Embeddings and the Mathematics of Attention / LM3-T1

LLM · Theory · LM3

LM3-T1 — From Token IDs to Embedding Vectors

Token IDs are labels. Embeddings are where each label gets a place in a space that the model can compute with.

  • Lesson 1 of 6
  • Module 3: Embeddings and the Mathematics of Attention
  • Theory
  • Difficulty: Beginner
  • About 8 minutes to read
  • Prerequisite: LM2-T6

After tokenization (Module 2) a text is a list of integers, and an integer is a poor thing to compute with: 262 is not twice as much of anything as 131. The model therefore replaces each ID by a vector of numbers, the token’s embedding, and from that point on all computation is linear algebra on vectors. This lesson explains the lookup table behind that step, how vectors can encode similarity, how the table is learned and what it costs. Lab LM3-L1 uses small vectors to compute attention on top of embeddings like these.

Learning objectives

After this lesson, you should be able to:

  • Describe an embedding table as a learned matrix of shape V × d and the lookup as row selection.
  • Show that multiplying a one-hot vector by the table gives the same row as indexing.
  • Compute dot products and cosine similarity between embedding vectors and interpret them.
  • State how the table is trained and compute its parameter count.

The idea: give every token a location

Think of every token as a point in a space with d dimensions, for example d = 768. The embedding table stores one point per vocabulary entry. When the model reads the token with ID 1, it fetches row 1 of the table. That row, a vector of d numbers, is what flows through the rest of the network.

An embedding table is a lookupA table with four rows labelled robot, arm, box and tool, each a vector of three numbers. The token ID 1 selects the second row. The input sequence of IDs robot, arm, box becomes a matrix of three rows and three columns.Token IDs select rows of the embedding table E (shape V × d) 0 robot1.0 0.0 1.01 arm0.9 0.1 0.82 box0.0 1.0 0.03 tool−1.0 0.0 0.5 E: 4 rows (tokens) × 3 columns (features) → input IDs [0, 1, 2] 1.0 0.0 1.00.9 0.1 0.80.0 1.0 0.0 x: 3 tokens × 3 features
The embedding table is indexed by token ID. The three input tokens become a 3 × 3 matrix: one row per token.

Why vectors?

A vector can express degrees of similarity that an ID cannot. Two tokens with similar roles (“robot” and “arm”, both things that act) can end up with vectors that point in similar directions, while an unrelated token (“box”) points elsewhere. Operations such as dot products then measure how alike two tokens are. The model is free to arrange the points however helps it predict the next token; nobody designs the axes. A single coordinate rarely has a human-readable meaning, but directions and distances often carry structure.

Where the numbers come from

The table is a matrix of learned parameters. It starts as small random numbers and is changed by gradient descent along with every other weight (Module 5). A token that is used in similar contexts receives similar gradient updates and drifts to a similar place. That is the practical form of the old idea that a word is characterised by the company it keeps.

Lookup, not computation

The embedding step does no arithmetic on its input: it copies a row. This is why it is fast, and why the gradient with respect to the table is sparse: in each step only the rows of the tokens that actually appeared receive a non-zero gradient.

What embeddings do not contain

The row for “box” is the same wherever the token appears. It knows nothing about its neighbours or its position. Context-dependence comes later: attention (Lesson LM3-T3) mixes the vectors of neighbouring tokens, and position information is added separately (Lesson LM3-T2).

The mathematics: lookup, one-hot products and similarity

Let E be the embedding matrix with V rows (one per token) and d columns. For a sequence of token IDs t1, …, tn the output is the matrix X whose row i is row ti of E:

embedding lookup
X[i, : ]=E[ti, : ]X[i,\,:\,]=E[t_{i},\,:\,]
E
(V, d)→(V,\,d)\to
X
(n, d)(n,\,d)
V
vocabulary size: number of rows of E.
d
embedding width: number of columns; the model’s hidden size.
ti
the integer ID of the i-th token, 0 ≤ ti < V.
X
the matrix of embeddings of the sequence; shape (n, d), or (B, n, d) for a batch of B sequences.

One-hot view. Let oi be the one-hot vector of length V with a 1 at position ti and 0 elsewhere. Then

one-hot product equals lookup
xi=oi⋅Ex_{i}=o_{i}\cdot E
(1×V) times(V×d)→(1×d)(1\times V)\,\text{times}(V\times d)\to (1\times d)

because every other term of the product is multiplied by 0. Frameworks index instead of multiplying: the result is identical and needs d copies rather than V · d multiplications.

Similarity. Two embedding vectors a and b have a dot product and a cosine similarity:

dot product and cosine similarity
a⋅b=∑k ak bka\cdot b=\sum _{k}\,a_{k}\,b_{k}
cos⁡(a, b)=a⋅b∥a∥∥b∥\cos (a,\,b)=\frac{a\cdot b}{\lVert a\rVert \lVert b\rVert }
ak, bk
component k of the two vectors, k = 1, …, d.
‖a‖
the length of a: the square root of the sum of its squared components.
cos(a, b)
between −1 and 1: 1 means the same direction, 0 unrelated (orthogonal), −1 opposite.

Attention (Lesson LM3-T3) uses the raw dot product, which also grows with vector length; cosine similarity removes the length and is the usual way to inspect embeddings.

Size. The table has V · d parameters. GPT-2 small has V = 50,257 and d = 768, so 50,257 × 768 = 38,597,376 parameters: roughly 31% of its 124 million. In float32 that is about 154 MB for the table.

A worked example: four tokens with three features

Use the toy table from the figure, with token IDs robot = 0, arm = 1, box = 2, tool = 3:

A toy embedding table (invented numbers)
IDTokenEmbedding (d = 3)
0robot[1.0, 0.0, 1.0]
1arm[0.9, 0.1, 0.8]
2box[0.0, 1.0, 0.0]
3tool[−1.0, 0.0, 0.5]

Dot products. robot · arm = 1.0 × 0.9 + 0.0 × 0.1 + 1.0 × 0.8 = 1.7. robot · box = 0 + 0 + 0 = 0. robot · tool = −1.0 + 0 + 0.5 = −0.5.

Cosine. ‖robot‖ = √2 ≈ 1.414, ‖arm‖ = √(0.81 + 0.01 + 0.64) = √1.46 ≈ 1.208, so cos(robot, arm) = 1.7 / (1.414 × 1.208) ≈ 0.995, almost the same direction. cos(robot, box) = 0 (orthogonal) and cos(robot, tool) = −0.5 / (1.414 × 1.118) ≈ −0.316 (a mild opposition). In this invented table “robot” and “arm” are close, “box” is unrelated.

The sequence [0, 1, 2] (robot, arm, box) becomes the 3 × 3 matrix whose rows are the first three rows of the table. A batch of two such sequences has shape (2, 3, 3). Nothing about order or neighbours is in the matrix yet.

The same thing in PyTorch

import torch
import torch.nn as nn

table = torch.tensor([[ 1.0, 0.0, 1.0],
                      [ 0.9, 0.1, 0.8],
                      [ 0.0, 1.0, 0.0],
                      [-1.0, 0.0, 0.5]])          # V = 4, d = 3

emb = nn.Embedding(num_embeddings=4, embedding_dim=3)
with torch.no_grad():
    emb.weight.copy_(table)                       # use our toy numbers instead of random ones

ids = torch.tensor([0, 1, 2])
x = emb(ids)                                      # lookup: shape (3, 3)
print(tuple(x.shape))                             # (3, 3)

one_hot = torch.nn.functional.one_hot(ids, num_classes=4).float()
print(torch.allclose(x, one_hot @ table))         # True: one-hot times the table equals the lookup

cos = torch.nn.functional.cosine_similarity
print(round(cos(table[0], table[1], dim=0).item(), 3))   # 0.995
print(round(cos(table[0], table[3], dim=0).item(), 3))   # -0.316
print(sum(p.numel() for p in emb.parameters()))   # 12  (V * d)

nn.Embedding holds the table as emb.weight, shape (V, d), and is called with an integer tensor of any shape; the output has one extra trailing dimension of size d.

Engineering implications and limitations

IDs must be integers (long tensors). Passing floats raises an error. A frequent bug is an ID that is out of range (≥ V), which gives an index error on CPU and a cryptic device-side assertion on GPU.

Initialisation matters little but not nothing. The book initialises from a normal distribution; any small random values break symmetry. All-zero embeddings would give every token the same gradient.

The embedding table is often tied to the output layer. Some models reuse the transposed table for the final projection to vocabulary logits (weight tying), saving V · d parameters and often helping small models. GPT-2 does this; the book’s version keeps them separate for clarity and mentions the choice.

Rare tokens get poor embeddings. A token that appears twice in the training data hardly moves from its random start. This is one reason subword tokenizers avoid very rare tokens, and a reason that glitchy, almost-unused tokens can behave strangely.

Do not over-read geometry. Nearest-neighbour lists and 2-D projections of embeddings are useful for debugging, but a single dimension is not “the gender axis”, and cosine similarity in one layer says nothing about what the full model does.

Memory. The table is a large share of a small model’s parameters. Training updates it with the optimizer state (Adam keeps two extra values per parameter), so the training memory for the table is about four times its size.

For robots. When mixing text with other signals (Physical AI and VLA tracks), non-text inputs such as image patches or joint readings are also mapped to vectors of the same width d and treated as tokens, so the idea of “everything becomes a row of a matrix” carries over; see the Vision-Language-Action track for how that is done.

Common misconceptions

“The embedding of a token is fixed, like a dictionary definition.”

It is a learned parameter, changed by training. Different models, and different training runs, give different tables.

“Each dimension of an embedding has a meaning.”

Usually not individually; meaning is spread over directions. Rotating the whole space would give an equally good model.

“The embedding already contains context.”

It depends only on the token ID. Context is added by attention in the layers that follow.

“Embeddings are computed by a network on the token.”

The input embedding is a table lookup. Only the table entries are learned.

“A larger d is always better.”

It increases capacity and cost (parameters, memory, compute). The right width depends on the model size and data.

Engineering takeaways

  1. An embedding table E of shape (V, d) maps token IDs to d-dimensional vectors; the lookup selects rows and equals a one-hot product.
  2. The sequence of n tokens becomes a matrix of shape (n, d), or (B, n, d) for a batch.
  3. Dot products and cosine similarity measure how alike two vectors are; the table is learned, so similarity emerges from training.
  4. The table has V × d parameters: 38,597,376 for GPT-2 small, about a third of the model.
  5. Embeddings carry no context or position by themselves; attention and position encodings supply both.

References and further reading

See Chapter 2 of the book (creating token embeddings) and the PyTorch documentation for torch.nn.Embedding.

Knowledge check

Three conceptual questions. Write an answer, then reveal the explanation. Your answers stay in your browser.

Question 1

A vocabulary has 50,000 tokens and the embedding width is 1,024. How many parameters does the embedding table have, and how much memory does it take in 16-bit floats?

Explanation

50,000 × 1,024 = 51,200,000 parameters. At 2 bytes each that is 102,400,000 bytes, about 102 MB.

Question 2

Two embeddings are a = [3, 4] and b = [4, 3]. Compute their dot product and cosine similarity.

Explanation

Dot product: 3·4 + 4·3 = 24. Lengths: ‖a‖ = ‖b‖ = 5. Cosine = 24 / 25 = 0.96, so the vectors point in almost the same direction.

Question 3

A batch of 8 sequences of 128 token IDs is passed through an embedding layer with d = 256. What is the output shape, and why does it not depend on the vocabulary size?

Explanation

The output shape is (8, 128, 256). The lookup copies one row of length d per token; the vocabulary size only determines the number of rows in the table, not the shape of the result.

What’s next

Next: why attention needs position information and how it is added to the embeddings.

Practice this lesson

Compute Attention Step by Step

Compute scores, softmax weights and context vectors for a short sentence by hand-written code.

Next lesson

LM3-T2 — Positional Information

Show why attention needs position and compare absolute learned, sinusoidal and relative schemes.

Nothing below is required to finish this lesson.