Token到底是什么?Tokenizer分词机制与中文token开销入门科普

一、为什么同样是"500字",中英文花的token差这么多?

用过模型 API 的人,一定对 token 不陌生------计费按它算、上下文窗口按它算、报错"超出 max_tokens"也是因为它。但你有没有疑惑过:

  • 英文一句话 "Hello world" 几个 token?中文一句"你好世界"又是几个?
  • 为什么有人说中文比英文更"费"token
  • token 和"字数"到底是什么换算关系?

这篇文章把 token 这件事彻底讲明白:模型怎么把文字切成 token、BPE 分词怎么工作、中文为什么 token 贵,以及它对上下文窗口和计费的影响。全程 Python 可运行,看完你对 token 的理解会超出绝大多数人。

二、模型不吃文字,只吃数字:先有词表

大模型本质是"按概率预测下一个 token"的机器。但它面对的不是文字,而是数字 id------所以任何输入都得先翻译成一串整数,模型才看得懂。

这个翻译过程分两步:

  1. 分词(Tokenization):把原始文本切成一串 token(可以近似理解为"小块")
  2. 映射:查词表(vocabulary),把每个 token 变成它在词表里的编号(id)

每个模型有自己的词表------通常是几万到十几万个 token(GPT-4 系列约 10 万级别)。词表是训练时定死的,不会因为你换了文本而变。

拿到 tokenizer 之后,一切就透明了(以 OpenAI 官方 tiktoken 为例):

复制代码
pip install tiktoken
python 复制代码
import tiktoken

enc = tiktoken.get_encoding("cl100k_base")

tokens_en = enc.encode("Hello world, this is a test.")
tokens_zh = enc.encode("你好世界,这是一次测试。")

print("英文token数:", len(tokens_en), tokens_en)
print("中文token数:", len(tokens_zh), tokens_zh)

输出类似(id 具体值取决于词表):

复制代码
英文token数: 8 [15496, 995, 11, 2023, 374, 257, 2566, 13]
中文token数: 14 [..., ..., ...]

有意思的来了:同样的一句话,"你好世界,这是一次测试。" 的 token 数明显多于 "Hello world, this is a test."------中文每个字常常对应 1 个甚至多个 token,而英文单词常由多个"更小单位"共享词表。这就是"中文更费 token"的来源。

三、token 不是字,也不是词:它是 BPE 的"子词"

你可能以为 token = 词。其实主流模型用的是子词(subword)分词 ,最著名的算法叫 BPE(Byte Pair Encoding,字节对编码)

BPE 的核心思想:从字符出发,反复把"最常见的相邻片段"合并成一个新 token,直到词表大小达到目标。

看个直觉例子------假设语料里 "ing" 这个片段出现极多,BPE 就会把它合并成一个 token;于是:

  • "running" → ["runn", "ing"](两个 token)
  • "talking" → ["talk", "ing"](两个 token)

"ing" 这一个 token 被所有以 ing 结尾的词共享------这就是子词方案能压缩词表、又比纯字符方案更省 token 的原因。

Python 里自己实现一个极简 BPE 训练,体会"合并最频繁片段"的过程:

python 复制代码
def build_bpe(text, num_merges=10):
    vocab = {"<w>": i for i, ch in enumerate(set(text))}  # 先按字符切
    tokens = list(text)
    merges = {}
    for _ in range(num_merges):
        # 统计相邻 token 对
        pairs = {}
        for a, b in zip(tokens, tokens[1:]):
            pairs[(a, b)] = pairs.get((a, b), 0) + 1
        if not pairs:
            break
        best = max(pairs, key=pairs.get)     # 最频繁的一对
        merges[best] = True
        # 替换文本里的这对
        i, new = 0, []
        while i < len(tokens):
            if i < len(tokens) - 1 and (tokens[i], tokens[i+1]) == best:
                new.append(best[0] + best[1]); i += 2
            else:
                new.append(tokens[i]); i += 1
        tokens = new
    return tokens, merges

tokens, merges = build_bpe("aaaaabbbbbaaaaacccc")
print("合并后token:", tokens)
print("合并规则数:", len(merges))

看到没有,BPE 就是不断把高频相邻片段"焊"成一个新 token。工业级实现还加上了字节级回退(遇到生僻字/emoji 时降到字节),所以理论上任何文本它都能切,不会碰到"词表外"的报错。

四、为什么中文 token 更"贵"?三个原因

同样长度的内容,中文 token 开销通常更大,主要是这几个原因:

  1. 中文字符多、组合复杂:汉字几万个常用字,英文只有 26 个字母,BPE 从字节/字符起步合并时,中文能形成的高频"子词"相对少,很多字只能单独成 token 甚至拆字节
  2. 词表共享效率低:英文 "ing"、"tion" 这种后缀能被大量词共享;中文没有天然的空格分隔和词形变化,一个字往往只能"独享"一个 token
  3. 标点与空格的代价:英文按空格天然分段,BPE 容易形成整词 token;中文句间没有空格,分词边界需要更细

