你在 GitHub 上看程式碼改動時,系統會用紅綠底色標出「這次到底改了哪幾行」——電腦怎麼認出哪裡是新增、哪裡是 刪掉?這就是 Myers Diff 在做的事:它像核對兩份行程表,只圈出不一樣的地方,用最少的增刪把舊版變成 新版。BPE 則管另一件事:AI 讀你的句子前,得先把文字切成一塊塊小單位,它的做法是把最常一起出現的 字母黏成「零件」(像把 e、s 黏成 es),這樣常見詞用幾塊就拼得出、罕見詞也拆得開。下面你會看到這兩件事 各自一步步發生。
兩者都是把「文本」變成演算法可操作的結構化資料的基礎工具,但服務的問題不同:Myers Diff 在兩份文本間 找出最短編輯腳本(Shortest Edit Script)——在「編輯圖」(edit graph)上逐輪推進差異量 d,沿每條對角線 貪婪 snake 前進,找出從 A 轉換為 B 所需的最少插入/刪除步驟,是 git diff、多數版本控制與 IDE 比對工具 背後的核心演算法;BPE(Byte Pair Encoding)則是把文本切成「子詞」(subword)單元——逐輪統計相鄰 token pair 的加權頻次、合併頻次最高者、詞彙表隨之成長,在「詞級別」與「字元級別」間取得平衡,是幾乎 所有現代 LLM tokenizer(GPT 系列、RoBERTa 等)的基礎。
逐輪推進差異量 d(d=0,1,2,...):第 d 輪窮舉所有與 d 同奇偶的對角線 k(k = x−y,範圍 −d..d,step 2), 每條對角線先比較上一輪鄰居 V[k−1]+1(刪除 A 一字元)與 V[k+1](插入 B 一字元)何者較大,取較大者為本輪 furthest-reaching 起點 x(k=−d 或 k=d 邊界時僅一種來源),再沿對角線貪婪 snake 前進(連續相同字元可 「白吃」,不計入編輯距離)。一旦某條對角線走到終點(x=|A|、y=|B|),該輪 d 即為最短編輯腳本長度; 本輪其餘對角線仍算完(不提前中止),隨後由終點沿 V 陣列逐輪回溯,重建出由前往後排列的編輯腳本。
每個詞先依字元切分、尾端附加詞尾標記 </w>(Sennrich et al. 2016 論文慣例,用來區分
「詞尾」與「詞中」出現的相同子詞),得到初始 token 化與初始詞彙表。逐輪:(1) 統計全語料所有詞、所有
相鄰 token pair 的加權頻次(加權 = 該詞的語料出現頻次,而非詞種數——出現 5 次的詞,其 pair
貢獻頻次即為 5);(2) 取頻次最高的 pair 合併為單一新 token(若並列最高,取字典序較小者:先比 pair 的
left token 字串,相同再比 right token 字串);(3) 將該 pair 在所有詞的 token 序列中由左到右不重疊
掃描式合併,詞彙表新增合併後的 token。固定跑 6 輪。
</w> 為詞尾標記,本身也是可被合併的 token(如 round 3 合併出
est</w>)。藍色外框(active)= 本輪操作影響的格;粉紅(pivot)本頁未使用
(BPE 每輪為全語料批次合併,不是單一格的比較/確認,故以 active 標示本輪新生成的 token 位置更貼切)。
tie-break 誠實揭露:round 1/2/4/6 頻次並列最高,取字典序較小者勝出,並非「隨機」或「先出現者」;
round 3/5 無並列。與 LLM tokenizer 的關聯:GPT 系列、RoBERTa 等現代 LLM 的 tokenizer 皆以此
演算法(或其變體)離線訓練固定大小的子詞詞彙表,推論時用相同規則把輸入文字切成 token。