Token 是什么意思?为什么 AI 都按 Token 算

2小时前发布

一句话说清:token 是模型处理文字时切出来的最小单位,它不等于字,也不等于词。模型读一段话、写一段话,都是先把文字拆成一串 token,再按这串 token 去算。你看到的字数,只是这些碎片重新拼回去之后的样子。

所以同一段话交给不同的模型,算出来的 token 数可能不一样。切法不同,数量就不同。这也是为什么按字数估费用,总会差那么一截。

token 到底是什么东西

模型本身不认识汉字,也不认识英文单词。它能处理的是一张表里的编号,表里每一项就是一个 token。这张表叫词表,通常在训练之前就定好了。

词表怎么来的?拿大量文本跑统计,把反复出现的字符组合挑出来。出现得越频繁的片段,越容易被单独收进表里。所以词表里既有单个汉字,也有「今天」「系统」「不错」这种常用组合,英文那边还有大量带词根词缀的半截单词。

它切的是常见片段,不是语法单位

切分的时候,程序从前往后扫,尽量往长了去匹配表里已有的条目。碰上表里没有的组合,就退一步找短一点的,再找不到就落到单个字符甚至字节。

拿「人工智能」举例。如果这四个字在词表里各有一条,也可能有一条「人工」加一条「智能」,切出来就是两段。换一个分词表更细的模型,也许切成「人」「工」「智」「能」四段。字一个没少,token 数差了一倍。

一个汉字可以是一段,也可以是两三段

常用汉字大多能单独成 token。生僻字、繁体字、网上流行的怪写法,经常被拆成几个字节片段,一个字的开销就上去了。

英文的规律不太一样,它按子词切。一个长单词可能被拆成三截,前面是词根,后面是词缀。所以英文里一个 token 常常对应四个字符上下,而不是一个单词。

这就是为什么说 token 既不是字也不是词。它是模型自己的一套切法,跟人怎么读、怎么断句没有必然关系。你按语感断出来的词,它未必认。

桌面上摊开的书页与旁边的笔记本电脑

为什么按 token 算,不按字数算

模型内部的运算是一步一步走的,每一步处理一个 token。输入二十个 token,就往前走二十步;输出二十个 token,也走二十步。计算量跟 token 的数量直接挂钩,跟这段文字有几个汉字只是大致相关。

举个反例就清楚了。同样一百个汉字,全是「今天」「我们」「可以」这类高频组合,算子可能只给八十来个 token;换成一段夹着生僻人名、化学式、乱码符号的文字,同样一百个字,token 数能翻一倍。

字数一样,模型干的活差了一倍。按 token 计量,等于按它实际干的活计量;按字数计量,等于按你眼睛看到的长度计量。后者对不上前者的开销。

还有一层。模型生成的时候,是一个 token 一个 token 往外蹦的,每蹦一个都要重新过一遍网络。这种逐步生成的方式,天然就是以 token 为单位在计时。你要它写五百字,它心里算的是这五百字大概要蹦多少下。

中文和英文,哪个更费 token?

常见的说法是:中文一个字大致对应一到两个 token,英文大约四个字符对应一个 token。记住这是区间,不是死比例,不同模型的分词表差别不小。

同样一段意思,中文写出来往往比英文多占一些 token。原因在于英文词表收录得细,常见单词整条进表,一个词就是一段;中文的常用词组收录得少一些,一个词被拆成两三段的情况挺常见。

我拿一段两百字的中文新闻稿试过,返回的输入用量在三百多。换成意思差不多的英文版本,字符数涨了不少,token 数反而没怎么变。这个对比挺能说明问题:字符多不等于 token 多,关键看切得碎不碎。

数字、符号、空格也要占位

一串数字经常被切得很碎。十一位的手机号,可能切成五六段;带小数点的价格、带连字符的编号,也是一段一段算。

代码更明显。缩进、括号、换行符、引号,全都要占位置。你贴一段 JSON 或者一段报错日志进去,感觉没多少内容,token 数却涨得很快。填表格、贴清单这类活,估算的时候要多留点余量。

白板上写满文字段落的工作讨论场景

上下文长度为什么也按 token 算