实操验证一下中英 token 差异的直观比例:

python 复制代码
text_en = "Artificial intelligence is transforming the way we work and live every single day."
text_zh = "人工智能正在改变我们每天工作和生活的方式。"
print("英文:", len(enc.encode(text_en)), "token")
print("中文:", len(enc.encode(text_zh)), "token")
print("中文/英文字符比:", len(text_zh) / len(text_en))

一般经验是:同样语义下,中文 token 大约是英文的 1.3~2 倍 (具体因模型 tokenizer 而异)。这意味着如果你在调多语言系统,中文提示词会更快填满上下文窗口、花更多钱------这不是玄学,是分词机制决定的。

五、Token 对工程实践的三个直接影响

理解了机制,下面这些"行业常识"你就能看透本质:

1. 上下文窗口 = 输入 token 上限(含历史)

模型"记得多少"是按 token 算的,不是按字。上下文窗口 128K 意味着输入 + 历史 + 输出加起来不能超过 128K token。中文用户尤其要注意:同样的窗口,能塞的中文文本量只有英文的一半多。

2. 计费按 token,不是按字/按条

所有 API 都按 token 计费(输入、输出单价常不同)。设计提示词时,把冗余修饰词去掉、用尽量少的 token 表达同样的指令,是实打实的省钱手段。

3. 长文本处理常先"按 token 切块"

RAG 的文档切片、上下文管理,业界都是按 token 阈值切(比如 800~1000 token 一段),而不是按固定字符数------因为模型能"看"的单位是 token。切块代码通常是这种:

python 复制代码
def chunk_by_tokens(text, enc, chunk_size=800):
    ids = enc.encode(text)
    chunks = []
    for i in range(0, len(ids), chunk_size):
        chunks.append(enc.decode(ids[i:i + chunk_size]))
    return chunks

print(len(chunk_by_tokens("你好世界。" * 200, enc, 100)))

按 token 切块的好处:每段都不会"撑爆"模型单次处理范围,也不会因为字符计数失真而浪费 token

六、总结 + 实用清单

概念 一句话理解 对你的实际影响
Token 模型处理文本的"最小单位" 计费与窗口的计算单位
词表 token 与 id 的映射表 训练时定死,不随文本变
BPE 分词 高频相邻片段合并成子词 英文省 token,中文相对费
上下文窗口 输入+历史+输出上限 决定单次能"看"多长
token 计费 按输入+输出 token 算钱 精简提示词=省钱
token 切块 长文按 token 切段 RAG/长文档处理的标准做法

实用小贴士(可以直接抄):

  • 估 token :拿不准就 len(tokenizer.encode(text)),别用字数估算,尤其中文
  • 省 token:提示词去掉"请你帮我""好的呢"这类冗余,指令紧凑表达
  • 看窗口:用中文做长文档问答前,先估一下整段会不会超出上下文,超了就分块
  • 调中文系统:预留"中文 token 系数",缓存、计数都按 token 记,别按字符记

一句话收尾:token 是模型世界里唯一"看得懂"的文字单位,中文的 token 贵不是玄学,是 BPE 子词方案在无空格、高组合语言上的必然结果。 理解了 tokenizer,再看上下文窗口、计费、RAG 切块这些工程问题,就都串起来了。

本文为技术科普,示例基于 tiktoken(OpenAI 词表);不同模型词表不同,token 数会有差异,但 BPE 原理与"中文相对费 token"的结论通用。

相关推荐
盗理者1 小时前
AI Agent 技能分享|从零实现一个 MCP Server,让 AI Agent 安全调用内部系统
网络·人工智能·安全·agent
@卓越俊逸_角立杰出@1 小时前
快速学会 Java 实现意图识别:从规则匹配到 BiLSTM 分类器
java·开发语言·人工智能
william_yangshun1 小时前
招投标应答Agent实战:从2周人工赶工到48小时自动成稿,中标率+25%
人工智能
buyue__1 小时前
Python实现连接MySQL数据库并执行目录下的所有SQL文件,遇到错误时终止执行。
python·mysql
AndrewHZ1 小时前
【LLM技术全景】RAG 从原理到实战——检索增强生成完整指南
人工智能·深度学习·算法·llm·检索增强·生成式模型·rag
爆写加倍1 小时前
2026年3款视频转文字软件测评技术升级让转写整理更准更省心
人工智能·ai
樊小肆1 小时前
DeepSeeker-Code源码导读02-runAgent主循环
人工智能·agent
SuperByteMaster1 小时前
autosar 架构脚本提示语
python
ACP广源盛139246256731 小时前
WAIC2026 国产算力浪潮@ACP#YLB3118 在算力矩阵中的存储定位与落地场景
大数据·人工智能·分布式·单片机·嵌入式硬件