Token —— LLM眼里的最小单位
上一篇我留了个尾巴:LLM 没有记忆,你以为的“他记得上文”,其实是上文被重新喂了一遍。
那接下来必然会有一个问题:喂进去的这一大坨东西,我该怎么算量?
这就是 掏啃(Token,词元),你肯定见过他,不是在账单上(“本次对话消耗 114,514 Token”),就是在报错里(“context(上下文)已超出上限”)。但大概率没人认真跟你讲过,这个“掏啃”到底是个什么玩意。
首先要明白一点:LLM 看到的不是字,也不是词
先说结论:Token 是模型处理文本的最小单位,而他既不是字,也不是词。
举个最简单的例子。你对他说:
我爱北京天安门
你看到的是七个字。但他眼里大概率是这样的:
["我爱", "北京", "天安门"]
三块,这一句话就是被分成三块。
会不会有点意外?“北京”两个字被当成一个整体,“天安门”三个字也是一块,而“我爱”也挤在了一起。
那我们可爱的屏幕前的你又要问了:为什么我们不干脆一个字一个字地处理?
是两个原因:一个省事,一个必需。
省事:把“天安门”当成一个单元,比拆成“天”“安”“门”少算两步。而且拆开反而容易出岔子——“门”会被往 door 那个意思上带偏。语义相关的字打包在一起,既快又准。
必需:模型要处理的不只是中文。英文、日文、阿拉伯语,还有代码和表情符号,全都得用同一套逻辑过一遍。字数和单词数在不同语言里根本不是一回事,而 Token 是所有语言都能换算过去的那个共同刻度。
切文本的那套程序在干什么
负责切文本的程序叫分词器(Tokenizer),现在主流用的是 BPE(字节对编码),原理其实并不复杂:
从单个字符开始,统计哪两个字符最常挨在一起出现,把它们合并成一块。合并完再统计,再合并。反复几千轮,最后得到一张几万到十几万块的词表。
所以一个词会被切成几块,取决于它在训练语料里出现的频率,而不是长度。常见的词整块留着(“人工智能”很可能就是一块),生僻的词被拆开——“饕餮”这两个字,在 GPT 的分词器里能拆成四块。
注意看,这里写的是频率,不是长短,所以“你好”是一块“掏啃”,某个很长的英文单词也可能是一块“掏啃”——只要它够常见。
中文到底贵不贵
这是互联网上一堆人们最容易吵起来的问题,因为真正的答案要取决于你用哪个模型。
早期大家都拿 GPT 系列说事,那时候中文确实吃亏:一个汉字经常要 1.5 到 2.5 个 Token,因为它的词表是按英文语料建的,中文只能靠字节级别硬拼。同一段话,用中文发出去,账单就是比英文贵一截。
但你现在用的国产模型,情况完全不一样了:Qwen、文心、豆包这些,都把中文词表重新做过,基本能做到一个汉字等于一个 Token,有的甚至一个 Token 能装下 1.5 到 2 个汉字。
(这里小小地插一句嘴:你可能会在别处看到“一个 Token 大约等于 1.5 到 2 个汉字”这种说法,但别被绕进去——那是国产模型的口径,拿 GPT 去套你会骂人的,相信我,一定会。)
所以现在的实际情况是:同样一段意思,中文用的 Token 往往比英文少,因为一个汉字带的信息密度,本来就比一个英文字母高得多。(谢谢你,我的老祖宗们呐)
然后……为什么输出比输入贵好几倍
你随便打开一家 API 的价目表,输出价格基本都是输入的 2 到 4 倍。
原因不在“输出更值钱”,而在生成方式不一样:
输入的时候,模型是一次把整段话全看完的,可以并行处理,算力摊得很平。
输出的时候,他是一个字一个字往外蹦的——生成第 1 块,然后拿第 1 块去算第 2 块,再然后拿前两块去算第 3 块,再再然后……哎哎哎这是废话,在 AI 这里废话也是要收 token 的,所以注意用词的准确简练,你懂我意思就行,所以 LLM 输出每一步都得等上一步,没法并行。
一个是同时读,一个是排队写。慢的那个自然要贵。
(以及这也是为什么你会觉得 AI“在打字”,他不是在装作打字,我们勤勤恳恳的大语言模型们呐,他是真的在一块一块地辛辛苦苦算。)
最后记住一句话
Token 是模型眼里的最小单位,他不是字也不是词,是被“频率”切出来的语义积木。你付的钱、他的记忆上限、他最远能看多远,全都按这个单位算。
下一篇讲他的记忆上限——上下文窗口,以及他为什么会忘事。