跳到主要内容

模型眼里的文字是一串编号 — 切法、温度(控制随机程度的旋钮),以及那些奇怪的错误

这一章讲三件事: 文字进模型之前要被切成什么(切法是一门学问); 一个回答是怎么从一串概率里被挑出来的(温度那几个旋钮到底在拧什么); 以及那些广为流传的怪错,为什么大半能追溯回这条链路。

它在全书链条里的位置: 第 12 章讲了训练题是什么, 这一章讲这台机器日常怎么干活。第 15、16 章讲它怎么被造出来之前, 先看清它的输入输出口。

1. 模型看到的不是字

先破一个几乎所有人的默认想象:你以为模型在读「句子」, 它读的是一串编号1

你打进去「上海天气」,它看到的不是这四个字, 而是类似 101、5821 这样的一串数字;每个数字再被换成一串几百位的向量, 才送进第 10 章那块积木。文字和模型之间,隔着一个翻译官:分词器。

这个翻译官的切法,决定了模型眼里世界的样子—— 而这一章会看到,很多怪错的根子就埋在这里。

2. 按字切太细,按词切切不动

怎么切?两个极端都不行2

按字切(一个字母、一个汉字一个单位):太细。 「extraordinary」拆成 13 个单位,一句话变成几百个单位的长序列—— 第 11 章那张平方账单立刻吃不消。

按词切:切不动。 英文还好办,中文、日文的「词」边界本来就模糊—— 「我爱机器学习」到底算几个词?三个?两个?连人都达不成一致, 更别说拿它当机器的固定单位。

所以工程上的答案落在中间:让数据自己决定切多粗。 这就是下一节的算法。

3. 字节对编码:从最高频那一对开始合

现在主流的切法叫字节对编码(BPE)。 它的想法朴素:从频率统计出发——常见词整切,稀有词切成子词(更小的词块)3

直觉例子,书里给了三个4:

  • 「the」「and」出现得极多,各自就是一个完整单位;
  • 「extraordinary」出现得少些,切成「extra」+「ordinary」;
  • 一个生僻词「ultraconfucianism」,切成「ultra」+「confucian」+「ism」。

中文同理:「机器学习」出现得多,可能是一个单位; 「量子纠缠」中等,可能是「量子」+「纠缠」; 一个罕见词可能被切成几个单字。

它没有任何语言学知识,只数频率。 常见的东西,给一个整编号,省长度; 罕见的东西,拆碎——反正任何词都能被拆出来,词表(模型认识的全部单位清单)里不存在「不认识的词」

4. 一次合并到底做了什么

这个算法具体怎么学出切法?流程只有一句话: 反复找出全文里最高频的相邻一对,给它发一个新编号,全文替换。

走一遍迷你的(语料——即训练用的文本库——和频率都是编的,只为演示):

语料:机器学习 我爱 机器学习 我爱 机器
第 1 轮:最高频的一对是「机+器」(出现 3 次)→ 合并成新单位「机器」
第 2 轮:最高频的一对是「机器+学习」(出现 2 次)→ 合并成「机器学习」
……几千轮之后,常见词各自有了整编号

这张图看的是合并的全部:找最高频的一对、发新编号、替换,重复几千轮。

补充(不在书里,依据我们的 frontier 书架): 一个教学级实现里, 每一轮的核心就是一行:在所有相邻对的计数里,挑出计数最高的那一对5。 词表就是这样一圈一圈长出来的。

5. 词元和字数,对不上

切出来的单位叫词元(模型眼里的最小文字块: 可能是一个字、一个词,也可能只是词的一部分)6

于是有了一个日常会撞见的换算问题:词元数和你数的字数,对不上。 书里给的换算:英文一个词元大致相当于 0.75 个单词 (100 个单词大约 130 个词元);中文一个词元大致相当于 1 到 1.5 个汉字7

这不是抬杠,是钱。API(模型服务的收费入口)按词元收费,窗口按词元算长度—— 你以为「这句话没几个字」,账单按它自己的数法算。

6. 为什么它数不清单词里有几个字母

现在可以讲那个著名的怪错了:问模型「strawberry 里有几个 r」, 它常常答错。

根子在第 3 节:在它眼里,strawberry 不是一个一个字母, 而是两三个词元块8。你让它数字母, 就像让一个人隔着磨砂玻璃数葡萄—— 他看到的是一团紫色,不是每一颗葡萄9