每个模型有一个上下文窗口,常见的从几万到几十万 token 不等。这个数字的意思是:一次对话里,你发过去的内容加上它回过来的内容,合起来不能超过这个数。

所以一份三万字的产品手册,直接整篇粘进去,很可能就顶到上限了。不是文件太大传不上去,是拆成 token 之后超出了窗口。这时候要么分段喂,要么先做检索,只把相关的那几段放进去。

聊天记录同样占位置。你和它来回聊了三十轮,前面那些问答还留在窗口里,每一轮都在吃额度。聊到后来它开始答非所问、忘了你前面说过的条件,多半不是它变笨了,是早先的内容被挤出去了。

长文档处理不好,很多时候不是模型能力不够,是塞进去的方式不对。把十万字硬灌进去,它要在里面找那三句有用的,找到的概率反而不如你先把范围缩小。

计费里的输入和输出,为什么不是一个价

接口按 token 收钱,输入一段、输出一段,分开计价。输出的单价普遍比输入高,常见是两三倍,个别模型更高。

原因不难想。输入是一次性读完的,可以并行处理,效率高;输出要一个接一个往外生成,每生成一个都要把前面的内容重新算一遍,慢且贵。你看到打字机一样的效果,背后就是这个过程。

这条规律对日常使用有实际影响。让模型总结一份长文档,输入大、输出小,账单不算吓人;让它照着提纲写三千字,贵就贵在输出那一头。同一个任务换个问法,费用能差出不少。

怎么粗略估算一段文字有多少 token

拿一段已知字数的文字去试一次

我的做法很土:找一篇自己写的、字数确定的稿子,比如八百字,丢给接口跑一次,看返回结果里的用量字段。用总 token 数除以字数,得到一个系数。以后估算,拿这个系数乘一下就行。

这样做比背换算表可靠。系数是拿你自己的文本、你自己常用的模型试出来的,中英混排的比例、专业词的密度,全都算在里面了。

换了模型要重新试

不同厂商的分词表不一样,同一个模型的不同版本也可能改过。换模型之后系数会变,差个一两成很常见。做预算的时候,宁可往上留一点。

没有接口权限也有办法。不少厂商提供在线的分词演示页,把一段文字贴进去,切分结果和数量直接显示出来。看着那些被切碎的词,你对 token 的感觉会比看一堆数字快得多。

手机屏幕上的文字输入界面特写

还有一个更省事的判断:把你准备粘贴的内容,先在心里乘个一点五。中文技术文档、带表格的、混着代码的,按这个粗估,很少会低估得太离谱。

几个容易搞混的地方

「一个 token 就是一个字。」不对。英文里一个 token 常常是几个字母,中文里一个 token 也可能是一个常用词。反过来,一个汉字占两段 token 的情况也不少见。

「字数和 token 数是固定比例。」不对。同一段中文,换一个模型,数量能差两三成;同一段话里塞几个生僻字或者一串数字,比例也会变。任何写死的换算表,都只是某个模型在某个语料上的平均值。

「token 塞得越满,回答越好。」不一定。上下文填得太满,模型抓重点的能力会下降,关键的几句容易被淹没在无关材料里。给它干净、贴题的内容,比给它一大坨更有用。

「按 token 收费是在玩文字游戏。」不是。它确实对应着真实的计算量。你交的钱,买的是模型读了多少、写了多少,而不是你屏幕上显示了多少字。

用的时候记住这几条

  • 估算费用,先用自己的一段文字试出系数,别照搬网上的换算表
  • 贴长文档之前先看它的量,超窗口就分段,或者只挑相关的段落
  • 写长文这类任务,贵的在输出,要求一次说清,少来回返工
  • 对话聊久了主动开新会话,把要用的结论手动带过去
  • 看账单上的用量数字,比按字数猜靠谱
  • 做预算时往上留一两成余量,中英混排的文本尤其如此

这几条不难,难的是养成习惯。我刚开始用的时候,一份两万字的资料反复粘、反复报错,折腾了半天才意识到是窗口的问题。知道 token 是按什么算的,这类坑就少踩很多。

回到那句话:token 是模型切出来的处理单位,不是你眼里的字。凡是跟模型打交道的地方,长度、费用、速度,背后量的都是它。按 token 去想问题,很多看着奇怪的现象就顺了。