Look up token embeddings
A model cannot do arithmetic on words, so each token is first given a whole number, its ID. But the ID itself is only a label: token 7 is not seven times token 1. So every ID is swapped for a list of numbers, called an embedding, taken from a table with one row per token. Looking up a token means picking its row. During training the rows change until tokens that behave alike end up with similar rows.
Learn it
Words to know
- token
- One unit of text as the model sees it: a character, a piece of a word or a whole word.
- token ID
- The whole number that stands for a token.
- embedding
- A list of numbers that stands for a token. The model learns these numbers during training.
How it works
- The table has one row per token ID. Row 0 belongs to token 0, row 1 to token 1, and so on.
- For each ID in the sequence, take the row at that index.
- A token that appears twice gets the same row twice. A sequence of 3 IDs becomes 3 rows.
Worked example
Input ids = [1, 0, 1] table = [[1, 2], [3, 4]] Output [[3, 4], [1, 2], [3, 4]]
| Position | Token ID | Row taken |
|---|---|---|
| 0 | 1 | [3, 4] |
| 1 | 0 | [1, 2] |
| 2 | 1 | [3, 4] |
Token 1 appears at positions 0 and 2 and gets the same row both times. The lookup knows nothing about position yet.
Why it matters
The first layer of a GPT is this lookup, done with torch.nn.Embedding. The lesson on positions adds the missing sense of order.
Your turn
Replace each token ID with its row from an embedding table.
ids- a list of token IDs; each is a valid row index, and the list may be empty
table- the embedding table: one row of numbers per token
- Returns
- A new list with a copy of the table row for each ID, in the same order.
Example 1
Input ids = [1, 0, 1] table = [[1, 2], [3, 4]] Output [[3, 4], [1, 2], [3, 4]]
IDs 1, 0, 1 pick rows [3, 4], [1, 2] and [3, 4].
Example 2
Input ids = [] table = [[1]] Output []
No IDs, so no rows.
Example 3
Input ids = [2, 2] table = [[0, 0, 0], [1, 1, 1], [5, 6, 7]] Output [[5, 6, 7], [5, 6, 7]]
The same ID twice gives the same row twice.
Hints
Each hint gives away a little more. Open one only when you need it.
Hint 1: Where to start
This is a lookup, not arithmetic. Each ID is an index into
table.Hint 2: The key step
For each ID, take
table[i]. Wrap it inlist(...)so the answer holds copies, not the table's own rows.Hint 3: The outline
Return a list with
list(table[i])for eachiinids.
Solution
From here on the page gives the method away. If you are still solving, go back to the hints.
Step by step
- The ID is a row number: pick that row. Nothing is computed from the ID's value. Token 1 is not smaller than token 2 in any useful sense.
- Copy it, so changing the answer cannot change the table. Without the copy, two positions with the same token would share one list, and editing one would edit both.
The same numbered steps are the comments in the solution.
Python
def solve(ids, table):
rows = []
for token_id in ids:
# 1. The ID is a row number: pick that row
row = table[token_id]
# 2. Copy it, so changing the answer cannot change the table
rows.append(list(row))
return rowsWatch out
- Do not multiply the row by the ID or use the ID as a number in any formula. It only says which row to take.
- Keep duplicates and keep the order. The output has one row per position in the sequence.
- The checks compare values only, so they cannot see whether you copied the rows. Copy anyway: an answer that shares its lists with the table is a bug that shows up much later.
Check yourself
Why is a token ID not fed to the model as a number?
Its size means nothing. The model would treat token 100 as a hundred times token 1, which says nothing about the words.
Where do the numbers in an embedding table come from?
They start random and are changed by training, like any other weights.