这不是模型笨,是它的视力和你不一样。 你看到的是字母流,它看到的是词元块。 凡是依赖「字母级」视力的任务——数字母、比大小写、 精确到某个字符的拼写检查——都是它的先天弱项。

7. 走查:一次生成的完整链路

这一章的主走查:从「上海天气」到它答出下一个词,一步不落。

①「上海天气」
② 分词器切分 → 101, 5821, ……(一串编号)
③ 每个编号换向量 → 每个编号变成 768 个数
④ 多层积木处理 → 经过 12 层(第 10 章那六步,重复 12 次)
⑤ 原始分数 → 词表几万个候选词元,各得一个分数(logits)
⑥ 归一成概率 → 很好 0.4、晴 0.3、热 0.15、冷 0.05、……
⑦ 挑一个 → 按某种策略挑出一个,比如「晴」
⑧ 接回输入 →「上海天气晴」,回到第 ① 步,再猜下一个

这张图看的是一次生成的全链路。每一个回答,都是这个循环转了几十上百圈的结果。

第⑤步的「原始分数」值得停一下。它有个专门的名字:logits—— 书里的比方是卷面原始分:几万个候选各有一个分, 但还不是「选谁」的概率10

第⑥步那道归一(就是第 09 章那道 Softmax)才把它折算成 概率分布(所有候选各领到一份、加起来等于 1 的比例)。原始分数和概率是两样东西: 概率是最后一步折算出来的。

第⑦步的「挑一个」,就是接下来三节的主角—— 挑法不同,同一个模型的「性格」完全不同。

8. 温度:把分布拧尖,还是摊平

最直接的挑法是每次都挑概率最高的那个(贪心)。 问题是:它死板。「前一句很好」之后最可能的总是「是的」, 贪心会一直写「是的、是的、是的」——对话场景下这是灾难11

要多样性,就得按概率随机挑。而随机的程度,可以用一个旋钮调: 温度。它拧的是第⑤步那些原始分数12:

温度分布变成什么样出来的东西
接近 0拧到极尖,几乎只剩最高分像字典:总挑最常见的答案
1 左右原样正常发挥
远大于 1摊平,高低分都差不多像喝醉的人,开始胡言乱语

这张表看的是温度的本质:它不是「随机性开关」,是在缩放原始分数。

实际使用中常设在 0.7 左右——在「每遍一样」和「胡言乱语」之间。 所以同一句话问两遍答案不一样,不是出了故障,是这个旋钮在正常工作13。 书里的分工建议:严谨的代码生成用低温度(0.1–0.3), 创意写作用高温度(0.8–1.2)14

9. 只在前几个里挑:Top-K 与 Top-P

温度管「整体多随机」,还有两个旋钮管「把长尾砍掉」。

概率分布有一条长长的尾巴:几万个候选里, 排几千名之后的那些词,单个概率极小,但偶尔也会被抽中—— 一抽中就是离谱的词。两个砍法15:

  • Top-K:只留概率最高的 K 个(比如 50 个),其余全部清零,再在里面挑;

  • Top-P(也叫核采样):从最高的往下累加,凑够某个比例(比如 0.9)就停, 只在这个动态大小、最靠前的一小段里挑。

Top-P 更常用,因为它自适应:分布尖的时候头部(排最前的候选)只有两三个候选(很稳), 分布平的时候头部有几百个(很活)——它随题目的确定程度自动收放。 实际使用里常见的组合就是:温度控制整体,Top-P 砍掉长尾16

10. 束搜索:为什么用得越来越少

还有一种更「理性」的挑法:不只看下一步,同时保留最可能的 K 条路径往前走, 最后取总概率最高的整条。它叫束搜索,过去是机器翻译的标配17

为什么现在用得越来越少?因为它找到的是「总分最高」的文本, 而总分最高的文本往往是最安全也最平庸的—— 概率最高的措辞,永远是人人都说的那几句。 对话和创作要的不是「最不会错」,是「好」。 生成这件事的评价标准,从「像标准答案」换成了「像好回答」, 束搜索就退场了18

11. 分词决定了很多奇怪的错误

收个尾,把这一章解释得掉的怪错归个堆:

怪错根子在哪一节
数不清单词里有几个字母第 6 节:它看到的是词元块,不是字母
同一句话问两遍答案不一样第 8 节:温度在正常工作
偶尔蹦出一个离谱的词第 9 节:长尾没砍干净
回答又安全又平庸第 10 节:总分最高不等于好
账单和「字数」对不上第 5 节:词元有自己的数法

