admin管理员组

文章数量:1631703

问题重现

在调用 ChatGPT API 并使用流式输出时,我们经常会遇到网络问题导致的超时情况。有趣的是,笔者发现在本地调试遇到的超时,会在 10 分钟后自动恢复(为什么是 10 分钟?我们留到后面解释),但是在服务器上等待一会儿却会失败,报出超时异常(错误代码 502)。

笔者认为,本地能恢复的原因可能是自动重试,只是重试的时间有点久(ChatGPT API 没有重试功能,这是项目加入的)。服务器返回「502」是因为内容从后台返回到前端需要经过网关层,而网关层超时校验的时间比自动重试的时间(10 分钟)更短,所以撑不到重试就会报超时异常。

基于以上场景,本文着手解决 ChatGPT API 调用超时问题。

优化诉求

  • 不向用户展示超时的报错信息。

  • 缩短超时后重试的时间间隔。

解决思路

笔者考虑了两种方案。

一是彻底解决网络问题,但难度有点大。 这属于 OpenAI 服务器问题,即使是部署在国外的服务器也会出现超时的情况。

二是利用自动重试解决问题。 通过调整超时的时间,提升响应速度,方案可行。

实施解决方案

解决过程中,笔者分两步由浅至深地调整了超时时间;如果想直接了解最终方案,请移步「解决方案二」~

  • 运行环境:

Python: 3.10.7

openai: 0.27.6

  • 调用方法:

openai.api_resources.chat_completion.ChatCompletion.acreate

( 这是异步调用 ChatGPT 的方法。)

  • 方法调用链路:

超时参数 ClientTimeout,一共有 4 个属性 totalconnectsock_readsock_connect

# 方法 -> 超时相关参数
openai.api_resources.chat_completion.ChatCompletion.acreate -> kwargs
openai.api_resources.abstract.engine_api_resource.EngineAPIResource.acreate -> params
openai.api_requestor.APIRequestor.arequest -> request_timeout
# request_timeout 在这一步变成了 timeout,因此,只需要传参 request_timeout 即可
openai.api_requestor.APIRequestor.arequest_raw -> request_timeout
aiohttp.client.ClientSession.request -> kwargs
aiohttp.client.ClientSession._request -> timeout
    tm = TimeoutHandle(self._loop, real_timeout.total) -> ClientTimeout.total
    async with ceil_timeout(real_timeout.connect): -> ClientTimeout.connect
# 子分支1
aiohttp.connector.BaseConnector.connect -> timeout
aiohttp.connector.TCPConnector._create_connection -> timeout
aiohttp.connector.TCPConnector._create_direct_connection -> timeout
aiohttp.connector.TCPConnector._wrap_create_connection -> timeout
    async with ceil_timeout(timeout.sock_connect): -> ClientTimeout.sock_connect
# 子分支2
aiohttp.client_reqrep.ClientRequest.send -> timeout
aiohttp.client_proto.ResponseHandler.set_response_params -> read

本文标签: 在这思路技术chatGPTAPI