上一节看到,Qwen3.5 的词表有 24.8 万个 token。如果我们的迷你模型直接用它,会发生什么?
算一下:迷你模型每个 token 用 512 维,词嵌入矩阵就是 248320 × 512,约 1.27 亿个参数。
为什么词表一大,词嵌入就跟着大?上一节讲过,词嵌入是一张表,词表里每个 token 占一行,每行 512 个数字。
词表有多少个 token,这张表就有多少行:248320 行 × 512 列,就是 1.27 亿个数字。
而整个迷你模型计划只有两千多万参数。光是一本"词典",就比整个模型大四五倍。
所以小模型要配一本小词典。这一节我们用上一章下载的预训练语料,训练一个只有 8192 个 token 的分词器。
学完你能做到:讲清楚 BPE 是怎么一步步"学"出词表的,知道词表大小怎么取舍,并且得到一个能直接用于预训练的分词器。
一、BPE:从字节开始,一步步合并
现在主流模型用的分词算法,大多是 BPE(字节对编码)或它的变体。它的思路很朴素:
- 一开始,词表里只有 256 个字节。任何文字都能拆成字节,所以从一开始就不会有"不认识的字"。
- 统计语料里哪两个相邻的 token 一起出现得最多,把它们合并成一个新 token,加进词表。
- 重复第 2 步,直到词表达到预定的大小。
拿中文举个例子。先说清"字节"是什么:电脑里的所有文字,最后都存成一串数字,每个数字就是一个字节,大小在 0 到 255 之间,一共只有 256 种。
文字怎么变成字节,有一套通用的规则,叫 UTF-8:一个英文字母占 1 个字节,比如"A"就是 65;一个汉字通常占 3 个字节,比如"天"是 229、164、169 这三个数。
所以词表一开始放进这 256 个字节,就像拿到了 256 种最小的积木:不管什么字、哪国文字,甚至表情符号,都能用它们拼出来。BPE 接下来做的,就是把经常挨在一起的积木粘成更大的一块。
训练刚开始时,"天"是 3 个字节 token;因为这 3 个字节总是一起出现,很快就会被合并成一个"天"字 token。
再往后,"天"和"气"经常挨着,又被合并成"天气";如果语料里"今天天气"出现得足够多,连这四个字都会合成一个 token。

合并的顺序就是一张规则表。分词时,按同样的顺序把新句子里能合并的地方合并起来,就得到了 token。
用一个极小的例子走一遍。为了看得清楚,这里把每个汉字当作一个起点,省掉字节合并成汉字那一步。假设语料只有三句话:
天气好 天气冷 今天天气好| 轮次 | 出现最多的相邻组合 | 合并后的结果 |
|---|---|---|
| 第 1 轮 | "天"+"气",出现 3 次 | 天气 好 / 天气 冷 / 今 天 天气 好 |
| 第 2 轮 | "天气"+"好",出现 2 次 | 天气好 / 天气 冷 / 今 天 天气好 |
| 第 3 轮 | 剩下的组合都只出现 1 次,按规则任选一个继续,或者词表满了就停 |
三轮过后,词表里多了"天气"和"天气好"两个 token。真实的训练要在几十 MB 的语料上做几千次这样的合并,原理完全一样。
画成积木是这样的,每一轮都把挨着出现最多的那一对粘成一块:

这两轮也留下了一张规则表:第 1 条,"天"+"气"→"天气";第 2 条,"天气"+"好"→"天气好"。
前面说"分词时按同样的顺序合并",就是拿新句子照着这张表一条条做。比如来了一句没见过的"明天天气好":
一开始: 明 天 天 气 好
按第 1 条:明 天 天气 好
按第 2 条:明 天 天气好最后切成"明""天""天气好"三个 token。训练是"学规则",分词是"用规则":用的时候不再数数,只照着表做。
你可能听说过,处理中文要先"分词",比如用 jieba 这类工具把句子切成词语。
BPE 不需要这一步:它不懂什么是词,只看统计,哪些字经常挨在一起就合并哪些。
好处是不依赖任何词典,新词、网络用语、中英混杂的句子都能处理。
代价是它合出来的 token 不一定是语言学意义上的词,比如下面会看到的"我们去""模型的"。对模型来说,这并不影响它学习。
二、词表开多大
词表大小是一个取舍:
| 词表小 | 词表大 | |
|---|---|---|
| 词嵌入和输出层 | 参数少 | 参数多 |
| 同一段话切出的 token | 多,序列长,算得慢 | 少,序列短,算得快 |
| 生僻词 | 拆得很碎 | 更可能是完整的 token |
| 适合 | 小模型 | 大模型、多语言模型 |
表里这几行,各自是怎么来的:
- 参数多少:词嵌入表每个 token 一行,词表多一个 token,表就多一行 512 个数字。我们的迷你模型,输出层和词嵌入共用这张表,所以两头一起变大。
- 序列长短:词表小,能收进去的"大积木"就少,同一句话只能用更多小积木拼。第四部分会看到,"大语言模型的推理速度主要受内存带宽限制。"这句话,我们 8192 的词表切出 14 个 token,千问 24.8 万的词表只要 11 个。每个 token 都要走完模型的每一层,token 越多,计算越多;上下文长度也是按 token 算的,token 越多,同样大的窗口装下的字就越少。
- 生僻词:词表里没有的词,只能拆成更小的块,最碎的时候会拆回单个字,甚至拆回字节。
几个真实模型的词表大小:MiniMind 用 6400,Mistral 早期版本用 32000,Llama 3 用约 12.8 万,Qwen3.5 用约 24.8 万。
模型越大,词嵌入在总参数里占的比例越小,词表就可以开得越大。