キャッシング生成的LLMs | APIコストの節約

キャッシング生成的LLMs | APIコストの節約' Condensed 'キャッシング生成的LLMs | APIコストの節約

はじめに

生成AIは非常に広まっており、私たちのほとんどは、画像生成器または有名な大規模言語モデルなど、生成AIモデルを使用したアプリケーションの開発に取り組んでいるか、既に取り組んでいます。私たちの多くは、特にOpenAIなどのクローズドソースの大規模言語モデルを使用して、彼らが開発したモデルの使用に対して支払いをする必要があります。もし私たちが十分注意を払えば、これらのモデルを使用する際のコストを最小限に抑えることができますが、どういうわけか、価格はかなり上昇してしまいます。そして、この記事では、つまり大規模言語モデルに送信される応答/ API呼び出しをキャッチすることについて見ていきます。Caching Generative LLMsについて学ぶのが楽しみですか?

学習目標

  • Cachingとは何か、そしてそれがどのように機能するかを理解する
  • 大規模言語モデルをキャッシュする方法を学ぶ
  • LangChainでLLMをキャッシュするための異なる方法を学ぶ
  • Cachingの潜在的な利点とAPIコストの削減方法を理解する

この記事は、Data Science Blogathonの一部として公開されました。

Cachingとは何か?なぜ必要なのか?

キャッシュとは、データを一時的に保存する場所であり、このデータの保存プロセスをキャッシングと呼びます。ここでは、最も頻繁にアクセスされるデータがより速くアクセスできるように保存されます。これはプロセッサのパフォーマンスに劇的な影響を与えます。プロセッサが計算時間がかかる集中的なタスクを実行する場合を想像してみてください。今度は、プロセッサが同じ計算を再度実行する状況を想像してみてください。このシナリオでは、前回の結果をキャッシュしておくと非常に役立ちます。タスクが実行された時に結果がキャッシュされていたため、計算時間が短縮されます。

上記のタイプのキャッシュでは、データはプロセッサのキャッシュに保存され、ほとんどのプロセスは組み込みのキャッシュメモリ内にあります。しかし、これらは他のアプリケーションには十分ではない場合があります。そのため、これらの場合はキャッシュをRAMに保存します。RAMからのデータアクセスはハードディスクやSSDからのアクセスよりもはるかに高速です。キャッシュはAPI呼び出しのコストも節約することができます。例えば、Open AIモデルに類似のリクエストを送信した場合、各リクエストに対して請求がされ、応答時間も長くなります。しかし、これらの呼び出しをキャッシュしておくと、モデルに類似のリクエストをキャッシュ内で検索し、キャッシュ内に類似のリクエストがある場合は、APIを呼び出す代わりにデータ、つまりキャッシュから応答を取得することができます。

大規模言語モデルのキャッシュ

私たちは、GPT 3.5などのクローズドソースのモデル(OpenAIなど)が、ユーザーにAPI呼び出しの料金を請求していることを知っています。請求額または関連する費用は、渡されるトークンの数に大きく依存します。トークンの数が多いほど、関連するコストも高くなります。これは大金を支払うことを避けるために慎重に扱う必要があります。

さて、APIを呼び出すコストを解決する/削減する方法の一つは、プロンプトとそれに対応する応答をキャッシュすることです。最初にモデルにプロンプトを送信し、それに対応する応答を取得したら、それをキャッシュに保存します。次に、別のプロンプトが送信される際には、モデルに送信する前に、つまりAPI呼び出しを行う前に、キャッシュ内の保存されたプロンプトのいずれかと類似しているかどうかをチェックします。もし類似している場合は、モデルにプロンプトを送信せずに(つまりAPI呼び出しを行わずに)キャッシュから応答を取得します。

これにより、モデルに類似のプロンプトを要求するたびにコストを節約することができ、さらに、応答時間も短縮されます。なぜなら、キャッシュから直接データを取得するため、モデルにリクエストを送信してから応答を取得する必要がないからです。この記事では、モデルからの応答をキャッシュするための異なる方法を見ていきます。

LangChainのInMemoryCacheを使用したキャッシュ

はい、正しく読みました。LangChainライブラリを使用して、応答とモデルへの呼び出しをキャッシュすることができます。このセクションでは、キャッシュメカニズムの設定方法と、結果がキャッシュされており、類似のクエリに対する応答がキャッシュから取得されていることを確認するための例を見ていきます。必要なライブラリをダウンロードして開始しましょう。

!pip install langchain openai

まず、LangChainとOpenAIのライブラリをpip installします。OpenAIモデルで作業し、API呼び出しの価格設定方法とキャッシュの使用方法を確認します。さあ、コードを始めましょう。

import os
import openai
from langchain.llms import OpenAI


os.environ["OPENAI_API_KEY"] = "あなたのAPIトークン"

