LLM 基础系列 · 第 3 篇
你问 AI 问题,账单上写的是"消耗 Token 数"。AI 的参数规模------GPT-4 是"约 1.8 万亿参数,上下文 128K Token"。
Token 是 AI 世界的基本计量单位------就像物理学里的原子。这篇文章告诉你:Token 是怎么切出来的?为什么同一个词在中英文里 Token 数不一样?以及为什么你调 API 的时候,价格跟"问题长度"不是比例关系。
Token 不是"字",也不是"单词"
给出一句话:
"今天天气真好"
GPT-4 的 Tokenizer 把它切成:
今 / 天 / 天 / 气 / 真 / 好
6 个字 → 6 个 Token。但英文 "The weather is really nice today":
bash
The / weather / is / really / nice / today
6 个词 → 6 个 Token。到这里似乎 Token = 单词------但继续看:
"unbelievably"
un / belie / vably
一个单词 → 3 个 Token。
"ChatGPT is amazing"
csharp
Chat / G / PT / is / amazing
"ChatGPT"被拆成了三块:"Chat" 是一个 Token、"G" 是一个、 "PT" 是一个。一个单词 → 3 个 Token。
所以 Token 不是字、不是词、而是子词(Subword) ------比字母大、比单词小。而子词不是人工定义的------是 BPE(Byte Pair Encoding)算法从海量文本里自动学出来的。
BPE 是怎么"长"出词典的
BPE 是纯统计驱动的------它不"理解"语言,只是一直合并出现频率最高的字符对。
从零开始的推演:
erlang
初始状态:每个字符是一个独立的 Token
训练文本(极简版):
"low" → l, o, w
"lower" → l, o, w, e, r
"lowest" → l, o, w, e, s, t
统计所有字符对的频率:
l+o: 3 次 ← 最高频 → 合并为 "lo"
o+w: 3 次 ← 合并为 "ow"
w+e: 2 次 ← 合并为 "we"
...
合并后:
"low" → lo, w (两个 Token)
"lower" → lo, we, r (三个 Token)
"lowest" → lo, we, s, t (四个 Token)
继续合并 lo+w → "low"
"low" → low (一个 Token!)
"lower" → low, er (两个 Token)
"lowest" → low, est (两个 Token)
继续合并 e+r → "er", e+s+t → "est"
"lower" → low, er (前缀 + 比较级后缀)
"lowest" → low, est (前缀 + 最高级后缀)
这就是 BPE 在微观层面的作用------通过反复合并高频对,最终词典里汇聚了大量有意义的语言单元:"low" 是一个 Token(高频词根)、"er" 和 "est" 各是一个 Token(高频后缀)。
训练完成后------这个词典大小通常是 50000 个 Token(GPT-3)或 100000 个 Token(GPT-4)。
每个模型切 Token 的方式不一样
BPE 的训练数据决定了哪些字符对是"高频"的。GPT-4 用的是 OpenAI 自己的训练数据。Claude 用的是 Anthropic 的训练数据。同一个句子,两个模型切出的 Token 数量可能不同------因为它们各自的频率统计来源不同。
后果:你不能简单比较"GPT-4 消耗 1000 Token"和"Claude 消耗 1200 Token"------可能是两个模型切的 Token 数量客观上不同,而不是"谁更省"。你只能用各自的 Token 计数器做预算。
为什么中文的 Token 效率低
同样的信息量,中文通常比英文消耗更多 Token。根本原因是:
-
中文没有空格分界。BPE 依赖"统计共现频率"------没有空格,Tokenizer 很难确定"哪里是词边界"。英文有空格天然标识出词之间的间隔,BPE 只需要在词内部合并。中文的一串汉字连在一起------BPE 需要额外"猜测"哪些字应该合并------这天然更困难。
-
中文字是多字节 UTF-8。BPE 的输入是字节流,不是字符。一个英文字母 = 1 字节(UTF-8),一个中文字 = 3 字节(UTF-8)。Tokenizer 看到的是一串字节------中文要比英文多处理 3 倍的"输入单元"才能找到相同的 Token 边界。
-
常用中文字符数远多于英文字母。英文 26 个字母的组合空间很小------高频组合(如 "ing", "tion")非常密集------BPE 迅速将它们合并成有意义的子词。中文常用字有 3500 个------组合空间比英文大两个数量级------相同训练迭代下------BPE 较难学到最优的切分边界。
具体代价:一篇 1000 字的中文文章,GPT-4 消耗约 3500-4000 个 Token。同样内容的英文,消耗 1800-2200 个 Token。同等信息量------中文 Token 成本约是英文的 1.7-2 倍。
Token 限制上下文窗口------128K 够不够?
GPT-4 的上下文是 128K Token。这里的"128K"不是字数------是 Token 数。
128K Token ≈
├── 30 万英文字 (约 500 页 PDF)
├── 5-8 万中文字 (约 100-150 页 PDF)
└── 或者 50 轮你 + AI 的来回对话
你的对话越长、发的文件越多------窗口被塞得越满。满了之后------AI 需要"压缩"或"丢弃"最早的对话------这就是你问了很多问题之后 AI 突然"不听话"的原因。
而且有一个容易被忽略的点:位置在中间的细节最容易被 AI 忽略 ------这叫"Lost in the Middle"效应。AI 对长文本的开头和结尾有较强的注意力,中间部分容易被"稀释"。所以如果你要让 AI 遵循某个重要规则------把规则写在 Prompt 的开头 或结尾------不要藏在中间。
一句话总结
Token 是 AI 的"原子"------BPE 算法从海量文本里统计高频字符对、一层一层合并------最终形成一个大小约 5 万到 10 万的词典。你的问题在进入 AI 之前被切成了一串 Token------每个 Token 对应一个向量------然后送入 Transformer。中文的 Token 效率天然低于英文------这是 UTF-8 编码和分词难度决定的,不是厂商的差别对待。
下一篇:Context Window(上下文窗口)------为什么 128K Token 不是"越大越好"?滑动窗口、RoPE、以及你怎么组织 Prompt 能最大化利用窗口的"有效范围"。