[翻訳]LLMで1年間開発して学んだこと〜LLMプロダクト開発を成功に導くための実践的ガイド〜
今は大規模言語モデル(LLM)を使った開発がとってもエキサイティングな時期です。この1年間で、LLMは実世界のアプリケーションに対して「十分に良い」ものになりました。そして、年々良くなり、安くなっています。ソーシャルメディア上でのデモの数々と相まって、2025年までにAIへの投資額は推定2000億ドルに上ると言われています。さらに、LLMがAPIで使えるようになってより身近なものになり、機械学習エンジニアや科学者だけでなく、誰もが自分のプロダクトにAIを組み込むことができるようになりました。
とはいえ、AIを使った開発への参入障壁は低くなったものの、デモで終わらずに効果的なプロダクトやシステムを作ることは、想像しているよりも難しいのが現状です。
私たちは過去1年間、開発に取り組み、その過程で多くの困難に直面してきました。業界全体を代表して語ることはできませんが、私たちの失敗を避け、より速くイテレーションを回せるよう、学んだことをシェアしたいと思います。これらは以下の3つのセクションに分かれています。
- 戦術(Tactical):プロンプト、RAG、フローエンジニアリング、評価、モニタリングのためのいくつかのプラクティス。LLMを使って開発を行う実務者の方のために書かれたセクションです。
- 運用(Operational):プロダクトを運用する際の組織的、日常的な課題と、効果的なチームを作る方法。持続的かつ確実にデプロイするために、プロダクト・技術リーダーの方に向けて書かれています。
- 戦略(Strategic):長期的、大局的な視点で、「PMF前にGPUは不要」「モデルではなくシステムに注力すべき」などの提言や、イテレーションの方法を述べています。創業者や経営者の方々を念頭に書かれています。
LLMを使って成功するプロダクトを作るための実用的なガイドにしたいと考えており、私たち自身の経験を元に、業界の事例を紹介しています。
では早速見て行きましょう!
1 戦術(Tactical):LLMを使う上での基本
ここでは、LLMを使ったプロダクトを開発していく上でのコアな要素たちのベストプラクティスを紹介します。品質と信頼性を向上させるためのプロンプトのヒント、出力を評価するための評価戦略、正確性を向上させるためのRAGのアイデア、Human-in-the-loopなワークフローの設計方法などです。技術はまだ発展途上ですが、これらの教訓は広く適用可能であり、堅牢なLLMアプリケーションのリリースに役立つと信じています。
1.1 プロンプト
新しいアプリケーションのプロトタイプを作成する際は、プロンプトから始めることをお勧めします。プロンプティングの重要性は過小評価も過大評価もされがちです。適切なプロンプト技術を正しく使用すれば非常に高い精度を出せる、という意味では過小評価されていますが、プロンプトベースのアプリケーションではプロンプト周りに大規模なエンジニアリングが必要、という意味では過大評価されています。
1.1.1 基本的なプロンプト技術を最大限に活用する
さまざまなモデルとタスクでパフォーマンスを向上させるのに一貫して役立っているプロンプト技術がいくつかあります。n-shotプロンプトとIn-Context Learning、CoT、関連リソースの提供などです。
n-shotプロンプト(訳註:Few-shotsとかともよく呼ばれます)によるIn-Context Learningのアイデアは、LLMにタスクを実演し、出力を期待に合わせるための例を提供することです。
n-shotを活用する上でのいくつかのTips:
- n数が少なすぎると、モデルはそれら特定の例に過剰に引きづられ、汎化する能力が損なわれる可能性があります。経験則として、n≧5を目指してください。数十まで増やしても構いません。
- 例は、本番の分布を代表するものでなければなりません。例えば映画要約器を構築する場合は、実際に予想されるのとほぼ同じ割合で、異なるジャンルのサンプルを含めます。
- 常に入力-出力のペアを提供する必要はありません。望ましい出力の例だけで十分な場合もあります。
- LLMにツールを使用させる予定の場合は、それらのツールを使用する例を含めてください。(訳註:Function Calling などで使う Tool の話)
Chain-of-Thought(CoT)プロンプトでは、最終的な答えを返す前に、LLMに思考プロセスを説明するよう促します。LLMにメモ帳を渡して、すべてをメモリに保持しなくて大丈夫なようにするようなものと考えてください。
元(訳註: CoTが最初に提唱された論文のこと)のアプローチは、単に「段階的に考えてみましょう(Let’s think step by step)」というフレーズを指示の一部として追加することでしたが、CoTをより具体的にすることが役立つことが今では分かっています。1、2文追加して具体性を高めると、しばしばハルシネーション率が大幅に減少します。
例えば、会議の文字起こしを要約するようLLMに求める場合、次のように手順を明示することができます。
- まず、議事録に主要な決定事項、フォローアップ項目、および関連するステークホルダーを列挙します。
- 次に、議事録の詳細が文字起こしと事実上一致していることを確認します。
- 最後に、重要なポイントを簡潔な要約にまとめます。
ただ、最近この手法が信じられているほど強力かどうかについて疑問が投げかけられていることに注意してください。また、CoTが使用されている間の推論中に正確に何が起こっているかについても、大きな議論があります。とはいえ、この手法は可能な限り実験する価値があります。
関連リソースを提供することは、モデルの知識ベースを拡張し、ハルシネーションを減らし、ユーザーの信頼を高めるための強力なメカニズムです。多くの場合、RAGによって実現されますが、モデルに直接利用できるテキストのスニペットを提供することは不可欠な手法です。
関連リソースを提供する際、単にプロンプトに含めるだけでは不十分です。モデルにそれらの使用を優先するよう伝える、及びリソースが不十分な場合にその旨を伝えることを忘れないでください。
1.1.2 入力と出力を構造化する
構造化された入力と出力は、モデルが入力をより良く理解し、下流のシステムと確実に統合できる出力を返すのに役立ちます。入力にシリアライゼーション形式(訳註:MarkdownなりJSONなりの構造化されたフォーマット)を追加すると、コンテキスト内のトークン間の関係、特定のトークンに関する追加のメタデータ、またはリクエストをモデルのトレーニングデータの類似の例に関連付けるための手がかりをモデルに提供するのに役立ちます。
例えば、インターネット上のSQLの書き方に関する質問の多くは、最初にSQLスキーマを指定しています。したがって、Text-to-SQLの効果的なプロンプトには、構造化されたスキーマ定義を含める必要があると予想できます。
構造化された入力は、タスクを明確に表現し、トレーニングデータの書式に類似しているため、より良い出力が得られる可能性が高くなります。構造化された出力は、システムの下流のコンポーネントへの統合を簡単にします。構造化された出力には、InstructorとOutlinesが適しています。(LLM API SDKをインポートする場合はInstructorを、セルフホストモデル用にHuggingfaceをインポートする場合はOutlinesを使用します。)
構造化された入力を使用する場合、各LLMのモデルにはそれぞれの好みがあることに注意してください。Claudeは<xml>
を好みますが、OpenAIのGPTはMarkdownとJSONを好みます。XMLを使用すると、次のように<response>
タグを指定することで、Claudeの応答を事前に入力することもできます。
messages=[
{
"role": "user",
"content": """Extract the <name>, <size>, <price>, and <color> from this product description into your <response>.
<description>The SmartHome Mini is a compact smart home assistant available in black or white for only $49.99. At just 5 inches wide, it lets you control lights, thermostats, and other connected devices via voice or app—no matter where you place it in your home. This affordable little hub brings convenient hands-free control to your smart devices.
</description>"""
},
{
"role": "assistant",
"content": "<response><name>"
}
]
1.1.3 1つのことをうまく行う小さなプロンプトを作る
ソフトウェアにおける一般的なアンチパターン/コードスメルは、「神オブジェクト」です。これは、すべてを行う単一のクラスや関数を持っている状態です。これはプロンプトにも当てはまります。
プロンプトは通常、シンプルに始まります。数文の指示と2、3の例があれば、すぐに使えます。しかし、パフォーマンスを向上させ、より多くのエッジケースを処理しようとすると、複雑さが忍び寄ってきます。
より多くの指示、多段階の推論、数十のn-shots...。
最初はシンプルだったプロンプトが、今では2,000トークンのフランケンシュタインになっています。さらに悲しいことに、より単純な入力と比較してパフォーマンスが悪化しているのです!GoDaddyは、LLMを使った構築から学んだ教訓の中で、この課題を第1位に挙げています。
システムやコードをシンプルに保つように奮闘するのと同じように、プロンプトもシンプルにすべきです。例えば、会議の文字起こしの要約のために単一の包括的なプロンプトを用意するのではなく、以下のようにステップに分割することができます。
- 主要な決定事項、アクション項目、所有者を構造化された形式で抽出する
- 抽出された詳細を元の文字起こしと照合して整合性をチェックする
- 構造化された詳細から簡潔な要約を生成する
その結果、1つのプロンプトを複数のプロンプトに分割しました。それぞれがシンプルで、目的が明確で、理解しやすくなっています。また、分割することで、各プロンプトを個別に反復し、評価することができるようになりました。
1.1.4 コンテキストトークンを慎重に作る
含める必要があるコンテキストの量について慎重に考え直してみてください。
ミケランジェロのように、コンテキストの彫刻を作り上げるのではなく、余分な素材を削ぎ落としてください。RAGは、潜在的に関連するであろうすべての情報を取得するための一般的な方法ですが、その中から必要なものを抽出するためにはどうしたらいいと思いますか?
最終的なプロンプトを白紙に書き出して読むだけで、コンテキストの構築、メタプロンプティング、RAGの結果など、モデルに送信されるプロンプトを見直すのに非常に役立つことがわかりました。そうすることによって冗長性や自己矛盾する内容、不適切な書式などなどが見つかります。
もう1つの重要な最適化は、コンテキストの構造です。与えられたコンテキスト情報が人間にも理解し難い場合、エージェントにとっても良いとは限りません。コンテキストの構造を慎重に検討して、その部分間の関係を強調し、抽出をできるだけ簡単にします。
より多くのプロンプティングのメンタルモデル、事前入力、コンテキストの配置など、プロンプトの基本についてはこちらをご参照ください。
1.2 情報検索 / RAG
プロンプト以外のLLMの性能を引き出す効果的な方法は、プロンプトの一部として知識を提供することです。この知識はIn-Context Learningに使用され、これは、retrieval-augmented generation(RAG)と呼ばれています。RAGは出力の改善に効果的であり、ファインチューニングと比較して、はるかに少ない労力とコストで扱うことができます。
1.2.1 RAGの精度は検索されたドキュメントの「関連性、密度、詳細」によって決まる
RAGの出力の品質は、検索されたドキュメントの品質に依存しており、いくつかの要因に沿って考えることができます。
最も明白な指標は、関連性です。これは通常、平均逆順位(MRR)や正規化された割引累積利得(NDCG)などのランキング指標で定量化されます。MRRは、システムがランク付けされたリストで最初の関連結果をどれだけうまく配置するかを評価し、NDCGはすべての結果とその位置の関連性を考慮します。
これらは、システムが関連性の高いドキュメントを高くランク付けし、関連性の低いドキュメントを低くランク付けする能力を測定します。例えば、映画レビューの要約を生成するためにユーザーの要約を検索する場合、特定の映画のレビューを高くランク付けし、他の映画のレビューを除外したいと考えるでしょう。
従来の推薦システムと同様に、検索結果の順位は、LLMが下流のタスクでどのようなパフォーマンスを発揮するかに大きな影響を与えます。この影響を測定するために、RAGベースのタスクを実行しますが、検索結果をシャッフルして順番を変えてみてください。そうすると、RAGの出力はどのようなパフォーマンスを示すでしょうか?
第二に、情報の密度も考慮します。2つのドキュメントが等しく関連している場合、より簡潔で、無関係な詳細が少ないほうを選ぶべきです。映画の例に戻ると、映画の文字起こしとすべてのユーザーレビューは、広い意味で関連していると考えるかもしれません。それでも、高く評価されたレビューやエキスパートのレビューは、情報がより密であると考えられます。
最後に、ドキュメントで提供される詳細のレベルを考慮してください。
例として、自然言語からSQLクエリを生成するRAGシステムを構築していると想像してみてください。単純に列名を含むテーブルスキーマの情報を渡すこともできますが、それに加えて列の説明といくつかの代表的な値を含めたらどうでしょうか?追加の詳細情報は、LLMがテーブルのセマンティクスをより良く理解し、より正確なSQLを生成するのに役立つ可能性があります。
1.2.2 キーワード検索を忘れずに、それをベースラインとしてハイブリッド検索も検討する
EmbeddingベースのRAGを使ったデモがとてもポピュラーなので、情報検索の分野における何十年もの研究と解決策を忘れたり見落としたりしがちです。
Embeddingは間違いなく強力なツールですが、万能な解決策ではありません。
第一に、高レベルの意味的類似性を捉えることに優れていますが、名前(例:Ilya)、頭字語(例:RAG)、ID(例:claude-3-sonnet)などの、より具体的なキーワードベースのクエリでは苦戦するかもしれません。BM25などのキーワードベースの検索は、この目的のために設計されています。
また、ユーザはキーワード検索の体験に慣れきっていて、検索対象のドキュメントが返されていない場合にフラストレーションを感じるかもしれません。
ベクトル埋め込みは、検索を魔法のように解決するわけではありません。実際、最も大変なところは意味的類似性検索で再ランク付けする前のステップにあります。BM25や全文検索を改善することは本当に難しいのです。— Aravind Srinivas, Perplexity.ai CEO
私たちは何ヶ月も前からこのことを顧客やパートナーに伝えています。ナイーブな埋め込みを使用した最近傍検索では、非常にノイズの多い結果が得られます。キーワードベースのアプローチから始めたほうがよいでしょう。— Beyang Liu, Sourcegraph CTO
第二に、キーワード検索では、なぜドキュメントが検索されたのかを理解するのがより簡単です--私たちはクエリに一致するキーワードを見ることができます。対照的に、Embeddingベースの検索は解釈しにくいです。また、LuceneやOpenSearchなどの何十年にもわたって最適化され、実戦で検証されたシステムのおかげで、キーワード検索は通常、計算効率が高くなります。
ほとんどの場合、ハイブリッドが最適に機能します。明らかな一致にはキーワードマッチングを、同義語、上位語、スペルミス、マルチモーダリティ(画像とテキストなど)にはEmbeddingを使用します。
参考までにShortwaveは、クエリの書き換え、キーワードと埋め込みの検索、ランキングを含む、RAGパイプラインの構築方法を書いてくれているのでご参照ください。
1.2.3 新しい知識の追加にはファインチューニングよりまずはRAG
RAGとファインチューニングはどちらも、LLMに新しい情報を組み込み、特定のタスクでのパフォーマンスを向上させるために使用できます。しかし、どちらを優先すべきでしょうか?
最近の研究では、RAGが優位に立つ可能性が示唆されています。ある研究では、RAGを教師なしファインチューニング(別名、continued pretraining)と比較し、両者をMMLUのサブセットと最新の出来事の情報で評価しました。
その結果、学習中に遭遇した知識と全く新しい知識の両方において、RAGが一貫してファインチューニングを上回ることがわかりました。別の論文では、農業データセットにおけるRAGと教師ありファインチューニングを比較しました。同様に、RAGによるパフォーマンスの向上は、特にGPT-4において、ファインチューニングを上回りました(表20参照)。
パフォーマンスの向上以外にも、RAGには他の実用的な利点があります。まず、継続的事前学習やファインチューニングと比較して、検索インデックスを最新の状態に保つことが容易で、コストも安くなります。次に、検索インデックスに有害なコンテンツや偏ったコンテンツを含む問題のあるドキュメントがある場合、簡単にそのドキュメントを削除または修正できます。
さらに、RAGのRは、ドキュメントの検索方法をよりきめ細かく制御できます。例えば、複数の組織向けにRAGシステムをホストしている場合、検索インデックスを分割することで、各組織が自身のインデックスからのみドキュメントを検索できるようにすることができます。これにより、ある組織の情報を別の組織に不注意に公開してしまうことを防げます。
1.2.4 長いコンテキストのモデルはRAGを無用の長物にしない
Gemini 1.5は最大1000万トークンのコンテキストウィンドウを提供しているため、RAGの将来について疑問を持ち始めた人もいます。
私は、Gemini 1.5がSoraによって大幅に誇張されていると考える傾向があります。1000万トークンのコンテキストウィンドウは、既存のRAGフレームワークのほとんどを不要にします。データをコンテキストに入れて、通常どおりモデルと対話するだけです。ほとんどのエンジニアリングの努力がRAGに費やされているスタートアップ、エージェント、langchainプロジェクトにどのような影響を与えるか想像してみてください😅 つまり、1000万のコンテキストがRAGを殺すのです。Geminiの素晴らしい仕事ですね。— Yao Fu
長大なコンテキストが複数のドキュメントの分析やPDFとのチャットなどのユースケースにとって画期的なものになるのは事実ですが、RAGの消滅を考えるのは大げさです。
まず、1000万トークンのコンテキストサイズであっても、関連するコンテキストを選択する方法が必要です。次に、Needle-in-a-haystackという評価基準(訳註: 長大なインプットの中から特定の情報を抜き出す性能を評価するベンチマーク)において、モデルが大きなコンテキストサイズで効果的に推論できるという説得力のあるデータはまだ見られません。したがって、適切な検索(およびランキング)がなければ、モデルに余計な情報を与え過ぎるリスクがあります。完全に無関係な情報ばかりでコンテキストウィンドウが埋まってしまう可能性さえあります。
最後に、コストの問題があります。推論中、Transformerの時間計算量はコンテキスト長に比例して拡大します。各質問に答える前に組織全体のGoogleドライブのコンテンツを読むことができるモデルが存在するからといって、それが良いアイデアだとは限りません。RAMの使用方法との類推を考えてみてください。数十テラバイトのRAMを搭載したコンピュートインスタンスが存在しますが、それもディスクから読み書きしています。
ですから、RAGをゴミ箱に捨てるのはまだ早いです。コンテキストサイズが大きくなっても、引き続き役に立つでしょう。
1.3 ワークフローのチューニングと最適化
プロンプトはほんの始まりに過ぎません。LLMを最大限に活用するには、単一のプロンプトを超えて考え、ワークフローを考える必要があります。
例えば、1つの複雑なタスクを複数のシンプルなタスクに分割するにはどうすればよいでしょうか?ファインチューニングやキャッシングは、パフォーマンスの向上やレイテンシー/コストの削減に役立つのはいつでしょうか?
ここでは、実証済みの戦略と実際の例を紹介し、信頼性の高いLLMワークフローを構築するのに役立てていただきます。
1.3.1 ステップバイステップの多段階の「フロー」は大きな効果をもたらす
1つの大きなプロンプトを複数の小さなプロンプトに分解することで、より良い結果が得られるということは一般的に知られています。例えば、AlphaCodiumでは、1つのプロンプトから多段階のワークフローに切り替えることで、CodeContestsにおけるGPT-4の精度(pass@5)を19%から44%に向上させました。
このワークフローには以下のようなものが含まれます。
- 問題について考える
- 公開テストについて推論する
- 可能な解決策を生成する
- 可能な解決策をランク付けする
- 合成テストを生成する
- 公開テストと合成テストで解決策を繰り返す
明確な目的を持つ小さなタスクは、エージェントやフローのプロンプトに最適です。すべてのエージェントプロンプトが構造化された出力を要求する必要はありませんが、構造化された出力は、エージェントと環境との相互作用を調整するシステムとのインターフェースに大いに役立ちます。
小さいプロンプトを作る時に試してみる価値のあるものは以下の通りです。
- 明確で具体的な計画のステップを含めること。あらかじめ用意した計画の中から選択できるようにすることも検討してみてください。
- ユーザーが最初に入力したプロンプトを、エージェントが理解しやすいプロンプトに書き換えること。ただし、この過程で情報が失われる可能性があることに注意が必要です!
- エージェントの動作を、単純な連鎖、有向非巡回グラフ(DAG)、ステートマシンなどの形で表現すること。タスクの規模に応じて、異なる依存関係やロジックの関係が適切な場合があります。タスクの構造を工夫することで、パフォーマンスの最適化が図れるかもしれません。
- 計画の妥当性を検証すること。他のエージェントからの応答を評価し、最終的な組み立てが適切に機能するための指示を計画に盛り込むことができます。
- エージェントプロンプトを設計する際は、そのプロンプトが呼び出される前に起こりうる様々な状況を想定し、それらの状況に対して適切に機能するようにすること。
1.3.2 決定論的なワークフローを優先する
AIエージェントはユーザーのリクエストや環境に動的に反応できますが、その非決定論的な性質によってプロダクトに組み込むことが難しくなります。
エージェントが実行する各ステップには失敗の可能性があり、エラーから回復する可能性は低いです。したがって、エージェントがマルチステップのタスクを正常に完了する可能性は、ステップ数の増加とともに指数関数的に低下します。このため、エージェントを構築するチームは信頼性の高いエージェントをデプロイすることに苦労しています。
考えられるアプローチは、エージェントシステムに決定論的な計画を生成させ、それを構造化された方法で実行することです。
まず、大まかな目標やプロンプトを与えてエージェントに計画を生成してもらい、次に、その計画が決定論的に実行されます。これにより、各ステップがより予測可能で信頼性の高いものになります。
利点は以下の通りです。
- 生成された計画は、エージェントにプロンプトを出したりファインチューニングしたりするためのFew-shotsサンプルとして機能します。
- 決定論的な実行により、システムの信頼性が高まり、テストとデバッグが容易になります。さらに、エラーがどのステップで起きたかもトレースすることができます
- 生成された計画は、有向非巡回グラフ(DAG)として表現できます。これは、静的なプロンプトと比較して、理解しやすく、新しい状況に適応しやすくなります。
最も成功しているエージェント開発者は、新人エンジニアの管理に関する豊富な経験を持っている人かもしれません。なぜなら、計画を生成するプロセスは、新人に指示を出したり管理したりする方法に似ているからです。新人には、あいまいで終わりのない指示ではなく、明確な目標と具体的な計画を与えます。エージェントに対しても同じようにすべきです。
つまるところ、信頼性が高く、機能するエージェントへの鍵は、より構造化された決定論的なアプローチを採用し、プロンプトを改良しモデルをファインチューニングするためのデータを収集することにあるでしょう。これがなければ、時々は非常にうまく機能するかもしれませんが、基本的にはユーザーを失望させるエージェントを構築することになります。
1.3.3 temperature以外の方法で多様な出力を得る
あるタスクでLLMの出力に多様性が求められるとします。例えば、ユーザーが以前に購入した製品のリストを基に、カタログから購入する製品を提案するLLMパイプラインを作成しているとします。プロンプトを複数回実行すると、結果として得られるレコメンデーションが類似しすぎていることに気づくかもしれません。そこで、LLMリクエストのtemperatureパラメータを上げてみるといいでしょう。
手短に言うと、temperatureパラメータを上げるとLLMの応答がより多様になります。サンプリング時に、次のトークンの確率分布が平坦になり、通常はあまり選ばれないようなトークンが頻繁に選ばれやすくなります。
それでも、temperatureを上げると、出力の多様性に関連するいくつかの欠陥に気づくかもしれません。例えば、カタログの中にはフィットするかもしれない製品があるのに、LLMでは出力されないかもしれません。LLMがトレーニング時に学習したことに基づいてプロンプトに続く可能性が高い場合、同じ一握りの製品が出力に過剰に表現されるかもしれません。temperatureが高すぎると、存在しない製品を参照する出力が得られるかもしれません。
言い換えれば、temperatureを上げても、LLMがあなたの期待する確率分布から出力をサンプリングすることは保証されません。それでも、出力の多様性を高めるための他のトリックがあります。
最も簡単な方法は、プロンプト内の要素を調整することです。例えば、プロンプトテンプレートに過去の購入履歴などのアイテムのリストが含まれている場合、プロンプトに挿入するたびにこれらのアイテムの順序をシャッフルすると、大きな違いが生まれます。
さらに、直近の出力のリストを保持しておくと冗長性を防ぐのに役立ちます。
例えば、その保持したリストからアイテムを提案しないようLLMに指示したり、最近の提案と似ている出力を拒否して再サンプリングしたりすることで、応答をさらに多様化できます。
もう1つの効果的な戦略は、プロンプトで使用するフレーズを変えることです。
例えば「ユーザーが定期的に使用したくなるアイテムを選んでください」や「ユーザーが友人にお勧めしそうな製品を選んでください」といったフレーズを取り入れることで、重点が移り、その結果、おすすめ商品の種類に影響を与えることができます。
1.3.4 キャッシュは過小評価されている
キャッシュは、同じ入力に対する応答の再計算をなくすことで、コストを節約し、生成のレイテンシーを排除します。さらに、応答が以前にガードレールされていた場合、これらの検証済みの応答を提供し、有害または不適切なコンテンツを提供するリスクを減らすことができます。
キャッシングの簡単なアプローチの1つは、新しい記事や製品レビューを要約する場合のように、処理中のアイテムに一意のIDを付与することです。リクエストが届いたら、キャッシュに要約がすでに存在するかどうかを確認します。存在する場合はすぐに返し、存在しない場合は生成し、ガードレールして、将来のリクエストのためにキャッシュに保存します。
より自由形式のクエリについては、オープンエンドの入力にもキャッシングを活用する検索分野の技術を活用することができます。オートコンプリート、スペルチェック、提案クエリなどの機能は、ユーザー入力を正規化し、キャッシュヒット率を高めるのにも役立ちます。
1.3.5 ファインチューニングのタイミング
緻密に設計されたプロンプトでも不十分なタスクがあるかもしれません。
大幅なプロンプトエンジニアリングを行った後でも、システムが信頼性が高く高品質な出力を返すまでにはまだまだ時間がかかるかもしれません。
その場合、特定のタスクのためにモデルをファインチューニングする必要が出てくる可能性があります。
ファインチューニングの実際の成功例は以下の通りです。
- Honeycombの自然言語クエリアシスタント: 当初、「プログラミングマニュアル」は、In-Context Learningのためのn-shotの例とともにプロンプトで提供されていました。これはうまく機能しましたが、モデルをファインチューニングすることで、ドメイン固有の言語の構文とルールに関する出力が改善されました。
- RechatのLucy: LLMは、フロントエンドが正しくレンダリングするために、構造化データと非構造化データを組み合わせた非常に特殊な形式で応答を生成する必要がありました。一貫して機能させるには、ファインチューニングが不可欠でした。
とはいえ、ファインチューニングは効果的ですが、大きなコストがかかります。
ファインチューニングデータにアノテーションを付け、モデルをファインチューニングして評価し、最終的にそれらをセルフホストしなければなりません。
したがって、より高い初期コストに見合うかどうかを検討してください。プロンプトで90点までいけるなら、ファインチューニングへの投資は割に合わないかもしれません。しかし、ファインチューニングすることに決めたなら、人間がアノテーションしたデータを収集するコストを削減するために、合成データを生成してファインチューニングしたり、OSSデータでブートストラップしたりすることができます。
1.4 評価とモニタリング
LLMの評価は地雷原であり、Anthropicのような最大の研究所でさえ困難に直面しています。LLMは自由形式の出力を返し、私たちが実行してほしいタスクは多岐にわたります。それでも、厳格で思慮深い評価は非常に重要です。OpenAIのテクニカルリーダーでも評価に取り組み、個々の評価にフィードバックを行うのは偶然ではありません。
LLMアプリケーションの評価には、多様な定義があります。単なるユニットテストであったり、オブザーバビリティに近かったり、あるいは単にデータサイエンスであったりします。私たちは、これらすべての視点が有用であることに気づきました。このセクションでは、評価とモニタリングのパイプラインを構築する上で重要な点についていくつかの教訓を提供します。
1.4.1 実際の入力/出力サンプルから少数のアサーションベースのユニットテストを作成する
本番環境からの入力と出力のサンプルで構成されるユニットテスト(つまり、アサーション)を作成します。出力に対する期待値は、少なくとも3つは評価基準が必要です。"3つ"の基準は恣意的に見えるかもしれませんが、とりあえず始めるのに実用的な数です。それより少ないと、タスクが十分に定義されていないか、汎用チャットボットのように自由形式すぎることを示している可能性があります。
これらのユニットテスト、つまりアサーションは、プロンプトの編集、RAGを介した新しいコンテキストの追加、その他の変更など、何かしらのパイプラインへの変更に対して実行されます。下記記事には、実際のユースケースにおけるアサーションベースのテストの例が示されています。
応答を含めるべき、または除外すべきフレーズを指定するアサーションから始めることを検討してみてください。また、単語数、アイテム数、文数が範囲内にあることを確認するチェックも試してみてください。
コード生成のようなその他の種類の生成では、アサーションは異なる形になる可能性があります。実行ベースの評価は、コード生成を評価する1つの方法です。生成されたコードを実行し、ランタイムの状態・結果がユーザーの要求に十分であるかどうかを確認します。
例として、ユーザーがfooという名前の新しい関数を要求した場合、エージェントの生成したコードを実行した後、fooが呼び出し可能でなければなりません。
しかし、エージェントが生成するコードは、人間が書くコードとは少し異なる形式になることがよくあります。例えば、変数名や関数名が異なっていたり、コードの構造が少し違っていたりする可能性があります。
このような場合、厳密に「fooという名前の関数が存在し、呼び出し可能である」というアサーションでは、エージェントが生成したコードが不必要に不合格となってしまう可能性があります。
そこで、「要求された機能を提供する関数が存在し、呼び出し可能である」というように、アサーションを少し緩和することが効果的な場合があります。これにより、コードの細部が少々異なっていても、全体としての機能が満たされていれば合格とみなすことができます。
最後に、プロダクトをユーザが実際に使うように使用すること(つまり、「ドッグフーディング」)は、実世界のデータでのエラー・課題に関する洞察を得られます。このアプローチは、潜在的な課題を特定するのに役立つだけでなく、評価に変換できる本番サンプルの有用な情報源にもなります。
1.4.2 LLM-as-Judgeは(ある程度)機能するが、万能ではない
LLM-as-Judgeは、強力なLLMを使用して他のLLMの出力を評価する手法ですが、しばしば懐疑的な見方をされています。(私たちの中にも、当初は大きな懐疑論者もいました。)それでも、適切に実装されたLLM-as-Judgeは、人間の判断とまずまずの相関を達成し、少なくとも新しいプロンプトや手法がどのように機能するかについての事前の知識を構築するのに役立ちます。
具体的には、ペアワイズ比較(control vs. treatment)を行う際、LLM-as-Judgeは通常、勝ち/負けの大きさがノイズになる可能性がありますが、方向性は概ね正しく判断します。
LLM-as-Judgeを最大限に活用するためのいくつかの提案を以下に示します。
- ペアワイズ比較を使用する:LLMにリッカート尺度で単一の出力を評価するよう求める代わりに、2つのオプションを提示し、より良いほうを選択するよう求めます。これにより、より安定した結果が得られる傾向があります。
- 位置バイアスを制御する:提示されるオプションの順序によって、LLMの決定にバイアスがかかる可能性があります。これを軽減するために、各ペアワイズ比較を2回行い、ペアの順序を毎回入れ替えます。
- 引き分けを許容する:場合によっては、両方のオプションが同等に良い場合があります。したがって、LLMが恣意的に勝者を選ばなくても済むように、引き分けを宣言できるようにします。
- CoTを使用する:最終的な答えを出す前にLLMに評価の理由を説明するよう求めることで、評価の信頼性を高めることができます。ボーナスとして、CoTを使うことにより、より弱いが高速なLLMでも同水準の評価結果を得ることができます。パイプラインのこの部分は通常バッチで実行されるため、CoTによる余分なレイテンシーは問題になりません。
- 応答の長さを制御する:LLMは長い応答にバイアスがかかる傾向があります。これを軽減するために、応答ペアの長さが同程度になるようにします。
LLM-as-Judgeの有用な応用例は、新しいプロンプト戦略を既存のものと照らし合わせてチェックすることです。本番での入出力のデータがある場合、それらの本番例を新しいプロンプト戦略で再実行し、LLM-as-Judgeを使用して新しい戦略のどの部分に問題があるかを迅速に評価できます。
こちらの記事では「LLMの応答、判断の批評(つまり、CoT)、最終的な出力結果」を記録しながら、ステークホルダーにレビューしてもらうことにより反復的にLLM-as-Judgeの精度を上げるプロセスが紹介されています。
実際にこのプロセスによって、わずか3回の反復を経て人間とLLMの一致率は68%から94%に向上しました。
ただし、LLM-as-Judgeは万能ではありません。最も強力なモデルでさえ、言語の微妙な側面を確実に評価できない場合があります。さらに、従来の分類器と報酬モデルは、LLM-as-Judgeよりも高い精度を達成でき、コストとレイテンシーも低いことがわかりました。またコード生成においては、LLM-as-Judgeは、実行評価のようなより直接的な評価戦略よりも精度が低い可能性があります。
1.4.3 生成物を評価するための「インターンテスト」
生成物を評価する際、次のような「インターンテスト」という思考実験をしてみるのが私の好みです。
言語モデルへの入力(コンテキストを含む)を取得し、関連する専攻の平均的な大学生にタスクとして与えた場合、彼らは成功できるでしょうか。どのくらいの時間がかかるでしょうか。
- 答えがノーで、LLMに必要な知識が不足している場合は、コンテキストを豊かにする方法を検討してください。
- 答えがノーで、コンテキストを改善しても修正できない場合は、現代のLLMにとって難しすぎるタスクにぶつかった可能性があります。
- 答えがイエスだが、時間がかかる場合は、タスクの複雑さを減らすことを試みることができます。分解可能でしょうか。タスクの一部をより テンプレート化できる側面はありますか。
- 答えがイエスで、すぐに理解できる場合は、データを掘り下げる時期です。モデルは何を間違えているのでしょうか。失敗のパターンを見つけることはできますか。応答の前後にモデルに自身を説明するよう求めて、心の理論(訳註: 他者の考えを予測する能力のこと)を構築するのに役立ててください。
1.4.4 特定の評価を過度に重視すると、全体的なパフォーマンスが低下する可能性がある
「ある指標がターゲットになると、それは良い指標ではなくなる」— グッドハートの法則
この例として、Needle-in-a-Haystack(NIAH)評価があります。
この評価では、コンテキストサイズの増大に伴うモデルのリコールを測定し、コンテキスト内での目標情報の位置がリコールにどのような影響を与えるかを調べました。しかし、この評価手法は過度に強調されすぎた側面があり、Gemini 1.5のレポートの図1でも取り上げられています。
この評価では、ポール・グレアムのエッセイを繰り返す長文書に特定のフレーズ(“The special magic {city} number is: {number}”)を挿入し、モデルにそのマジックナンバーを思い出すように促します。
一部のモデルはほぼ完璧なリコールを達成しますが、NIAHが実世界のアプリケーションに必要な推論とリコール能力を真に測定しているかどうかは疑問です。
より実用的なシナリオを考えてみましょう。1時間の会議の文字起こしが与えられた場合、LLMは主要な決定と次のステップを要約し、各項目を関連する人に正しく帰属させることができるでしょうか。このタスクは、機械的な暗記だけでなく、複雑な議論を解析し、関連情報を特定し、要約を合成する能力を考慮に入れたより現実的なものです。
上記課題の解決のために作られたベンチマークであるpractical NIAH evalでは、医師と患者の文字起こしを使用してLLMに患者の薬についての質問をしたり、より難しいタスクとしては「完璧なピザを作るために必要な秘密の材料は次のとおりです:エスプレッソに浸したデーツ、レモン、ヤギのチーズ」などのピザのトッピングからランダムな材料のフレーズを挿入する、というタスクがあります。
薬のタスクでのリコールは約80%、ピザのタスクでは約30%でした。
余談ですが、NIAH評価を過度に重視すると、抽出と要約のタスクのパフォーマンスが低下する可能性があります。これらのLLMはすべての文に注意を払うようにチューニングされているため、無関係な詳細を重要なものとして扱い始め、最終的な出力に含めてしまう可能性があります(含めるべきではないのに!)。
これは、他の評価やユースケースにも当てはまる可能性があります。例えば、要約です。事実の一貫性を重視すると、要約が具体性に欠け(したがって事実と矛盾する可能性が低く)、関連性が低くなる可能性があります。逆に、文章のスタイルと雄弁さを重視すると、事実の矛盾を引き起こす可能性のある、より華やかなマーケティング用の表現につながる可能性があります。
1.4.5 アノテーションをバイナリ(Yes/Noで答えられる)タスクまたはペアワイズ比較に単純化する
モデル出力に対するオープンエンドのフィードバックやリッカート尺度での評価を提供することは、人間の認知的に要求が厳しいものです。その結果、収集されたデータはノイズが多くなり(人間の評価者間のばらつきのため)、あまり役に立ちません。より効果的なアプローチは、タスクを単純化し、アノテーターの認知的負担を軽減することです。バイナリ分類とペアワイズ比較がしばしばうまくいきます。
バイナリ分類では、アノテーターにモデルの出力に対する単純なイエスかノーの判断を求めます。生成された要約がソース文書と事実上一致しているかどうか、提案された応答が関連しているかどうか、有害性が含まれているかどうか、などを尋ねることができるでしょう。リッカート尺度と比較して、バイナリの決定はより正確で、評価者間の一貫性が高く、スループットが高くなります。これは、Doordashがイエスかノーの質問のツリーを通じてメニュー項目にタグ付けするためのラベリングキューを設定した方法と同じです。
ペアワイズ比較では、アノテーターにモデルの応答のペアが提示され、どちらが優れているかを尋ねられます。人間にとって、AまたはBに個別にスコアを割り当てるよりも、「AはBより優れている」と言う方が簡単なため、アノテーションがより速くより信頼性の高いものになります(リッカート尺度よりも)。
Llama2のミートアップで、Llama2論文の著者の1人であるThomas Scialom氏は、ペアワイズ比較が、書面での回答などの教師あり微調整データの収集よりも高速かつ安価であることを確認しました。前者のコストは1ユニットあたり3.5ドルで、後者のコストは1ユニットあたり25ドルです。
ラベリングのガイドラインを作成する場合は、GoogleとBing検索の例のガイドラインを参照してください。
1.4.6 (リファレンスフリーの)評価とガードレールは交換可能である
ガードレールは不適切または有害なコンテンツを検出するのに役立ち、評価はモデルの出力の品質と正確性を測定するのに役立ちます。そして、リファレンスフリーの評価を仕様する場合、それらをガードレールとしても活用できます。リファレンスフリーの評価とは、人間が書いた回答などの「ゴールデン」リファレンスに依存せず、入力プロンプトとモデルの応答のみに基づいて出力の品質を評価できるものです。
例えば、要約の評価では、入力文書のみを考慮して、事実の一貫性と関連性について要約を評価します。これらの指標で要約の評価が低い場合、ユーザーに表示しないことを選択でき、実質的に評価をガードレールとして使用することができます。同様に、リファレンスフリーの翻訳評価では、人間が翻訳したリファレンスを必要とせずに翻訳の品質を評価できるため、これもガードレールとして使用できます。
1.4.7 LLMは、そうすべきでない場合でも出力を返す
LLMを扱う上での重要な課題の一つは、出力すべきでない場合でもしばしば出力を生成してしまうことです。これは無害だが意味不明な応答や、有害性や危険なコンテンツといったより深刻な欠陥につながる可能性があります。例えば、文書から特定の属性やメタデータを抽出するよう求められた場合、LLMはそれらの値が実際には存在しなくても自信を持って値を返すことがあります。また、コンテキストに英語以外の文書を提供したために、モデルが英語以外の言語で応答することもあります。
LLMに「該当なし」や「不明」という応答を返すよう促すことはできますが、それも完全ではありません。対数確率(訳註:言語モデルが特定の単語や文を生成する確率を対数スケールで表したもの。モデルの予測の確信度を示す指標として使われることがあります)が利用可能な場合でも、それは出力の品質を示す良い指標とは言えません。対数確率はトークンが出力に現れる可能性を示しますが、必ずしも生成されたテキストの正確性を反映するものではありません。
それどころか、クエリに答えて一貫性のある応答を生成するよう訓練された指示調整モデルの場合、対数確率は適切に調整されていない可能性があります。したがって、高い対数確率は出力が流暢で一貫性があることを示す可能性はありますが、それが正確または関連性があることを意味するわけではありません。
慎重なプロンプトエンジニアリングは、ある程度役立ちますが、望ましくない出力を検出してフィルタリング/再生成する堅牢なガードレールと組み合わせる必要があります。例えば、OpenAIは、ヘイトスピーチ、自傷行為、性的な出力などの安全でない応答を特定できるコンテンツモデレーションAPIを提供しています。
同様に、個人を特定できる情報を検出するためのパッケージは数多くあります。ガードレールの利点の1つは、ユースケースにほとんど依存せず、特定の言語のすべての出力に広く適用できることです。さらに、正確な検索により、関連するドキュメントがない場合、システムは決定論的に「わかりません」と応答できます。
ここでの付随的な点として、LLMが期待されている場合に出力を生成できないこともあります。これはAPIプロバイダーからの長いレイテンシーのような単純な問題から、コンテンツモデレーションフィルターによって出力がブロックされるような複雑な問題まで、さまざまな理由で起こり得ます。そのため、デバッグとモニタリングのために、入力と(場合によっては欠如している)出力を一貫してログに記録することが重要です。
1.4.8 ハルシネーションは根強い問題である
注目度が高くもめったに発生しないコンテンツセーフティーやPIIの欠陥とは異なり、事実の矛盾は頑固に存在し、検出がより困難です。事実の矛盾はより一般的で、5〜10%の基準率で発生します。要約のような単純なタスクでさえ、2%以下に抑えるのは難しいとされています。
これに対処するために、プロンプトエンジニアリング(生成の上流)と事実の矛盾を検出するガードレール(生成の下流)を組み合わせることができます。
プロンプトエンジニアリングでは、CoTのような手法を使用して、LLMに最終的な出力を返す前に推論を説明させることでハルシネーションを減らすことができます。そして、事実の矛盾を検出するガードレールを適用して要約の事実性を評価し、ハルシネーションを含む出力をフィルタリングしたり、再生成を促したりすることが可能です。
状況によっては、ハルシネーションを決定論的に検出することも可能です。例えば、Retrieval-Augmented Generation (RAG) を用いて検索結果からの情報を活用する場合、出力が構造化されていてリソースの出所が特定されていれば、それらが入力コンテキストから取得されたものであることを手動で確認できるはずです。
2 運用(Operational):日々の業務と組織の課題
2.1 データ
食材の品質が料理の味を決定するのと同様に、入力データの品質が機械学習システムのパフォーマンスを決定づけます。また、出力データはプロダクトが機能しているかどうかを判断する唯一の方法です。私たちはデータに注目し、データ分布(そのモード、エッジケース、モデルの制限)をよりよく理解するために、週に数時間、実際に起きている入力と出力を確認しています。
2.1.1 開発環境と本番環境の乖離を確認する
従来の機械学習パイプラインにおけるエラーの一般的な原因は、学習時と推論時の乖離です。これは、トレーニングに使用されるデータが、モデルが本番環境で遭遇するものと異なる場合に発生します。LLMはトレーニングやファインチューニングなしで使用できるため、トレーニングセットはありませんが、開発環境と本番環境のデータの乖離という同様の問題が発生します。開発中にシステムをテストするデータは、システムが本番環境で直面するものを反映している必要があります。そうでない場合、本番環境での精度が低下する可能性があります。
LLMの開発環境と本番環境の乖離は、構造的な乖離とコンテンツベースの乖離の2種類が存在します。
構造的な乖離とは、データ形式の不一致を指します。例えば、リスト型の値を持つJSONディクショナリとJSONリストの違い、一貫性のないケース、タイプミスや文の断片などのエラーが含まれます。LLMは特定のデータ形式でトレーニングされており、プロンプトが些細な変更に非常に敏感であるため、これらのエラーは予測不可能なモデルパフォーマンスにつながる可能性があります。一方、コンテンツベースまたは「意味的」な乖離とは、データの意味やコンテキストの違いを指します。
従来の機械学習と同様に、LLMにおいても入力/出力ペアの乖離を定期的に測定することが重要です。入力と出力の長さや、JSONやXMLなどの特定の書式要件といった単純な指標を用いることで、変更を追跡するための簡単な方法となります。さらに高度なドリフト検出では、入力/出力ペアの埋め込みをクラスタリングすることで、ユーザーが議論しているトピックのシフトなどの意味的なドリフトを検出することができます。これは、モデルがこれまでに触れたことのない領域を探索していることを示唆している可能性があります。
プロンプトエンジニアリングなどの変更をテストする際は、ホールドアウトデータセット(訳註: 学習データとテストデータが分かれたデータセットのこと)が最新のものであり、最も最近のユーザーインタラクションの種類を反映していることを確認してください。例えば、本番環境の入力でタイプミスが一般的な場合、ホールドアウトデータにもタイプミスが存在する必要があります。
また、単なる数値的な乖離の測定を超えて、出力に対して定性的な評価を行うことも大事です。モデルの出力を定期的にレビューすること(通称「バイブチェック」)により、結果が期待と一致し、ユーザーのニーズにマッチし続けていることを確認できます。
最後に、乖離チェックに非決定性を組み込むことも有用です。テストデータセットの各入力に対してパイプラインを複数回実行し、すべての出力を分析することで、稀にしか発生しない異常を検出する可能性が高くなります。
2.1.2 LLMの入力と出力のサンプルを毎日確認する
LLMは動的で常に進化しています。ゼロショット能力が優れており、多くの場合、出力を眺めるのは楽しいものですが、LLMが起こすエラーは非常に予測不可能です。独自のタスクでは、LLMがどのように機能するかを直感的に理解するために、データサンプルを定期的にレビューすることが不可欠です。
本番環境からの入力-出力ペアは、LLMアプリケーションの「現地現物」であり、代替することはできません。最近の研究では、開発者がより多くのデータとインタラクションするにつれて、「良い」出力と「悪い」出力の認識が変化することが強調されています(criteria driftと名付けられています)。
開発者は、LLMの出力を評価するための基準をある程度事前に考えることができますが、これらの事前に定義された基準は多くの場合不完全です。例えば、開発の過程で、良い応答の確率を高め、悪い応答の確率を下げるためにプロンプトを更新するかもしれません。この「評価、再評価、基準の更新」の反復プロセスはどうしても必要になってきます。なぜなら、出力を直接観察せずに、LLMの動作や人間の好みを予測することは難しいからです。
LLMの性能を効果的に管理するためには、入力と出力をログに記録することが不可欠です。毎日これらのログのサンプルをチェックすることで、新しいパターンや課題をいち早く発見し、素早く対応することができます。新しい問題が見つかった場合は、すぐにアサーションや評価を書くことができます。同様に、課題の定義が更新された場合は、評価基準にもその変更を反映させる必要があります。これらの「バイブチェック」は、モデルの出力に問題がある可能性を示す重要なシグナルです。コードとアサーションを使って、これらの問題を実用的に管理することができます。
最後に、この取り組みを組織全体で浸透させることが大切です。例えば、オンコール対応のローテーションに、入力と出力のレビューやアノテーションを追加するなどの方法が考えられます。このように、LLMの性能管理を日常的なタスクに組み込むことで、モデルの品質を継続的に高めていくことができるでしょう。
2.2 モデルの操作
LLM APIを利用することで、少数のプロバイダーが提供するAIに頼ることができます。これには大きなメリットがある一方で、パフォーマンス、レイテンシー、スループット、コストなどに関するトレードオフも存在します。また、ほぼ毎月のように新しく優れたモデルが登場しているため、古いモデルを廃止し、新しいモデルへ移行する際には、製品をアップデートする準備が必要です。
このセクションでは、モデルをセルフホストしたり、自分で管理したりすることができない環境における、完全にコントロールできない技術を使う上での教訓をシェアしていきます。
2.2.1 下流での活用を容易にするために構造化された出力を生成する
ほとんどの実際のユースケースでは、LLMの出力は、何らかのマシーンリーダブルな形を介して下流のアプリケーションで使われます。
例えば、不動産CRMのRechatでは、フロントエンドがウィジェットをレンダリングするために構造化されたレスポンスが必要でした。同様に、製品戦略のアイデアを生成するためのツールであるBobaでは、タイトル、要約、妥当性スコア、時間軸のフィールドを持つ構造化された出力が必要でした。最後に、LinkedInは、LLMにYAMLを生成させることについて書いています。生成されたyamlは、どのスキルを使用するかを決定したり、スキルを呼び出すためのパラメータを提供するために使用されたりします。
このようなアプリケーションパターンは、Postelの法則の極端なバージョンと呼べるでしょう: 入力には寛容に(任意の自然言語)、出力は厳密に(型付けされたマシーンリーダブルなオブジェクト)。
現在、InstructorとOutlinesというライブラリたちは、LLMから構造化された出力を引き出すための事実上の標準技術となっています。LLM API(Anthropic、OpenAIなど)を使用している場合はInstructorを、セルフホストモデル(Huggingfaceなど)を使用している場合はOutlinesを使用してください。
2.2.2 モデル間でのプロンプトの移行はものすごく面倒
慎重に作成したプロンプトが、あるモデルでは非常にうまく機能するものの、別のモデルでは機能しないことがあります。これは、さまざまなモデルプロバイダー間で切り替える場合だけでなく、同じモデルのバージョン間でアップグレードする場合にも発生する可能性があります。
例えば、Voiceflowは、gpt-3.5-turbo-0301からgpt-3.5-turbo-1106に移行すると、意図分類タスクで10%の精度低下が発生することを発見しました。(評価を用意してあったおかげで事なきを得ました!)同様に、GoDaddyは、バージョン1106にアップグレードすることで、gpt-3.5-turboとgpt-4のパフォーマンスの差が縮小するという、ポジティブな方向のトレンドを観察しました。(あるいは、物事を前向きに捉える人なら、新しいアップグレードによってgpt-4の優位性が縮まったことを残念に思うかもしれません)
したがって、モデル間でプロンプトを移行する必要がある場合は、単にAPIエンドポイントを入れ替えるだけでは済まず、想定より時間がかかることを覚悟してください。「同じプロンプトを使えば同程度またはより良い結果が得られる」と期待しないでください。
また、信頼性の高い自動評価を行うことで、移行の前後でタスクのパフォーマンスを測定し、手動検証に必要な労力を減らすことができます。
2.2.3 モデルのバージョンを管理し、固定する
機械学習パイプラインでは、「何かを変更すると、すべてが変更される」のが常です。これは、自分たちでトレーニングしていないLLMのようなコンポーネントに依存していて、知らないうちに変更される可能性がある場合に特に当てはまります。
幸いなことに、多くのモデルプロバイダーは、特定のモデルバージョン(gpt-4-turbo-1106など)を**「固定」**するオプションを提供しています。これにより、モデルの重みの特定のバージョンを使用でき、それらが変更されないようにすることができます。本番環境でモデルのバージョンを固定することで、モデルの動作が予期せず変更されるのを避けることができます。これにより、モデルを交換したときに発生する可能性のある、冗長な出力やその他の予期しないエラーによる顧客からの苦情を防ぐことができます。
さらに、本番環境をミラーリングしつつ、最新のモデルバージョンを使用する環境を作ることを検討してください。これにより、新しいリリースを安全に実験およびテストできます。これらの新しいモデルからの出力の安定性と品質を検証したら、本番環境のモデルバージョンを自信を持って更新できます。
2.2.4 タスクを完了できる最小のモデルを選択する
新しいアプリケーションに取り組む際は、利用可能な中で最強のモデルを使用したくなります。しかし、タスクが技術的に実現可能であることを確認したら、より小さなモデルで同等の結果を達成できるかどうかを実験する価値があります。
小さなモデルの利点は、レイテンシーとコストが低いことです。
精度が低くなる可能性がありますが、CoT、n-shotプロンプト、In-Context Learningなどの手法は、小さなモデルがその能力以上のパフォーマンスを発揮するのに役立ちます。LLM APIを使うだけに限らず、特定のタスクに対して自分たちでファインチューニングすることで、パフォーマンスを向上させることもできます。
まとめると、小さなモデルを使用して慎重に作成されたワークフローは、多くの場合、単一の大きなモデルの出力品質に匹敵する、あるいはそれを上回ることができ、より高速でコストも安くなります。
例えば、このツイートでは、Haiku + 10-shotプロンプトがゼロショットのOpusとGPT-4を上回るというエピソードが共有されています。
長期的には、出力品質、レイテンシー、コストの最適なバランスとして、より小さなモデルを使用したフローエンジニアリングの例がより多く見られるようになるのではないかと期待しています。
別の例として、一見シンプルな分類タスクを考えてみましょう。DistilBERT(6700万パラメータ)などの軽量モデルは、驚くほど強力なベースラインとなります。4億パラメータのDistilBARTは、もう1つの優れたオプションです。オープンソースデータでファインチューニングすると、ほとんどのLLMを上回る0.84のROC-AUCでハルシネーションを特定でき、レイテンシーとコストは5%未満です。
重要なのは、小さなモデルを軽視しないことです。巨大なモデルをすべての問題に投入するのは簡単ですが、創造性と実験を重ねることで、より効率的な解決策を見つけることができます。
2.3 プロダクト
新しい技術は新しい可能性を提供しますが、優れたプロダクトを構築する原則は不変です。したがって、新しい問題を初めて解決する場合でも、プロダクト設計の手順を再発明する必要はありません。
LLMアプリケーションの開発を堅実なプロダクト開発の基本に基づいて行うことで、多くの利益が得られます。これにより真の価値をユーザたちに提供できます。
2.3.1 デザインを早期かつ頻繁に取り入れる
プロダクト開発の早い段階からデザイナーに関与してもらうことには大きな意義があります。デザイナーは、プロダクトの構築方法やユーザーへの提示方法について深く理解し、考えるきっかけを与えてくれます。デザイナーは単に見た目を良くするだけの存在ではありません。ユーザーインターフェースの改善はもちろん、既存のルールや固定観念を打ち破ってでも、ユーザーエクスペリエンスをどのように向上させられるかを考えます。
デザイナーの強みは、ユーザーのニーズを様々な形で再構成できることです。その中には、他の形式よりも解決しやすいものもあり、AIソリューションの適用機会の多寡にも影響します。AIプロダクトの開発においても、技術ありきではなく、ユーザーが求める機能や体験を中心に据えるべきです。
自分自身に問いかけてみましょう。「ユーザーはこのプロダクトに何を求めているのか。その機能はチャットボットに適しているのか。それともオートコンプリートなのか。あるいは、まったく別のものかもしれない。」既存のデザインパターンを参考に、それらがユーザーのニーズとどう関連しているかを考えてみてください。こうした知見は、デザイナーがチームに提供できる価値ある資産なのです。
2.3.2 Human-in-the-Loop用のUXをデザインする
質の高いアノテーションを得る1つの方法は、Human-in-the-Loop(HITL)をユーザーエクスペリエンス(UX)に統合することです。ユーザーがフィードバックと修正を簡単に提供できるようにすることで、即時の出力を改善し、モデルを改善するための貴重なデータを収集できます。
ユーザーが製品をアップロードして分類するEコマースプラットフォームのUXを設計する際、いくつかのアプローチが考えられます。
- ユーザーが手動で正しい製品カテゴリを選択し、LLMがバックエンドで定期的に新製品をチェックして誤った分類を修正する方法。
- ユーザーがカテゴリを選択せず、LLMがバックエンドで定期的に製品を分類する方法(エラーの可能性あり)。
- LLMがリアルタイムで製品カテゴリを提案し、ユーザーが必要に応じてそれを検証・更新できる方法。
これらの3つのアプローチはいずれもLLMを活用していますが、ユーザー体験は大きく異なります。最初のアプローチでは、ユーザーに初期の負担がかかり、LLMは後処理のチェックとして機能します。2番目のアプローチでは、ユーザーの手間は全く必要ありませんが、透明性や制御機能に欠けます。3番目のアプローチは、両者のバランスを適切に取っています。LLMが事前にカテゴリを提案することで、ユーザーの認知負荷を軽減し、分類体系を学ぶ必要がなくなります。同時に、ユーザーが提案を確認・編集できるようにすることで、最終的な分類方法の決定権をユーザーに委ね、しっかりとコントロールできるようにしています。
さらに、3番目のアプローチには、モデル改善のための自然なフィードバックループが組み込まれているという利点もあります。適切な提案は受け入れられ(ポジティブラベル)、不適切な提案は修正されます(ネガティブラベルの後にポジティブラベル)。このようなフィードバックを通じて、LLMは継続的に学習・改善していくことができるのです。
ユーザーの提案の受け入れ、検証、それに基づくデータ収集のパターンは、様々なアプリケーションで一般的に見られます。
- コーディングアシスタント:ユーザーは提案を受け入れる(強いポジティブ)、提案を受け入れた上で調整を加える(ポジティブ)、あるいは提案を無視する(ネガティブ)ことができます。
- Midjourney:ユーザーは生成された画像を拡大してダウンロードすること(強いポジティブ)、画像を変更すること(ポジティブ)、あるいは新しい画像セットの生成を求めること(ネガティブ)ができます。
- チャットボット:ユーザーはボットの応答に対して親指を上げる(ポジティブ)または親指を下げる(ネガティブ)ことができます。また、応答が非常に不適切だった場合には、応答の再生成を要求することもできます(強いネガティブ)。
(訳註: 一応の補足として「親指を上げる/下げる」というのは Good/Bad のフィードバックをする時のよくあるUIのこと)
これらのフィードバックには、明示的なものと暗黙的なものがあります。明示的フィードバックとは、ユーザーがプロダクトの要求に応じて意図的に提供する情報のことです。一方、暗黙的フィードバックとは、ユーザーが明示的にフィードバックを提供しなくても、そのインタラクションから学習できる情報を指します。コーディングアシスタントやMidjourneyは暗黙的フィードバックの例であり、親指を上げ下げするのは明示的フィードバックの例です。
コーディングアシスタントやMidjourneyのように、ユーザー体験を適切に設計することで、製品やモデルの改善に役立つ大量の暗黙的フィードバックを収集することができます。ユーザーにとって自然で負担の少ない形でフィードバックを収集し、それを効果的に活用することが、AIを活用したアプリケーションの重要な鍵となるでしょう。
2.3.3 ニーズの階層を容赦なく優先順位付けする
デモを本番環境に移行する際には、以下のような要件について検討が必要です。
信頼性:99.9%の稼働時間を確保し、構造化された出力に準拠すること
無害性:攻撃的、NSFW、またはその他の有害なコンテンツを生成しないこと
事実の一貫性:提供されたコンテキストに忠実であり、でっち上げを行わないこと
有用性:ユーザーのニーズとリクエストに関連していること
スケーラビリティ:レイテンシーSLAを満たし、必要なスループットをサポートできること
コスト:無制限の予算があるわけではないため、コストを考慮すること
その他:セキュリティ、プライバシー、公平性、GDPR、DMAなどへの対応
これらの要件を一度にすべて満たそうとすると、なかなか製品をリリースできなくなってしまいます。そのため、優先順位付けが重要になります。妥協できない要件(信頼性、無害性など)を明確にし、それらが満たされなければ製品は機能せず、実現不可能だと認識することが大切です。
ポイントは、最小限の愛される製品(Minimum Lovable Product)を特定することです。最初のバージョンは完璧でなくても構いません。とにかく立ち上げて、フィードバックを得ながら改善を重ねていくことが重要なのです。
2.3.4 ユースケースに基づいてリスク許容度を調整する
言語モデルとアプリケーションの精査レベルを決定する際は、ユースケースとターゲットオーディエンスを考慮することが重要です。例えば、医療や金融のアドバイスを提供する顧客向けのチャットボットの場合、安全性と正確性については非常に高い基準が求められます。ミスや不適切な出力は、実際の被害を引き起こし、信頼を損なう可能性があるからです。
一方で、レコメンドシステムなどのそれほど重要ではないアプリケーション、あるいはコンテンツ分類や要約などの社内向けアプリケーションでは、過度に厳しい要件を設けると、大きな価値を付加することなく進歩を妨げるだけになってしまうかもしれません。
この傾向は、最近のa16zレポートでも指摘されています(下の画像参照)。多くの企業が、外部向けのLLMアプリケーションと比べて、内部向けのLLMアプリケーションの導入をより迅速に進めているというのです。社内の生産性向上のためにAIを試すことで、組織はよりコントロールされた環境でリスク管理の方法を学びながら、価値を得られるようになります。そして、自信がついたら、顧客向けのユースケースにも拡張していけるでしょう。
企業におけるLLMの内部および外部向けのユースケースの割合(出典:a16zレポート)
2.4 チームと役割
AIの活用が進む中で、チームの役割や責任の分担を明確にすることは容易ではありません。特に、AIエンジニアという新しい役割の位置づけについては、十分な議論が必要です。ただし、ここでは職名の定義やジョブディスクリプションの提案には立ち入らず、むしろチーム全体としての責任の割り当て方に焦点を当てたいと思います。
2.4.1 ツールではなくプロセスに注目する
LLMのような新しいパラダイムに直面すると、ソフトウェアエンジニアはついツールに目が行きがちです。しかし、そのためにツールで解決すべき問題やプロセスを見落としてしまうと、不必要な複雑さを抱え込むことになります。これは長期的にはチームの生産性を下げる要因となります。
例えば、この記事では、特定のツールを使ってLLM用のプロンプトを自動生成する方法が紹介されています。しかし、問題解決の方法論やプロセスを理解せずにこうしたツールを使うエンジニアは、余計な技術的負債を抱えることになると指摘されています。
不必要な複雑さに加えて、ツールの多くは十分に特化されていないという問題もあります。例えば、一般的な毒性、簡潔さ、トーンなどの汎用的な評価器を備えた「LLM評価イン・ア・ボックス」を提供するLLM評価ツールの業界が成長しています。多くのチームが、自分のドメインに特有の課題について批判的に考えることなく、これらのツールを採用しているのを見てきました。
これとは対照的に、EvalGenは、基準の設定からデータのラベル付け、評価のチェックまで、各ステップでユーザーを深く巻き込みながら、ドメイン固有の評価を作成するプロセスをユーザーに教えることに重点を置いています。このソフトウェアは、ユーザーを以下のようなワークフローに導きます。
Shankar, S., et al. (2024). Who Validates the Validators? Aligning LLM-Assisted Evaluation of LLM Outputs with Human Preferences. https://arxiv.org/abs/2404.12272 から取得
EvalGenは、LLM評価を作成するためのベストプラクティスをユーザーに示します。
- コードを使ったアサーションやLLM-as-a-Judgeを活用して、ドメイン固有のテストを定義します(プロンプトから自動的にブートストラップされます)。
- テストがユーザーの判断と一致することが重要です。これにより、ユーザーはテストが指定された基準を適切にキャプチャしていることを確認できます。
- システム(プロンプトなど)に変更があった場合は、テストを繰り返し行います。
EvalGenは、特定のツールに依存することなく、評価構築プロセスのメンタルモデルを開発者に提供します。このコンテキストを理解したAIエンジニアは、より軽量なツールを選択したり、独自のツールを構築したりすることをよく選択します。
プロンプトの作成と評価以外にも、LLMのコンポーネントは非常に多岐にわたるため、ここですべてを網羅的に列挙することはできません。しかし、AIエンジニアがツールを採用する前に、まずプロセスを理解するよう努めることが肝要です。
2.4.2 常に実験を行う
MLプロダクトの開発において、実験は非常に重要な役割を果たします。A/Bテストやランダム化比較試験だけでなく、システムの最小限の構成要素を頻繁に変更し、オフラインで評価を行うことも実験の一環です。誰もが評価に熱心な理由は、実際には信頼性と自信を得るためではありません。それは実験を可能にするためなのです!評価が優れていればいるほど、実験の反復速度が上がり、その結果、システムの最良のバージョンにより早く到達できます。
実験のコストが大幅に下がったことで、同じ問題に対して異なるアプローチを試すことが一般的になりました。
データ収集とモデルのトレーニングにかかる高いコストは最小限に抑えられます。プロンプトエンジニアリングのコストは、人間の時間よりもわずかに高いだけです。チームの全員がプロンプトエンジニアリングの基本を学べるような体制を整えましょう。これにより、全員が実験を行うことが奨励され、組織全体から多様なアイデアを引き出すことができます。
さらに、探索のためだけでなく、活用のためにも実験を行いましょう!
新しいタスクのやり途中のバージョンがありますか?チームの他のメンバーにも別の方法でアプローチしてもらうことを検討してみましょう。より高速に実行できる別の方法を試してみるのも良いでしょう。CoTやFew shotsなどのプロンプト技術を試して、品質を高めてください。もしツールが実験の障害になっているのであれば、それを再構築するか、改善のための投資を行うことを検討しましょう。
最後に、プロダクト/プロジェクトの計画時には、評価の構築と複数の実験の実行に時間を割いてください。
エンジニアリング製品の仕様について考える際には、評価の明確な基準を追加するようにしてください。また、ロードマッピングの際には、実験に必要な時間を過小評価しないよう注意が必要です。本番環境へのリリースを許可されるまでに、開発と評価を複数回繰り返す必要があると予想しておくべきでしょう。
2.4.3 全員が新しいAI技術を使用できるようにする
生成AIの普及に伴い、専門家だけでなく、チーム全体がこの新しい技術を理解し、活用できるようになることを望んでいます。LLMの動作原理(レイテンシー、エラー、UXなど)について直感的に理解するには、実際に使ってみるのが一番の方法です。幸い、LLMは比較的アクセスしやすいものです。パイプラインのパフォーマンス向上のためにコーディングする必要はありません。誰もがプロンプトエンジニアリングと評価を通じて貢献できるのです。
これを実現するには、教育が大きな役割を果たします。n-shotプロンプティングやCoTなどの手法がモデルを望ましい出力に調整するのに役立つプロンプトエンジニアリングの基本から始めることができます。知識のある人は、LLMが出力を生成する際に自己回帰であるなどの、より技術的な側面についても教えることができます。つまり、入力トークンは並列処理されますが、出力トークンは順次生成されるのです。その結果、レイテンシーは入力の長さよりも出力の長さに依存することになります。これは、UXの設計やパフォーマンスの期待値を設定する上で重要な考慮事項となります。
さらに、実践的な実験と探求の機会を提供することも有効です。例えば、ハッカソンを開催するのはどうでしょうか。チームに数日間、試験的なプロジェクトに取り組んでもらうのは高くつくように見えるかもしれませんが、その成果には驚かされるはずです。あるチームでは、ハッカソンを通じて、3年間のロードマップをわずか1年以内にほぼ完了させ、大幅に加速させたそうです。別のチームでは、ハッカソンがきっかけで、LLMによって実現可能になったパラダイムシフト的なUXに着目し、今年以降の優先事項に位置づけたといいます。
2.4.4 「AIエンジニアリングさえあればいい」という落とし穴に陥らないでください
新しい職名が作られると、その役割に関連する能力は最初は過大評価されがちです。これらの仕事の実際の範囲が明らかになると、多くの場合、痛みを伴う修正が行われます。この分野の新参者や採用担当者は、誇張された主張をしたり、過度な期待を抱いたりするかもしれません。過去10年間の顕著な例としては、データサイエンティストや機械学習エンジニア(MLエンジニア)があります。
- データサイエンティスト:「どのソフトウェアエンジニアよりも統計学に長けており、どの統計学者よりもソフトウェアエンジニアリングに長けている人」
- 機械学習エンジニア(MLエンジニア):機械学習のソフトウェアエンジニアリング中心の見方
当初、多くの人がデータサイエンティストだけでデータ主導のプロジェクトを遂行できると考えていました。しかし実際には、データサイエンティストがソフトウェアエンジニアやデータエンジニアと協力して、データプロダクトを効果的に開発・展開する必要があることが明らかになりました。
この誤解は、AIエンジニアという新しい役割でも再び表面化しており、一部のチームではAIエンジニアさえあればいいと考えています。実際には、機械学習やAIプロダクトを構築するには、幅広い専門的な役割が必要です。AIプロダクトに関して十数社の企業にコンサルティングを行ってきた経験から、「AIエンジニアリングさえあればいい」という落とし穴に陥っているケースを一貫して観察してきました。その結果、製品開発の際に重要な側面を見落としがちで、デモ以上にプロダクトを拡張するのに苦労することが少なくありません。
例えば、バイブチェックで得られるインサイト以上にプロダクトを拡張するには、評価と測定が不可欠です。効果的な評価のためのスキルは、機械学習エンジニアに伝統的に見られる強みの一部と重なっています。AIエンジニアのみで構成されたチームは、これらのスキルに欠けている可能性があります。著者の一人であるHamel Husainは、最近のデータドリフトの検出とドメイン固有の評価の設計に関する研究で、これらのスキルの重要性を示しています。
AIプロダクトを構築する過程で必要となる役割の種類と、それらが求められるタイミングの大まかな流れは以下の通りです。
- まず、プロダクトの構築に注力します。これにはAIエンジニアが含まれるかもしれませんが、必須ではありません。AIエンジニアはプロダクト(UX、パイプラインなど)のプロトタイピングと迅速な反復に役立ちます。
- 次に、システムの使われ方を計測してデータを収集することで、適切な基盤を作ります。データの種類と規模に応じて、プラットフォームエンジニアやデータエンジニアが必要になる場合があります。また、問題をデバッグするためにこのデータを照会および分析するシステムも必要です。
- 最終的には、AIシステムの最適化に取り組むことになるでしょう。これには、モデルのトレーニングは必ずしも含まれません。基本的な手順には、メトリクスの設計、評価システムの構築、実験の実行、RAG検索の最適化、確率的システムのデバッグなどがあります。MLエンジニアはこれに非常に適しています(ただし、AIエンジニアもそれらを習得できます)。通常、前提条件となるステップを完了していない限り、MLエンジニアを採用しても意味がありません。
これとは別に、常にドメインの専門家が必要です。小さな企業では、理想的には創業チームがこの役割を担うべきであり、大企業ではプロダクトマネージャーがこの役割を果たすことができます。
役割の進行とタイミングを認識することが重要です。間違ったタイミングで人材を採用する(例えば、MLエンジニアを早すぎる時期に採用する)こと、または間違った順序でプロダクトを構築することは、時間とお金の無駄であり、離職につながります。さらに、フェーズ1と2の間は、MLエンジニアに定期的にチェックインしてもらうこと(ただし、フルタイムで採用しないこと)で、企業が適切な基盤を構築するのに役立ちます。
3 戦略:LLMを使ったプロダクト開発で出し抜かれないために
成功するプロダクトには、熟考に基づく計画と優先順位付けが必要であり、終わりのないプロトタイピングや最新のモデルリリースのトレンドを追うことは必要ありません。
この最後のセクションでは、優れたAIプロダクトを構築するための戦略的な事柄について考えます。また、チームが直面する重要なトレードオフ(いつ構築し、いつ何にお金を使うかなど)を検討し、初期のLLMアプリケーション開発戦略の「プレイブック」を提案します。
3.1 PMFの前にGPUは不要
優れたプロダクトを開発するために、プロダクトは単に他社のAPIの薄いラッパー以上のものである必要があります。しかし、反対方向の間違いはさらにコストがかかる可能性があります。昨年は、明確なプロダクトビジョンやターゲット市場がないまま、モデルのトレーニングとカスタマイズに60億ドルのシリーズAを含む大量のベンチャーキャピタルが費やされました。このセクションでは、すぐに独自のモデルのトレーニングに飛びつくことが間違いである理由を説明し、セルフホスティングの役割について考えます。
3.1.1 ゼロからのトレーニングは(ほとんど)意味がない
ほとんどの組織にとって、LLMをゼロから作ることは、プロダクトを構築する上で合理的な選択肢になり得ません。
それがどれほどエキサイティングで、他の誰もがそれを行っているように見えるとしても、機械学習インフラの開発と保守には多くのリソースが必要です。これには、データの収集、モデルのトレーニングと評価、およびそれらのデプロイが含まれます。まだPMFを検証している段階であれば、これらに時間を使うことは中核製品の開発からリソースを逸らしてしまいます。
また、たとえ計算リソース、データ、技術的な能力があったとしても、事前学習されたLLMの開発は数か月で時代遅れになる可能性があります。
金融タスク用に特別にトレーニングされたLLMであるBloombergGPTの例を見てみましょう。このモデルは、AIエンジニアリングから4名、ML製品と研究から5名の合計9名のフルタイム従業員による英雄的な努力により、3630億トークンでプリトレーニングされました。それにもかかわらず、1年以内にgpt-3.5-turboとgpt-4にそれらのタスクで追い越されてしまいました。
この話は、ほとんどの実用的なアプリケーションでは、ドメイン固有のデータであっても、ゼロからLLMを事前学習することがリソースの最良の使い方ではないことを示唆しています。その代わりに、チームは利用可能な最強のオープンソースモデルを特定のニーズに合わせてファインチューニングすることをお勧めします。
もちろん例外はあります。輝かしい例の1つは、コード生成と理解のために特別にトレーニングされたReplitのコードモデルです。プリトレーニングにより、ReplitはCodeLlama7bなどのより大きなサイズの他のモデルを上回ることができました。しかし、他のより性能の高いモデルがリリースされるにつれて、有用性を維持するには継続的な投資が必要でした。
3.1.2 必要性が証明されるまでファインチューニングを行わない
ほとんどの組織にとって、ファインチューニングは明確な戦略的思考よりもFOMO(Fear of Missing Out, 取り残されることへの恐怖)に駆り立てられています。
組織は、「ただのラッパー」という非難に打ち勝とうとして、早すぎる段階でファインチューニングに投資します。実際には、ファインチューニングは重機であり、他のアプローチでは不十分であることを納得させる十分な例を収集した後にのみ考慮されるべきものです。
1年前、多くの企業がファインチューニングに興奮していると言っていました。PMFを見つけたチームはほとんどなく、ほとんどがその意思決定を後悔しています。
ファインチューニングを行うつもりなら、ベースモデルが改善されるたびに繰り返し行う準備ができていることを本当に確信する必要があります。詳しくはこの記事中の「モデルはプロダクトではなく、それを取り巻くシステムがプロダクトである」と「LLMOpsを構築するが、正しい理由で構築する:より速い反復」を参照してください。
実際にファインチューニングが正しい選択となるのはいつでしょうか?
「そのユースケースが、既存のモデルのトレーニングに使用されているほとんどオープンなウェブスケールのデータセットでは利用できないデータを必要とする場合」、そして「既存のモデルでは不十分であることを実証するMVPをすでに構築している場合」です。ただし取り組むことになったとしても注意が必要です。優れたトレーニングデータをモデル開発者がすぐに利用できない場合、どこからそれを入手するのでしょうか?
LLMを利用したアプリケーションは科学の見本市のプロジェクトではありません。それらへの投資は、ビジネスの戦略的目標と競争上の差別化に対する貢献に見合ったものでなければなりません。
3.1.3 APIを使うことから始めるが、セルフホスティングを恐れない
LLM APIにより、スタートアップは独自のモデルをゼロからトレーニングすることなく、言語モデリング機能を採用して統合することが以前よりも容易になりました。Anthropicや OpenAIなどのプロバイダーは、わずか数行のコードでプロダクトにAIを組み込むことができる一般的なAPIを提供しています。
これらのサービスを使用することで、かかる労力が減り、代わりに顧客に価値を提供することに集中できます。これにより、アイデアを検証し、PMFに向けてより迅速に反復検証ができます。
ただし、データベースと同様に、マネージドサービスは(特に規模と要件が増加するにつれ)すべてのユースケースに適しているわけではありません。
医療や金融などの規制業界で必要とされる、または契約上の義務や機密保持要件によって必要とされる、機密/プライベートデータをネットワーク外に送信せずにモデルを使用する唯一の方法は、セルフホスティングだけかもしれません。
さらに、セルフホスティングは、推論プロバイダーによって課せられるレート制限、モデルのdeprecation、使用制限などの制限を回避します。さらに、セルフホスティングではモデルを完全に制御できるため、差別化された高品質のシステムを構築しやすくなります。
また、ファインチューニングのセルフホスティングは、大規模な場合にコストを削減できます。例えば、Buzzfeedは、オープンソースのLLMをファインチューニングすることで、コストを80%削減したと述べています。
3.2 反復して品質を高める
長期的に競争力のある優位性を維持するには、LLMそのものを超えて考え、プロダクトを際立たせる要素を見出す必要があります。スピードは重要ですが、それが唯一の強みであってはなりません。
3.2.1 モデルはプロダクトではなく、それを取り巻くシステムがプロダクトである
モデルを自社で構築していないチームにとって、イノベーションの急速なペースは恩恵となります。コンテキストサイズ、推論能力、価格対性能比の向上を追求し、より優れたプロダクトを構築するために、あるSOTAモデルから次のモデルへと移行しているのです。この進歩は、ある程度予測可能でありながらもエキサイティングなものです。つまり、モデルはシステム内で最も耐久性の低いコンポーネントである可能性が高いということです。
そのため、代わりに次のような持続的な価値を提供するものに注力してください。
- 評価:モデル全体でタスクのパフォーマンスを確実に測定するため
- ガードレール:モデルに関係なく望ましくない出力を防ぐため
- キャッシング:モデルの推論を完全に回避することで、レイテンシーとコストを削減するため
- データフライホイール:上記すべての反復的な改善を促進するため
これらのコンポーネントは、モデル自体の機能よりもプロダクト品質のモートを作ります。
しかし、それはアプリケーション層での構築にリスクがないことを意味するわけではありません。実際に価値を産むエンタープライズソフトウェアを提供したい場合に、OpenAIやその他のモデルプロバイダーが解決する必要のある問題に、自ら取り組むべきではありません。
例えば、一部のチームは、独自モデルからの構造化された出力を検証するためのカスタムツールの構築に投資しました。ここでの最小限の投資は重要ですが、深い投資は時間の良い使い方ではありません。OpenAIは、ユーザがプロンプトの中で関数の呼び出しを求めたときに、有効な関数呼び出し(Function Calling)が得られるようにする必要があります。なぜなら、すべての顧客がこれを望んでいるからです。ここでは「戦略的な先延ばし」を採用し、絶対に必要なものだけを構築し、プロバイダーからの機能アップデートを待つことが賢明です。
3.2.2 小さなことから始めて信頼を築く
すべての人を満足させるプロダクトを構築しようとすることは、平凡さを生み出すレシピです。魅力的なプロダクトを作るには、企業はユーザーを引き付け続ける体験を構築する必要があります。
ユーザーが尋ねる可能性のあるあらゆる質問に答えることを目的とする汎用のRAGシステムを考えてみましょう。特定の領域への特化の欠如は、システムが最新の情報に優先順位を付けたり、ドメイン固有の形式を解析したり、特定のタスクのニュアンスを理解したりできないことを意味します。その結果、ユーザーは浅く信頼できない体験を経験し、ニーズを満たすことができず、チャーンにつながります。
これに対処するには、特定のドメインとユースケースに焦点を当ててください。広く浅くではなく、深く掘り下げることで範囲を絞ります。これにより、ユーザーに響くドメイン固有のツールが作成されます。特定の領域への特化により、システムの機能と制限について率直に説明することもできるようになります。システムができることとできないことについて透明性を持つことは、ユーザーがどこに最大の価値を付加できるかを理解するのに役立ち、したがって出力に対する信頼と自信を築きます。
3.2.3 LLMOpsを構築するが、正しい理由で構築する:より速い反復
DevOpsは、根本的に再現可能なワークフローやシフトレフト、2ピザチームのエンパワーメントに関するものではありません。YAMLファイルを書くことに関するものでもありません。
DevOpsは、作業とその結果の間のフィードバックサイクルを短縮することで、エラーではなく改善が蓄積されるようにすることに関するものです。その起源は、リーンスタートアップ運動を経て、金型交換の単一分間とカイゼンを重視するリーン生産とトヨタ生産方式にさかのぼります。
MLOpsは、DevOpsの形式をMLに適応させました。再現可能な実験と、モデル開発者にリリースを可能にするオールインワンスイートがあります。そして、YAMLファイルもあります。
しかし、業界としてMLOpsはDevOpsの機能を採用しませんでした。モデルとその推論、本番環境でのインタラクションの間のフィードバックギャップを縮めませんでした。
心強いことに、LLMOpsの分野は、プロンプト管理のような小さな問題から、評価によって連結された反復を阻害するより難しい課題へと焦点を移しています。
すでに、チャットとコーディングモデルの中立的でクラウドソースの評価のためのインタラクティブなアリーナがあります(訳註:おそらくChatbot Arenaのこと)。集合的で反復的な改善のループです。
LangSmith、Log10、LangFuse、W&B Weave、HoneyHiveなどのツールは、本番環境でのシステムの結果に関するデータを収集して照合するだけでなく、開発と深く統合することでプロダクトの改善に繋げることができます。これらのツールを利用するか、独自のツールを構築してみてください。
3.2.4 お金で手に入るLLMの機能は自分で構築しない
ほとんどの成功したビジネスはLLMビジネスではありません。一方で、ほとんどのビジネスにはLLMによって改善される機会があります。
このことは、リーダーをしばしば誤解させ、コストを増加させ品質を低下させてシステムにLLMを性急に後付けし、いまや恐れられているスパークルアイコンを完備した偽物の虚栄心の「AI」機能としてリリースします。
より良い方法があります。プロダクトの目標に真に合致し、コア業務を強化するLLMアプリケーションに注力してください。
チームの時間を無駄にするいくつかの誤った取り組みを考えてみましょう。
- ビジネス用のカスタムテキストからSQLへの機能を構築する。
- ドキュメントと対話するチャットボットを構築する。
- 顧客サポートチャットボットに企業のナレッジベースを統合する。
上記はLLMアプリケーションのハローワールドですが、プロダクトを開発している会社が自ら構築する意味はありません。
これらは多くのビジネスにとって一般的な問題であり、有望なデモと信頼できるコンポーネントの間に大きなギャップがあります。現在のYコンビネーターの投資先企業たちによって取り組まれている一般的な問題に貴重なR&Dリソースを投資することは無駄です。
これが陳腐なビジネスアドバイスのように聞こえるのは、現在のハイプの波の泡立つような興奮の中で、「LLM」に関するものは何でも最先端であるかのように感じ、どのアプリケーションがすでにありふれたものであるかを容易に誤解してしまうからです。
3.2.5 AI in the loop; Humans at the center
現時点では、LLMを利用したアプリケーションは脆弱です。信じられないほどの安全対策と防御的なエンジニアリングが必要ですが、予測は難しいままです。
しかし、厳密に範囲が限定されている場合、これらのアプリケーションは非常に有用になる可能性があります。つまり、LLMはユーザーのワークフローを加速するための優れたツールになります。
LLMベースのアプリケーションがワークフローを完全に置き換えることを想像するのは魅力的かもしれませんが、今日、最も効果的なパラダイムは人間とコンピュータのケンタウロス(ケンタウロスチェス)です。
人間がチューニングされたLLM機能とペアになると、タスクを行う生産性と幸福度が大幅に向上します。LLMのフラグシップアプリケーションの1つであるGitHub CoPilotは、このワークフローの力を実証しました。
「全体として、開発者はGitHub CopilotとGitHub Copilot Chatを使用すると、コーディングがより簡単、エラーが少ない、読みやすい、再利用可能、簡潔、保守可能、および回復力があると感じ、それらなしでコーディングするよりも自信を持っていると言いました。」- Mario Rodriguez, GitHub
長い間MLに携わってきた人は、「Human-in-the-loop」のアイデアに飛びつくかもしれませんが、そう急いではいけません。HITL機械学習は、人間の専門家がMLモデルが予測通りに動作することを保証するパラダイムです。関連はしていますが、ここではもっと繊細なニュアンスのことを提案しています。
LLM主導のシステムはにおいては、ほとんどのワークフローの中ではAIは単なるリソースになるべきであって、主要なドライバーであってはなりません。
人間を中心に置き、LLMがどのようにそのワークフローをサポートできるかを尋ねることで、プロダクトと設計の決定が大きく変わります。最終的に、すべての責任をLLMに迅速にオフショアしようとする競合他社とは異なるプロダクトを構築することになるでしょう。それはより優れた、より有用な、そしてリスクの少ないプロダクトになります。
3.3 プロンプト、評価、データ収集から始める
前のセクションでは、技術とアドバイスの数々を提供しました。一度に吸収するのは大変なので、最小限の有用なアドバイスを考えてみましょう。チームがLLMプロダクトを構築したい場合、どこから始めるべきでしょうか。
この1年間で、我々は成功するLLMアプリケーションがたどる一貫した軌跡を確信するのに十分な経験を積みました。このセクションでは、この基本的な「入門」プレイブックを説明します。
核心となるアイデアは、シンプルに始め、必要に応じて複雑さを追加していくことです。経験則として、洗練さのレベルが上がるごとに、その前のレベルよりも少なくとも1桁多くの労力が必要になります。
それでは、これらを念頭に置いて...
3.3.1 まずはプロンプトエンジニアリング
プロンプトエンジニアリングから始めましょう。前の戦術(Tactical)のセクションで説明したすべての技術を使用してください。CoT、n-shotの例、構造化された入力と出力、を採用することはほとんどの場合で良いアイデアになります。より弱いモデルからパフォーマンスを絞り出そうとする前に、最も高性能なモデルでプロトタイピングしてください。
プロンプトエンジニアリングで目的のパフォーマンスレベルを達成できない場合にのみ、ファインチューニングを検討してください。このセルフホスティングの可能性は、プロバイダーのモデルの使用ができなくなる非機能要件(データプライバシー、完全な制御、コストなど)がある場合により高まります。ただし、同じプライバシー要件がファインチューニング用のユーザーデータの使用をブロックしないか注意してください。
3.3.2 評価基盤を構築し、データフライホイールを開始する
LLMプロダクト開発に入門したばかりのチームでも評価が必要です。そうしないと、プロンプトエンジニアリングで十分かどうか、またはファインチューニングしたモデルがベースモデルに置き換える準備ができているかどうかがわかりません。
効果的な評価はタスクに固有のものであり、意図されたユースケースを反映しています。
私たちが推奨する最初のレベルの評価はユニットテストです。これらの単純なアサーションは、既知または仮説の課題・エラーを検出し、初期のデザインの意思決定を考えることに役立ちます。また、分類、要約などのその他のタスク固有の評価も参照してください。
ユニットテストとモデルベースの評価は役立ちますが、人間による評価の必要性に取って代わるものではありません。人々にモデル/プロダクトを使用してもらい、フィードバックを提供してもらいしょう。これは、実世界でのパフォーマンスとエラー率を測定すると同時に、将来のモデルをファインチューニングするために使用できる高品質のアノテーション付きデータを収集するという二重の目的を果たします。これにより、時間とともに複利的に増加するポジティブなフィードバックループ、つまりデータフライホイールが作成されます。
- 人間による評価によるモデルのパフォーマンスの評価および/または欠陥の発見
- アノテーション付きデータを使用してモデルをファインチューニングするか、プロンプトを更新する
- 上記を繰り返す🔁
例えば、LLMで生成された要約の欠陥を検査する際、事実の矛盾、無関係、スタイルの悪さを特定する詳細なフィードバックで各文にラベルを付ける場合があります。そして、これらの事実の矛盾のアノテーションを使用してハルシネーション分類器をトレーニングしたり、関連性のアノテーションを使用して関連性報酬モデルをトレーニングしたりできます。別の例として、LinkedInは、ハルシネーション、責任あるAIの違反、一貫性などを推定するためのモデルベースの評価器の使用における成功について以下の記事で紹介しています。
時間とともにその価値が複利的に増加する資産を作成することで、評価の構築を純粋に運用上の費用から戦略的投資へとアップグレードし、その過程でデータフライホイールを構築します。
3.4 低コストの知性が広がるトレンド
1971年、Xerox PARCの研究者たちは、私たちが今生きているネットワークでつながったパーソナルコンピュータの世界という未来を予測しました。イーサネットやグラフィックスレンダリングからマウスやウィンドウに至るまで、その未来を可能にする技術の発明に重要な役割を果たし、未来の誕生に貢献しました。
しかし、彼らはシンプルな取り組みも行いました。非常に有用だが(例えば、ビデオディスプレイ)、まだ経済的ではない(つまり、ビデオディスプレイを駆動するのに十分なRAMは数千ドルもする)アプリケーションを調べたのです。そして、その技術の歴史的な価格動向(ムーアの法則に倣って)を調べ、それらの技術が経済的になる時期を予測しました。
LLM技術についても、トランジスタ当たりの価格ほど明確な指標はありませんが、同じことができます。Massively-Multitask Language Understandingデータセットのような人気の長年のベンチマークと、一貫した入力アプローチ(five-shotプロンプティング)を用いてスコアを算出します。そして、このベンチマークでさまざまなパフォーマンスレベルの言語モデルを実行するコストを時間の経過とともに比較します。
一定のコストでは、性能が急速に向上しています。一定の性能レベルでは、コストが急速に下がっています。共著者のCharles Fryeが2024年5月13日に公開データを使用して作成
OpenAIのdavinciモデルがAPIとして発表されてから4年間で、100万トークン(このドキュメントの約100倍)の規模でそのタスクで同等のパフォーマンスを発揮するモデルを実行するコストは、$20から10セント未満に下がりました。半減期はわずか6か月です。同様に、2024年5月の時点で、APIプロバイダーまたは自分自身を介してMeta's LLaMA 38Bを実行するコストは、100万トークンあたりわずか20セントであり、ChatGPTを可能にしたモデルであるOpenAIのtext-davinci-003と同等のパフォーマンスを発揮します。
そのモデルも、2023年11月末にリリースされた時点では、100万トークンあたり約$20のコストがかかりました。これは、ムーアの法則が単なる倍増を予測する同じ期間である18か月で2桁の減少です。
では、非常に有用ですが(Park et alのようなジェネレーティブなビデオゲームキャラクターを実現する)、まだ経済的ではない(こちらではそのコストが1時間あたり$625と見積もられている)LLMのアプリケーションの例を見てみましょう。その論文が2023年8月に公開されて以来、コストは約1桁下がり、1時間あたり$62.50になりました。さらに9か月後には、1時間あたり$6.25に下がると予想されます。
一方、パックマンが1980年に発売された時、今日の1ドルで、数分から数十分プレイできるクレジットを買うことができました。1時間あたり6ゲームとして考えると、およそ1時間あたり6ドルです。この大まかな計算から、魅力的なLLMを使ったゲーム体験が2025年のある時点で経済的に実現可能になることが示唆されます。
これらのトレンドは新しく、わずか数年前に始まったばかりです。しかし、今後数年間でこのプロセスが遅くなることを期待する理由はほとんどありません。アルゴリズムとデータセットの改善による低コストの成果を使い尽くしたとしても(例えば、「チンチラ比」*を超えるようなスケーリング)、データセンターとシリコン層での深層の革新と投資が、その差を埋めることが期待できます。
*訳註:「チンチラ比」とは、言語モデルのパラメータ数に対して、学習に用いるトークン数の比率のこと。この比率が約20トークン/パラメータを超えると、モデルの性能向上が鈍化すると言われている。
そして、これがおそらく最も重要な戦略的事実です。今日の完全に実現不可能なデモや研究論文でも、数年後にはプレミアム機能になり、その後すぐに一般的なものになるでしょう。私たちは、このことを念頭に置いて、システムと組織を構築すべきです。
4 0から1へのデモはもう十分、今こそ1からNへの製品化の時
わかります。LLMのデモを作るのはとても楽しいことです。ほんの数行のコード、ベクターデータベース、そして慎重に作成されたプロンプトで、私たちは✨魔法✨を作り出します。そして過去1年間、この魔法はインターネット、スマートフォン、さらには印刷機に匹敵すると言われてきました。
残念ながら、実世界のソフトウェアの運用に携わったことがある人なら誰でも知っているように、制御された環境で機能するデモと、大規模に安定して動作するプロダクトとの間には大きな隔たりがあります。
想像し、デモを作ることは簡単にできるが、製品化するのは非常に難しい問題があります。例えば、自動運転。車が1ブロックを自動運転するデモは簡単ですが、それを製品にするには10年かかります。- Andrej Karpathy
例えば、自動運転車を見てみましょう。最初にニューラルネットワークで車が運転されたのは1988年のことでした。25年後、Andrej Karpathyは、Waymoで最初のデモ乗車をしました。
更にその10年後、同社は無人運転の許可を取得しました。プロトタイプから商用製品になるまでに35年もの厳しいエンジニアリング、テスト、改良、規制ナビゲーションが行われたのです。
産業界と学術界では、この1年間の浮き沈みを観察してきました。業界としてのLLMアプリケーション開発の1年目です。私たちが学んだ教訓が、評価、プロンプトエンジニアリング、ガードレールなどの戦術から、運用技術やチーム構築、そしてどの機能を内部で構築するかなどの戦略的視点まで、2年目以降の皆さんの助けになることを願っています。私たち全員が、このエキサイティングな新しい技術を一緒に構築していくために。
5 Stay In Touch
この記事が役に立ち、記事、コース、活動のアップデートの通知が欲しい場合は、以下にサブスクライブしてください。
著者の連絡先は、aboutページでもご覧いただけます。
6 謝辞
このシリーズは、グループチャットでの会話から始まりました。Bryanが「AIエンジニアリングの1年」を書きたいと思ったことがきっかけです。そして、✨魔法✨が起こり、私たち全員が今まで学んできたことを共有することになったのです。
私たちは、文書の大部分の統合と全体的な構成に加え、多くの教訓をリードしてくれたEugeneに感謝の意を表したいと思います。さらに、主要な編集責任と文書の方向性についても感謝しています。
また、この記事のきっかけを作ってくれたBryanにも感謝しています。戦術的、運用的、戦略的なセクションとその導入部分に記事を再構成し、私たちがどのようにしてコミュニティに手を差し伸べ、助けることができるかについて、より大きく考えるよう私たちを後押ししてくれました。
コストとLLMOpsについて深く掘り下げ、教訓を織り交ぜることで、より一貫性があり、よりコンパクトなものにしてくれたCharlesにも感謝しています。これが40ページではなく30ページで済んだのは、彼のおかげです。
クライアントにアドバイスし、最前線に立っているHamelとJasonの洞察力、クライアントから得た幅広く一般化できる学び、そしてツールに関する深い知識にも感謝の意を表します。
そして最後に、評価と厳格な製造実務の重要性を思い出させ、彼女の研究とオリジナルの結果を持ってきてくれたShreyaにも感謝しています。
最後に、このシリーズを通して参照させていただいた、皆様自身の課題と教訓を寛大にも共有してくださったすべてのチームの皆様、そしてこのグループに活発に参加し、関わってくださったAIコミュニティの皆様に感謝の意を表します。
6.1 著者について
著者の詳細については、紹介ページをご覧ください。
この記事が役に立った場合は、以下のように引用してください。
Yan, Eugene, Bryan Bischof, Charles Frye, Hamel Husain, Jason Liu, and Shreya Shankar. 2024. ‘Applied LLMs - What We’ve Learned From A Year of Building with LLMs’. Applied LLMs. 8 June 2024. https://applied-llms.org/.
or
@article{AppliedLLMs2024,
title = {What We've Learned From A Year of Building with LLMs},
author = {Yan, Eugene and Bischof, Bryan and Frye, Charles and Husain, Hamel and Liu, Jason and Shankar, Shreya},
journal = {Applied LLMs},
year = {2024},
month = {Jun},
url = {https://applied-llms.org/}
}
Discussion