An Embedding Is a Lookup, Not a Function
A First Layer After a Tokenizer
Tokenizer 會將模型輸入轉換為整數 ID:[256, 1842, 7301, ...]。Transformer 首先會將每個 ID 轉換為 d_model 維度的浮點向量。該向量存在於 d_model 維空間中(ANDREA-120M 使用 768 維)。
An embedding layer is a lookup table, not a function. Imagine a giant matrix:
shape: (V, d_model)
row 0: [e_0_0, e_0_1, ..., e_0_767]
row 1: [e_1_0, e_1_1, ..., e_1_767]
...
row 8448: [e_8448_0, e_8448_1, ..., e_8448_767]
Token ID i 選取第 i 列。直接陣列存取。無算術、無激活函數。僅為索引。
可訓練的浮點數
表格中的每個條目初始為一個小的隨機浮點數(通常從以 1/sqrt(d_model) 縮放的常態分佈中抽取)。每當批次中出現其對應的 Token ID 時,反向傳播就會更新該列。訓練完成後,相似的 Token(例如 cat、dog、pet)會擁有相似的向量;不相干的 Token(例如 cat、Tuesday、xylophone)則在向量空間中相距甚遠。
ANDREA-120M 詞嵌入成本
| 數量 | 數值 |
|---|---|
| V | 8,449 |
| d_model | 768 |
| 參數量 | 6,488,832 |
單獨在 token embedding table 中就存在約 650 萬個參數,約佔 ANDREA-120M 總參數的 5.4%。每個詞彙槽位都擁有這些 768 個浮點數。
Embedding Tables 的尺寸計算
內積衡量相似度
向量視為箭頭
一個 768 維的向量存在於人類無法想像的空間中,但相同的代數規則適用於任何維度。對 transformer 而言,有兩個關鍵運算:
大小(箭頭的長度):
||v|| = sqrt(v_0² + v_1² + ... + v_767²)
點積(兩個向量之間的對齊程度):
u · v = u_0 × v_0 + u_1 × v_1 + ... + u_767 × v_767
點積告訴你什麼
在任何維度中都成立的兩個事實:
- u · v = ||u|| × ||v|| × cos(theta),其中 theta 是兩向量之間的夾角。
- 指向相同方向的向量會產生較大的正點積。
- 指向相反方向的向量會產生較大的負點積。
- 互相垂直的向量其點積為零。
點積 = 未正規化的相似度。 兩個訓練過的 token 嵌入向量 cat 和 dog 會得到較高的點積,因為反向傳播將它們推向相近(兩者都預測與寵物相關的上下文)。cat 和 Tuesday 則幾乎正交,因為它們預測不同的上下文。
Why a Transformer Cares
Activity 5 (grow_a_language_model_attention) builds attention from dot products: a query vector dot-producted with key vectors yields scores that say which past tokens matter for predicting a next one. Embeddings & dot products together carry every interaction inside a transformer.
Predict Similarity
ANDREA 使用學習式位置嵌入
問題
詞嵌入告訴模型這個位置存在哪個詞,但它無法告訴模型該詞所處的位置。若沒有位置資訊,transformer 會將 the cat sat on a mat 與 mat a on sat cat the 視為相同:一組相同的詞元,卻沒有順序訊號。
Transformer 文獻中存在三種解決方案:
正弦波(Sinusoidal, Vaswani 2017)。 基於正弦與餘弦的固定數學公式。位置 0 會得到一個特定的 768 維向量;位置 1 會得到另一個;這些向量從不訓練,也不更新。透過公式可推廣至任何位置。
RoPE(旋轉位置嵌入)。根據位置對 query 與 key 向量進行旋轉。被 LLaMA、Qwen 等模型採用。無需額外參數,旋轉直接內建於注意力機制中。
Learned(學習式位置嵌入)。一個獨立的嵌入表,大小為 (T, d_model),其中 T 為上下文長度。每個向量如同 token embedding 一樣,透過反向傳播進行訓練。
ANDREA 的選擇:Learned
ANDREA 繼承自 microGPT,而 microGPT 繼承自 nanoGPT,nanoGPT 又繼承自 GPT-2,因此採用學習式位置嵌入。理由如下:
- 簡潔性。 注意力機制中無需特殊數學運算。位置表看起來就像一個 token 表。
- 與自訂 CUDA 相容。 ANDREA 的 microgpt_cuda.cu 引擎對兩種嵌入查找的處理方式完全相同;無需 sin/cos 核心。
- 適用於固定上下文。 ANDREA 將 T 上限設為 1024。對於固定長度的序列,學習式位置表已足夠。
ANDREA-120M 位置嵌入成本
| 項目 | 數值 |
|---|---|
| T (context) | 1,024 |
| d_model | 768 |
| Parameters | 786,432 |
位置嵌入的參數量為 0.79M。與詞元嵌入合併後:6.49M + 0.79M = 嵌入參數總計 7.27M,適用於 ANDREA-120M。
它們如何結合
在輸入序列的每個位置 t:
x_t = token_embedding[token_id_t] + position_embedding[t]
兩個 768 維向量,逐元素相加。結果 x_t 流入第一個 transformer block。模型永遠不會再將它們分開;它會學習如何使用這個合併後的訊號。
Learned Versus Sinusoidal
嵌入參數存放位置
完整的 ANDREA-120M 嵌入層
| 元件 | 形狀 | 參數數量 |
|---|---|---|
| Token embedding table | 8,449 × 768 | 6,488,832 |
| Position embedding table | 1,024 × 768 | 786,432 |
| Total | 7,275,264 |
約 730 萬個參數。ANDREA-120M 的總參數量:約 1.2 億。嵌入層僅佔 6%。其餘 94% 位於 transformer blocks(attention + MLP,詳見活動 5-7)。
Untied vs Tied Embeddings
許多 Transformer 設計(包含 GPT-2)會將 token embedding 與最終輸出投影綁定:同一個 V × d_model 矩陣同時用於輸入與輸出(對應詞彙表的 logits)。綁定可節省 V × d_model 參數,且常能提升模型品質。
ANDREA 使用未綁定嵌入:輸入嵌入與輸出投影以獨立矩陣進行訓練。Activity 7(grow_a_language_model_transformer_block)涵蓋最終層。
目前為止的前向傳遞
輸入:token ID [256, 1842, 7301, ...](共 1024 個)。每個 ID 查詢一個 768 維向量,每個位置也查詢一個 768 維向量。逐元素相加後,得到一個 (1024, 768) 的矩陣 x,內含 token 與位置向量。x 將流入 transformer block 1。
Activity 5(grow_a_language_model_attention)說明 block 1 的運作:使用因果遮罩與 softmax 的縮放點積注意力。