llm = OpenAI(model_name="text-davinci-002", openai_api_key=os.environ["OPENAI_API_KEY"])

llm("誰が最初に宇宙に行った人ですか?")

  • ここでは、OpenAIモデルを設定しています。os.environ[]にOpenAI APIキーを指定する必要があります。
  • 次に、LangChainのLLMラッパーをインポートします。ここで使用しているモデルは「text-davinci-002」であり、OpenAI()関数にはAPIキーを含む環境変数も渡しています。
  • モデルが動作するかをテストするために、簡単な質問でAPIを呼び出し、LLMにクエリを送信することができます。
  • 上記の画像でLLMによって生成された回答が表示されます。これにより、モデルが稼働しており、モデルにリクエストを送信し、生成された応答を受け取ることができることが確認されます。

LangChainを介したキャッシング

次に、LangChainを介したキャッシングについて見てみましょう。

import langchain
from langchain.cache import InMemoryCache
from langchain.callbacks import get_openai_callback


langchain.llm_cache = InMemoryCache()
  • LangChainライブラリには、InMemoryCacheというキャッシングのための組み込み関数があります。LLMのキャッシングにはこの関数を使用します。
  • LangChainでキャッシングを開始するためには、InMemoryCache()関数をlangchain.llm_cacheに渡します。
  • ここでは、まずLangChainでLLMキャッシュを作成しています。
  • 次に、InMemoryCache(キャッシング手法)を取得し、langchain.llm_cacheに渡します。
  • これにより、LangChainでInMemoryCacheが作成されます。別のキャッシュメカニズムを使用する場合は、InMemoryCacheを使用するキャッシュと置き換えることができます。
  • get_openai_callbackもインポートしています。これにより、API呼び出しが行われた際にモデルに渡されるトークンの数、かかるコスト、応答トークンの数、応答時間に関する情報を取得できます。

LLMへのクエリ

次に、LLMにクエリを行い、レスポンスをキャッシュし、類似の質問がされた場合にキャッシュからレスポンスが取得されるかどうかを確認します。

%%time
import time


with get_openai_callback() as cb:
  start = time.time()
  result = llm("地球と月の距離は何ですか?")
  end = time.time()
  print("レスポンスにかかった時間:", end-start)
  print(cb)
  print(result)

時間計測関数

上記のコードでは、%%timeline関数を使用してセルの実行時間を表示します。また、API呼び出しと応答の受信にかかる時間を取得するためにtime関数もインポートしています。ここでもget_openai_callback()を使用していることに注意してください。モデルにクエリを渡した後にこの関数を通過させると、渡されたトークンの数、API呼び出しの処理コスト、所要時間が表示されます。以下に出力を示します。

上記の出力は、リクエストの処理にかかる時間は0.8秒であることを示しています。送信したプロンプトクエリのトークン数が9であり、生成された出力のトークン数が21であることもわかります。また、API呼び出しの処理コストが生成されたコールバックで表示され、$0.0006であることもわかります。CPU時間は9ミリ秒です。同じクエリでコードを再実行して、生成される出力を確認してみましょう。

ここでは、レスポンスにかかった時間の大きな違いが見られます。0.0003秒であり、最初に実行したときの2666倍速いです。コールバックの出力でも、プロンプトトークンの数は0で、コストは$0で、出力トークンも0です。成功したリクエストも0に設定されており、モデルへのAPI呼び出し/リクエストが行われなかったことを示しています。代わりに、キャッシュから取得されました。

これにより、LangChainが以前に同じプロンプトで実行されたときにOpenAIの大規模言語モデルによってキャッシュされたプロンプトと生成された応答をキャッシュしたことがわかります。これは、LangChainのInMemoryCache()関数を使用してLLMをキャッシュする方法です。

SQLiteCacheを使用したキャッシュ

プロンプトと大規模言語モデルの応答をキャッシュするもう一つの方法は、SQLiteCacheを使用することです。それについてのコードを始めましょう

from langchain.cache import SQLiteCache

langchain.llm_cache = SQLiteCache(database_path=".langchain.db")

ここでは、以前に定義したLLMキャッシュを同じ方法でLangChainで定義しています。ただし、ここでは異なるキャッシュ方法を指定しています。私たちはSQLiteCacheで作業しており、データベースのプロンプトと大規模言語モデルの応答を保存しています。これらのプロンプトと応答を保存するデータベースのパスも指定しています。ここではlangchain.dbになります。

それでは、以前にテストしたようにキャッシュメカニズムを試してみましょう。OpenAIの大規模言語モデルにクエリを2回実行し、2回目の実行で生成される出力を観察してデータがキャッシュされているかどうかを確認します。これに対するコードは次のとおりです

%%time
import time

start = time.time()
result = llm("原子爆弾は誰が作りましたか?")
end = time.time()
print("レスポンスにかかった時間:", end-start)
print(result)

