Flask框架Stream为True的时候,计算token的问题
背景
现在有很多的短视频博主发布视频,说 openai 在封翻墙使用 chatgpt 的用户。力度之大,乃至付费的用户也被大批的封。我试了一下自己的,chat.openai.com
是被禁止访问了,但是API还是可以正常访问的,为了正常使用chatgpt,我试着使用 openai 的 api 自己撸一个服务端,对外提供的 chat/completions
API 完全模拟 https://api.openai.com/v1/chat/completions ,这样有一个好处,在 github 上开源的 chatgpt 的商户端就可以正常使用了。
项目的名称: chatgpt-mirror (暂时未在github开源,看官可以关注我的博客,随时有可能会开源)
大概的思路是,chatgpt-mirror 提供一个接口 /v1/chat/completions
会验证自己提供的一个 Fake api key, 在 chatgpt-mirror 上做验证,验证通过后,使用服务端配置的openai的api key 调用 openai 的 api 请求 chatgpt,再把返回结果返回给用户。
花了几天的时间撸完了 chatgpt-mirror ,有很多朋友得知,期望可以共享使用一下。 为了共享使用,我为chatgpt增加了一个功能,为每一个用户配置一个 Fake API key,并在每次请求的时候计算token的消耗量(毕竟token是花钱的)
为了解决token计算问题,分享两点经验
- 在SSE(stream == True)的时候如何获取 response。在openai提供的api中当
stream == True
的时候,返回的是一个迭代器,是获取不到token的数量等字段,此时需要单独计算 - 如何计算 token
Flask 框架中如何获取stream api的reponse内容
flask 框架内置了很多事件(事件驱动),但是并没有on_response_close
事件,查看文档发现,在response
对象中提供了一个hook的方法
1response = Response()
2response.call_on_close()
通过注册call_one_close()
的回调方法来实现获取response
的内容,以及处理response
的内容
如何计算token
在 openai 的官方文档中已经有token计算的方法,我看了一下,计算方法太复杂了,所以直接使用他们提供的 tiktoken 的包。
使用方法也很简单
通过 model 获取 encoding
1encoding = tiktoken.encoding_for_model("gpt-3.5-turbo")
通过 encoding 得到tokens
1num_tokens = len(encoding.encode(string))
写成一个方法:
1def num_tokens_from_string(string: str, model: str) -> int:
2 """Returns the number of tokens in a text string."""
3 encoding = tiktoken.encoding_for_model(model)
4 num_tokens = len(encoding.encode(string))
5 return num_tokens
1num_tokens_from_string("Count tokens by tiktoken!", "gpt-3.5-turbo")