编程基础篇 · 大模型肚子里的数据结构

词表与 Trie:Tokenizer 的切词秘密

还记得大模型原理篇那个细节吗——分词器把「五花肉」切成一整块词元,而不是三个字。当时我们说「常见组合当一个整体」,这次揭底层:分词器是怎么在几万个词里,瞬间认出「五花肉」该整块拿走的?答案是一种叫 Trie(前缀树)的收纳方式——把词表按「共享开头」挂成一棵树。

先看收纳 · 词表怎么挂成一棵树

假设词表里有这些词:五月五花肉今天天气。按第一个字、第二个字……一层层挂起来,共享开头的词就共享树枝——「五月」和「五花肉」挤同一根「五」枝。带绿色 ✓ 的节点表示「走到这里是一个完整的词」;注意「五→花」那个节点没有 ✓:它只是路过的中转站(「五花」不是词)。

选一句话:
点「开始分词」,光标会逐字沿着树往下走。留意两件事:走到 ✓ 时它不急着切(贪心,先试试能不能更长);走不通时它回退到最近的 ✓ 才切刀
分词结果:
全程约 15 秒,每一步有旁白
这套走法叫「贪婪最长匹配」:能走多深走多深,走不通就回退到最近的词尾切刀。为什么要贪?因为「五花肉」整块切,比「五 / 花 / 肉」三块更省 token、也更保住语义。而 Trie 的妙处在于:每一步只看「当前节点有没有这个字的树枝」,不用回头把词表翻一遍——几万个词的词表,判断一步只要一次查找。这又是「收纳得好,找起来快」。
揭底 · 真实大模型用的是 BPE,思想同源

🧩 BPE:把「最常一起出现的字符对」反复合并成块

真实的 Tokenizer(GPT、DeepSeek 都在用的 BPE)建词表的方式更野:先把所有文字拆成最小碎片,然后数一数哪两个碎片最常挨在一起,把它们粘成一块收进词表;再数、再粘,重复几万次。常见组合就这样一层层「长」成了大块词元——和 Trie「常见的词整块收纳」是同一个思想。

五花肉 → 高频,各自一整块
「饕餮」 饕(碎块1) 饕(碎块2) 餮(碎块1) 餮(碎块2) → 生僻,被拆成字节碎块

所以你见过的现象都有了解释:「的」「,」永远只占一个 token;生僻字反而被拆成好几块。这也是中文普遍比英文费 token 的原因——大多数词表以英文语料为主训练,英文常见词都攒出了整块词元,中文攒得少,只好多切几刀。同一句话,中文版账单往往更贵,根子就在词表这本「字典」收纳了谁。

✅ 这一课想和你分享的