%%time
import time

start = time.time()
result = llm("原子爆弾は誰が作りましたか?")
end = time.time()
print("レスポンスにかかった時間:", end-start)
print(result)

最初の出力では、大規模言語モデルへのクエリを最初に実行したとき、モデルにリクエストを送信してレスポンスを取得するまでの時間は0.7秒かかります。しかし、同じクエリを大規模言語モデルに実行しようとすると、レスポンスにかかる時間は0.002秒になります。これは、「原子爆弾は誰が作りましたか?」というクエリが最初に実行されたとき、プロンプトと大規模言語モデルによって生成された応答がSQLiteCacheデータベースにキャッシュされたことを証明しています。

その後、同じクエリを2回目に実行すると、最初にキャッシュを検索し、使用可能な場合はOpenAIのモデルにリクエストを送信してレスポンスを取得する代わりに、キャッシュから対応する応答を取得します。これは、大規模言語モデルをキャッシュする別の方法です。

キャッシュの利点

コストの削減

大規模言語モデルと連携する際に、キャッシュはAPIコストを大幅に削減します。APIコストは、モデルにリクエストを送信してその応答を受け取ることに関連しています。つまり、生成型の大規模言語モデルに対して送信するリクエストが多いほど、コストも大きくなります。同じクエリを2回目に実行したとき、クエリの応答がモデルにリクエストを送信する代わりにキャッシュから取得されることを確認しました。これは、大規模言語モデルに対して多くの類似のクエリが送信されるようなアプリケーションで非常に役立ちます。

パフォーマンスの向上/レスポンス時間の短縮

はい、キャッシュはパフォーマンス向上に役立ちます。直接ではなく、間接的にですが。パフォーマンスの向上は、プロセッサが計算にかなりの時間を費やした回答をキャッシュし、再計算する必要がある場合です。しかし、キャッシュしていれば、再計算する代わりに回答に直接アクセスできます。したがって、プロセッサは他の活動に時間を費やすことができます。

言語モデルのキャッシュに関しては、Promptと応答の両方をキャッシュします。したがって、類似のクエリを繰り返す場合、応答はモデルにリクエストを送る代わりにキャッシュから取得されます。これにより、応答時間が大幅に短縮されます。応答はキャッシュから直接取得されるため、モデルにリクエストを送信して応答を受け取る必要がありません。私たちは例を使って応答速度もチェックしました。

結論

この記事では、LangChainでのキャッシュの動作について学びました。キャッシュとは何か、そしてその目的は何かについて理解を深めました。キャッシュを使用することの潜在的な利点についても見てきました。LangChainでの大規模言語モデルのキャッシュの異なる方法(InMemoryCacheとSQLiteCache)を見てきました。例を通じて、キャッシュの利点、アプリケーションのコスト削減、迅速な応答の確保方法を発見しました。

キーポイント

このガイドの主なポイントは次のとおりです:

  • キャッシュは情報を保存し、後で取り出す方法です。
  • 大規模言語モデルはキャッシュできます。保存されるのはPromptと生成された応答です。
  • LangChainでは、InMemoryCache、SQLiteCache、Redisなど、さまざまなキャッシュ技術が利用できます。
  • 大規模言語モデルをキャッシュすることで、モデルへのAPI呼び出し数が減り、APIのコストが削減され、迅速な応答が得られます。

よくある質問

この記事で表示されているメディアはAnalytics Vidhyaの所有ではなく、著者の裁量で使用されています。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

データサイエンス

「深層学習技術を利用した人工知能(AI)によるADASの向上」

ディープラーニングは、リアルタイムのセンサーデータを使用して、正確な物体検出、衝突予測、および積極的な意思決定を実現...

人工知能

AIの革新的なイノベーションが開発者を強化する

SAPは、Build CodeやHANA Cloudなどの複数の生成AI機能を導入し、開発者が迅速にデータから価値を生み出し、革新するのを支援...

機械学習

AIがYouTubeの多言語吹替を開始します

世界最大の動画共有プラットフォームであるYouTubeは、AI技術の統合により、コンテンツクリエイターが世界中の観客と接触する...

機械学習

「ゲート付き再帰型ユニット(GRU)の詳細な解説:RNNの数学的背後理論の理解」

この記事では、ゲート付き再帰ユニット(GRU)の動作について説明しますGRUは、長期短期記憶(LSTM)の事前知識があれば簡単...

機械学習

「自己改善のための生成AIと強化学習の統合」

イントロダクション 人工知能の進化する領域において、二つの主要な要素が刷新を果たしました:生成型AIと強化学習。これらの...

機械学習

ディープラーニングのためのPythonとC++による自動微分

このストーリーでは、トレーニングループ中にパラメータの勾配を自動的に計算する現代のディープラーニングフレームワークの...