这张表的共同教训:模型很大一部分「错」,错在它看世界的最小单位,不在它的脑子。 再遇到它犯怪,先问一句:这件事在它的词元眼里,长什么样?

12. 作者的判断与证据

有证据的部分。 BPE 的算法、0.75 与 1–1.5 的换算、 解码各策略的定义,都是公开实现和标准做法; 「隔着磨砂玻璃数葡萄」是书里自己的比方。

要分开看的三处:

  1. 0.7、0.1–0.3、0.8–1.2 这些温度值是经验习惯,不是标准。 不同模型、不同任务的顺手区间不同。
  2. 「字母级任务都是弱项」。 大致成立,但模型可以学会绕过: 先把单词拼写出来逐字母列,再数——这是第 17 章「把话问对」里的一条。 弱的是直接判断,不是「无解」。
  3. 「束搜索退场」。 指的是开放式对话与创作; 在翻译、摘要这类「有标准答案可逼近」的任务里,它并没有消失。

判断(我们的,不是书里的):这一章最被低估的是第 2 节那句「中文的词边界本来就模糊」。 分词不是工程的细枝末节,是这台机器和语言之间的第一道翻译—— 它的偏见、它的粒度,会被后面所有层继承。 两个模型能力相当,分词器不同,在同一句中文上的表现可以差出一截。 如果错,会错在: 模型规模的扩大在一定程度上消化了分词的不完美—— 足够大的模型能从「切得不好」里自己学出补偿。 分词的重要性在下降,但它「决定最小单位」这件事本身不会消失。

13. 边界与局限

  • 词元怎么变成向量,只给了一句话。 那是一张巨大的查表,第 02 章讲过表示, 这一版不再展开。
  • BPE 的几个变种只给了名字。 思路相同,细节各异,书里没有展开19
  • logits 怎么从最后一层算出来,没有讲。 只需知道它是「几万个候选各一个分」。
  • 「词元偏见」没有系统数据。 不同语言在词元上的效率差异很大 (同样一段意思,有的语言要花更多词元),书里没给对比数。
  • 这一章只讲了「一个模型单独生成」。 多次采样再挑、 生成时自我检查这些「多花计算」的做法,第 17 章讲。

14. 可带走的

  1. 模型读的不是字,是一串编号。 文字和模型之间隔着分词器。
  2. 字节对编码:常见词整切,稀有词切子词。 它只数频率,不懂语言学。
  3. 一次合并 = 找最高频的一对、发新编号、全文替换。 重复几千轮,词表就长出来了。
  4. 词元有自己的数法:英文 1 词元 ≈ 0.75 个单词,中文 ≈ 1–1.5 个汉字。 账单按词元算。
  5. 数不清字母,因为它是隔着磨砂玻璃数葡萄。 词元块里没有字母。
  6. 一次生成八步:切分、编号、向量、多层、原始分数、概率、挑一个、接回去。
  7. 原始分数不是概率;概率是最后一步折算(归一化——即把各种原始分数换算成同一把尺子下、总和为 1 的比例)出来的。
  8. 温度拧的是原始分数:0 像字典,1 正常,远大于 1 像喝醉。 答案不一样不是故障。
  9. Top-P 随题目确定程度自动收放;温度 + Top-P 是常见组合。
  10. 束搜索找的是总分最高,而总分最高常常最平庸。 标准从「不错」换成「好」,它就退场了。
  11. 遇到怪错先问:这件事在它的词元眼里长什么样?

15. 原文地图

主题原书章原文位置
编号与生成链路图第8章 语言的魔法:大语言模型text/09-ch08.txt:183(搜「词元编号」)
两极端都不行第8章 语言的魔法:大语言模型text/09-ch08.txt:179(搜「边界很模糊」)
BPE 的想法第8章 语言的魔法:大语言模型text/09-ch08.txt:196(搜「常见词整切」)
BPE 三个例子第8章 语言的魔法:大语言模型text/09-ch08.txt:198(搜「ultraconfucianism」)
词元与字数换算第8章 语言的魔法:大语言模型text/09-ch08.txt:204(搜「0.75」)
磨砂玻璃数葡萄第8章 语言的魔法:大语言模型text/09-ch08.txt:209(搜「磨砂玻璃」)
logits第8章 语言的魔法:大语言模型text/09-ch08.txt:129(搜「logits」)
贪心第8章 语言的魔法:大语言模型text/09-ch08.txt:134(搜「贪心解码」)
温度第8章 语言的魔法:大语言模型text/09-ch08.txt:139(搜「温度」) · :141(搜「像字典」) · :143(搜「0.7」)
Top-K 与 Top-P第8章 语言的魔法:大语言模型text/09-ch08.txt:144(搜「Top-K」) · :146(搜「Top-P」)
束搜索第8章 语言的魔法:大语言模型text/09-ch08.txt:148(搜「束搜索」)
组合与分工第8章 语言的魔法:大语言模型text/09-ch08.txt:150(搜「组合」) · :151(搜「低温度」)
词元定义第8章 语言的魔法:大语言模型text/09-ch08.txt:29(搜「词元」)
香蕉与鸡蛋第8章 语言的魔法:大语言模型text/09-ch08.txt:109(搜「鸡蛋通常是」)

