2.1 一句话先搞懂 Token

Token 就是模型处理文字的最小单位。

模型不认识汉字,也不认识英文单词,它只认识数字。所以任何文字进入模型之前,都要先被切成一小块一小块,每一块转换成一个数字(编号),这个"块"就叫 Token。

"我爱北京天安门"
    ↓ 分词
["我", "爱", "北京", "天安门"]
    ↓ 查表编号
[8593, 2679, 3111, 5511]

模型看到的是 [8593, 2679, 3111, 5511] 这串数字,而不是汉字本身。

在这里插入图片描述

图:一篇文章被"切"成一个个带编号的小纸片(Token),模型读的是编号,不是文字。


2.2 为什么不能一个字一个字地教?

可能你会想:直接按字切不就行了吗?问题出在词汇表上。

方案一:按字切

  • 常用汉字大约 3500 个,全量汉字几万个 —— 词汇表还不算太大
  • 字没有完整语义:"北京"是两个字的组合,单看"北"和"京"意思差远了
  • 英文更麻烦:“run”、“running”、“ran” 都要当独立词

方案二:按词切

  • 英文看起来合理,但词汇表会爆炸:互联网上的英文单词有几百万个(拼写变体、专业术语、人名地名)
  • 词汇表越大,模型越难学,内存占用越高
  • 还永远会遇到没见过的词(OOV,out-of-vocabulary)

所以需要一种折中方案:把文字切成比字大、比词小的单位 —— 这就是 Token。


2.3 主流分词算法:BPE

BPE = Byte Pair Encoding(字节对编码),现在几乎所有主流模型(GPT、Llama、Qwen 等)都在用它。

核心思想

字母/字节开始,反复把"出现频率最高的相邻对"合并成一个新单位。

初始:['l', 'o', 'w', 'e', 'r', 'l', 'o', 'w']
统计相邻对频率:'lo' 出现 2 次,'ow' 出现 2 次
第 1 轮合并 'lo' → ['lo', 'w', 'e', 'r', 'lo', 'w']
第 2 轮合并 'ow' → ['lo', 'w', 'e', 'r', 'lo', 'w']
第 3 轮合并 'low' → ['low', 'e', 'r', 'low']

合并一定次数后,词汇表里就既有"低层"的字母,又有"高层"的常见词了。

在这里插入图片描述

图:BPE 就像积木拼接——小字母一次次合并成更大的单位,拼出常见词。

BPE 的好处

特点说明
词汇表可控一般 3 万 ~ 20 万,不膨胀
没有 OOV任何生词都能拆成字节拼出来
常见词整词存储“the”、“北京” 是一个 Token,效率高
生僻词拆开没见过的新词拆成更小片段,也能处理

通俗理解:BPE 就是"把最常用的组合装进缓存"。天天见的词直接整体识别,不认识的拆开了也能拼读。


2.4 其他算法:WordPiece 与 SentencePiece

WordPiece(BERT 在用)

和 BPE 很像,区别在于合并的判定标准:BPE 看"出现频率",WordPiece 看"合并后带来的收益"(语言模型概率提升多少)。效果更精细,但计算更重。

SentencePiece(T5、Llama 在用)

它的特殊之处是:不预先切词,直接拿原始文本(包括空格)当字节流处理

英文原句: "Hello world" → ["▁Hello", "▁world"]
中文原句: "我爱北京"   → ["我", "爱", "北", "京"]

注意那个 符号,它代表"空格"。SentencePiece 把空格也当成普通字符处理,所以中文和英文用同一套流程,不需要语言专属的预处理。


2.5 中文的特殊性:为什么中文"贵"?

这是大家最关心的问题。同样一句话,中文和英文的 Token 消耗差很多:

文本大致 Token 数
“I love Beijing”3 ~ 5
“我爱北京”3 ~ 6
1000 个英文单词约 1300
1000 个汉字约 1500~2000

经验法则:1 个汉字 ≈ 1~2 个 Token;1 个英文单词 ≈ 1.3 个 Token。

在这里插入图片描述

图:同样的语义,中文要切出更多 Token,天平自然向"更贵"的一侧倾斜。

为什么中文更"贵"?因为中文没有天然的空格分词。像"北京"这种常用双字词可以合成一个 Token,但很多单字组合必须拆开,导致同样语义下 Token 数更多。而 Token 数直接决定 API 费用(输入输出都按 Token 计费),所以中文项目的成本天然比英文高一些。

实用建议

  • 一个模型的上下文窗口(如 8K、128K)指的也是 Token 数,不是字数
  • 长文本处理前,先用工具统计 Token,防止超出窗口
  • 提问尽量简洁,能省不少钱

2.6 怎么统计 Token?

用 tiktoken(OpenAI 官方库)

pip install tiktoken
import tiktoken

# 选择对应模型的编码器
enc = tiktoken.encoding_for_model("gpt-4o")

text = "我爱北京天安门"
tokens = enc.encode(text)

print(f"Token 数量: {len(tokens)}")
print(f"Token 编号: {tokens}")
print(f"还原文本:  {enc.decode(tokens)}")

输出类似:

Token 数量: 6
Token 编号: [8593, 2679, 3111, 5511, 5511, 354]
还原文本:  我爱北京天安门

按 Token 裁剪长文本

def truncate_to_tokens(text, max_tokens=2000):
    """把文本裁剪到指定 Token 数以内"""
    enc = tiktoken.encoding_for_model("gpt-4o")
    tokens = enc.encode(text)
    if len(tokens) <= max_tokens:
        return text
    return enc.decode(tokens[:max_tokens])

2.7 常见问题

问题答案
词汇表大小一般是多少?3 万 ~ 20 万之间,不同模型不同
为什么有些模型处理中文特别强?训练数据里中文占比高 + 词汇表对中文优化
Token 数和字节数有什么关系?一个 UTF-8 英文字符 1 字节,一个汉字 3 字节,但 Token 是"语义单位"不是字节
不同的模型 Token 切法一样吗?不一样!每个模型有自己的分词器,Token 数只能估算
max_tokens 设多少合适?看任务:短回答 200-500,长文 2000-4000,别超过模型上限

更多推荐