ChatGPT APIをLambdaで利用する時、レスポンス時間の短縮方法を調査してみた

ChatGPT APIをLambdaで利用する時、レスポンス時間が長かったため、短くする方法がないか調査しました。
2023.03.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

ChatGPT APIをLambdaで利用するブログをいくつか書きましたが、Lambdaの実行時間のうち、APIからのレスポンス時間が意外とかかっているため、レスポンス時間を短縮する方法について調査してみました。

先に結論

レスポンス時間を短縮するためには、以下の2つの方法が効果的と分かりました。

  • ChatGPTの応答時の文字数を減らす
  • 使用するモデルをgpt-3.5-turboからtext-davinci-003(厳密にはChatGPT APIではありません)に変える

検証環境の構築

検証するにあたり、Lambdaのコードなどの検証環境は、下記ブログ通りに作成しましたので、参考にしてください。

また、今回のレスポンス時間の短縮は、Lambdaが実行してから実行完了までの時間を短縮することとします。

あくまでも純粋なAPIのレスポンス時間ではなく、LambdaのAPIリクエストを含めたコード内の処理時間という点は、御了承ください。

Lambdaのコード

参考ブログにも記載していますが、Lambdaのコードを載せておきます。

from decimal import Decimal
import json
import os
import openai

openai.api_key = os.environ['API_Key']
API_ENDPOINT = 'https://api.openai.com/v1/engine/davinci-codex/completions'
input_text = '日本の文化について教えて下さい'

def decimal_to_int(obj):
    if isinstance(obj, Decimal):
        return int(obj)

def lambda_handler(event, context):

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": input_text}, 
        ]
    )
    print("Received response:" + json.dumps(response,default=decimal_to_int, ensure_ascii=False))
    return response["choices"][0]["message"]["content"]

実行すると、以下のテキストが出力されます。文字数は、591文字でした。

日本の文化には、以下のような特徴があります。1. おもてなしの心:日本では、「おもてなしの心」という考え方が重んじられています。これは、自分が招いた人を大切に扱い、心のこもったもてなしをするという意味であり、日本人にとっては当たり前のことです。2. 祭りや行事:日本には多くの祭りや行事があります。春には桜の花見、夏にはお祭り、秋にはスポーツの大会や文化祭、冬には年末年始のお正月など、四季を楽しむ行事が盛りだくさんです。3. 和食:日本人が代表的な食文化として誇るのが和食です。バランスの良い食事であり、野菜や魚、豆類、米などを豊富に使っています。また、器や盛り付けにも工夫が凝らされ、美しさも大切にされます。4. 茶道:茶道は、日本独自の文化であり、お茶を点て、お茶の香りや味を楽しむことが主眼です。また、床の間や花、茶器、菓子などを用いた空間演出が大切で、美意識や礼儀作法も重要視されます。5. 着物:着物は、日本の伝統的な衣服であり、男女ともに着用されます。季節や行事に合わせた着物の種類や柄、帯の結び方にもルールがあり、日本文化の一つとして大切にされています。6. アニメや漫画:日本は、アニメや漫画の発祥の地としても知られており、多くの人々に愛されています。キャラクター商品やイベントも盛んで、若者を中心にカルチャーとしても広がっています。以上が、日本文化の代表的な特徴の一部です。

Lambdaのメモリを上げる

まずは、Lambdaのメモリを128MBから1024MB、10240MBに上げてみて、Lambdaの実行時間に違いが出るか確認しました。

調査結果

128MB

- 実行完了時間 文字数
1 48639.75 ms 628
2 41208.22 ms 627
3 45699.27 ms 644
4 37043.60 ms 482
5 45060.64 ms 649

48639.75 msは、48.63975秒です。

1024MB

- 実行完了時間 文字数
1 30535.60 ms 449
2 38966.69 ms 579
3 41154.19 ms 619
4 39579.34 ms 587
5 35037.22 ms 477

10240MB

- 実行完了時間 文字数
1 32995.25 ms 512
2 31711.43 ms 490
3 43079.04 ms 619
4 37546.06 ms 527
5 33523.75 ms 526

