BPE (Byte Pair Encoding)
3 秒看懂
BPE 是一種”先拆字、再合併”的分詞演算法:從最小單元(字元或位元組)出發,反覆將語料中出現頻率最高的相鄰符號對合併為新符號,直到詞表達到預設大小。它是 GPT 系列、LLaMA 系列等主流大語言模型的底層分詞方案——你輸入的每個 token,都是 BPE(或其變體)切出來的。
3 分鐘產業解釋
為什麼分詞器(Tokenizer)是大型模型的”入口基礎設施”?
大語言模型不能直接吃文本字串,必須先把文本切成離散的 token 序列再送入模型。分詞器的質量直接影響:
- 壓縮率 / 序列長度:同樣的文本,切出的 token 越少,推論時 KV Cache 越小、吞吐越高、上下文視窗能塞進更多內容。
- OOV(未登入詞)魯棒性:老式按詞分詞(word-level)遇到新詞就爆;BPE 能把未知詞拆成已知子詞,永不 OOV。
- 多語言公平性:對英語以外的語言(中文、日語、阿拉伯語等),分詞粒度差異極大。同樣的語義,中文可能比英文多消耗 1.5–3 倍 token——這直接決定中文 API 的真實成本。
- 訓練-推論一致性:分詞器在預訓練前確定後通常不再更換。它是模型”認識世界的第一道門”。
BPE 及其變體(Byte-level BPE、WordPiece、Unigram) 幾乎壟斷了當前主流 LLM 的分詞方案。OpenAI 的 tiktoken、Google 的 SentencePiece、HuggingFace tokenizers 是三大主流實現庫。
15 分鐘專家深入
BPE 的核心演算法流程
- 初始化:將訓練語料中所有詞拆成最小粒度單元——
- 經典 BPE(Sennrich 2016):以 Unicode 字元為底,詞尾加特殊符號
</w>以區分詞內與跨詞邊界。 - Byte-level BPE(Radford 2019 / GPT-2):以 256 個位元組為底,任何 Unicode 文本均可無損編碼為位元組序列,徹底消除 UNK。
- 經典 BPE(Sennrich 2016):以 Unicode 字元為底,詞尾加特殊符號
- 統計:遍歷語料,統計所有相鄰符號對(bigram)的出現頻率。
- 合併:選頻率最高的一對
(a, b)→ 合併為新符號ab,寫入合併規則表(merge table)。 - 重複:回到步驟 2,直到詞表大小達到預設上限(如 32K / 50K / 100K)。
推論時:載入合併規則表,對新文本按規則逐步合併,得到 token 序列。這是確定性的、可逆的(BPE 解碼 = 拼接 token 字串)。
Byte-level BPE 的關鍵突破
GPT-2 論文(Radford et al., 2019)引入的 byte-level BPE 解決了一個根本問題:Unicode 字元集(14 萬+)太大,字元級底座詞表過大且對罕見字元不友好。改用 256 個位元組作底,任何語言、任何符號都可以表示,base vocabulary 僅 256 個 token,極其緊湊。
這帶來的好處:
- 零 UNK:理論上不可能出現無法編碼的輸入。
- 語言無關:同一套分詞器天然覆蓋所有語言(雖然壓縮效率有差異)。
- 實現簡潔:tiktoken 等庫的核心就是位元組級 BPE。
技術原理(深入機制)
1. 演算法虛擬碼
Input: 語料庫 corpus, 最大詞表大小 V_max
Output: 合併規則表 merges[], 詞表 vocab[]
# 初始化
vocab ← {所有基礎單元} # 字元級: Unicode字元集; 位元組級: 0x00~0xFF
for each word in corpus:
word ← 拆為字元/位元組序列 + 詞尾標記
# 迭代合併
while |vocab| < V_max:
pairs ← 統計語料中所有相鄰符號對頻率
(a, b) ← argmax(pairs) # 選最高頻對
merges.append((a, b)) # 記錄合併規則
vocab.add(concat(a, b)) # 新符號入詞表
corpus ← 將所有 (a, b) 替換為 concat(a, b)
return merges, vocab
2. 編碼(推論)流程
Input: 待編碼文本 text
Output: token_id 序列
tokens ← 將 text 拆為基礎單元序列
for (a, b) in merges: # 按訓練時的合併順序
while (a, b) in tokens:
tokens ← 替換 (a, b) → concat(a, b)
return tokens 的 id 序列
關鍵點:合併是有優先順序的——先學到的合併規則先應用。這就是為什麼 merge table 的順序至關重要。
3. 與其他分詞方案的技術對比
| 維度 | BPE | WordPiece | Unigram LM |
|---|---|---|---|
| 合併依據 | 純頻率(count) | 似然增益(likelihood gain) | 基於機率模型剪枝 |
| 建置方向 | 自底向上(合併) | 自底向上(合併) | 自頂向下(從大詞表裁剪) |
| 代表模型 | GPT-2/3/4, LLaMA, Mistral | BERT, DistilBERT | T5(SentencePiece Unigram模式) |
| 實現庫 | tiktoken (OpenAI), HuggingFace tokenizers | HuggingFace tokenizers | SentencePiece (Google) |
| 底層單元 | 位元組 or 字元 | 字元 (以 ## 標記續接) | 字元 or 位元組 |
| 確定性 | 確定 | 確定 | 取樣可選(訓練時可隨機) |
| 核心優勢 | 實現簡單、零 UNK | 似然驅動、理論上更優 | 可給出 token 機率、支援正則化 |
WordPiece 與 BPE 的核心差異:BPE 選”頻率最高的對”合併;WordPiece 選”合併後使語言模型似然提升最大的對”。WordPiece 的合併更”有意義”但計算開銷更大。實際效果差距有限。
技術演進史
| 時間 | 事件 | 意義 |
|---|---|---|
| 1994 | Philip Gage 提出 BPE | 原始目標是資料壓縮演算法(C Users Journal) |
| 2016 | Sennrich, Haddow, Birch 發表論文 “Neural Machine Translation of Rare Words with Subword Units” | 將 BPE 引入 NMT 分詞,解決稀有詞問題;提出字元級 BPE + </w> 方案 |
| 2018 | Google 釋出 SentencePiece 庫(Kudo & Richardson) | 實現 BPE + Unigram 兩種演算法,語言無關(raw text in),成為事實標準工具 |
| 2019 | OpenAI GPT-2 釋出(Radford et al.) | 引入 byte-level BPE,以 256 位元組為底座,徹底消除 UNK;詞表約 50,257 |
| 2020 | GPT-3 延續 GPT-2 分詞器 | 確認 byte-level BPE 作為 GPT 系列標準 |
| 2023 | OpenAI 開源 tiktoken 庫;GPT-3.5/4 切換至 cl100k_base | 更高效的 BPE 實現(Rust 核心),詞表擴大到 ~100K,壓縮率提升 |
| 2023 | Meta LLaMA/LLaMA 2 使用 SentencePiece BPE | 詞表 32,000;證明 BPE 在開源模型中的可行性 |
| 2024 | GPT-4o 引入 o200k_base | 詞表擴充套件到 ~200K,多語言壓縮率顯著改善 |
技術路線對比
主流 LLM 分詞器參數列
| 模型 | 分詞演算法 | 底層單元 | 詞表大小 | 實現庫 | 來源 |
|---|---|---|---|---|---|
| GPT-2 | Byte-level BPE | 256 位元組 | ~50,257 | 自研 | [OpenAI GPT-2 論文] |
| GPT-3.5 / GPT-4 | Byte-level BPE | 256 位元組 | ~100,256 | tiktoken (cl100k_base) | [tiktoken 官方] |
| GPT-4o | Byte-level BPE | 256 位元組 | ~200,019 | tiktoken (o200k_base) | [tiktoken 官方] |
| LLaMA / LLaMA 2 | BPE | 位元組(byte fallback) | 32,000 | SentencePiece | [Meta LLaMA 論文] |
| Mistral / Mixtral | BPE | 位元組(byte fallback) | 32,000 | SentencePiece | [Mistral 官方] |
| BERT | WordPiece | 字元 | ~30,522 | HuggingFace tokenizers | [Google BERT 論文] |
| T5 | Unigram | 字元 | 32,000 | SentencePiece | [Google T5 論文] |
| Qwen (通義千問) | Byte-level BPE | 位元組 | ~151,936 | 自研 (tiktoken-based) | [阿里 Qwen 技術報告] |
| DeepSeek | Byte-level BPE | 位元組 | ~100,015 | tiktoken 變體 | [DeepSeek 技術報告] |
注:詞表大小資料來自各模型公開技術報告或開原始碼,部分為近似值。
上下游
上游:資料與算力
- 訓練語料:分詞器的合併規則完全由語料決定。語料的語言構成、領域分佈、文本清洗方式直接影響 token 粒度。通常在預訓練語料的一個子集上訓練分詞器。
- 計算:BPE 訓練本身並不需要 GPU——純 CPU 即可完成(本質是頻率統計+排序),訓練時間從幾分鐘到幾小時不等,取決於語料規模。
下游:模型與應用
- 模型輸入層:Embedding 矩陣的行數 = 詞表大小。詞表越大,Embedding 引數越多(~詞表 × hidden_dim)。
- 推論成本:token 數 × 每 token 的計算量 = 總推論成本。更好的壓縮率 = 更少的 token = 更低的推論成本。
- 上下文視窗:4K / 8K / 128K / 1M 上下文視窗的”K”指的就是 token 數。分詞器的壓縮率決定了能塞進多少實際文本。
- 多語言公平性:不同語言的 token 效率差異巨大。對於同一條語義,中文通常消耗的 token 數約為英文的 1.5–3 倍(估算,具體取決於模型的分詞器),日語、韓語等也類似。
產業鏈定位
語料資料 ──→ 分詞器訓練(CPU)──→ 合併規則表 + 詞表
│
▼
模型預訓練(GPU 叢集)
│
▼
推論服務 ──→ token 計費(API)
關鍵指標
| 指標 | 定義 | 說明 |
|---|---|---|
| 詞表大小 (Vocab Size) | 分詞器輸出的不重複 token 總數 | 直接影響 Embedding 引數量和 softmax 計算量 |
| 壓縮率 (Fertility) | 平均每個原始字元被切成多少個 token | 越低越好;中文大約 1 字 ≈ 1–3 token(因模型而異) |
| 字元/token 比 | 壓縮率的倒數 | 越高越好,表示每個 token 編碼的原始資訊越多 |
| OOV 率 | 無法編碼的輸入比例 | Byte-level BPE 理論上為 0 |
| 編碼速度 | 每秒編碼的字元/token 數 | tiktoken(Rust)顯著快於純 Python 實現 |
| 跨語言公平性 | 同語義在不同語言間的 token 數比值 | 理想狀態為 1:1,實際差距可達 1:3+ |
供需與市場資料
分詞器的”隱性成本”
分詞器看似”無成本”(訓練只需 CPU、幾分鐘),但其影響滲透到整個推論鏈路:
- API 定價基礎:OpenAI、Anthropic、Google 等 API 均按輸入+輸出 token 數計費。分詞器決定了一美元能買多少語義。
- 上下文視窗利用率:128K 上下文的模型,如果分詞器對目標語言壓縮率差,實際能塞進的有效內容大打折扣。
- KV Cache 視訊記憶體:token 數量直接決定 KV Cache 大小,這在長上下文推論中是視訊記憶體瓶頸。
量化估算
- GPT-2 分詞器(50K 詞表)處理英文約 1 token ≈ 4 字元 ≈ 0.75 單詞。
- 中文約 1 漢字 ≈ 1–2 token(GPT-2 分詞器),GPT-4 的 cl100k_base 可壓縮到約 1 漢字 ≈ 0.6–1.2 token(估算,取決於具體文本)。
- o200k_base 進一步提升多語言壓縮率,具體資料 [未充分揭露]。
代表公司與資本對映
| 公司 / 機構 | 角色 | 關鍵動作 |
|---|---|---|
| OpenAI | BPE 最大的工業推動者 | GPT-2 引入 byte-level BPE;開源 tiktoken;持續擴充套件詞表 |
| SentencePiece 開發者 | SentencePiece 支援 BPE + Unigram,被開源社群廣泛採用 | |
| HuggingFace | 開源 tokenization 工具鏈 | tokenizers 庫(Rust 實現),支援 BPE/WordPiece/Unigram |
| Meta | 開源 LLM 分詞器標準制定者 | LLaMA 系列使用 SentencePiece BPE,32K 詞表成為開源模型標配 |
| 阿里 (通義千問) | 多語言最佳化 | Qwen 擴充套件詞表到 ~152K,改善中文壓縮率 |
| DeepSeek | 中文最佳化 | 詞表 ~100K,中文壓縮率顯著優於早期 GPT 分詞器 |
投資邏輯
1. 分詞器是”隱性護城河”
分詞器訓練成本極低(<1000 美元的 CPU 算力),但它在以下層面建置壁壘:
- 相容性鎖定:模型一旦訓練完成,分詞器不可更換(否則 Embedding 層、所有權重全部作廢)。換模型 = 換分詞器 = 重做下游所有適配。
- 多語言體驗差異化:對中文使用者,分詞器效率直接決定使用成本。Qwen、DeepSeek 的大詞表分詞器在中文場景有實質優勢。
2. 關注詞表擴充套件趨勢
從 GPT-2 的 50K → GPT-4 的 100K → GPT-4o 的 200K,詞表在快速擴充套件。驅動力:
- 多語言覆蓋需求
- 更高壓縮率 → 更低推論成本
- Embedding 層引數佔比隨詞表增大而增加,但在大型模型中佔比很小(<1% 總引數)
3. 非投資標的,但影響投資判斷
分詞器不是獨立產品/公司,但它是評估 LLM 競爭力的隱藏維度:
- 同等模型能力下,分詞效率更高的模型推論成本更低。
- 中文場景評估必須考慮分詞器效率,不能只看 benchmark 分數。
常見誤讀糾偏
❌ 誤讀 1:“BPE 是一種壓縮演算法,用於減少模型儲存”
糾偏:BPE 起源於資料壓縮,但在 LLM 場景中它不是壓縮模型權重的——它是將文本離散化為 token 序列的演算法。它壓縮的是”文本到 token 的對映”(即用更少的 token 表示同樣的文本),而非模型引數。模型權重壓縮是量化(INT8/INT4)、蒸餾等技術的事。
❌ 誤讀 2:“BPE 分詞器越大越好,詞表越大型模型越強”
糾偏:詞表大小需要權衡。更大的詞表意味著:
- ✅ 更好的壓縮率(更短的序列)
- ❌ 更大的 Embedding 引數(詞表 × hidden_dim)
- ❌ 訓練時每個 token 被見到的次數更少(語料中低頻 token 學不充分)
- ❌ 輸出層 softmax 計算量增大(需遍歷整個詞表)
LLaMA 選擇 32K、Qwen 選擇 152K,各有取捨,沒有絕對最優。對英文為主的場景,32K 夠用;對多語言場景,更大詞表通常更優。
❌ 誤讀 3:“Byte-level BPE 可以完美處理所有語言”
糾偏:雖然 Byte-level BPE 保證零 UNK(任何輸入都能編碼),但不同語言的壓縮效率差異巨大。英文每 token 編碼約 4 字元,中文可能每 token 只編碼 1–3 位元組(即 1–1.5 個漢字)。這意味著同樣的 128K 上下文視窗,中文能放的有效內容顯著少於英文。這是當前大型模型的結構性不公平,o200k_base 等新詞表正在改善但尚未完全解決。
❌ 誤讀 4:“GPT-4 和 GPT-2 用同一個分詞器”
糾偏:GPT-2 使用約 50K 詞表的 r50k_base / p50k_base;GPT-3.5/4 使用約 100K 詞表的 cl100k_base;GPT-4o 使用約 200K 詞表的 o200k_base。它們都是 byte-level BPE,但合併規則表完全不同,因此同一個句子在不同模型中會切成不同的 token 序列。這意味不同模型之間的 token 數對比不是線性的。
學習路徑
入門(30 分鐘)
- 動手實驗:開啟 tiktokenizer.vercel.app,輸入中英文文本,觀察不同模型的分詞結果差異。
- 概念理解:閱讀 HuggingFace NLP Course 的 Tokenizer 章節(免費線上)。
進階(2–3 小時)
- 經典論文:Sennrich et al. (2016), “Neural Machine Translation of Rare Words with Subword Units”——BPE 引入 NLP 的奠基論文,6 頁,可讀性極強。
- GPT-2 論文:Radford et al. (2019), “Language Models are Unsupervised Multitask Learners”——Byte-level BPE 的引入。
- 實現閱讀:閱讀 HuggingFace
tokenizers庫的 BPE trainer 原始碼(Rust,但邏輯清晰)。
深度(1 天)
- SentencePiece 論文:Kudo & Richardson (2018), “SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing”。
- 對比實驗:用同一語料分別訓練 BPE、WordPiece、Unigram 分詞器,對比壓縮率和 token 分佈。
- 中文分詞分析:對比 GPT-4(cl100k_base)與 Qwen 在中文語料上的 token 效率,量化差距。
一句話總結
BPE 是大語言模型的”第一道翻譯”——它決定了模型以什麼粒度”閱讀”人類語言,直接影響推論成本、上下文利用率和多語言公平性。
延伸閱讀與來源
| 來源 | 內容 | 型別 |
|---|---|---|
| Gage, P. (1994). “A New Algorithm for Data Compression.” C Users Journal. | BPE 原始論文 | 學術論文 |
| Sennrich et al. (2016). Neural Machine Translation of Rare Words with Subword Units. ACL. | BPE 引入 NLP | 學術論文 |
| Radford et al. (2019). Language Models are Unsupervised Multitask Learners. OpenAI. | GPT-2 / Byte-level BPE | 技術報告 |
| Kudo, T. & Richardson, J. (2018). SentencePiece. EMNLP. | SentencePiece 架構 | 學術論文 |
| tiktoken GitHub | OpenAI 分詞器實現 | 開原始碼 |
| HuggingFace tokenizers | Rust 實現的分詞器庫 | 開原始碼 |
| tiktokenizer.vercel.app | 視覺化分詞實驗 | 線上工具 |
⚠️ 免責宣告:本頁中涉及的具體詞表大小、壓縮率資料等,凡標註 [估算] 或 [未充分揭露] 的,均為基於公開資訊的推測,非精確規格。各模型實際分詞器引數請以其官方技術報告或開原始碼為準。