ChatGPT를 사용하다 보면 가끔 답변을 안하는 경우가 있다.
이럴때 보통 Timeout Error가 발생하는데 이 에러는 클라이언트 측에서 어떻게 할 방법이 없다.
하지만 OpenAI 공식사이트에서 이를 예방하는 방법을 적어두어 공유해보고자 한다.
속도 제한 오류를 방지하는 쉬운 방법 중 하나는 요청을 자동으로 재시도하는 것입니다. 지수 백오프로 다시 시도하는 것은 속도 제한 오류가 발생했을 때 짧은 대기 시간을 가지고 해당 요청을 다시 시도하는 것을 의미합니다. 요청이 여전히 실패하는 경우 대기 시간이 증가하고 이 과정이 반복됩니다. 요청이 성공하거나 최대 다시 시도 횟수에 도달할 때까지 이어집니다. 이 접근 방식에는 다양한 이점이 있습니다.
요약하면, 에러가 났을때 다시 요청해서 응답을 받는 방법
Tenacity는 Python으로 작성된 Apache 2.0 라이센스 범용 재시도 라이브러리로, 거의 모든 것에 재시도 동작을 추가하는 작업을 단순화합니다. 요청에 지수 백오프를 추가하려면 tenacity.retry데코레이터를 사용할 수 있습니다. 아래 예에서는 이 tenacity.wait_random_exponential함수를 사용하여 요청에 임의 지수 백오프를 추가합니다.
import openai
from tenacity import (
retry,
stop_after_attempt,
wait_random_exponential,
) # for exponential backoff
@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(6))
def completion_with_backoff(**kwargs):
return openai.Completion.create(**kwargs)
completion_with_backoff(model="gpt-3.5-turbo-instruct", prompt="Once upon a time,")
@retry(stop=stop_after_attempt(2), wait=wait_fixed(1))
async def reply(prompt, query) -> str:
messages = [{"role": "system", "content": prompt}]
messages.append({"role": "user", "content": query})
completion = await chat_complete(
messages=messages,
max_tokens=64,
temperature=1,
frequency_penalty=3,
)
answer = completion.choices[0].message["content"].strip()
return answer
@retry(stop=stop_after_attempt(2), wait=wait_fixed(1))
이 코드를 해석하면, 1초 간격으로 2번의 재요청을 보내라는 뜻이다.
실제로 Tenacity 패키지를 설치하고 데코레이터를 추가한 결과
에러 발생률이 현저하게 떨어졌다 (5000번의 요청에 1번꼴로 발생)
그리고 놀라웠던 점은 retry를 한다고해서 요청 시간이 크게 늘어나지 않았다는 점이다.
챗봇이 대답을 못하는 경우는 서비스에서 치명적인데,
retry를 2번정도 하게 코드를 수정하면서 좀 더 안정적으로 서비스할 수 있게 되었다.