下面是對 BPE(Byte Pair Encoding)分詞算法的深入介紹,涵蓋其背景、原理、實現細節、數學機制、優缺點以及在自然語言處理中的實際應用。
一、背景與動機
在自然語言處理中,模型輸入通常需要被轉換為數值序列,而這首先需要將文本拆分為可處理的最小單元。傳統的分詞策略有三類:
詞級分詞(Word-level Tokenization):容易出現 OOV(Out-of-Vocabulary)問題;
字符級分詞(Character-level Tokenization):過于細碎,序列長度太長;
子詞級分詞(Subword-level Tokenization):在這兩者之間取得平衡,BPE 就屬于這一類。
BPE 分詞的核心思想是:通過數據驅動的方法找出最常見的字符組合,以此構建詞匯表,使模型既能處理高頻詞,又能組合出低頻詞或新詞。
二、BPE 的起源
最早的 BPE 是一種用于數據壓縮的算法,由 Philip Gage 在 1994 年提出。它的原始用途是用頻繁的字節對替換為一個新符號,從而減少文件大小。
2016 年,Sennrich 等人將其引入自然語言處理,用于構建子詞單元,從而提升神經機器翻譯的效果(論文標題為 "Neural Machine Translation of Rare Words with Subword Units")。
三、BPE 分詞算法的核心思想
BPE 是一個基于統計的、貪心的合并策略,其核心思想是:
不斷合并訓練語料中出現頻率最高的符號對(symbol pair)為新符號,直到達到預定詞表大小或合并次數。
這些“符號”最初是字符,隨著合并的進行,可能變成字符組合。
四、BPE 的詳細算法流程
輸入:
語料(文本數據)
目標詞匯表大小(或最大合并次數)
步驟:
第一步:初始化
將所有詞語按字符劃分,每個詞結尾添加一個特殊終止符,如 </w>
,以區分詞邊界。例如:
"low" → l o w </w>
"lower" → l o w e r </w>
"newest" → n e w e s t </w>
每個詞都被拆成字符序列,并統計出現頻率。
第二步:統計字符對頻率
遍歷整個詞表,統計每個相鄰字符(或子詞)對出現的總次數。
例如:
"l o w </w>":字符對 ("l", "o")、("o", "w")、("w", "</w>")
將這些字符對及其頻率記錄下來。
第三步:合并頻率最高的字符對
找出出現頻率最高的字符對(如 "o w"),并將其視為一個新子詞 "ow"。
例如:
"l o w </w>" → "l ow </w>"
"l o w e r </w>" → "l ow e r </w>"
更新詞表,替換所有出現該字符對的地方。
第四步:重復步驟 2~3
繼續統計新的子詞對頻率,并合并頻率最高的一對,直到達到指定的合并次數或詞表大小為止。
第五步:構建最終詞表
在所有合并步驟中出現過的子詞都可以構成詞表(vocabulary),用于編碼文本。
舉個簡化例子:
給定詞頻如下:
low: 5
lowest: 2
newest: 6
newer: 3
初始化分詞(添加 </w>
):
l o w </w> ×5
l o w e s t </w>×2
n e w e s t </w>×6
n e w e r </w> ×3
第一輪統計所有字符對頻率,如 ("e", "s") 出現頻率最高 → 合并為 "es"
繼續合并 → ("es", "t") → "est" → ("n", "e") → "ne"……
直到構建出子詞如:
"low", "new", "est", "er", "ne", "er", "lowest", "newest"
這樣,無論是高頻詞(如 newest)還是低頻詞(如 newer),都能被拆解成已知子詞。
五、BPE 分詞的編碼與解碼
編碼:
編碼時,BPE 會根據訓練生成的子詞詞表,用最長匹配的策略將輸入詞切分為子詞組合。
比如輸入詞 newer
:
子詞詞表有:
new
、er
輸出:
new er
若詞表沒有 newer
但有 n
、e
、w
、er
,則輸出:n e w er
解碼:
將子詞逐個拼接回原始詞,如果有 </w>
終止符,就表示到一個詞的結尾。
六、BPE 的優點與缺點
優點:
處理 OOV(未登錄詞)能力強:所有詞都可以拆成子詞,模型不會因不認識詞而出錯。
詞表大小可控:相比整詞級分詞,詞表更小,占用內存更少。
訓練速度快,易于實現。
子詞建模兼顧精細性與語義性,保留了一定的語言結構信息。
缺點:
合并操作是貪心策略,非全局最優。
同一個詞可能被拆分成不同子詞序列,影響一致性(尤其在跨語料中)。
不會考慮上下文:合并是基于頻率的,無法根據語境靈活調整。
七、BPE 與其他分詞算法對比
方法 | OOV處理 | 詞表大小 | 序列長度 | 是否上下文相關 |
---|---|---|---|---|
Word-level | 差 | 大 | 短 | 否 |
Char-level | 好 | 小 | 長 | 否 |
BPE | 好 | 中 | 中 | 否 |
Unigram LM | 更靈活 | 中 | 中 | 否 |
SentencePiece | 更健壯 | 中 | 中 | 否 |
八、在實際系統中的應用
1. HuggingFace Transformers
HuggingFace 的 tokenizers
庫中提供了 ByteLevelBPETokenizer
,被 GPT-2 和 RoBERTa 等模型使用。
2. SentencePiece + BPE 模式
Google 的 BERT 和 T5 使用 SentencePiece,它支持 BPE 和 Unigram 模型。
3. GPT 系列
OpenAI GPT 系列(包括 GPT-2、GPT-3)使用了一種改進版的 BPE,稱為 Byte-Level BPE,對輸入進行字節級別處理,能處理任意 UTF-8 字符。
九、小結
BPE 是一種高效的分詞算法,介于詞級和字符級之間。通過頻率驅動的合并策略,構建出對語言有表達能力的子詞單元,有效減少詞表大小,提升模型泛化能力。如今,它已成為現代 NLP 模型(如 Transformer 系列)的基礎技術之一。