Token计算深度分解:搞懂大模型的“计价单位”
你有没有遇到过这种情况:在OpenAI的API里输入一段中文,Token数比你预想的多出一大截;换成英文,同样意思的内容Token却少了很多。或者用DeepSeek和Claude处理同一段文本,算出来的Token数居然不一样。
这不是错觉,而是Token计算本身的复杂性造成的。
Token可以理解为大模型处理文本时的最小“积木块” 。它既不是字也不是词,而是介于两者之间的“子词(subword)”或“字节序列”。大模型看不懂原始文字,只能看懂数字。所以每一段文字输入模型之前,都要先被切分成Token,再映射成数字ID。
一、Token是怎么“切”出来的?——Tokenization的核心流程
把文本变成Token的过程叫Tokenization(分词) ,整个过程可以分为三步:

1.1 为什么不用“字”或“词”做最小单位?
如果用词做单位(比如英文单词),会遇到生僻词问题——模型不可能认识所有单词,遇到不认识的词就不知道怎么办了。
如果用字/字符做单位,又会导致序列太长——一个英文句子平均5个字符才等于1个词,序列长度直接膨胀5倍,计算量暴涨。
所以主流方案取了个折中:用子词(Subword) 做单位。高频词保留为完整Token,低频词拆分成共享子词单元。这样既控制了词表大小,又能覆盖几乎所有文本。
举个直观的例子:英文单词"unhappiness"可能被拆成"un" + "happiness"两个Token,而不是一个完整的词,也不是一个一个字母。
二、三大主流分词算法:BPE、WordPiece、SentencePiece
不同模型用不同的分词算法,这是导致同样文本在不同模型里Token数不一样的根本原因。
2.1 BPE(Byte-Pair Encoding)——最主流
代表模型:GPT系列、Llama、Qwen2等
核心思想:从字母开始,不断合并出现频率最高的相邻字符对。
训练过程(简化):
初始词表:a, b, c, d, e, ...
第1步:发现 "ab" 出现次数最多 → 合并成 "ab"
第2步:发现 "ab" + "c" 出现最多 → 合并成 "abc"
第3步:继续合并,直到词表达到预定大小
特点:
-
纯数据驱动,只看统计频率
-
可逆且无损,Token可以完美还原回原文
-
OpenAI的tiktoken就是基于BPE的快速实现
2.2 WordPiece——BERT的选择
代表模型:BERT
与BPE的区别:BPE选频率最高的合并,WordPiece选能最大提升似然概率的合并——简单说,BPE看“谁出现最多”,WordPiece看“谁合并后效果最好”。
2.3 SentencePiece——语言无关的解决方案
代表模型:LLaMA、T5、ALBERT等
最大特点:把空格也当成普通字符处理,不需要预先按空格分词。这让它天然支持中文、日文等没有空格的语言。
三种算法对比总结:
| 算法 | 代表模型 | 核心逻辑 | 中文支持 |
|---|---|---|---|
| BPE | GPT、Llama、Qwen2 | 合并频率最高的相邻对 | 一般 |
| WordPiece | BERT | 合并后似然提升最大的对 | 一般 |
| SentencePiece | LLaMA、T5 | 把空格当字符,不依赖预分词 | 优秀 |
三、Token计算框架:模型是怎么算Token的?
3.1 OpenAI:tiktoken
OpenAI官方提供了一个叫tiktoken的Python库,专门用来计算OpenAI模型的Token数。
import tiktoken
# 根据模型名称获取对应的编码器
encoding = tiktoken.encoding_for_model("gpt-4o")
# 计算Token数
text = "Hello, how are you?"
tokens = encoding.encode(text)
print(f"Token数量: {len(tokens)}")
print(f"Token列表: {tokens}")
tiktoken的编码规则:不同模型用不同的编码(encoding)。比如cl100k_base是GPT-4系列用的编码,词汇表有10万个Token。
英文的估算规则:
-
1个Token ≈ 4个字符
-
1个Token ≈ 0.75个单词
-
100个Token ≈ 75个单词
3.2 DeepSeek:基于BPE的自研分词器
DeepSeek同样采用BPE算法,但词汇表和具体切分规则与OpenAI不同。这就是为什么同样一段中文,在DeepSeek和OpenAI里算出来的Token数不一样。
一个有意思的发现:在DeepSeek-V3和Qwen 3.6上,中文比英文更省Token——同样的内容,中文版的Token数只有英文版的0.65倍。这与OpenAI的情况正好相反(OpenAI里中文通常比英文更费Token)。
3.3 Hugging Face Tokenizers:统一框架
Hugging Face提供了tokenizers库,统一实现了BPE、WordPiece、Unigram等多种算法。
from transformers import AutoTokenizer
# 加载任何Hugging Face模型的tokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
# 分词并计算Token数
tokens = tokenizer.tokenize("Hello, how are you?")
print(f"Token列表: {tokens}")
print(f"Token数量: {len(tokens)}")
Tokenizer的完整流水线:
-
Normalizer:标准化(转小写、去重音等)
-
Pre-tokenizer:预切分(按空格等规则初步拆分)
-
Model:核心分词算法(BPE/WordPiece/Unigram)
-
Post-processor:后处理(添加特殊标记如
[CLS]、[SEP]等)
四、模型之间Token计算的差异:为什么同样文本在不同模型里不一样?
4.1 差异来源一:词表大小不同
每个模型训练时都会构建自己的词表。词表越大,一个Token能覆盖的文本就越多。
| 模型 | 词表大小(约) |
|---|---|
| GPT-2 | 50,257 |
| GPT-4 (cl100k_base) | 100,000 |
| Llama 2 | 32,000 |
| DeepSeek-V3 | 129,000 |
词表越大,生僻词越可能被保留为完整Token而不是拆成多个,Token数就越少。
4.2 差异来源二:分词粒度不同
同样是中文"人工智能":
| 模型 | 可能的切分方式 | Token数 |
|---|---|---|
| 模型A | ["人工智能"] | 1 |
| 模型B | ["人工", "智能"] | 2 |
| 模型C | ["人", "工", "智", "能"] | 4 |
没有一个“标准答案” ,全看模型训练时的分词策略。
4.3 差异来源三:特殊Token的添加
很多模型会在输入前后自动添加特殊Token:
-
[CLS](分类标记)—— BERT系列 -
[SEP](分隔标记)—— BERT系列 -
<|im_start|>、<|im_end|>(消息起止)—— 部分开源模型 -
<|endoftext|>(文本结束)—— GPT系列
这些特殊Token也会计入总数,而且不同模型加的数量不一样。
五、多模态Token计算:图像、音频是怎么变成Token的?
多模态模型的Token计算比纯文本复杂得多——不同模态的Token是分开计算的,而且计算方式完全不同。
5.1 图像转Token:视觉编码器
多模态模型处理图像时,不是直接把图片“当作”Token,而是通过视觉编码器把图片转换成Token序列。
典型的转换流程:

