大規模言語モデル(LLM)、エージェント型ワークフロー、ベクトル・ストアは着実に強力になり、AIアプリケーションの開発を効率化するフレームワークの人気が高まっています。DSPyは、プロンプト・エンジニアリングと自然言語の直接入力をPythonコードを使用した構成に置き換える汎用モジュールを提供するツールキットです。
一般的に、LLMまたは基盤モデルを操作するには、ユーザーが適切なアウトプットを得るためにテキストプロンプトを微調整する、慎重なプロンプト・エンジニアリングが必要です。このアプローチは効果的ではありますが、時間がかかり、エラーが発生しやすく、モデルの新しいバージョンがリリースされるときに更新する必要がある脆弱なツールチェーンが生じます。アプリケーション構築用のLangChainチェーン言語モデルやLlamaIndexなどの人気のフレームワークは、テキスト内の検索機能の向上に重点を置いています。これらの開発者は、プロンプトをファイン・チューニングするための専門知識と、目的のアウトプットを得るために各プロンプトをテストするための時間を必要とします。DSPyは、言語モデルの動作を指導し、制限するプログラムによるアプローチによって、このプロンプト調整プロセスを簡素化します。
DSPyはプロンプト構築の最適化の自動化に重点を置いています。DSPyはプロンプト・ハッキングや1回限りの合成データ・ジェネレーターを置き換えるために、プログラム内のパラメーターを更新するアルゴリズムである一般オプティマイザーを提供します。コード、データ、アサーション、またはメトリックを変更するたびに、プログラムを再度コンパイルすることで、DSPyがプロンプトの最適化を行い、変更に適合する新しい効果的なプロンプトを作成します。
自動プロンプトの最適化とは、LLMがユーザー生成のプロンプトを批判して改善するシステムを構築することだと想像する方もいます。これはLLMを使用する最も効果的な方法ではありません。DSPyでは、LLMのアイデア生成力を利用して、独自のプロンプトを生成します。次に、評価指標セットを使用してこれらのバリエーションをテストし、問題をより適切に解決できるかどうかを確認します。ユーザーが割り当てたメトリクスにおいて数値的に優れたパフォーマンスを発揮しない場合、新しいプロンプトは破棄されます。これは、プロンプトの適合性を評価し、繰り返し改善する進化的アルゴリズムに似ています。
DSPyは、さまざまな種類のワークフローやシナリオで役立ちます。最も一般的に使用されるものには、検索拡張生成、マルチホップ質問応答、ドキュメント要約などがあります。
思考の連鎖(CoT)プロンプティングでは、モデルに複雑なタスクを最終的な解決に向けた一連の論理的なステップに分解するように要求することで、人間のような推論プロセスをシミュレートします。これらの推論ステップはモデルのコンテキスト・ウィンドウに組み込まれ、手元のタスクへの基盤を強化し、複雑なシナリオでもより良い応答につながることがよくあります。DSPyは、言語モデルに思考の連鎖プロンプトとストラテジーを生成させ、それらを言語モデルでテストして、特定のモデルに対して最も効果的なCoTプロンプトを生成することで支援します。
検索拡張生成(RAG)は、LLMがソースからの大規模な知識コーパスを活用し、その知識保管を照会して関連する文章やコンテンツを見つけ、洗練された応答を生成できるようにするアプローチです。RAGにより、LLMは、主題について当初からトレーニングされていない場合でも、リアルタイムの知識を動的に使用して正しい回答を得ることができます。この追加の力により、RAGパイプラインを設定する際の複雑さが増します。DSPyでは、プロンプト・パイプラインを設定し、効果的なプロンプトを生成する(プロンプト・チューニング)か、小規模なモデルの場合はモデルの重み自体をファイン・チューニングするためのシームレスなアプローチを提供します。
RAGパイプラインは、ラベル付きサンプルを使用するか、Bootstrappingを使用するかの2つの方法でDSPyを使用して最適化できます。ラベル付きサンプルは単に既存のものであり、手動ラベル付きサンプルは学生モデルを直接トレーニングするために使用されます。DSPyの文脈におけるBootstrappingは、教師と生徒のパラダイムで言語モードを使用することを意味します。教師は、ユーザーが提供した数個のプロンプトに基づいて、新しいトレーニングサンプルを生成します。これらのBootstrappingされたサンプルは、手動でラベル付けされたサンプルと共に、またはその代わりに使用され、正しい回答を提供するまで学生モジュールをトレーニングします。正しい応答を生成するプロンプトは、DSPyパイプライン全体で繰り返し更新されます。
多くの場合、複雑な質問応答タスクには一つの検索クエリーだけでは不十分です。人気のあるHotPot質問応答データセットは、回答する前に複数の質問の解析と取得を必要とする質問で構成されています。例えば、「Bill Nelsonはペイロード・スペシャリストとして、何年後に初めて自動運転されたスペース・シャトルに乗りましたか?」この回答には、Bill Nelson氏がスペース・シャトル・コロンビアで飛行したことを知り、コロンビア号が1981年に最初に飛行したことを特定できる必要があります。
検索拡張文献におけるこの課題に対する標準的なアプローチは、マルチホップ検索システムを構築することです。これらのシステムでは、取得した結果を読み取り、追加のクエリーを生成して、最終的な回答を導き出す前に、必要に応じて追加の情報を収集します。DSPyを使用すると、モデルを更新し、パイプラインをやり直すことのできる堅牢な方法により、数行のコードで同じシステムを作成できます。
要約では、重要な情報やメイン・アイデアを保持しながら、長いテキストを短いバージョンに凝縮します。これは、アプリケーションが記事の要約の作成から長い文書からの簡潔なレポートの生成まで、LLMがうまく機能するための強力なスキルです。
言語モデルによって生成された要約の品質を評価するには、大きな課題があります。明確な正解や不備があるタスクとは異なり、要約の品質は主観的なものであり、文脈に依存することがよくあります。このモデルでは、元のテキストのトーンと意図を維持し、エラーを引き起こさずに事実の正確さを確保しながら、情報保持と簡潔性のバランスを取る必要があります。さまざまな種類のソース資料や要約目的に適応させるには、さらなる課題が生じます。DSPyを使用すると、ラベル付きデータを使用して要約プロンプトをチューニングし、可能な限り最良の応答を得ることができます。
DSPyには独自の語彙と用語があります。これらの重要な用語のいくつかを学ぶことで、一般的なアーキテクチャーを理解することができます。
コンパイル:このプロセスは、DSPyがPythonベースのプログラムを言語モデルが理解して効率的に実行できる命令に変換する方法です。
署名:これらはモジュールのインプットとアウトプットの型を定義し、DSPyプログラム内の異なるモジュール間の互換性を確保するクラスです。署名のサンプルとしては、質問をインプットして推論と回答を出力したり、文書をインプットとして受け取って要約を出力したりするタスクなどがあります。
オプティマイザー:DSPyのこのコンポーネントでは、GPT3.5-TurboやGPT-4.0、Llama 3.1など、使用している特定の言語モデルに合わせてコンパイルされたプログラムをファイン・チューニングします。オプティマイザーにより、確実にプログラムのパフォーマンスと精度を最大化できます。古いバージョンのDSPyでは、テレプロンプターと呼ばれていました。DSPyプログラムは、DSPyモジュールとして積み重ねられた言語モデルへの複数の呼び出しで構成されます。各DSPyモジュールには、LMの重み、従うべき命令、入力/出力の動作の保管されたデモンストレーションの3種類の内部パラメーターがあります。
測定基準が与えられると、DSPyでは多段階最適化アルゴリズムですべての重み、指示、モデル動作を使用して、最適化されたプロンプトを作成します。勾配降下法(言語モデルの重み用)と、離散言語モデル駆動型の最適化(命令の作成や更新、デモンストレーションの作成や検証)を組み合わせることができます。DSPyデモンストレーションはfew-shotのサンプルに似ていますが、はるかに強力です。それらは、プログラムを考慮して最初から作成することができ、その作成と選択は多くの効果的な方法で最適化できます。
多くの場合、コンパイルは人間が書くよりも優れたプロンプトを生み出します。なぜなら、オプティマイザーは人間よりも多くのことを、はるかに体系的に試行し、メトリクスを直接チューニングできるからです。
パイプライン:「パイプライン」とは、DSPyが複雑なタスクを達成するために連携して動作する一連の接続されたモジュールを指す方法です。例えば、パイプラインは記事を要約し、ソース言語からターゲット言語に変換し、それに関する質問をターゲット言語で生成する場合があります。
メトリクス:DSPyでは、アウトプットのパフォーマンスを測定するためにいくつかの異なるメトリクスを定義します。例えば、アウトプットをラベルに正確に一致させる必要がある場合に役立ちます。また、部分一致がニーズに適している場合もあります。DSPyによって提供される一般的に使用されるメトリクスはセマンティックF1です。このメトリクスでは、ラベル内の情報が回答にどの程度含まれているか、およびラベル付きターゲット応答にはない無関係なデータが回答にどの程度存在しているかを測定します。パフォーマンスを測定する別の方法が必要な場合は、独自のカスタム・メトリクスを提供することもできます。
DSPyの使用は、pip install dspy-aiを呼び出すだけで簡単に使用できます。ほとんどのモデルはAPIを通じてクラウドで使用するか、ローカルで実行できるため、特別なハードウェアは必要ありません。ローカルで実行することも、Google ColabやWatson Studioなどのホストされたノートブック環境で実行することもできます。
検索拡張生成のための典型的なDSPyパイプラインは、言語モデルと検索モデルで構成されています。例えば、OpenAI GPT-3.5 Turboを言語モデルとして、ColBERTV2リトリーバーを検索モデルとして動作させるには、DSPyを次のように設定します。
署名は、言語モデルと検索モデルのインプットとアウトプットフィールドをどのように構造化できるかを構成できるテンプレートです。例えば、次のコード・スニペットは、コンテキストを備えた言語モデルと、構造を備えた検索モデルをプロンプトする構文を示しています。
モデルが受け取るもの、生成するべきものに関するより堅固なガイドラインを定義するために、コンテキストと回答フィールドの簡単な説明を含めています。
署名を定義したら、プログラムを実行し、タスクに適切なオプティマイザーを使用して、タスクに最適なプロンプトを作成できます。DSPyで。このプロセスはコンパイルと呼ばれます。プログラムをコンパイルすると、各モジュールに保存されているパラメーターが更新されます。ほとんどのシナリオでは、これは主にプロンプト内に含める優れたデモンストレーションを収集して選択するという形で行われます。
コンパイルには次のものが必要です。
• トレーニングセットまたはブートストラップされたサンプル。
• 検証のためのメトリクス。RAGシナリオでは、これは、予測された回答の精度と、取得されたコンテキストにその回答が含まれているかどうかを測定する方法です。
• テスト対象のプロンプトを生成する特定のオプティマイザー。例えば、BootstrapFewShotオプティマイザーはプロンプトを生成し、その生成されたプロンプトをテストするために使用できます。
DSPyプログラムをコンパイルするには、使用するモデルを設定し、それらを選択したオプティマイザーのコンパイル・メソッドに渡します。例えば、RAGアプリケーションのプログラムには、言語モデルと検索モデルが含まれます。次に、これらはコンパイル・メソッドに渡され、オプティマイザーは取得したデータを使用して言語生成のコンテキストを設定します。
次に、検索モデルと言語モデルの両方を評価するためのメトリクスを定義します。そのメトリクス定義は、BootstrapFewShotやLabeledFewShotオプティマイザーなどのオプティマイザーに与えられ、言語モデルによって生成されたプロンプトを評価する際に使用されます。最後に、オプティマイザーは、トレーニングデータセットとともに定義したforwardメソッドを含むカスタムモジュールをコンパイルします。
使用するオプティマイザーを選択するには通常、実験が必要ですが、ガイドラインがあります。
• サンプルが非常に少ない場合(約10個)は、BootstrapFewShotから始めて、新しいトレーニングデータを生成することができます。
• 例えば50個以上のサンプルなど、より多くのデータがある場合は、BootstrapFewShotWithRandomSearchを使用して、トレーニングデータのランダムな部分に新しいトレーニングデータを生成してください。
• 非常に効率的なプログラムが必要な場合は、BootstrappingFinetuneを使用してタスクに合わせて小規模なLLMをファイン・チューニングできます。
プログラムをコンパイルしてメトリクスを比較した後は、成果に満足しているかもしれません。また、選択したメトリクスに従って、最終的なプログラムや成果の何かが気に入らないという点があることもあるでしょう。反復的な開発が鍵となります。DSPyでは、データの反復処理、プログラム構造、選択したメトリクス、選択したオプティマイザーの更新を通じて段階的に行うためのツールを提供します。
DSPyはオープンソースであるため、コードを検査し、開発の進行状況を確認できます。GithubのStanfordNLPサイトのドキュメントには、DSPyを使い始める方法に関するドキュメントと複数の段階的なチュートリアルとデモが含まれています。