Footnotes

  1. 出处:「第8章 语言的魔法:大语言模型」第 183 段(text/09-ch08.txt:183,搜「词元编号」)。 原文:「大语言模型并不直接『看见文字』,它先把文字变成词元编号,再变成向量」。

  2. 出处:「第8章 语言的魔法:大语言模型」第 179 段(text/09-ch08.txt:179,搜「边界很模糊」) 与第 180 段(text/09-ch08.txt:180,搜「那样太细」)。

  3. 出处:「第8章 语言的魔法:大语言模型」第 196 段(text/09-ch08.txt:196,搜「常见词整切」)。

  4. 出处:「第8章 语言的魔法:大语言模型」第 198 段(text/09-ch08.txt:198,搜「ultraconfucianism」)。

  5. 补充(不在书里,依据我们的 frontier 书架):minbpe 的训练循环里, 每一轮就是从计数中挑出最高频的那一对,发新编号、全文替换。 依据: shelf=ai-frontier-reference/minbpe@src:minbpe/basic.py:35 @1acefe89412b20245db5a22d2a02001e547dc602 事实=pair = max(stats, key=stats.get),随后 merge 替换全部出现。

  6. 出处:「第5章 注意力:引爆大模型的引擎」第 43 段(text/06-ch05.txt:43,搜「词元」)。 原文:「它可能是一个汉字、一个英文词,也可能只是一个词的一部分」。

  7. 出处:「第8章 语言的魔法:大语言模型」第 204 段(text/09-ch08.txt:204,搜「0.75」)。 括号里的「100 个单词约 130 个词元」是我们按 0.75 换算的。

  8. 出处:「第8章 语言的魔法:大语言模型」第 208 段(text/09-ch08.txt:208,搜「几个字母」)。

  9. 出处:「第8章 语言的魔法:大语言模型」第 209 段(text/09-ch08.txt:209,搜「磨砂玻璃」)。

  10. 出处:「第8章 语言的魔法:大语言模型」第 129 段(text/09-ch08.txt:129,搜「logits」) 与第 130 段(text/09-ch08.txt:130,搜「卷面原始分」)。

  11. 出处:「第8章 语言的魔法:大语言模型」第 134 段(text/09-ch08.txt:134,搜「贪心解码」)。

  12. 出处:「第8章 语言的魔法:大语言模型」第 139 段(text/09-ch08.txt:139,搜「温度」)。 原文:「它可以理解成对 Softmax 前 logit 的缩放」。

  13. 出处:「第8章 语言的魔法:大语言模型」第 141 段(text/09-ch08.txt:141,搜「像字典」) 与第 143 段(text/09-ch08.txt:143,搜「0.7」)。

  14. 出处:「第8章 语言的魔法:大语言模型」第 151 段(text/09-ch08.txt:151,搜「低温度」)。

  15. 出处:「第8章 语言的魔法:大语言模型」第 144 段(text/09-ch08.txt:144,搜「Top-K」) 与第 146 段(text/09-ch08.txt:146,搜「Top-P」)。

  16. 出处:「第8章 语言的魔法:大语言模型」第 150 段(text/09-ch08.txt:150,搜「组合」)。 「Top-P 自适应收放」是我们对它机制的解读,书里没展开。

  17. 出处:「第8章 语言的魔法:大语言模型」第 148 段(text/09-ch08.txt:148,搜「束搜索」)。

  18. 出处:「第8章 语言的魔法:大语言模型」第 149 段(text/09-ch08.txt:149,搜「安全但平庸」)。

  19. 出处:「第8章 语言的魔法:大语言模型」第 195 段(text/09-ch08.txt:195,搜「WordPiece」)。