LLM无法正确计算"strawberry"中R的数量,根源在于tokenization机制——模型处理的是token而非字母,若单词被切分为单个token则无法访问内部字符。
问一个 LLM"strawberry"中有多少个 R,它通常会回答两个。这不是愚笨——它是一扇直接窥探这些模型如何"看"文本的窗口,理解这一点能解释它们诸多古怪行为的出乎意料的原因。
模型从未"看到"字母。它看到的是 token。一旦你理解了 tokenization(分词),一整类"它为什么会那样做"的谜团就烟消云散了。
在任何一个单词抵达神经网络之前,它已经被切分成 token——这些块通常是完整的单词,有时是词片段,有时只是几个字符。"strawberry"可能变成一个单独的 token,也可能被拆分成"straw"和"berry"。模型只在这些块及其数字 ID 上进行运算。它无法直接访问 token 内部的单个字母。
这就是为什么它数字母会很难:如果"strawberry"是一个不透明的 token,模型从来就没有被给予过那些 R 来计数。它不是在推理拼写,而是在推理一个代表单词的符号。让一个人去数一个只能听、不能看的单词里的字母,他也会同样困难。
这不是一个 trivia 细节——它有真实的后果:
成本和限制以 token 而非单词计算。 你的上下文窗口、你的 API 账单、你的速率限制——统统以 token 计量。大致来说,英语约为每 token 0.75 个单词,但代码、标点符号和其他语言差异巨大。
某些语言要"纳税"。 Tokenizer 通常针对英语优化。相同含义的句子,用代表性较弱的语言可能要多消耗两到三倍的 token——意味着更高的成本和更少的上下文窗口空间。
生僻词会碎裂。 常用词是一个干净的 token;一个生僻的名字或新造的字符串会碎成很多片,模型处理起来就没那么从容。
空白和格式也是 token。 你的文本如何空格、如何标点,会悄悄改变模型看到的 token 流。
理解这些会改变你编写 prompt 的方式以及估算成本的方法——这类底层细节是我在构建系统时一直关注的。
以下是它如何与整体技术栈相连。每个 token ID 都被映射到一个 embedding——一个捕获其含义的向量——模型实际推理的是这些向量。Tokenization 是门;embeddings 是门后的房间。如何切分文本的选择,从一开始就决定了模型得以操作的素材。
当模型在拼写、字符计数或罕见字符串上做出令人困惑的行为时,你的第一个念头应该是:那个东西在 token 层面长什么样?有一半的时候,"推理失败"实际上是 tokenization 的人工痕迹——模型回答的是一个它从字面上根本看不到各个碎片的问题。
知道模型的视野从哪里开始、到哪里停止,是区分"猜测它的行为"和"理解它的行为"的关键。更多内容见 www.divyakush.com。
Embeddings and semantic search, from the ground up — what happens to tokens once they become vectors.
Divyakush Punjabi · Full-Stack & AI Engineer Portfolio · GitHub · LinkedIn
For further actions, you may consider blocking this person and/or reporting abuse