流式输出ChatGPT时如何获取token?Tokenizer计算值与API不符怎么办?
流式输出ChatGPT API的Token统计问题解决办法
一、流式输出时获取Token的方案
由于OpenAI的流式ChatCompletion API不会返回usage字段,只能通过本地实时计算统计Token使用量,分为两步:
- 提前计算Prompt的Token总数
- 对流式返回的每一段Completion内容,实时计算其Token数并累加
二、解决Tokenizer计算与API返回不一致的问题
你遇到的计算值差异,核心原因是未遵循OpenAI官方的对话Token计算规则——API会将对话的结构标记、角色字段、特殊分隔符全部计入Token,而非仅统计消息内容的Token。
关键规则说明
对于gpt-3.5-turbo、gpt-4等对话模型,Token计算包含以下部分:
- 每个消息的完整结构:
<|im_start|>{role}\n{content}<|im_end|>(特殊标记、角色文本都会被编码为Token) - 固定开销:每个消息额外占用4个Token的结构成本,最后加2个Token作为模型生成的前缀开销
- 若消息包含
name字段,会有对应的Token数量调整
代码实现(Python)
使用OpenAI官方的tiktoken库(唯一能匹配API计算逻辑的工具):
- 安装依赖
pip install tiktoken openai
- 实现Prompt Token计算函数
import tiktoken import openai def calculate_prompt_tokens(messages, model="gpt-3.5-turbo"): """按照OpenAI官方规则计算对话Prompt的Token数""" encoding = tiktoken.encoding_for_model(model) num_tokens = 0 for message in messages: # 每个消息的基础结构开销 num_tokens += 4 for key, value in message.items(): num_tokens += len(encoding.encode(value)) # 包含name字段时的调整 if key == "name": num_tokens -= 1 # 模型生成前缀的开销 num_tokens += 2 return num_tokens
- 流式输出并统计总Token
def stream_chat_with_token_count(messages, model="gpt-3.5-turbo"): prompt_tokens = calculate_prompt_tokens(messages, model) completion_tokens = 0 encoding = tiktoken.encoding_for_model(model) # 调用流式API stream = openai.ChatCompletion.create( model=model, messages=messages, stream=True ) print("流式输出内容:") for chunk in stream: content_chunk = chunk.choices[0].delta.get("content", "") if content_chunk: # 计算当前片段的Token数并累加 chunk_token_count = len(encoding.encode(content_chunk)) completion_tokens += chunk_token_count # 输出流式内容 print(content_chunk, end="", flush=True) # 输出Token统计结果 print(f"\n\nToken统计:Prompt={prompt_tokens},Completion={completion_tokens},Total={prompt_tokens + completion_tokens}") return prompt_tokens + completion_tokens
注意事项
- 必须使用
tiktoken库,第三方Tokenizer无法匹配OpenAI的编码规则 - 不同模型对应不同编码方案(如gpt-3.5-turbo用cl100k_base,text-davinci-003用p50k_base),务必用
encoding_for_model获取对应编码 - 流式返回的片段是增量内容,不要重复计算已输出文本的Token
内容的提问来源于stack exchange,提问作者FengZi
相关产品推荐
相关产品推荐