以ViT-L/14为例,处理224×224分辨率图像时,默认生成196个Patch Token。分辨率越高,Token越多。
不同平台的图像Token计算规则:
| 平台/模型 | 图像Token计算方式 |
|---|---|
| StepFun | 默认每张图169 Token,开启detail模式后根据图片大小计算 |
| 通义千问VL | 最小28×28像素=1 Token,每张图最少4 Token,最多1280 Token |
| Qwen3-Omni | 图片/视频输入单独计价,与文本输入价格不同 |
5.2 音频转Token:声学特征提取
音频的处理方式又不一样——通过声学特征提取把声音信号转成Token序列。
不同模态的Token价格完全不同。以阿里云Qwen3-Omni-Flash为例:
| 模态 | 输入价格(元/百万Token) |
|---|---|
| 文本 | 3.156 |
| 图片/视频 | 5.725 |
| 音频 | 27.962 |
音频Token的价格是文本的将近9倍。
5.3 多模态Token是“相互”还是“分开”计算的?
答案是:分开计算,但合并计费。
-
计算上分开:文本走文本分词器,图像走视觉编码器,音频走声学编码器——各自独立转换成Token
-
计费上合并:最终把所有模态的Token数加在一起,按各自的价格分别计费
计费公式:
总费用 = (图像Token数 × 图像单价) + (音频Token数 × 音频单价) + (文本Token数 × 文本单价) + (输出Token数 × 输出单价)
5.4 多模态模型的“隐藏成本”
多模态调用有一个容易被忽略的成本:即使你只问了一个简单问题,模型也要先把整张图片转成几百个Token才能处理。
比如你发一张高清图问“这是什么?”,模型可能先消耗了500个图像Token“读图”,再用10个文本Token生成回答。读图的成本远高于回答本身。
六、VSCode实战:Token计算的完整代码示例
6.1 使用tiktoken计算OpenAI模型的Token
import tiktoken
def count_tokens_openai(text, model="gpt-4o"):
"""
使用tiktoken计算OpenAI模型的Token数
"""
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
# 如果模型名不存在,使用默认编码
encoding = tiktoken.get_encoding("cl100k_base")
tokens = encoding.encode(text)
return len(tokens), tokens
# 测试不同文本
test_texts = [
"Hello, how are you?", # 英文
"你好,最近怎么样?", # 中文
"Artificial Intelligence", # 英文单词
"人工智能", # 中文词汇
]
for text in test_texts:
count, tokens = count_tokens_openai(text)
print(f"文本: {text}")
print(f" Token数: {count}")
print(f" Token IDs: {tokens[:5]}...") # 只显示前5个
print()
运行结果示例(实际数字可能因模型版本而异):
文本: Hello, how are you?
Token数: 6
Token IDs: [9906, 11, 703, 527, 499, 30]...
文本: 你好,最近怎么样?
Token数: 7
Token IDs: [44300, 106395, 16, 38412, 102, 450, 116]...
文本: Artificial Intelligence
Token数: 3
Token IDs: [21646, 12518]...
文本: 人工智能
Token数: 2
Token IDs: [44300, 106395]...
6.2 使用Hugging Face Tokenizer计算任意模型
from transformers import AutoTokenizer
def count_tokens_hf(text, model_name="Qwen/Qwen2.5-7B"):
"""
使用Hugging Face加载指定模型的tokenizer并计算Token
"""
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokens = tokenizer.tokenize(text)
token_ids = tokenizer.encode(text)
return len(tokens), tokens, token_ids
# 测试
text = "人工智能正在改变世界"
count, tokens, ids = count_tokens_hf(text)
print(f"文本: {text}")
print(f"Token数: {count}")
print(f"Token列表: {tokens}")
print(f"Token IDs: {ids}")
6.3 对比不同模型的Token计算差异
import tiktoken
from transformers import AutoTokenizer
def compare_tokenizers(text, models):
"""
对比不同模型对同一段文本的Token切分
"""
results = {}
# OpenAI模型
for model in models.get("openai", []):
try:
enc = tiktoken.encoding_for_model(model)
tokens = enc.encode(text)
results[f"OpenAI-{model}"] = {
"count": len(tokens),
"tokens": tokens[:10] # 只显示前10个
}
except:
pass
# Hugging Face模型
for model in models.get("hf", []):
try:
tokenizer = AutoTokenizer.from_pretrained(model)
tokens = tokenizer.tokenize(text)
ids = tokenizer.encode(text)
results[f"HF-{model}"] = {
"count": len(tokens),
"tokens": tokens[:10]
}
except:
pass
return results
# 测试文本
text = "大语言模型的Token计算方式因模型而异"
# 要对比的模型
models = {
"openai": ["gpt-4o", "gpt-3.5-turbo"],
"hf": ["Qwen/Qwen2.5-7B", "meta-llama/Llama-2-7b"]
}
results = compare_tokenizers(text, models)
for model_name, data in results.items():
print(f"{model_name}: {data['count']} 个Token")
print(f" 前10个Token: {data['tokens']}")
print()
6.4 多模态Token估算(模拟)
def estimate_multimodal_tokens(image_resolution=(224, 224), text="", audio_seconds=0):
"""
估算多模态请求的Token消耗(模拟)
"""
total = 0
details = {}
# 图像Token估算(基于ViT风格)
if image_resolution:
patch_size = 16
h, w = image_resolution
image_tokens = (h // patch_size) * (w // patch_size)
details["图像Token"] = image_tokens
total += image_tokens
# 文本Token估算(粗略)
if text:
# 粗略估算:中文约1.5 Token/字,英文约0.25 Token/字符
chinese_chars = sum(1 for c in text if '\u4e00' <= c <= '\u9fff')
other_chars = len(text) - chinese_chars
text_tokens = int(chinese_chars * 1.5 + other_chars * 0.25)
details["文本Token"] = text_tokens
total += text_tokens
# 音频Token估算(粗略:1秒≈50 Token)
if audio_seconds > 0:
audio_tokens = int(audio_seconds * 50)
details["音频Token"] = audio_tokens
total += audio_tokens
details["总计"] = total
return details
# 示例:一张图 + 一段文字 + 10秒音频
result = estimate_multimodal_tokens(
image_resolution=(224, 224),
text="请分析这张图片的内容",
audio_seconds=10
)
print("多模态Token估算:")
for key, value in result.items():
print(f" {key}: {value}")
输出示例:
多模态Token估算:
图像Token: 196
文本Token: 7
音频Token: 500
总计: 703
| 维度 | 核心要点 |
|---|---|
| Token是什么 | 大模型处理文本的最小单元,介于字和词之间的“子词” |
| 怎么计算 | 预处理 → 分词(BPE/WordPiece/SentencePiece)→ 映射为ID |
| 三大算法 | BPE(最主流)、WordPiece(BERT用)、SentencePiece(支持中文好) |
| 为什么不同模型不一样 | 词表大小不同、分词粒度不同、特殊Token不同 |
| 多模态怎么算 | 图像→视觉编码器转Token,音频→声学编码器转Token,分开计算、合并计费 |
| 主要框架 | OpenAI tiktoken、Hugging Face Tokenizers、Google SentencePiece |
小编建议
-
不要用字符数估算Token数:中文1个字≈1.5-2 Token,英文1个词≈1-1.5 Token
-
不同模型用不同的计算工具:OpenAI用tiktoken,Hugging Face用AutoTokenizer
-
多模态调用前先估算图像Token:一张高清图可能消耗几百个Token,成本远超你的想象
-
中文场景优先选中文优化好的模型:DeepSeek和Qwen的中文Token效率优于OpenAI
-
生产环境务必在代码里精确计算Token:不要靠猜,用官方工具算
小编团自动研发 大型文件翻译、文本润色链接
更多推荐


所有评论(0)