TikToken 使用教程:从原理到实战,一文搞懂 OpenAI 的文本分词利器
tiktoken 是 OpenAI 开发的高效分词工具,采用字节对编码(BPE)算法,专为 GPT 系列模型设计。该工具支持多种编码器类型(cl100k_base、o200k_base等),与 GPT-4、GPT-3.5-turbo 等模型完全兼容。文档详细介绍了安装配置、Python API 使用方法、核心概念及实际应用场景,包括 token 计算、成本估算和文本截断处理。tiktoken 具有
tiktoken 使用说明文档(词元计数库)
token 词元
tiktoken 词元计数工具
目录
- 1. 概述
- 2. 历史背景与发展
- 3. 资源与链接
- 4. 核心概念
- 5. 编码器类型与模型对应
- 6. 安装与配置
- 7. Python 使用方法详解
- 8. 实际应用示例
- 9. 局限性与注意事项
- 10. 最佳实践建议
- 11. 参考资料
1. 概述
tiktoken 是由 OpenAI 开发的一个快速、高效的开源分词器(tokenizer),专门用于处理 OpenAI 大语言模型的文本分词任务。它基于字节对编码(Byte Pair Encoding, BPE)算法实现,能够将文本字符串分割成模型可理解的标记(token)序列。作为 OpenAI 官方推出的分词工具,tiktoken 与 GPT-4、GPT-3.5-turbo、GPT-4o 等主流模型紧密配合,确保了分词结果与模型实际处理方式的一致性。
在使用 OpenAI API 进行开发时,准确计算和管理 token 数量至关重要。一方面,API 按照 token 数量计费,精确估算 token 消耗有助于成本控制;另一方面,每个模型都有最大上下文长度限制,超出限制的请求将被拒绝或截断。tiktoken 提供了一种在本地快速计算 token 数量的解决方案,无需发送请求到 API 服务器,既节省了网络开销,又避免了不必要的 API 调用费用。
与传统的分词器相比,tiktoken 具有显著的性能优势。根据官方测试数据,在处理 1GB 文本时,tiktoken 的速度比同类 Python 分词器快 3-5 倍。这得益于其核心算法使用 Rust 语言实现,并提供了对 Python 的原生绑定接口。对于需要处理大量文本或频繁进行分词操作的应用场景,tiktoken 的高效性能够带来可观的性能提升。
核心功能:
- 将文本字符串编码为 token ID 序列
- 将 token ID 序列解码还原为文本
- 支持多种 OpenAI 模型的编码器
- 提供精确的 token 数量计算
2. 历史背景与发展
2.1 分词器的重要性
在深入理解 tiktoken 之前,我们需要首先认识到分词器在大语言模型中的核心地位。大语言模型并不直接处理原始文本,而是通过分词器将文本转换为一系列数字标记(token)。每个 token 可以是一个完整的单词、一个子词(subword)、甚至是一个字符。分词器的设计直接影响模型的词汇覆盖率、处理效率以及最终的性能表现。
OpenAI 在早期模型(如 GPT-2)中使用的分词器虽然功能完备,但在处理大规模文本时效率有限。随着 GPT-3 及后续模型的推出,模型规模和应用场景不断扩大,对分词器性能的要求也随之提高。特别是在 API 服务层面,准确预估 token 数量对于用户费用计算和请求限制管理变得至关重要。
分词器演进历程:
| 阶段 | 模型 | 分词方案 | 特点 |
|---|---|---|---|
| 早期 | GPT-2 | BPE (50,257 tokens) | 基础分词能力 |
| 中期 | GPT-3 | r50k_base | 扩展词汇表 |
| 成熟 | GPT-3.5/GPT-4 | cl100k_base | 优化效率 |
| 最新 | GPT-4o | o200k_base | 大规模词汇表 |
2.2 tiktoken 的诞生
tiktoken 由 OpenAI 于 2022 年 12 月正式发布,作为 OpenAI Cookbook 系列教程的一部分首次向公众介绍。该项目的推出旨在解决开发者在使用 OpenAI API 时面临的 token 计算难题。在此之前,开发者要么通过发送实际请求来获取 token 数量(浪费资源),要么使用非官方的分词器(结果可能不准确)。
tiktoken 的设计目标是提供一个与 OpenAI 模型完全兼容的分词器,同时具备高性能和易用性。项目采用 Rust 语言编写核心算法,通过 Python 绑定提供接口,既保证了执行效率,又降低了使用门槛。自发布以来,tiktoken 已成为 OpenAI 生态系统中的基础设施组件,被广泛应用于聊天机器人、文本分析、成本估算等多种场景。
发布时间线:
2022年12月 ─────► tiktoken 首次发布
│
│ 支持 GPT-3 系列模型
│ 提供 r50k_base 编码器
│
2023年3月 ──────► 支持 GPT-3.5-turbo
│
│ 添加 cl100k_base 编码器
│ 优化性能
│
2023年中期 ─────► 支持 GPT-4
│
│ 扩展 cl100k_base 支持
│ 改进文档和示例
│
2024年5月 ──────► 支持 GPT-4o
│
│ 引入 o200k_base 编码器
│ 词汇表扩展至 200K
│
至今 ───────────► 持续维护更新
2.3 持续演进
随着 OpenAI 模型家族的不断扩展,tiktoken 也在持续更新以支持新的模型和编码方式。2023 年,随着 GPT-4 的发布,tiktoken 添加了对 cl100k_base 编码的支持;2024 年,为配合 GPT-4o 系列模型,又引入了 o200k_base 编码。截至当前,tiktoken 支持包括 GPT-4o、GPT-4、GPT-3.5-turbo、Codex 等在内的所有主流 OpenAI 模型,成为了开发者不可或缺的工具。
版本更新要点:
- 性能优化: 持续改进分词算法效率
- 模型支持: 及时跟进新模型发布
- 离线能力: 增强离线使用支持
- 跨平台: 改进各平台兼容性
3. 资源与链接
以下是 tiktoken 的官方资源链接,开发者可以通过这些渠道获取最新版本、查阅文档、报告问题或参与社区讨论:
| 资源类型 | 链接地址 | 说明 |
|---|---|---|
| GitHub 仓库 | https://github.com/openai/tiktoken | 源代码、Issue 追踪、贡献指南 |
| PyPI 包索引 | https://pypi.org/project/tiktoken/ | 安装包下载、版本历史 |
| OpenAI Cookbook | https://developers.openai.com/cookbook/examples/how_to_count_tokens_with_tiktoken | 官方教程和示例 |
| Tokenizer 工具 | https://platform.openai.com/tokenizer | 在线可视化分词工具 |
提示: 建议定期查看 GitHub 仓库的 Release 页面,以获取最新版本更新和变更日志。
4. 核心概念
4.1 Token 与分词
Token 是大语言模型处理文本的基本单位。在自然语言处理中,将文本分割成 token 的过程称为分词(tokenization)。一个 token 可以是:一个完整的英文单词(如 hello)、一个单词的一部分(如 ing)、一个标点符号(如 !)、或者多个字符的组合。在中文环境中,一个 token 可能对应一个或多个汉字,具体取决于分词器的训练方式。
Token 特征:
英文文本示例:
"tiktoken is great!"
↓ 分词
["tiktoken", " is", " great", "!"]
↓ 映射为 ID
[83, 1609, 5963, 0]
中文文本示例:
"人工智能"
↓ 分词
["人", "工", "智能"]
↓ 映射为 ID
[xxxx, xxxx, xxxx]
理解 token 的概念对于有效使用 OpenAI API 至关重要。经验法则:
- 英文: 1 token ≈ 4 字符 ≈ 0.75 单词
- 中文: 1 token ≈ 1-2 汉字(取决于具体内容和编码器)
4.2 字节对编码(BPE)
字节对编码(Byte Pair Encoding, BPE)是 tiktoken 采用的核心分词算法。BPE 最初是一种数据压缩算法,由 Philip Gage 于 1994 年提出,后来被成功应用于自然语言处理领域。BPE 的工作原理是迭代地合并最频繁出现的字节对(或字符对),直到达到预设的词汇表大小。
BPE 算法核心步骤:
1. 初始化: 将文本分解为字符序列
2. 统计: 计算所有相邻字节对的出现频率
3. 合并: 将最高频的字节对合并为新符号
4. 迭代: 重复步骤 2-3 直到达到目标词汇表大小
在 tiktoken 的实现中,BPE 算法首先将文本转换为字节序列,然后根据预训练的合并规则将这些字节组合成 token。这种方法的优势在于:
- 通用性: 能够处理任意 Unicode 字符
- 效率: 保持合理的词汇表大小
- 压缩: 常见词组被合并为单个 token
4.3 编码(Encoding)与解码(Decoding)
在 tiktoken 中,编码(encoding)是指将文本字符串转换为 token ID 序列的过程,而解码(decoding)则是其逆过程——将 token ID 序列还原为文本字符串。
┌─────────────┐ encode() ┌─────────────┐
│ 文本字符串 │ ─────────────────► │ Token ID 列表│
│ "Hello!" │ │ [15496, 0] │
└─────────────┘ └─────────────┘
▲ │
│ │
└──────────── decode() ◄───────────┘
关键要点:
- 每个 token 在词汇表中都有唯一的整数 ID
- 编码结果是一个整数列表
- 解码可以还原原始文本(信息无损)
- 编码器的词汇表大小决定了 ID 的范围
5. 编码器类型与模型对应
tiktoken 支持多种编码器,每种编码器对应不同的模型系列。选择正确的编码器对于获得准确的 token 计算结果至关重要。
| 编码器名称 | 对应模型 | 词汇表大小 | 发布时间 |
|---|---|---|---|
o200k_base |
GPT-4o、GPT-4o-mini | ~200,000 | 2024年5月 |
cl100k_base |
GPT-4、GPT-3.5-turbo、text-embedding-ada-002 | 100,000 | 2023年3月 |
p50k_base |
Codex 模型(代码生成) | 50,257 | 2022年 |
r50k_base |
GPT-3(davinci、curie 等) | 50,257 | 2020年 |
编码器选择建议:
# ✅ 推荐:通过模型名称自动获取编码器
encoding = tiktoken.encoding_for_model("gpt-4")
# ⚠️ 备选:手动指定编码器(仅在明确知道时使用)
encoding = tiktoken.get_encoding("cl100k_base")
重要: 使用
encoding_for_model()函数可以确保选择与目标模型匹配的编码器,避免因手动指定错误导致的不一致问题。
6. 安装与配置
6.1 系统要求
| 要求项 | 说明 |
|---|---|
| Python 版本 | 3.8 及以上 |
| 操作系统 | Windows、macOS、Linux |
| 依赖项 | 无特殊依赖(核心算法预编译) |
6.2 安装方法
方法一:使用 pip 安装(推荐)
pip install tiktoken
方法二:使用 conda 安装
conda install -c conda-forge tiktoken
方法三:从源码安装(开发用)
git clone https://github.com/openai/tiktoken
cd tiktoken
pip install -e .
验证安装:
python -c "import tiktoken; print(tiktoken.__version__)"
6.3 离线使用配置
tiktoken 在首次使用新编码器时会从网络下载词汇表文件。对于离线环境,需要预先配置:
步骤 1:设置缓存目录
# Linux/macOS
export TIKTOKEN_CACHE_DIR="/path/to/cache/directory"
# Windows (PowerShell)
$env:TIKTOKEN_CACHE_DIR="C:\path\to\cache\directory"
步骤 2:预先下载词汇表
# 在有网络的环境中运行
import tiktoken
# 预下载常用编码器的词汇表
tiktoken.get_encoding("cl100k_base")
tiktoken.get_encoding("o200k_base")
步骤 3:验证离线可用
# 在离线环境中运行
import os
os.environ["TIKTOKEN_CACHE_DIR"] = "/path/to/cache/directory"
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
print(enc.encode("test")) # 应正常工作
7. Python 使用方法详解
7.1 基本导入与初始化
import tiktoken
# 方式一:通过编码器名称获取
enc = tiktoken.get_encoding("cl100k_base")
# 方式二:通过模型名称自动获取对应编码器(推荐)
enc = tiktoken.encoding_for_model("gpt-4")
# 支持的模型名称示例
models = [
"gpt-4o",
"gpt-4o-mini",
"gpt-4",
"gpt-4-turbo",
"gpt-3.5-turbo",
"text-embedding-ada-002"
]
for model in models:
enc = tiktoken.encoding_for_model(model)
print(f"{model}: {enc.name}")
7.2 文本编码(encode)
encode() 方法将文本字符串转换为 token ID 列表:
import tiktoken
# 初始化编码器
enc = tiktoken.encoding_for_model("gpt-4")
# 编码文本
text = "tiktoken is a great tool for tokenization!"
tokens = enc.encode(text)
print(f"原始文本: {text}")
print(f"Token IDs: {tokens}")
print(f"Token 数量: {len(tokens)}")
输出示例:
原始文本: tiktoken is a great tool for tokenization!
Token IDs: [83, 1609, 5963, 374, 264, 3404, 3376, 369, 7602, 0]
Token 数量: 10
encode() 方法参数:
| 参数 | 类型 | 说明 |
|---|---|---|
text |
str | 要编码的文本字符串 |
allowed_special |
set | 允许的特殊 token 集合 |
disallowed_special |
set | 禁止的特殊 token 集合 |
7.3 Token 解码(decode)
decode() 方法将 token ID 列表还原为文本字符串:
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4")
# 编码
text = "Hello, World!"
tokens = enc.encode(text)
print(f"Token IDs: {tokens}")
# 解码
decoded_text = enc.decode(tokens)
print(f"解码文本: {decoded_text}")
# 验证一致性
assert text == decoded_text, "解码结果与原文不一致"
输出示例:
Token IDs: [9906, 11, 4435, 0]
解码文本: Hello, World!
7.4 查看实际 Token 内容
使用 decode_tokens_bytes() 方法查看每个 token 的原始字节内容:
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4")
text = "tiktoken is great!"
tokens = enc.encode(text)
# 查看每个 token 的字节内容
token_bytes = enc.decode_tokens_bytes(tokens)
print("Token 详情:")
for i, (token_id, token_bytes_repr) in enumerate(zip(tokens, token_bytes)):
try:
token_str = token_bytes_repr.decode('utf-8')
except:
token_str = str(token_bytes_repr)
print(f" [{i}] ID: {token_id:6d} → '{token_str}'")
输出示例:
Token 详情:
[0] ID: 83 → 't'
[1] ID: 1609 → 'ik'
[2] ID: 5963 → 'token'
[3] ID: 374 → ' is'
[4] ID: 3404 → ' great'
[5] ID: 0 → '!'
7.5 编码器属性
编码器对象提供多个属性用于获取元信息:
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4")
print(f"编码器名称: {enc.name}")
print(f"词汇表大小: {enc.n_vocab}")
print(f"最大 Token ID: {enc.max_token_value}")
输出示例:
编码器名称: cl100k_base
词汇表大小: 100277
最大 Token ID: 100276
8. 实际应用示例
8.1 计算对话消息的 Token 数量
在使用 ChatGPT API 时,消息格式本身也会占用 token。以下函数展示了如何准确计算:
import tiktoken
def num_tokens_from_messages(messages, model="gpt-4"):
"""
计算对话消息的 token 数量
Args:
messages: 消息列表,格式为 [{"role": "user", "content": "..."}]
model: 模型名称
Returns:
int: token 总数
"""
encoding = tiktoken.encoding_for_model(model)
num_tokens = 0
for message in messages:
# 每条消息的固定开销(字段分隔符等)
num_tokens += 4
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name": # name 字段有额外开销
num_tokens -= 1
# 对话开始标记
num_tokens += 2
return num_tokens
# 使用示例
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello, how are you?"},
{"role": "assistant", "content": "I'm doing well, thank you for asking!"},
{"role": "user", "content": "Can you help me with Python?"}
]
total_tokens = num_tokens_from_messages(messages, model="gpt-4")
print(f"对话总 token 数: {total_tokens}")
8.2 成本估算工具
创建一个简单的成本估算工具:
import tiktoken
def estimate_cost(
text: str,
model: str = "gpt-4",
input_rate: float = 0.03, # 美元/1K tokens
output_rate: float = 0.06 # 美元/1K tokens
) -> dict:
"""
估算文本处理的 API 成本
Args:
text: 要处理的文本
model: 模型名称
input_rate: 输入 token 每 1000 个的价格(美元)
output_rate: 输出 token 每 1000 个的价格(美元)
Returns:
dict: 包含 token 数量和预估成本
"""
encoding = tiktoken.encoding_for_model(model)
tokens = encoding.encode(text)
num_tokens = len(tokens)
input_cost = (num_tokens / 1000) * input_rate
return {
"token_count": num_tokens,
"input_cost_usd": round(input_cost, 6),
"model": model,
"encoding": encoding.name
}
# 使用示例
long_text = """
人工智能(Artificial Intelligence,简称 AI)是计算机科学的一个分支,
致力于研究和开发能够模拟、延伸和扩展人类智能的理论、方法、技术及应用系统。
""" * 100
result = estimate_cost(long_text, model="gpt-4")
print(f"Token 数量: {result['token_count']}")
print(f"预估输入成本: ${result['input_cost_usd']}")
print(f"使用编码器: {result['encoding']}")
8.3 文本截断处理
按 token 数量安全截断文本:
import tiktoken
def truncate_text_by_tokens(
text: str,
max_tokens: int,
model: str = "gpt-4",
suffix: str = "..."
) -> str:
"""
按 token 数量截断文本
Args:
text: 原始文本
max_tokens: 最大 token 数量
model: 模型名称
suffix: 截断后添加的后缀
Returns:
str: 截断后的文本
"""
encoding = tiktoken.encoding_for_model(model)
tokens = encoding.encode(text)
if len(tokens) <= max_tokens:
return text
# 预留后缀的 token 空间
suffix_tokens = encoding.encode(suffix)
truncated_tokens = tokens[:max_tokens - len(suffix_tokens)]
result = encoding.decode(truncated_tokens) + suffix
return result
# 使用示例
long_text = "This is a very long text. " * 1000
truncated = truncate_text_by_tokens(long_text, max_tokens=50)
encoding = tiktoken.encoding_for_model("gpt-4")
print(f"截断后 token 数: {len(encoding.encode(truncated))}")
print(f"截断后文本预览: {truncated[:100]}...")
8.4 中英文混合文本处理
处理中英文混合文本:
import tiktoken
def analyze_mixed_language_text(text: str, model: str = "gpt-4") -> dict:
"""
分析中英文混合文本的分词情况
Args:
text: 要分析的文本
model: 模型名称
Returns:
dict: 分析结果
"""
enc = tiktoken.encoding_for_model(model)
tokens = enc.encode(text)
token_bytes = enc.decode_tokens_bytes(tokens)
# 统计
chinese_chars = sum(1 for c in text if '\u4e00' <= c <= '\u9fff')
english_words = len([w for w in text.split() if w.isascii()])
return {
"text": text,
"total_chars": len(text),
"chinese_chars": chinese_chars,
"english_words": english_words,
"token_count": len(tokens),
"tokens_detail": list(zip(tokens, token_bytes)),
"chars_per_token": round(len(text) / len(tokens), 2)
}
# 使用示例
chinese_text = "人工智能正在改变世界"
mixed_text = "OpenAI 的 GPT-4 模型非常强大,支持多种语言。"
print("=== 中文文本分析 ===")
result_cn = analyze_mixed_language_text(chinese_text)
print(f"文本: {result_cn['text']}")
print(f"Token 数: {result_cn['token_count']}")
print(f"字符/Token 比: {result_cn['chars_per_token']}")
print("\n=== 混合文本分析 ===")
result_mix = analyze_mixed_language_text(mixed_text)
print(f"文本: {result_mix['text']}")
print(f"Token 数: {result_mix['token_count']}")
print(f"中文字符: {result_mix['chinese_chars']}")
print(f"英文单词: {result_mix['english_words']}")
print(f"字符/Token 比: {result_mix['chars_per_token']}")
9. 局限性与注意事项
9.1 已知局限
| 局限类型 | 具体说明 | 缓解措施 |
|---|---|---|
| 编码器版本 | 新模型可能使用新编码器,旧版本可能不支持 | 定期更新 tiktoken 版本 |
| 特殊字符 | 某些罕见 Unicode 字符可能产生较多 token | 使用 decode_tokens_bytes() 验证 |
| 消息格式 | 简单的 encode 无法计算消息格式开销 | 使用专门的计算函数(见 8.1 节) |
| 流式输出 | 无法实时追踪流式响应的 token | 只能事后计算 |
9.2 常见问题排查
问题 1: 编码结果与 API 返回不一致
可能原因:
- 使用了错误的编码器
- 消息格式有额外开销
- 文本预处理方式不同
解决方案:
# 确保使用正确的编码器
enc = tiktoken.encoding_for_model("gpt-4") # 使用目标模型名称
# 对于对话,使用专门的计算函数
# 参考 8.1 节的 num_tokens_from_messages 函数
问题 2: 离线环境无法加载编码器
解决方案:
# 方法 1: 设置环境变量
import os
os.environ["TIKTOKEN_CACHE_DIR"] = "/path/to/cachedir"
# 方法 2: 在线预先下载
import tiktoken
tiktoken.get_encoding("cl100k_base") # 首次会下载并缓存
问题 3: 特殊 token 处理
# 允许特定特殊 token
enc.encode("Hello<|endoftext|>", allowed_special={"<|endoftext|>"})
# 禁止所有特殊 token(遇到时报错)
enc.encode("Hello<|endoftext|>", disallowed_special=())
10. 最佳实践建议
10.1 编码器选择
- 始终使用
encoding_for_model()- 自动匹配正确的编码器
- 避免手动指定导致的错误
- 复用编码器实例
- 编码器初始化有开销
- 在循环中复用同一实例
# ✅ 推荐
enc = tiktoken.encoding_for_model("gpt-4")
for text in texts:
tokens = enc.encode(text)
# ❌ 不推荐
for text in texts:
enc = tiktoken.encoding_for_model("gpt-4") # 每次重新初始化
tokens = enc.encode(text)
10.2 性能优化
- 批量处理优化
- 使用列表推导式提高效率
- 避免在循环中频繁调用
# ✅ 高效
enc = tiktoken.encoding_for_model("gpt-4")
token_counts = [len(enc.encode(t)) for t in texts]
# ❌ 低效
token_counts = []
for t in texts:
enc = tiktoken.encoding_for_model("gpt-4")
token_counts.append(len(enc.encode(t)))
- 内存优化
- 大文本分块处理
- 及时释放不需要的变量
10.3 准确性保障
- 验证分词结果
- 定期检查 decode 结果
- 特别关注特殊字符
# 验证编码-解码一致性
text = "你的文本内容"
tokens = enc.encode(text)
decoded = enc.decode(tokens)
assert text == decoded, f"不一致: {text} vs {decoded}"
- 关注版本更新
- 订阅 GitHub Release
- 及时更新到新版本
10.4 生产环境建议
# 推荐:封装为可复用模块
class TokenCounter:
"""Token 计算工具类"""
_instances = {}
@classmethod
def get_encoder(cls, model: str):
"""获取或创建编码器实例(单例模式)"""
if model not in cls._instances:
cls._instances[model] = tiktoken.encoding_for_model(model)
return cls._instances[model]
@classmethod
def count_tokens(cls, text: str, model: str = "gpt-4") -> int:
"""计算文本 token 数量"""
enc = cls.get_encoder(model)
return len(enc.encode(text))
@classmethod
def count_messages_tokens(cls, messages: list, model: str = "gpt-4") -> int:
"""计算对话消息 token 数量"""
# 使用 8.1 节的函数
return num_tokens_from_messages(messages, model)
11. 参考资料
- OpenAI. (2022). tiktoken: a fast BPE tokeniser for use with OpenAI’s models. GitHub. https://github.com/openai/tiktoken
- OpenAI. (2022). How to count tokens with tiktoken. OpenAI Cookbook. https://developers.openai.com/cookbook/examples/how_to_count_tokens_with_tiktoken
- Gage, P. (1994). A New Algorithm for Data Compression. C Users Journal, 12(2), 23-38.
- Sennrich, R., Haddow, B., & Birch, A. (2016). Neural Machine Translation of Rare Words with Subword Units. Proceedings of the 54th Annual Meeting of the Association for Computational Linguistics.
- OpenAI. (2024). Tokenizer Tool. OpenAI Platform. https://platform.openai.com/tokenizer
更多推荐



所有评论(0)