一、什么是 Token?
在大型语言模型(LLM)的世界里,Token 是模型处理文本的最小单元。它并不是简单地等同于一个“字”或一个“词”。模型在训练前,会通过一个分词器 将原始的文本字符串拆解成一系列的 Token 序列。这个分词过程对中英文的处理方式截然不同。
对于英文,常见的做法是使用类似 BPE(字节对编码)的算法,将长单词拆分成有意义的子词片段。例如,“unhappiness” 可能会被拆分为 ["un", "happi", "ness"] 三个 Token。对于中文,情况更复杂一些,由于中文没有天然的空格分隔,分词器可能将单个汉字作为一个 Token,也可能将常见的词语组合在一起。例如,“人工智能” 有可能是四个 Token(["人", "工", "智", "能"]),也可能在更先进的模型中被识别为一个或两个 Token(["人工智能"] 或 ["人工", "智能"])。
提示:Token 化是大模型理解人类语言的基础步骤。不同的模型(如GPT-4、Claude、Llama)可能使用不同的分词器,因此同一段文本在不同模型中的 Token 数量可能不同。
二、为什么按 Token 而非字数计费?
你可能会有疑问,为什么不直接按字数或字符数计费呢?这主要源于大模型的核心工作原理。
首先,计算成本与序列长度直接相关。模型处理文本的本质是进行大量的矩阵运算,其计算复杂度和内存占用与输入序列的长度(即 Token 数量)密切相关。输入 100 个 Token 和 1000 个 Token,所需的算力是天壤之别。
其次,Token 是模型内部的真实“货币”。模型的词表大小固定(例如,GPT-3 的词表约有50,257个 Token),它能够“认识”和生成的所有元素都在这个词表中。无论是你输入的 prompt,还是模型输出的 completion,在模型看来都是一串连续的 Token ID。因此,按 Token 计费是最直接、最准确地反映模型实际工作量的方式。
最后,这种模式具有普适性。它不依赖于语言(中文、英文、代码)的字符集差异,统一用 Token 作为度量标准,便于API提供商制定清晰的定价策略。
三、API 如何计费:输入与输出
当你调用如 OpenAI、Anthropic 等提供的大模型 API 时,计费通常遵循一个核心原则:输入 Token 和输出 Token 分开计算,且价格不同。
- 输入 Token:指你发送给模型的提示文本(Prompt)。这部分通常用于引导模型理解你的问题或指令。
- 输出 Token:指模型根据你的输入生成的回复文本(Completion)。这部分是模型创造性工作的成果。
输出 Token 的单价通常显著高于输入 Token。这是因为生成每一个 Token 都需要模型进行复杂的自回归预测,计算开销比一次性理解输入要大得多。例如,某个模型的定价可能是:输入 $0.00X / 1K tokens,输出 $0.00Y / 1K tokens(其中 Y > X)。
一个请求的总费用计算公式为: 总费用 = (输入Token数 / 1000 * 输入单价) + (输出Token数 / 1000 * 输出单价)
提示:很多API提供商会对“系统提示词”和“用户提示词”统一按输入Token计费。此外,部分服务(如批量处理)可能有折扣价。
四、动手计算:用代码统计 Token 数量
在实际开发中,精确估算 Token 数量对成本控制至关重要。我们不能靠感觉,必须借助工具。Python 的 tiktoken 库是 OpenAI 官方提供的分词器,可以用来统计 GPT 系列模型所使用的 Token 数。
下面是一个简单的示例,演示如何使用它:
import tiktoken
# 选择对应模型的分词器编码。对于GPT-3.5-Turbo和GPT-4,通常使用 "cl100k_base"
enc = tiktoken.get_encoding("cl100k_base")
text_en = "Hello, how are you doing today?"
text_zh = "你好,你今天过得怎么样?"
text_combined = "这是一个测试,Testing 123。"
# 对文本进行编码,得到Token列表
tokens_en = enc.encode(text_en)
tokens_zh = enc.encode(text_zh)
tokens_combined = enc.encode(text_combined)
print(f"英文: '{text_en}' -> {len(tokens_en)} 个 Tokens")
print(f"中文: '{text_zh}' -> {len(tokens_zh)} 个 Tokens")
print(f"混合: '{text_combined}' -> {len(tokens_combined)} 个 Tokens")
# 输出可能是:
# 英文: 'Hello, how are you doing today?' -> 8 个 Tokens
# 中文: '你好,你今天过得怎么样?' -> 6 个 Tokens (注意标点也可能占一个Token)
# 混合: '这是一个测试,Testing 123。' -> 8 个 Tokens
运行这段代码,你会发现中文的 Token 数通常比其字符数少,而英文的 Token 数也比单词数少,这直观地展示了分词器的工作方式。
五、优化成本的核心策略
理解了 Token 和计费原理后,我们就可以有的放矢地优化 API 使用成本。
- 精简你的提示词:这是最有效的方法。在保证指令清晰的前提下,删除冗余的描述、客套话和不必要的上下文。与其说 “你好,我是一名学生,正在做一个作业,请你帮我总结一下下面这段非常长的文章,要求重点突出,分点列出。”,不如直接说 “请将以下文章总结为要点列表:”。
- 明智地管理上下文:在多轮对话中,每次都发送完整的聊天历史会导致输入 Token 剧增。可以定期进行“总结”来压缩历史上下文,或者只发送最近的几轮关键对话。
- 合理设置 0 参数:在API调用时,通过
max_tokens(或类似参数)明确限制模型输出的最大长度。这既能防止模型“喋喋不休”产生高额费用,也能确保获得所需长度的回复。 - 选择合适规格的模型:并非所有任务都需要最强大、最昂贵的模型。对于简单的分类、提取任务,使用更小、更便宜的模型(如 GPT-3.5-Turbo 替代 GPT-4)往往性价比更高。
六、超越基础:批量处理与缓存
对于生产环境下的大规模应用,还可以考虑更高级的优化手段。
- 批量 API 调用:部分服务提供商(如 OpenAI)提供批量 API,允许你将多个独立的请求打包成一个文件提交。虽然单个请求的延迟可能增加,但总费用通常有显著折扣,非常适合非实时、大规模的数据处理任务。
- 实现结果缓存:如果你的应用中存在大量重复或相似度极高的请求(例如,对同一份标准文档的提问),可以在自己的业务层实现缓存机制。相同的输入直接返回缓存的结果,避免重复调用API产生费用。
七、未来展望与思考
随着技术发展,Token 和计费模式也在不断演进。一些趋势值得关注:
- 多模态输入的 Token 化:当模型处理图像、音频时,这些非文本信息也会被转换为一系列 Token。图像可能被分割成小块(Patches),每个 Patch 对应一个 Token。这将使 Token 的概念更加通用,但计费方式也可能变得更复杂(例如,不同模态的 Token 价格不同)。
- 更高效的分词器:研究人员一直在设计能更高效编码信息的分词器,目标是在减少 Token 数量的同时保持甚至提升模型的理解能力,这直接有助于降低使用成本。
- 更灵活的定价策略:未来可能出现基于请求复杂度、实时性要求等更多维度的动态定价模型,而不仅仅是静态的“每千 Token 价格”。
总之,Token 是连接人类语言与机器计算的桥梁,而计费是驱动我们编写更高效代码的现实动力。深入理解其原理,是每一位AI应用开发者控制成本、构建可持续产品的必修课。