Tokenizer 原理
什么是 Tokenizer
Tokenizer 将原始文本转换为模型可处理的 Token ID 序列。理解 Tokenizer 对于:
- 准确估算 API 费用
- 优化 Prompt 长度
- 处理特殊字符和多语言文本
至关重要。
BPE(字节对编码)
GPT 系列使用 BPE 算法:
python
from transformers import AutoTokenizer
# 加载 GPT-2 tokenizer
tokenizer = AutoTokenizer.from_pretrained("gpt2")
text = "Hello, I am a financial AI assistant."
tokens = tokenizer.tokenize(text)
ids = tokenizer.encode(text)
print(f"原文: {text}")
print(f"Tokens: {tokens}")
print(f"Token IDs: {ids}")
print(f"Token 数量: {len(ids)}")
# 输出: ['Hello', ',', 'ĠI', 'Ġam', 'Ġa', 'Ġfinancial', 'ĠAI', 'Ġassistant', '.']千问 Tokenizer
python
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(
"Qwen/Qwen2-7B-Instruct",
trust_remote_code=True
)
# 中文 token 统计
zh_text = "分析招商银行2024年年报中的风险因素"
en_text = "Analyze risk factors in CMB 2024 annual report"
zh_tokens = tokenizer.encode(zh_text)
en_tokens = tokenizer.encode(en_text)
print(f"中文: {len(zh_tokens)} tokens,约 {len(zh_text)/len(zh_tokens):.1f} 字/token")
print(f"英文: {len(en_tokens)} tokens,约 {len(en_text.split())/len(en_tokens):.1f} 词/token")Token 数量估算
python
def estimate_tokens(text: str, lang: str = "zh") -> int:
"""快速估算 token 数量(无需加载模型)"""
if lang == "zh":
# 中文约 1.5 字/token
return int(len(text) / 1.5)
else:
# 英文约 0.75 词/token
words = len(text.split())
return int(words / 0.75)
def estimate_cost(tokens: int, model: str = "qwen-turbo") -> float:
"""估算 API 费用(元)"""
prices = {
"qwen-turbo": 0.3 / 1_000_000,
"qwen-plus": 0.8 / 1_000_000,
"qwen-max": 40 / 1_000_000,
}
return tokens * prices.get(model, 0.3 / 1_000_000)
text = "这是一段测试文本,用于估算 token 数量和 API 调用费用。"
tokens = estimate_tokens(text)
cost = estimate_cost(tokens)
print(f"估算 {tokens} tokens,费用约 ¥{cost:.6f}")特殊 Token
python
# 查看特殊 token
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-7B-Instruct")
print(f"BOS token: {tokenizer.bos_token} (id: {tokenizer.bos_token_id})")
print(f"EOS token: {tokenizer.eos_token} (id: {tokenizer.eos_token_id})")
print(f"PAD token: {tokenizer.pad_token}")
# Chat template 格式化
messages = [
{"role": "system", "content": "你是金融助手"},
{"role": "user", "content": "什么是 P/E 比率?"}
]
# 应用对话模板
formatted = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True
)
print(formatted)注意事项
- 不同模型的 Tokenizer 不通用,千问和 GPT 的 token 数量会有差异
- 代码、数学公式的 token 效率较低
- 中文标点符号通常单独占一个 token