@[toc]
tiktoken 是 OpenAI 开发的一个快速 BPE 分词器库,用于将文本转换成 GPT 模型使用的 token ID。以下是详细的用法指南:
安装
pip install tiktoken
基本用法
1. 初始化编码器
import tiktoken
# 获取不同模型的编码器
enc = tiktoken.get_encoding("cl100k_base") # GPT-4, GPT-3.5-turbo
enc = tiktoken.encoding_for_model("gpt-4") # 根据模型名自动选择编码
# 支持的编码类型:
# - "gpt2":GPT-2
# - "p50k_base":Codex 模型
# - "cl100k_base":GPT-4, GPT-3.5-turbo
# - "o200k_base":最新模型
2. 基本编码解码
import tiktoken
# 初始化编码器
enc = tiktoken.get_encoding("cl100k_base")
# 编码文本 -> token IDs
text = "Hello, world! 你好,世界!"
token_ids = enc.encode(text)
print("Token IDs:", token_ids)
# 输出: [9906, 11, 1917, 0, 123, 123, 123, 123] (示例)
# 解码 token IDs -> 文本
decoded_text = enc.decode(token_ids)
print("Decoded text:", decoded_text)
# 直接查看 tokens
tokens = enc.encode_ordinary(text)
print("Tokens:", tokens)
3. 按模型使用
import tiktoken
def num_tokens_from_string(text: str, model_name: str) -> int:
"""返回文本的 token 数量"""
encoding = tiktoken.encoding_for_model(model_name)
return len(encoding.encode(text))
# 示例
text = "这是一个测试句子。"
models = ["gpt-4", "gpt-3.5-turbo", "text-davinci-003"]
for model in models:
token_count = num_tokens_from_string(text, model)
print(f"{model}: {token_count} tokens")
高级功能
1. 批量编码和解码
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
# 批量编码
texts = ["Hello world", "Python编程", "机器学习"]
batch_tokens = [enc.encode(text) for text in texts]
print("Batch tokens:", batch_tokens)
# 批量解码
decoded_texts = [enc.decode(tokens) for tokens in batch_tokens]
print("Decoded texts:", decoded_texts)
2. 处理特殊 tokens
import tiktoken
enc = tiktoken.get_encoding("cl100k_base")
# 允许特殊 tokens
text = "Hello<|endoftext|>World"
tokens_with_special = enc.encode(text, allowed_special="all")
print("With special tokens:", tokens_with_special)
# 不允许特殊 tokens(默认)
tokens_without_special = enc.encode(text, allowed_special={})
print("Without special tokens:", tokens_without_special)
# 自定义允许的特殊 tokens
tokens_custom = enc.encode(text, allowed_special={"<|endoftext|>"})
print("Custom special tokens:", tokens_custom)
3. 分块处理长文本
import tiktoken
def chunk_text_by_tokens(text, model_name, max_tokens=2048):
"""将长文本按 token 数量分块"""
encoding = tiktoken.encoding_for_model(model_name)
tokens = encoding.encode(text)
chunks = []
for i in range(0, len(tokens), max_tokens):
chunk_tokens = tokens[i:i + max_tokens]
chunk_text = encoding.decode(chunk_tokens)
chunks.append(chunk_text)
return chunks
# 使用示例
long_text = "很长很长的文本..." * 1000
chunks = chunk_text_by_tokens(long_text, "gpt-4", max_tokens=1000)
print(f"分成了 {len(chunks)} 个块")
实际应用示例
1. 计算聊天消息的 tokens
import tiktoken
def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
"""计算聊天消息的总 token 数"""
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
encoding = tiktoken.get_encoding("cl100k_base")
# 不同模型的 token 计算方式
if model in {
"gpt-3.5-turbo-0613",
"gpt-3.5-turbo-16k-0613",
"gpt-4-0314",
"gpt-4-32k-0314",
"gpt-4-0613",
"gpt-4-32k-0613",
}:
tokens_per_message = 3
tokens_per_name = 1
else:
tokens_per_message = 3
tokens_per_name = 1
num_tokens = 0
for message in messages:
num_tokens += tokens_per_message
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name":
num_tokens += tokens_per_name
num_tokens += 3 # 每个回复都以 assistant 开头
return num_tokens
# 使用示例
messages = [
{"role": "system", "content": "你是一个有帮助的助手。"},
{"role": "user", "content": "你好,请介绍一下Python。"}
]
token_count = num_tokens_from_messages(messages, "gpt-4")
print(f"消息总 tokens: {token_count}")
2. 价格计算器
import tiktoken
class TokenCalculator:
def __init__(self, model_name):
self.model_name = model_name
self.encoding = tiktoken.encoding_for_model(model_name)
self.prices = {
"gpt-4": {"input": 0.03, "output": 0.06}, # 每千token价格(美元)
"gpt-3.5-turbo": {"input": 0.0015, "output": 0.002},
}
def calculate_cost(self, input_text, output_text=""):
input_tokens = len(self.encoding.encode(input_text))
output_tokens = len(self.encoding.encode(output_text))
if self.model_name in self.prices:
price_info = self.prices[self.model_name]
cost = (input_tokens / 1000 * price_info["input"] +
output_tokens / 1000 * price_info["output"])
return {
"input_tokens": input_tokens,
"output_tokens": output_tokens,
"total_tokens": input_tokens + output_tokens,
"cost_usd": round(cost, 4)
}
return None
# 使用示例
calculator = TokenCalculator("gpt-4")
result = calculator.calculate_cost("请写一篇关于AI的文章", "AI是...")
print(result)
3. 文本截断工具
import tiktoken
def truncate_text_by_tokens(text, model_name, max_tokens):
"""根据 token 数量截断文本"""
encoding = tiktoken.encoding_for_model(model_name)
tokens = encoding.encode(text)
if len(tokens) <= max_tokens:
return text
truncated_tokens = tokens[:max_tokens]
return encoding.decode(truncated_tokens)
# 使用示例
long_text = "这是一段很长的文本..." * 100
truncated = truncate_text_by_tokens(long_text, "gpt-4", max_tokens=50)
print(f"截断后长度: {len(truncated)}")
性能优化技巧
import tiktoken
import time
# 1. 重复使用编码器实例
enc = tiktoken.get_encoding("cl100k_base") # 初始化一次,多次使用
# 2. 批量处理
texts = ["text1", "text2", "text3"] * 1000
# 慢的方式
start = time.time()
for text in texts:
tokens = tiktoken.get_encoding("cl100k_base").encode(text)
print(f"单次编码: {time.time() - start:.2f}秒")
# 快的方式
start = time.time()
for text in texts:
tokens = enc.encode(text)
print(f"复用编码器: {time.time() - start:.2f}秒")
常见问题处理
1. 处理编码错误
import tiktoken
def safe_encode(text, encoding_name="cl100k_base"):
"""安全编码,处理异常字符"""
enc = tiktoken.get_encoding(encoding_name)
try:
return enc.encode(text)
except Exception as e:
print(f"编码错误: {e}")
# 替换或忽略无法编码的字符
text_clean = text.encode('utf-8', 'ignore').decode('utf-8')
return enc.encode(text_clean)
# 使用示例
problematic_text = "正常文本 + 异常字符: \uFFFF"
tokens = safe_encode(problematic_text)
2. 多语言支持
import tiktoken
def compare_token_count(texts, model_name="gpt-4"):
"""比较不同语言文本的 token 数量"""
enc = tiktoken.encoding_for_model(model_name)
for text in texts:
tokens = enc.encode(text)
print(f"文本: {text[:30]}...")
print(f"字符数: {len(text)}, Token数: {len(tokens)}")
print(f"比例: {len(tokens)/len(text):.2f}\n")
# 测试不同语言
texts = [
"This is an English sentence.",
"这是一个中文句子。",
"これは日本語の文章です。",
"이것은 한국어 문장입니다."
]
compare_token_count(texts)
这些用法涵盖了 tiktoken 的主要功能,可以帮助您有效地处理文本 tokenization 任务。