著者: ヤン・マジェフスキー 編纂者:Yue Yang 著者がGPT-4oで生成した画像 高コストとレイテンシは、大規模な言語モデルを実稼働環境に適用する際の主な障害の 1 つであり、どちらもプロンプト情報のサイズと密接に関連しています。 大規模言語モデル(LLM)の幅広い応用範囲を考えると、多くの人がLLMを様々な問題を解決する万能薬と考えています。検索拡張(RAG)技術やAPI呼び出しなどのツールと統合し、洗練されたガイドプロンプトを併用することで、LLMは人間に近いパフォーマンスを発揮することがよくあります。 しかし、この包括的なアプリケーション戦略は、プロンプトワードの情報内容が急速に拡大する可能性があり、使用コストの上昇と応答の大幅な遅延に直接つながり、LLM を実際の運用環境に導入することが非常に困難になります。 LLMを高価値タスク(コード最適化など)に使用する場合、コストの考慮は二の次になるかもしれません。通常30分かかるコードが30分で完了するようになった場合、ある程度のコストは許容範囲となります。しかし、To C分野では、数千ものリアルタイム対話リクエストに対応するため、コスト管理と応答速度がプロジェクトの成否を左右する鍵となります。 この記事では、Resider.pl の LLM を活用した不動産検索アシスタント「Mieszko」の構築に関する洞察を共有します。印象的な概念実証 (POC) の作成と、 LLM の効果的な実践導入の間のギャップを埋めることに焦点を当てています。 01. プロンプトだけが頼り「Mieszko」の開発にあたっては、優れたフレームワークであるLangChainに大きく依存しました。このフレームワークは、複雑なロジックやコンポーネントを整然とした明確な方法で抽象化し、わずか数行のコードで呼び出せる、効率的で使いやすいプロンプトWordテンプレートを備えています。 LangChainの使いやすさゆえに、うっかり核心的な点を忘れてしまうかもしれません。ソリューションがどれほど複雑であっても、すべてのコンポーネントは本質的にLLMに渡される長いテキストメッセージ、つまり「コマンドプロンプト」に集約されるのです。以下は、LLMエージェントがコマンドプロンプトを受け取ったりタスクを実行したりする前の入力プロンプトの基本構造と主要コンポーネントを示す一般的な例です。 LLMエージェントの命令型プロンプトテンプレートを使用する際に使用される基本構造 02 使用コストと応答遅延に影響を与える要因は何ですか?LLM (大規模言語モデル) は、これまでに構築された中で最も複雑な AI モデルの 1 つですが、その応答遅延と使用コストは、タスク自体の難易度ではなく、主に入力と出力で処理されるトークンの数によって決まります。 執筆時点では、OpenAI の主力モデルである GPT-4 Turbo の価格設定は、おおよそ次のようになります。 応答遅延の計算方法はそれほど簡単ではありませんが、「Mieszko」のアプリケーション シナリオに基づくと、次の式に簡単にまとめることができます。 コストの観点から見ると、LLMの利用コストの大部分は入力トークンによって占められており、その価格は出力トークンの3分の1程度です。しかし、より複雑なタスクでは、プロンプトの長さがユーザーに表示される出力トークンの長さをはるかに超える場合があります。 ただし、レイテンシは主に出力トークンの影響を受け、出力トークンの処理には入力トークンよりも約 200 倍の時間がかかります。 LLMエージェントを使用する場合、トークンの約80%は入力トークン、主に初期の手がかりとエージェント推論時のオーバーヘッドから発生します。これらの入力トークンは使用コストの重要な要素ですが、応答時間への影響は限定的です。 03 トークン消費の監視と管理LLM アプリケーションを構築する場合、最初のプロンプト ワード テンプレートに加えて、少なくとも次のコンポーネントが必要です。
技術的には任意の数のツールを追加できますが、最もシンプルなエージェントとツールのアーキテクチャに依存すると、システムのスケーラビリティが低下する可能性があります。利用可能なツールごとに、エージェントが呼び出されるたびに、APIドキュメントなどの詳細なドキュメントを送信する必要があります。 新しいシステムコンポーネントを準備する際には、各呼び出しにどれだけの追加トークンが必要かを検討する必要があります。OpenAIのモデルを使用する場合、新しいツールや追加のガイダンスプロンプトの「トークン消費量」を次のように簡単に評価できます。
tiktokendef num_tokens_from_string(string: str, model_name: str) -> int をインポートします:
試す:
encoding = tiktoken.encoding_for_model(model_name) except KeyError as e: raise KeyError(f"エラー: モデル '{model_name}' に使用できるエンコードがありません。モデル名を確認して、もう一度お試しください。")
num_tokens = len(encoding.encode(string)) num_tokensを返す04 正確さを犠牲にせずにプロンプトを簡潔に保つ方法大規模言語モデル(LLM)は一見すると圧倒的に思えるかもしれませんが、結局のところ、私たちが扱っているのはあくまでソフトウェアであることを忘れてはなりません。つまり、エラーを予測し、ソフトウェアシステム設計における抽象度とモジュール性のレベルを管理・制御し、サブタスクを処理するためのより効率的なソリューションを模索する必要があるのです。 Mieszkoの開発において、特に役立つと感じた一般的なテクニックを以下に示します。今後数週間のうちに、これらの一般的なテクニックのほとんどについて解説する続編の記事を執筆する予定です。最新情報をご希望の場合は、こちらのページ(https://medium.com/@janekmajewski/subscribe)を購読して、記事が公開された際に通知を受け取ってください。 4.1 プロンプトを呼び出す前に、大きなブロックを複数のレイヤーに分割します。ソフトウェアエンジニアリングの重要な原則の一つは、モジュール性と抽象化です。複雑な問題を単一のヒントで処理しようとするのは、メンテナンス不可能な「スパゲッティコード」を書くのと同じくらい非効率的です。(訳者注:この比喩は、絡み合って分離しにくいスパゲッティのイメージに由来しています。明確な構造、適切なモジュール分割、論理的な順序がなく、ネストされた条件文、無秩序なジャンプ、反復的なコードブロックで満たされたコードは、「スパゲッティコード」とみなされます。) Mieszko の構築時にパフォーマンスが大幅に向上した主な要因は、プロンプトを 2 つの部分に分割したことです。
階層的意思決定と実行アーキテクチャ図 階層的な意思決定と実行呼び出しアーキテクチャ図。画像は元の著者から提供されました。 このアーキテクチャにより、大量のトークンを消費する実行命令を添付することなく、各呼び出しで使用する特定のタスク プロンプトを選択できるようになり、トークンの使用量を平均で 60% 以上削減できます。 4.2 各通話の最後のプロンプトワードを必ず監視してください。LLMが受信する最終的なプロンプトは、最初のプロンプトテンプレートとは大きく異なる可能性があります。ツール、メモリ、コンテキスト、そしてエージェントの内部推論を通してプロンプトテンプレートを拡充するプロセスにより、プロンプトの数が数千トークンへと大幅に増加する可能性があります。 さらに、LLM 取得者は、ロッキー・バルボアのような回復力を発揮し、不正確な質問や矛盾した質問に直面しても「立ち上がって」合理的な答えを出すことができることもあります。 数十ものLLM呼び出しを注意深く検証し、大規模言語モデル(LLM)が実際にどのような情報を受け取っているかを深く理解することで、重要なブレークスルーやバグの排除に役立つ貴重な洞察が得られます。詳細な分析にはLangSmithのご利用を強くお勧めします。 最もシンプルな解決策をお探しの場合は、LangChainのデバッグ機能を有効にすることもできます。これにより、各呼び出しで送信された正確なプロンプトワードに加え、プロンプトワードの内容をより適切に監視および最適化するのに役立つ豊富な情報が得られます。 langchainをインポートする langchain.debug=True 4.3 ほんの数行のコードで実行できる場合は、LLM に提出する前によく考えてください。LLMを使用する際の最大の誤解は、プログラミングを使って問題を解決できることを忘れてしまうことです。例えば、私の場合、LLM呼び出しの上流と下流の非常に単純なタスクをPython関数で処理することで、パフォーマンスが大きく向上しました。 これはLangChainを使用する場合に特に便利です。LangChainを使用すると、LLM呼び出しを従来のPython関数と簡単に連結できます。以下は、私が問題を解決するために使用した簡略化された例です。LLMにユーザーのメッセージと同じ言語で応答するように指示したにもかかわらず、LLMはデフォルトで英語で返信していました。 現在の会話の言語を検出するためにLLMに頼る必要はありません。Google Translate APIやシンプルなPythonライブラリ(langdetectなど)を使えば、このタスクをより迅速かつ正確に実行できます。入力言語を特定したら、それをガイダンスプロンプトに明示的に渡すことができるため、LLMを呼び出す際に必要な作業量を削減できます。 langdetectからdetectをインポート
プロンプト = """
次のメッセージを{language}で要約してください。
メッセージ: {input}
"""prompt = ChatPromptTemplate.from_template(prompt)def detect_language(input_message):
input_message["language"] = detect(input_message["input"]) 入力メッセージを返す
検出言語ステップ = RunnablePassthrough.assign(入力メッセージ = 検出言語)
メッセージの言語でチェーンを要約する = (
言語ステップの検出
* 実行可能パススルー.割り当て(
language=lambda x: x["入力メッセージ"]["言語"]
)
* プロンプト
* llm ) 4.4 エージェントのプロンプトは通常少なくとも 2 回呼び出されるため、その設計には慎重に考慮する必要があります。ツールを統合するエージェントはLLMの機能を新たなレベルに引き上げることができますが、同時に大量のトークン(コンピューティングリソース)を消費します。下の図は、LLMエージェントがクエリに回答を提供する際の一般的な論理フローを示しています。 AIエージェントはLLMを2回呼び出します。画像は元の著者から提供されました。 上の図に示すように、エージェントは通常、LLMを少なくとも2回呼び出す必要があります。1回目はツールの使用方法を計画するため、2回目はこれらのツールの出力を解析して最終的な回答を提供するためです。この特性は、プロンプトの設計時に節約するトークン1つ1つが、実際には2倍のメリットをもたらすことを意味します。 より単純なタスクの場合、エージェントベースのアプローチは過剰である可能性がありますが、「完了」というシンプルなガイドプロンプトを使用するだけで同様の結果が得られ、場合によっては2倍の速度になることもあります。例えば、Mieszkoプロジェクトでは、ほとんどのタスクをマルチエージェントアーキテクチャからタスク固有のエージェント+完了モデルに移行することを決定しました。 4.5 大規模言語モデルと従来のプログラミングツールを組み合わせて、それぞれの長所を活用する(推論にはLLMを使用し、計算と集計はSQLまたはPythonで実行する)以前のGPT-3.5と比較すると、最新のトップレベルの大規模言語モデルは、基本的な数式を扱う際に誤りを犯していたにもかかわらず、大きな進歩を遂げています。現在、LLMはセグメント平均の計算などのタスクにおいて、数百の数値を簡単に処理できます。 しかし、LLMはPythonやSQLの記述に優れており、数兆ものモデルパラメータを必要とせずに複雑な数学演算を100%の精度で実行できます。しかし、LLMに大きな数値を渡すと大量のトークンが消費されます。最良の場合でも、3桁ごとに1つのトークンに変換されますが、数値が大きい場合は、1桁の数値が複数のトークンを占有することもあります。 数学的な演算を分析し、より効率的かつ低コストで結果を得るには、LLM を使用して問題と手元のデータを理解し、それを数学的な分析により適した SQL や Python などのプログラミング言語に変換することが鍵となります。 実際には、記述されたコードは関数に埋め込んで実行することができます。この関数は、データソースに接続し、最終的な分析結果をLLMに提示して直接理解・分析できるようにする役割を担います。 05 要約この記事で紹介した一般的な手法が、読者の皆様がLLMアプリケーションのコストと応答遅延に影響を与える主な要因と、それらを最適化する方法についてより深く理解する一助となれば幸いです。本番環境レベルのLLMベースアプリケーションの開発から得た重要な教訓を、可能な限り多く共有したいと考えています。このシリーズの今後の記事では、より具体的で実践的なケーススタディから始めていきます。
最後に、Mieszkoエンジンの共同開発者であるFilip Danieluk氏に心からの感謝と敬意を表します。数え切れないほどの日々の綿密な議論とペアプログラミングを通して、このシリーズの記事で紹介する内容が生まれました。これらの知見は、私とFilip氏双方の財産です。 読んでくれてありがとう! ヤン・マジェフスキ https://medium.com/@janekmajewski LLMを活用して不動産検索を変革。NLP、地理分析、価格ベンチマークに情熱を注ぐデータサイエンティスト 終わり この記事は、原著者の許可を得てBaihai IDPによって翻訳されました。翻訳の転載をご希望の場合は、お問い合わせください。 オリジナルリンク: https://towardsdatascience.com/streamline-your-prompts-to-decrease-llm-costs-and-latency-29591dd0e9e4 |