分詞器吃什麼,就知道什麼
分詞器飲食:定義
Harris 分詞器在語料庫樣本上訓練。它對該樣本進行分布分析,挑選最強烈重複出現的 N 個片段,並將其寫入詞彙表。訓練後,這 N 個片段成為語言模型用於一切的固定字母表:訓練、推論、每個輸入、每個輸出。
分詞器飲食 = 分詞器訓練的文字樣本。
訓練飲食 = 語言模型訓練的語料庫。
當兩種飲食不同時,分詞器會學習針對模型永遠不會看到的文本進行調整的片段。嵌入容量(每個詞彙條目一個槽位)會浪費在訓練期間無法獲得獎勵的片段上。
ANDREA-12M的錯誤
ANDREA-12M 使用原始的 megachat-v8.txt 檔案頭部來訓練其 Harris tokenizer。該檔案頭部包含程式碼範例與工具呼叫資料。然而,訓練課程卻排除了程式碼與工具呼叫;ANDREA-12M 只看到對話文字。
結果:tokenizer 從 Python 關鍵字、JSON 大括號、shell 旗標中學習了片段。一個訓練於字典條目與對話的模型。仅有 36.4% 的片段與課程加權樣本重疊。 剩餘 63.6% 的詞彙槽位被分配給模型在訓練時永遠不會遇到的片段。
為什麼這很重要
每個詞彙條目都會消耗嵌入參數:嵌入矩陣的一行,形狀為 V × d_model(在活動 4 中涵蓋)。在 V = 4353 與 d_model = 384 的情況下,每個詞彙槽位成本 384 個浮點數。浪費 63.6% 就等於浪費嵌入矩陣的 63.6% 用在模型永遠不會看到的資料上。
陳述一個飲食規則
N 應該有多大
詞彙科學掃描
ANDREA-120M 進行了一個詞彙科學實驗:在相同的 1.25B 字元火hose 語料庫上,以不同 N 值(請求的片段數)訓練 Harris tokenizer。測量 tokenizer 實際找到的片段數。繪製結果。
| 請求的 N | 實際找到的片段數 | 狀態 |
|---|---|---|
| 2,048 | 2,048 | 未飽和(還有成長空間) |
| 4,096 | 4,096 | 未飽和 |
| 8,192 | 8,192 | 飽和點 |
| 16,384 | 13,106 | 語料庫耗盡 |
飽和的意義
在小的 N 時,語料庫有大量重複模式;分詞器能填滿每個它要求的槽位。在大的 N 時,分詞器用盡了統計上有意義的邊界。一個 1.25B 字元語料庫在頻率閾值以上,大約包含 13,106 個不同的語素形狀片段。要求 16,384 會得到 13,106;剩餘的 3,278 個槽位會被填充或留空。
飽和點:要求 N = 發現 N 的點。 超出飽和點,分詞器無法發現更多片段而不稀釋品質(降低頻率閾值並接受雜訊)。
8192 的甜蜜點
ANDREA-120M 選擇 N = 8192。理由如下:
- 低於 8192(例如 4096):詞彙未充分捕捉常見語素;序列碎片化成更多 token;吞吐量下降。
- 在 8192:每個片段槽位對應語料庫中的一個真實、重複模式。
- 高於 8192:邊際效益遞減;13,106 < 16,384 表示槽位被浪費。
最終 ANDREA-120M 詞彙:256 + 8192 + 1 = 8449 個 token。平均壓縮率:每個 token 5.91 個 UTF-8 位元組,意味著每個 token 取代約 5.9 個位元組的原始文字。這個比率決定模型的有效上下文:在 1024 個 token × 5.91 位元組/token 下,ANDREA-120M 每次前向傳遞讀取約 6,050 個字元的上下文。
高於或低於飽和點
63.6% 從何而來
計算浪費的槽位
ANDREA-12M 的 tokenizer 在原始 megachat-v8.txt 上訓練(要求 4096 個片段,已找到)。團隊抽樣了一個課程加權子集:根據每個來源被 bandit 拉取的頻率加權的語料庫。他們在該加權樣本上重新運行 Harris 分析,並詢問:原始 4096 個片段中有多少仍然出現?
結果:36.4% 重疊。4,096 個片段中有 1,491 個匹配課程加權。其餘 2,605 個片段來自模型排除的來源。
模型從未見過的位元組佔用了 63.6% 的詞彙槽位。
嵌入成本
每個詞彙條目佔用嵌入矩陣的一行,形狀為 (V, d_model)。對於 ANDREA-12M:
- V = 4353 (256 + 4096 + 1)
- d_model = 384
- 嵌入參數 = V × d_model = 4353 × 384 = 1,671,552 個參數
那些參數中有 63.6% 未用於對話訓練。1,063,107 個參數分配,0 獎勵信號。ANDREA-12M 存活下來是因為 256 個基礎位元組總是能涵蓋任何字符;但每個參數的容量急劇下降。
ANDREA-120M 如何修復它
ANDREA-120M 的 tokenizer 在完整的火水管(1.25B 字符,21 個來源)上訓練,飽和 N = 8192。訓練語料庫 = 同樣的火水管。飲食對齊:100%。在聊天加權樣本上的重疊結果:36.5%。(注意:36.5% 是重疊,不是覆蓋率;聊天僅是完整火水管的子集,因此這個數字與 12M 的 36.4% 表現不同。)
有效壓縮:每個 token 5.91 UTF-8 位元組。ANDREA-120M 的嵌入矩陣:8449 × 768 = 6,488,832 個參數。每個參數都獲得獎勵信號,因為每個片段都對應到模型實際訓練的文本。
覆蓋率與重疊
為什麼 5.91 Bytes Per Token 很重要
壓縮比率
平均 UTF-8 bytes per token 衡量每個詞彙條目壓縮多少原始文字。ANDREA-120M 平均 5.91。具有較短片段的模型(3 bytes/token)每次前向傳遞讀取較少上下文;具有較長片段的模型(8 bytes/token)讀取更多但訓練較慢(每個片段需要更多樣本來學習良好)。
有效上下文
| 數量 | 值 |
|---|---|
| Token 上下文窗口 | 1,024 tokens |
| 每個 token 的平均位元組數 | 5.91 |
| 有效字元上下文 | 1024 × 5.91 ≈ 6,050 |
大約 6,000 個 UTF-8 字元適合一個 ANDREA-120M 前向傳遞。一頁密集的英文散文約有 ~3,000-4,000 個字元;ANDREA 每傳遞讀取約一頁半。
飲食收緊壓縮
良好對齊的 tokenizer 能更好地壓縮。當 tokenizer 學習到訓練語料中反覆出現的片段時,每個 token 能容納更多文字。ANDREA-12M 的不良對齊 tokenizer 在聊天內容上壓縮較差(因為聊天片段在詞彙表中較稀疏,因此花費更多位元組在 byte-fallback 片段上)。ANDREA-120M 的飲食對齊 tokenizer 將聊天形狀的片段保持在快速路徑上,並將罕見腳本置於 byte fallback。
活動 4 繼續
Activity 4 (grow_a_language_model_embeddings) 涵蓋了那 8449 個詞彙條目會發生什麼:它們成為一個形狀為 V × d_model 的嵌入矩陣的行,然後在流入第一個 transformer 區塊之前加上學習的位置嵌入。