Token计算深度分解:搞懂大模型的“计价单位”

📅 2026/7/8 3:53:33 👁️ 阅读次数 📝 编程学习
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等

最大特点:把空格也当成普通字符处理,不需要预先按空格分词。这让它天然支持中文、日文等没有空格的语言

三种算法对比总结

算法代表模型核心逻辑中文支持
BPEGPT、Llama、Qwen2合并频率最高的相邻对一般
WordPieceBERT合并后似然提升最大的对一般
SentencePieceLLaMA、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的完整流水线

  1. Normalizer:标准化(转小写、去重音等)

  2. Pre-tokenizer:预切分(按空格等规则初步拆分)

  3. Model:核心分词算法(BPE/WordPiece/Unigram)

  4. Post-processor:后处理(添加特殊标记如[CLS][SEP]等)

四、模型之间Token计算的差异:为什么同样文本在不同模型里不一样?

4.1 差异来源一:词表大小不同

每个模型训练时都会构建自己的词表。词表越大,一个Token能覆盖的文本就越多。

模型词表大小(约)
GPT-250,257
GPT-4 (cl100k_base)100,000
Llama 232,000
DeepSeek-V3129,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

小编建议

  1. 不要用字符数估算Token数:中文1个字≈1.5-2 Token,英文1个词≈1-1.5 Token

  2. 不同模型用不同的计算工具:OpenAI用tiktoken,Hugging Face用AutoTokenizer

  3. 多模态调用前先估算图像Token:一张高清图可能消耗几百个Token,成本远超你的想象

  4. 中文场景优先选中文优化好的模型:DeepSeek和Qwen的中文Token效率优于OpenAI

  5. 生产环境务必在代码里精确计算Token:不要靠猜,用官方工具算

小编团自动研发 大型文件翻译、文本润色链接

[免费]翻译全文网页,你是否为翻译烦恼?-CSDN博客