qinghuan
← 回到知识探索

AI 直觉 / 常见误区

同样一百个字,为什么 Token 数不同?

先分清人眼看到的字符、程序里的编码单位和模型使用的 Token,才知道该怎样估算输入。

展开本文目录
  1. 同一段文字,可以有几种长度
  2. 分词器按自己的词表和规则拆分
  3. 把估算变成可核对的记录
  4. 记住这三点
  5. 别把例子用过头
  6. 自己试一小步
  7. 查原始资料
  8. 找一份资料继续练
开始前,会这些就够了
  • 会运行一小段 Python;代码部分可选
遇到不熟悉的词,先看这 2 个解释
Token(词元)
语言模型处理文本时使用的基本单位。一个单位可能对应一个字、一个词的一部分,也可能是表示消息边界的特殊标记;具体怎样划分由配套分词器决定。
分词器
按照一套确定的词表和规则,把文本变成词元编号的程序。模型接收这些编号后才能继续计算;分词器还可能配合对话模板加入表示角色或边界的特殊标记。
打开完整术语小抄 ↗

假设你准备把两段笔记交给同一个模型,一段是自然语言,另一段混有类名、路径和符号。编辑器都显示差不多一百个字,却不能据此断定它们占用相同的输入空间。模型先经过分词器,把文本变成一串编号;它接收的是这串编号,而不是编辑器给出的字数。

Token 通常译作词元,但它并不总是一个完整的词,也不固定等于一个汉字。理解这一点的目的,是避免错误估算容量,而不是记住某个“字数乘系数”的口诀。

同一段文字,可以有几种长度

人眼看到的一个字符,程序可能用多个 Unicode 码点表示;码点再编码成 UTF-8 时,又可能占多个字节。Python 字符串的 len 统计码点数量,编码后字节串的 len 统计字节数量。这两种计数有明确用途,但都没有运行模型的分词规则。

下面把拉丁字母、汉字、表情和两种重音字母表示放在一起。composed 与 combining 在合适字体中可能看起来相同,码点数却不同。这个实验只展示“长度要先说明单位”,不负责计算任何模型的 Token,更不能把字节数当成模型用量。

小实验 · python
examples = {
    "latin": "A",
    "han": "中",
    "emoji": "🙂",
    "composed": "é",
    "combining": "e\u0301",
}
for label, text in examples.items():
    print(label, len(text), len(text.encode("utf-8")))

怎样运行:Python 3.10+;保存为 token_units.py,在该目录运行 python token_units.py。只用标准库,无需联网。

运行后对照结果
latin 1 1
han 1 3
emoji 1 4
composed 1 2
combining 2 3

分词器按自己的词表和规则拆分

常见的子词分词器会把文本拆成可在词表中找到的片段,再把片段换成编号。常见片段可能整块保留,不常见的拼写可能拆成几块;空格、标点和大小写也可能参与规则。这里的片段只是模型处理单位,不能要求每一块都像语文课里的词。

BPE 是一种从数据学习片段组合的办法,但“使用 BPE”仍不足以确定切分结果:训练材料、词表、预处理和具体模型版本都可能不同。Qwen 文档和 Hugging Face 文档可以帮助认识机制,不能把其中某个例子的分词数推广到所有模型。比较用量时,要固定分词器和输入文本。

聊天输入还常带有角色和轮次标记。你在输入框里只看到一句话,实际送入模型的序列可能包含模板加入的控制 Token。因此统计用户正文,只回答了正文有多长,没有回答整次请求占多少输入。模板是否添加额外标记,要查看所用模型的实际格式。

把估算变成可核对的记录

做本地实验时,记录模型名称、分词器版本、原始文本和是否使用聊天模板,再统计编码后编号序列的长度。先比较普通句子、代码片段和含空格的文本,比盲目追求一个通用换算率更有用。没有相应分词器时,可以保留粗估,但必须把它标成估算。

容量规划还应给回答留出空间,并按具体接口说明核对上下文与输出限制。字符数适合界面长度限制,字节数适合传输和存储,Token 数适合模型序列预算;三者可以同时记录,但不要互相冒名。把计数单位写清,往往比把估算小数位写得很精细更可靠。

记住这三点

  • Token 数由具体分词器和输入格式决定,不能固定换算成汉字数。
  • Python 的码点数、UTF-8 字节数和模型 Token 数是三种计数。
  • 核对模型容量时,连同聊天模板及输出预留一起考虑。

别把例子用过头

  • 本地代码没有实现分词器,输出不能用于模型计费或上下文计数。
  • 文档里的示例比例或词表数字只属于相应模型范围,不能推广到所有新版本。

自己试一小步

怎样证明你的“文本长度”记录没有混用单位?

  1. 准备一句中文、一段路径和一组组合字符,先写出自己想统计的单位。
  2. 用本地代码记录码点数与字节数;若已有模型分词器,再单独记录其 Token 数及版本。
  3. 对聊天格式与纯文本格式分别保留输入,比较计数方法。

做到这些,就算完成

  • 表头明确区分码点、字节和 Token。
  • 没有分词器的格子标为未测,没有拿字节数代填。
  • 能指出聊天模板是否包含在统计范围内。

查原始资料

想确认一个细节,先看这份资料对应的部分,不必从头读完所有文档。

找一份资料继续练

先选一项,按下面的范围继续学;不必从头读完整门课程。