
Token是什么?带你从词表编号彻底搞懂大模型的最小单位
我一开始接触大模型的时候,满脑子都是「字数」「字符数」,直到第一次看到 API 按 token 计费,才意识到:模型眼里根本没有「字」这个概念。
这篇我想把 token 这件事讲透——不是背定义,而是搞清楚它到底是什么、怎么被切出来的、在模型内部扮演什么角色。看完你就知道为什么中文比英文「贵」、为什么上下文会满、为什么有时候模型答非所问。
先说结论:token 是「模型能处理的最小文本块」
大模型不认识汉字,也不认识字母,它只认识整数。所以我们得先把文本切成一小块一小块,每一块去查一张超大的「对照表」,得到一个编号。这个编号就叫 token。
所以 token 其实有三重身份,理解了这三层,后面全通了:
- 切分单位:文本被切成的小块,可能是完整单词、词根、几个字母,也可能是汉字的一部分。
- 词表编号:每一块对应词表里的一个整数 ID,这才是模型真正「读」进去的东西。
- 计量单位:API 计费、上下文长度限制、生成速度,全都以 token 为基本单位。
token 不是「字」,也不是「词」
很多人以为 token 就是词,其实差得挺远。我做了个对比表,一看就懂:
| 单位 | 是什么 | 例子 | 能否直接喂给模型 |
|---|---|---|---|
| 字符 | 文本的显示单位 | 你、a、逗号 | 不能 |
| 字节 | 计算机存储单位 | 一个汉字常占 3 字节 | 不能 |
| 词 | 语言学单位 | 「今天」「天气」 | 不能 |
| token | 词表里的条目 | 今天、天气、un、##ing | 能,被转成整数 ID |
一句话记忆:token 是「词表切出来的块」,不是语言学意义上的词。
一个 token 是怎么被「切」出来的
主流大模型大多用 BPE(Byte Pair Encoding,字节对编码)这类算法。我把它拆成 4 步,你跟着走一遍就有感觉了:
步骤 1:先把文本切成初始小块。 早期做法按单词和标点切,现在更多是直接从字节开始,这样任何语言、任何生僻字都能处理。
步骤 2:统计相邻小块出现的频率。 比如语料里 low、lower、lowest 反复出现,切完后 l、o、w、e、r、s、t 这些碎片总是挨在一起。
步骤 3:把最高频的相邻对合并成新块。 比如 l 和 o 常一起出现,就合并成 lo,再把 lo 和 w 合并成 low。反复做几万到几十万次。
步骤 4:把最终得到的所有块写进词表。 这张词表可能有几万到十几万条目,训练前就固定下来了。推理时就是拿这张表来切你的输入。
所以你会看到很有趣的现象:
- 高频英文单词(比如 the、ing)往往一个 token 就搞定。
- 生僻词会被拆成好几块,比如一个长单词可能占 4、5 个 token。
- 中文常见字词通常一个字约 1 到 2 个 token,但冷僻字可能被拆成更多块。
注意:不同模型的词表和切法不一样,所以同一段文本在不同模型里 token 数不同。具体以官方为准,最好的办法是自己数一下。
token 在模型里的真实身份:一串整数
这一层是我之前一直忽略、但特别关键的。完整流程是这样的:
- 你的文字被切分器切成 token。
- 每个 token 查词表,变成一个整数 ID。
- 整数 ID 查「嵌入表」,变成一长串浮点数(向量)。
- 模型在向量上做运算,输出也是向量,再反查词表变回文字。
所以模型的输入输出本质上都是数字序列,token 只是这套数字和文字之间的「中间表示」。
自己动手数一数 token
别猜,直接数。用官方开源的分词库就能做,比如 tiktoken:
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
text = "今天天气不错,适合出去走走。"
tokens = enc.encode(text)
print("文本长度(字符):", len(text))
print("token 数量:", len(tokens))
print("token 的整数 ID:", tokens)
print("还原回来:", enc.decode(tokens))
跑完你会直观看到:字符数和 token 数完全对不上,这就是「按字数估成本」经常翻车的原因。
如果你想数某个开源模型的 token,可以用 HuggingFace 的分词器:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("这里填模型仓库名")
ids = tokenizer.encode("今天天气不错")
print("token 数量:", len(ids))
要点:一定要用目标模型对应的分词器去数,用别家的数字只是参考。
弄懂 token 之后,三件事立刻就清楚了
| 场景 | 为什么和 token 有关 | 实用结论 |
|---|---|---|
| 费用 | API 通常按输入和输出的 token 计费 | 精简提示、控制输出长度就是省钱 |
| 上下文 | 模型一次能装的内容有 token 上限 | 长文档要分段或摘要后再喂 |
| 速度 | token 越多,处理和生成越慢 | 别把无关内容一股脑塞进去 |
关于中英文成本差异的直觉解释:同样的意思,英文常常更省 token,因为英文高频词直接整词入表;中文信息密度高,但切块粒度不同,所以不能想当然。建议拿你自己的真实语料测一下,那才是最准的预算依据。
我踩过的坑,你别再踩
- 坑 1:用 Word 的字数统计去估成本。 字数、字符数、token 是三码事,误差可能很大。
- 坑 2:以为代码和结构化文本不占 token。 代码、JSON、表格统统都要占 token,而且符号和缩进也算。注意:示例代码里的花括号等符号在模型看来也是 token 的一部分。
- 坑 3:忘记系统提示和历史对话也算 token。 你看到的「一句话提问」背后,可能已经消耗了几千 token。
- 坑 4:图片、音频的计量规则想当然。 多模态内容的 token 折算方式各模型不同,以官方为准。
上手清单:今天就能做的三步
- 挑一段你常用的提示词,用上面的代码数一下 token。
- 对比它的字符数,感受一下差异有多大。
- 把这段提示词精简 30%,再数一次,看看省了多少。
做完这三步,你对 token 的感觉就不再是抽象概念,而是能换算成时间和钱的具体数字了。
总结
token 就是「文本切块 + 词表编号」的产物,是模型真正的输入输出单位。搞懂它,你就能解释中英文成本差异、上下文为什么会满、模型为什么有时答非所问。下一篇我会接着聊怎么在实际工作里省 token,我们到时候见。