OpenAI APIをPythonで呼び出すとき、GPTのstreamとtimeoutを併用するとどうなるのか、検証します。
はじめに
OpenAI APIをPythonで呼び出すときは、timeoutやstreamを設定できます。
- OpenAI Python Libraryでtimeoutを設定する - BioErrorLog Tech Blog
- OpenAI APIでGPTのstreamレスポンス | Python - BioErrorLog Tech Blog
このtimeoutとstreamを併用するとどのタイミングでタイムアウトが発生するのか、パッとわからなかったので検証しました。
OpenAI APIで、streamとtimeoutを併用したときの振る舞いがパッとわからなかったので検証してみました.
— BioErrorLog (@bioerrorlog) September 2, 2023
timeoutは、stream開始時点に対して実行される.
GPTのstreamとtimeoutを併用した時の挙動 | OpenAI Python Library - BioErrorLog Tech Blog https://t.co/DuWvS7LdVf pic.twitter.com/g6FtSynTrM
GPTのstreamとtimeoutを併用した時の挙動
仮説
2つ仮説があります。
仮説1:timeoutはstream終了時点に対して実行される
この挙動の場合、streamレスポンスが返って来てても、timeout時間が来たら途中で処理がタイムアウトする、という挙動になります。
仮説2:timeoutはstream開始時点に対して実行される
こちらの挙動の場合、streamレスポンスが開始したら、もうタイムアウトが実行されることはありません。
検証方法
Streamレスポンスがちょうど返ってきている途中でタイムアウトする、という条件でOpenAI APIを呼び出し、挙動を確認します。
具体的には、下記のPythonコードを実行します。
import os import time import openai openai.api_key = os.environ["OPENAI_API_KEY"] def main() -> None: start_time = time.time() response = openai.ChatCompletion.create( model="gpt-3.5-turbo-0613", messages=[ {'role': 'user', 'content': 'Tell me about the Japanese history.'} ], stream=True, request_timeout=3, ) collected_chunks = [] collected_messages = [] for chunk in response: chunk_time = time.time() - start_time collected_chunks.append(chunk) chunk_message = chunk['choices'][0]['delta'].get('content', '') collected_messages.append(chunk_message) print(f"Message received {chunk_time:.2f} seconds after request: {chunk_message}") full_reply_content = ''.join(collected_messages) print(f"Full conversation received: {full_reply_content}") if __name__ == "__main__": main()
Ref. python-examples/openai_stream_timeout/main.py at main · bioerrorlog/python-examples · GitHub
ポイントは、
- 回答の生成に時間がかかる質問を投げる
- streamレスポンスが開始し、回答が生成しきらないタイミングでtimeoutを設定する
です。
では、結果を見ていきましょう。
検証結果
結果、タイムアウトは発生しませんでした。
つまり、先述した仮説2の挙動であり、timeoutはstream開始時点に対して実行されるようです。
# 実行結果 $ python main.py Message received 1.86 seconds after request: Message received 1.86 seconds after request: Japanese Message received 1.86 seconds after request: history # 中略 # 設定したtimeout時間(3 sec)でタイムアウトが発生しない Message received 2.80 seconds after request: The Message received 2.82 seconds after request: earliest Message received 2.98 seconds after request: known Message received 2.99 seconds after request: human Message received 3.01 seconds after request: hab Message received 3.02 seconds after request: itation Message received 3.03 seconds after request: in Message received 3.04 seconds after request: Japan # 以下略
ちなみに、streamが開始される前にtimeoutを設定する(0.5secなど)と、普通にタイムアウトは発生します。
まとめ
まとめると、streamとtimeoutを併用した時の挙動は下記のようになります。
- stream開始が、設定したtimeoutより遅かった場合、タイムアウトが発生する
- 設定したtimeoutが、stream開始よりも遅かった場合、タイムアウトは発生しない
おわりに
以上、GPTのstreamとtimeoutを併用した時の挙動を検証しました。
少し気になっていたポイントだったので、スッキリしました。
どなたかの参考になれば幸いです。
[関連記事]
参考
openai-cookbook/examples/How_to_stream_completions.ipynb at main · openai/openai-cookbook · GitHub
Using server-sent events - Web APIs | MDN
python-examples/openai_stream_timeout/main.py at main · bioerrorlog/python-examples · GitHub