请求大模型接口时抛出 ReadTimeout,日志里写着 HTTPSConnectionPool read timed out。模型生成长文本本来就要时间,默认超时往往只有几秒,不改配置必然偶发失败。

超时要分成两段设

resp = requests.post(url, headers=h, json=body,
    timeout=(5, 120))

括号里第一个是建立连接的超时,第二个是等待响应的超时。连接超时短一点能快速失败,读取超时按最长生成时间给足,不要只写一个数字。

长文本改用流式接收

一次性返回几万字时,读超时很难估。开流式后每收到一段就重置计时,稳定性明显提升:

resp = requests.post(url, headers=h, json=body,
    timeout=(5, 60), stream=True)
for line in resp.iter_lines():
    if line:
        print(line.decode("utf-8"))

重试要挑状态码

from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
retry = Retry(total=3, backoff_factor=1,
    status_forcelist=[502, 503, 504])
s = requests.Session()
s.mount("https://", HTTPAdapter(max_retries=retry))

超时和 5xx 可以重试,400 和 401 重试没有意义,只会放大错误。重试前确认请求是幂等的,生成类接口重复调用会产生重复计费。

排查是网络还是服务端慢

用 curl 加 -w 参数看各阶段耗时,connect_time 正常而 total 很长,说明是服务端生成慢,不是本地网络问题,此时调大读取超时才是对症的做法。

上线前把超时和重试参数写进配置项,不要散落在代码里。服务扩容或切换模型版本时,这两个值通常需要一起调整。

作者 9823189

发表回复