Tokenization
Basics
將自然語言輸入給模型需要經過轉換 (變成 embedding), 主要有以下兩步驟:
- 分詞, 並把詞轉為 Token
- 把 Token 轉換為 Embedding
Tokenize 分為三種粒度:
- Word: 最簡單的語言單元, 常見的語言可以用空格或是標點符號(e.g. 英文) 拆分詞彙, 並在 Embedding Matrix 中查詢對應 Token 的 Embedding Vector, 實作相對簡單, 缺點為 Embedding Matrix 的大小會很大, 且容易 OOV
- Char: 基本的字, 數量相對很少, 缺點為因為 Embedding 的基數太小, 在學習時每個 Vector 都會學到太多語義, 且無法保留詞彙的語義與邊界, 更會顯著增加模型輸入計算壓力
- Subword: 介於 Word 和 Char 之間, 平衡了詞彙量與每個 Vector 的語義獨立性, 對於常用詞保留原狀, 對於生僻詞則使用拆分, 共享 Token 壓縮空間, 整體相對較優
BPE (Byte-Pair Encoding)
一種Subword tokenize算法, 參考 Neural Machine Translation of Rare Words with Subword Units 的程式碼:
import re, collections
def get_stats(vocab): pairs = collections.defaultdict(int) for word, freq in vocab.items(): symbols = word.split() for i in range(len(symbols)-1): pairs[symbols[i],symbols[i+1]] += freq return pairs
def merge_vocab(pair, v_in): v_out = {} bigram = re.escape(' '.join(pair)) p = re.compile(r'(?<!\S)' + bigram + r'(?!\S)') for word in v_in: w_out = p.sub(''.join(pair), word) v_out[w_out] = v_in[word] return v_out
vocab = {'l o w </w>' : 5, 'l o w e r </w>' : 2, 'n e w e s t </w>':6, 'w i d e s t </w>':3}num_merges = 10
for i in range(num_merges): pairs = get_stats(vocab) best = max(pairs, key=pairs.get) vocab = merge_vocab(best, vocab) print(best)首先初始化詞彙表: 把所有的 word 拆分成 char 列表:
'l o w </w>' : 5'l o w e r </w>' : 2'n e w e s t </w>' : 6'w i d e s t </w>' : 3接著計算 pair 的頻率, 再合併頻率最高的 pair
當詞彙表到達指定的數量則停下, 算是一種 greedy 算法
在比較近代的模型 (GPT-2, RoBERTa, …) 中, 為避免新的詞被標記成 [UNK], 不使用 Unicode 字元, 使用 Byte, 來保證任何文本都可以輸入, 也能處理複雜符號 (emoji)
WordPiece
與 BPE 類似, 都是由小到大合併的策略, 但在合併階段選擇最大分數的 pair, 而非最大頻率. 分數的計算方式類似互信息(Mutual Information):
這種方式傾向合併那些「共同出現頻率高, 但各自單獨出現頻率低」的 pair, 能更好地捕捉有意義的子詞組合
使用 WordPiece 的模型:BERT、DistilBERT 等
Unigram Language Model
與 BPE「由小到大合併」不同, Unigram 採用「由大到小剪枝」的策略
核心假設
假設每個子詞獨立出現, 序列機率為各子詞機率的乘積:
詞彙表建立
給定語料庫, Unigram 的目標是最大化以下似然:
其中 是單詞 所有可能的分割集合
建立流程:
- 初始化一個大型種子詞彙表(所有字元 + 高頻子字串)
- 用 EM 演算法估計每個子詞的機率
- 計算每個子詞的 loss(移除後似然度下降量)
- 移除 loss 最小的子詞(保留前 η%, 如 80%)
- 重複步驟 2-4, 直到達到目標詞彙大小
因為始終保留單一字元,確保不會有 OOV 問題
與 Subword Regularization 的關係
Unigram 的優勢在於能輸出多種分割及其機率, 這使它可以搭配 Subword Regularization 訓練策略使用
傳統 NMT 使用固定分割, 優化:
Subword Regularization 改為對所有可能分割取期望:
這讓模型在訓練時看到同一句子的不同分割方式, 增強魯棒性
SentencePiece
- 把句子視為原始字元流(包含空格),不依賴預先的詞邊界切分
- 用特殊符號
▁標記詞的開頭(空格位置) - 支援 BPE 和 Unigram 兩種演算法
例如 “Hello World” → “▁Hello” “▁World” 或 “▁He” “llo” “▁Wor” “ld”
使用 SentencePiece + Unigram 的模型:XLNet、T5、ALBERT 等