Token 与分词器:为什么「你好」是 2 个 token,中文还比英文贵
几乎所有 LLM 开发者的第一个疑问,都来自计费页面:"为什么同样一句话,中文比英文贵?"
如果你用过任何大模型 API,一定见过 token 这个词:按 token 计费、上下文窗口是 N 个 token、输出被截断也是因为 token。但 token 到底是什么?为什么 "hello" 是 1 个 token,而 "你好" 却是 2 个 token?为什么中文普遍比英文"贵"?
这些问题背后,藏着一个被大量开发者忽视、却直接影响成本与性能的基础概念——分词器(Tokenizer)。
一、Token:大模型世界里最小的"原子"
人类阅读时,天然以"字"或"词"为单位。但大模型并不认识"字",它只认识数字。把一段文本变成模型能计算的数字序列,需要经过一道关键工序——分词(Tokenization)。token 就是这道工序产出的最小语义单元。
关键区别在于:token 不等于字,也不完全等于词。一个 token 可能是:
- 一个完整的常见词:
"hello"→ 1 个 token - 一个词的一部分:
"unbelievable"可能被拆成"un" + "believ" + "able"→ 3 个 token - 一个标点或空格:
",""。"各自是独立 token - 一个汉字:
"你""好"各自是 1 个 token
所以 "hello" 是 1 个 token,而 "你好" 是 2 个 token——这正是中文"贵"的第一个来源:中文的常用词,常常需要多个 token 才能表示。
二、BPE:分词器是怎么"学会"切词的
主流大模型(GPT、LLaMA 等)几乎都用同一类算法:字节对编码(Byte Pair Encoding,BPE)。
BPE 的思路可以一句话概括:从字符开始,反复把"出现频率最高的相邻对"合并成一个新符号。
- 初始词汇表里只有最基础的字符(甚至字节):
a, b, c, ..., 空格。 - 统计语料,发现
"t" + "h"一起出现的频率最高,合并成一个新 token"th"。 - 接着
"e" + 空格最常见,合并成"e "。 - 不断重复几千上万次,最终得到一个包含几万个 token 的词汇表。
关键洞察:合并次数多的组合(高频词)会成为独立的短 token,而罕见词不会被充分合并,只能拆成一堆小碎片。所以 "the"、"hello" 这类高频串是 1 个 token,而一个生僻人名、一段乱码、一个 URL,可能被拆成十几个 token。
token 数量 ≈ 文本的"稀有度":越常见,越省 token;越生僻,越费 token。
三、为什么中文普遍比英文"贵"?
1. 中文字符信息密度高,但 BPE 合并效率低
英文常见词是 26 个字母的排列组合,"hello" 作为一个整体高频出现,BPE 很容易把它合并成 1 个 token。中文则是几万个独立汉字,常用词由 2 到 3 个汉字组成,组合数量远大于英文,BPE 词汇表不可能为每个常用中文词都留位置。结果就是:大量中文词被拆成"逐字"的 token。
2. 字节层面的差异被进一步放大
BPE 的底层常常是字节(UTF-8 编码)。一个英文字母占 1 字节,而一个汉字占 3 字节。在字节级 BPE 里,一个汉字天然需要更多底层符号,合并成本更高。
综合结果:表达同样一段语义,中文的 token 数量通常是英文的 1.5 到 2 倍。这直接翻译成了更高的 API 账单。
四、Token 决定了三件事:成本、窗口、能力上限
- 成本:API 计费 =(输入 token × 输入单价)+(输出 token × 输出单价)。输入和输出通常不同价,输出往往更贵。
- 上下文窗口:模型一次能"看见"的 token 总量是固定的(8k、128k)。窗口里要塞进 system prompt、历史对话、工具返回,还要给回答留空间。
- 能力边界:很多"模型变笨了"的抱怨,其实是内容悄悄超了窗口,被截断或压缩导致的。token 预算管理,是 LLM 应用的核心工程问题。
五、为什么模型"数不清字数"?
你可能问过模型:"strawberry 这个词里有几个 r?"——它常常答错。
答案就藏在分词器里:模型看到的不是 s-t-r-a-w-b-e-r-r-y 这些字母,而是一串 token,可能是 "st" + "raw" + "berry" 之类的拆分。字母的边界在分词时被抹掉了,模型根本无法"看到"单个字母。
同理,模型"算不对"一段话有几个字、几个词,不是笨,而是它从未见过"字"这个单位,它只见过 token。
绝佳的提醒:不要用人类的"字/词"直觉去推理模型行为。模型的世界是 token 的世界。
六、工程实践:如何数 token、如何省钱
1. 用官方工具精确数 token
- OpenAI:
tiktoken库,encoding_for_model()精确对应模型的 tokenizer。 - 其他模型:
transformers库的AutoTokenizer。 - 注意:不同模型的 tokenizer 不同,同一文本在 GPT-4 和 Claude 里的 token 数可能不一样。
2. 省钱策略
- 精简 system prompt:它每次请求都被完整计入输入 token,冗长的 system prompt 会持续"烧钱"。
- 控制历史对话长度:只保留必要轮次,或用摘要替代旧对话。
- 复用缓存:很多服务商支持 prompt caching,命中缓存的输入 token 更便宜。
- 中文场景:成本敏感时,评估是否用更精简的表述,或选择对中文分词更友好的模型。
3. 实用的经验法则
英文:1 token ≈ 4 个字符 ≈ 0.75 个单词;中文:1 个汉字 ≈ 1 到 2 个 token。用这个粗略估算,就能在开发前预估成本与窗口占用。
结语:先懂 token,再谈大模型开发
Token 是最不起眼、也最基础的概念。但恰恰是它,决定了你的账单、你的上下文预算、以及模型"看起来聪明还是笨"。
在动手写任何 LLM 应用之前,先回答三个问题:我的文本会被拆成多少 token?这些 token 要花多少钱?它们在我的上下文窗口里占多大比例?搞懂这三个问题,你就已经超过了大多数"凭感觉调 API"的开发者。