結論を申し上げると、メモリを上げてもあまり変わらないです。

Lambda内の処理は、APIをリクエストしているだけのため、処理に対してメモリを上げても変わらないということですね。

ただ、Lambdaのコード量が多ければ、実行完了時間短縮には繋がります。

この調査で分かったこととして、ChatGPTの文字数によって、処理時間が変わるということが分かりました。

ChatGPTの応答時の文字数を減らす

先程の調査から、ChatGPT応答時の文字数を減らすことで、Lambdaの実行時間が減る傾向がわかりましたので、具体的にどの程度効果があるか調べてみます。

Lambdaのコードを修正

コードの8行目あたりを修正します。

ChatGPTに質問する際に、文字数を指定しました。

from decimal import Decimal
import json
import os
import openai

openai.api_key = os.environ['API_Key']
API_ENDPOINT = 'https://api.openai.com/v1/engine/davinci-codex/completions'
character_limit = 250
input_text = '日本の文化について教えて下さい。' + str(character_limit) + '以内にまとめてください'

def decimal_to_int(obj):
    if isinstance(obj, Decimal):
        return int(obj)

def lambda_handler(event, context):

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "user", "content": input_text}, 
        ]
    )
    print("Received response:" + json.dumps(response,default=decimal_to_int, ensure_ascii=False))
    return response["choices"][0]["message"]["content"]

ちなみに、create関数内でmax_tokensプロパティで文字数を指定することもできますが、このプロパティは、250文字で返答が切られてしまいます。

そのため、今回は使用せず、質問時に文字数指定するようコードを修正しました。

調査結果

メモリは、128MBです。

- 実行完了時間 文字数
1 26755.01 ms 265
2 19717.53 ms 266
3 17091.63 ms 211
4 23718.74 ms 311
5 17430.75 ms 239

文字数が630程度ですと、40秒ほど時間を要していましたが、250文字程度ですと、20秒程度しかかかりませんでした。

そのため、回答の文字数を減らすことで、APIのレスポンス時間(Lambdaの実行完了時間)を短縮することができると言えます。

使用するモデルを変える

ChatGPTは、GPT-3.5系のモデルの一つであるgpt-3.5-turboが使用されています。

同じGPT-3.5系のモデルの一つであるtext-davinci-003のAPIも提供されております。

厳密には、ChatGPTでは使われていないのですが、text-davinci-003を使用して、時間短縮に繋がるか試してみます。

Lambdaのコード

参考ブログにも記載していますが、Lambdaのコードを載せておきます。

from decimal import Decimal
import json
import os
import openai

openai.api_key = os.environ['API_Key']
API_ENDPOINT = 'https://api.openai.com/v1/engine/davinci-codex/completions'
character_limit = 300
input_text = '日本の文化について教えて下さい。' + str(character_limit) + '以内にまとめてください'

def decimal_to_int(obj):
    if isinstance(obj, Decimal):
        return int(obj)

def lambda_handler(event, context):
    response = openai.Completion.create(
        engine="text-davinci-003",
        prompt=input_text,
        max_tokens=1000
    )

    print("Received response:" + json.dumps(response,default=decimal_to_int, ensure_ascii=False))
    return response.choices[0].text.replace('\n', '')

調査結果

メモリ128MB

- 実行完了時間 文字数
1 13626.64 ms 260
2 14566.90 ms 286
3 12654.31 ms 289
4 13255.36 ms 243
5 13626.64 ms 255

text-davinci-003は、gpt-3.5-turboに比べ、30~40%ほど、実行時間が短縮されました。

実行時間の短縮はされますが、APIのコストは、gpt-3.5-turboの方が10分の1ですので、どちらを使用するか判断する際、能力だけでなくコストと実行時間を考慮する必要がありそうですね。

レスポンス時間短縮方法のまとめ

レスポンス時間を短縮するためには、以下の2つの方法が効果があることが分かりました。

  • ChatGPTの応答時の文字数を減らす
  • 使用するモデルをtext-davinci-003に変える

ChatGPTでLambdaを使用する時の参考になればと思います。

参考