単純なユースケースを解決するためのカスタマイズ可能な大規模言語モデルの開発のための初心者ガイド
著者: ラチェル・マルティネス | 役割: 開発者 | タグ: AI エージェント
導入
私たちの技術ブログへようこそ。ここでは、専門的な知識や経験の有無にかかわらず、複雑な概念を誰もが理解できるように解説しています。本日、私たちは多様なタスクに適応できる大規模言語モデル(LLM)エージェントの開発という刺激的なプロジェクトに取り組みます。
タスクごとに最も適切なLLMを選択するために、堅牢な検索、拡張、生成(RAG)インフラストラクチャを作成します。H2OやHuggingFaceなどの企業はすでに同様のシステムを立ち上げており、我々のAI技術を自社のアプリケーションに統合したいと望むスタートアップからの関心も寄せられています。
我々の特定のユースケースでは、LLMに対して単一の入力(ワンショット)または複数のプロンプトを連鎖させることでプロンプトを送信する機能が必要です。これには、さまざまなシナリオに対応するためのカスタマイズ可能で使いやすいLLMモジュールの作成が必要です。
この旅に出かける際、各ステップをシンプルかつ魅力的に解説していきます。おたのしみに!
現在の使用ケース
現在のユースケースでは、ユーザーの履歴書のコンテンツを2段階のプロセスで強化します。
- ユーザーは、自分の履歴書の「プロフェッショナルサマリー」と「経験」セクションを入力し、LLMに対してテキストをより洗練されたバージョンに生成するよう指示します。
- レビュー:ユーザーはLLMで生成されたコンテンツを確認し、独自のスキルや経験に合うよう出力を洗練・パーソナライズするために追加のプロンプトやガイダンスを提供します。
このアプローチにより、ユーザーはLLMの力を活用して、潜在的な雇用主から注目される魅力的な履歴書を作成することができます。
ターゲット
私たちは、自社のユースケースに対応し、履歴書作成プロセスを少なくとも部分的に自動化できる、完全にカスタマイズ可能なLLMモジュールの開発を目指しています。
実装
ステップ1:LLMを選ぶ
ニーズに合ったLLMを選択する際は、主にオープンソースLLMとプロプライエタリLLMの2つのカテゴリを検討する。両方のグループから代表的な選択肢を紹介し、オープンソースLLMを選ぶメリットに焦点を当てる。
オープンソースLLM
ミストラル AI、Phi 3、LLaMa 3。
利点:
- コミュニティサポート: 大規模で活発な開発者およびユーザーのコミュニティが、ガイダンスを提供し、リソースを共有し、改善に協力します。
- カスタマイズ性: ソースコードへのアクセスにより、特定のユースケースに合わせて修正や適応が可能。
- 透明性: モデルの内部動作を理解することは、厳格な倫理規定やプライバシー基準を有するアプリケーションにおいて不可欠です。
独自開発のLLM
GPT-4.
利点: 印象的なパフォーマンスと独自の機能。
制限事項:
- カスタマイズ性の欠如: モデルをそのままで使用するしかない。
- コスト: 使用量に応じた料金が発生し、時間とともに高額になる可能性があります。
- 不透明性: 内部の仕組みを理解しにくく、透明性や説明可能性を重視する人々にとって懸念材料となる。
結論として、オープンソースと独自開発のLLMにはそれぞれメリットとデメリットがあるが、Mistral AI、Phi 3、LLaMa 3のようなオープンソースLLMは、幅広いユーザーにとって非常に有益なアクセシビリティ、カスタマイズ性、透明性を提供する。
ステップ2:コストと機能を確認する
オープンソースLLMは通常、コスト効率が高いことが特徴であり、自社のサーバーまたは、AzureやAWSのようなプロバイダーを使用して、従量課金制でホストできるためである。以下は、さまざまなLLMのホストに関するコストと機能の概要である。
| LLM | 詳細 | コンテキストの長さ | 費用 |
|---|---|---|---|
| ミクストラル 8x7B | MoE LLM by Mistral A | 学習済み: 8192トークン | $0.7/1Mトークン(chea |
| ミクストラル 8x22B | 後継者、ミクストラル | 学習済み: 32768トークン | 1Mトークンあたり2ドル(利用可能) |
| LLaMa 3 70B | MetによるNon-MoEモデル | 学習済み: 2048トークン | $0.02/1Kトークン(アズ) |
| Phi 3 128K | マルチモーダル-SLM by Me | 訓練済みおよび合計:3 | $0.002/1Kトークン(Az) |
| GPT-4 ターボ | OによるLLMの独自性 | 16K デフォルト、高解像度 | AWSでは利用できません |
ステップ3:OpenRouterに準拠したパブリックAPIを使用したテスト
最適なLLMを選択しテストするには、さまざまなモデルにアクセスし評価するための効率的な手段が必要です。OpenRouterは、オープンソースのAPI標準であり、複数のAIモデルやサービス間のシームレスな切り替えを可能にします。プロバイダーとしてFireworksAIを選択した理由は次のとおりです:
- 【モデルの多様性】AIモデルを幅広く提供し、Mistral AI、Phi 3、LLaMa 3 などの人気オープンソースLLMを含みます。
- 統合の容易さ: OpenRouter規格に準拠しており、既存インフラへの統合を簡素化します。
- スケーラビリティ: 大量のリクエストを処理でき、シームレスに拡張可能。
ここでは、同じハードウェアを使用してモデルの応答を呼び出すサンプル関数とレイテンシ結果を示します:
import json
def get_sanitized_json_response(user_input, guardrail):
final = chain.invoke({"text": f"Sanitize {user_input}. Guardrail: {guardrail}"})
final = chain.invoke({"text": final.content})
return json.loads(final.content.replace("<json>", "").replace("</json>", "").replace("\n",""))
| モデル | レイテンシー | 備考 |
|---|---|---|
| ミクストラル 8x7B | 2.1秒 | 最軽量モデル、パフォーマンス |
| ミクストラル 8x22B | 5.3秒 | 後継モデル、シミュレーション |
| LLaMa 3 70B | 2.6秒 | まともな返答だが |
| Phi 3 128K | 1.5分 | マルチモーダルモデル |
上記を検証するために、非常に単純なガードレールと入力が使用されました:
guardrail = """Format details as bullets and use the XYZ method to format the relevant detail.
For example:
- I did X boosting Y percent resulting in Z.
"""
呼び出し後に取得した以下のサニタイズ済みJSONレスポンス:
get_sanitized_json_response("""I served as Junior as a Software Engineer at TechCorp in Sydney in January 2011 and worked there until December 2018. During my tenure,
私は、何億ものレコードを処理するための高度なAI駆動型金融分析ツールの開発チームを率いました。
分散環境を構築し、同社の独自データパイプラインの初期バージョンを作成した。私の役割において、私は以下の責任を負っていました
ソリューションの設計と複数のAPIの実装。過去1年間、ブロックチェーンソリューションに特化したチームを管理してきた。""", ガードレール)
「経験」: [{'タイトル': 'ソフトウェアエンジニア',
'会社': 'TechCorp',
'location': 'シドニー',
'start_date': '2011-01',
'end_date': '2018年12月',
「ハイライト」:[『主要プロジェクトでスケーラブルなデータベースシステムを構築し、クライアントのデータ処理速度を40%向上させた』]
「AI駆動型ソリューションに注力したチームを率いた。」
「分散環境において1億件以上のレコードを処理するAI駆動の金融分析ツールを開発。」
「会社の独自データパイプラインを作成。」
「最終学年では、ブロックチェーンソリューションのチームを管理しました。」
In conclusion, since the response quality was fairly comparable among all these models, it came down to latency and cost. The experiment was run 3 times achieving very similar results. So we chose Mistral AI’s Mixtral 8x7B due to its favorable balance of latency and cost.
Step 4: Building an Orchestration Layer
Managing and coordinating multiple large-scale language models or a single model across various applications is crucial for optimal performance and adaptability. Instead of building from scratch using vanilla PyTorch, employing an orchestration framework is more practical and efficient. Here are three options:
Langchain
Advantages: Vast array of integrations, supports Python and JavaScript, extensive community support.
Drawbacks: Introduces an additional dependency, potential learning curve.
LlamaIndex
Advantages: Backed by Meta, offers interoperability with Langchain.
Drawbacks: Less developer-friendly syntax.
Haystack
Advantages: User-friendly syntax, supported by prominent tech corporations.
Drawbacks: Limited integrations as it’s still maturing.
Using an orchestration framework simplifies development, improves scalability, and provides access to a supportive community, making it a more favorable choice for our project.
Design and Data Flow
The following image shows the design diagram:
The data flow within our AI-driven system is an essential aspect of ensuring a seamless and efficient user experience. While the design diagram provides a visual representation of the process, a detailed explanation can help clarify the steps involved:
- User Input: The journey begins when the user enters their details, such as the “about” and “experience” sections of their resume, into the system.
- Prompt Generation: The user’s input is then processed and transformed into one or more prompts, which will be used to query the Large Language Model (LLM) for a more polished and impressive version of the text.
- LLM Integration via Langchain: The generated prompts are passed to Langchain, our chosen orchestrator framework, which facilitates the interaction with the LLM client. Langchain leverages a Pydantic schema in the form of a class to parse and validate the data using kor, ensuring that it adheres to the required format.
- JSONResponse Generation: Once the data is validated, it is converted into a final JSONResponse, a structured and easy-to-work-with data format that simplifies further processing and manipulation.
- Content Extraction and Indexing: The content part of the JSONResponse is extracted using kor and indexed by computing embeddings, which are mathematical representations of the text. These embeddings are then stored in a vector database, such as Qdrant, for efficient retrieval and comparison during subsequent queries.
- Caching for Context Module: The entire JSONResponse is cached for the context module to function correctly. This ensures that the system can maintain the context of the user’s input and the LLM’s output during follow-up queries.
- Follow-up Queries: When the user provides additional input or requests further refinement of the generated text, the cached JSONResponse is modified according to the new context and chained to the updated prompt. This modified prompt then goes through the entire process again, from LLM integration to content extraction and indexing, to provide the user with a tailored and accurate response.
By understanding the data flow within our system, we can appreciate the importance of each step and the role of the orchestrator framework in streamlining the process, ultimately resulting in an efficient and user-friendly AI-driven solution.
LCELを用いたプロンプト構築と連鎖
これはPromptTemplateのサンプルです:
from langchain.core.output_parsers import PydanticOutputParser
prompt = PromptTemplate(
template="Please extract the following information from the given text and format it as a JSON object according to the schema:\n\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": output_parser.get_format_instructions()},
)
chain = prompt | chat_model | output_parser
典型的なテンプレートは、2つの主な引数(他の引数もありますが、それはこのブログの範囲外です)で構成されます。これらはinput_variablesとtemplateです。最初の引数は、実行時にプロンプトテンプレートに注入される文字列のリストを受け取ります。この変数は、通常、Jinja2Templateやf-stringsのような動作をします。ここでのchat_modelは、使用しているLLMであり、プロンプトに連結されています。|(パイプ)演算子は、BASHの|演算子と同様に、連結を表します。これは、LCEL(LangChain式言語)仕様によって提供される便利なショートハンドです。これにより、1つのプロンプトの応答を別のプロンプトの入力に連結できます。また、関数呼び出しもサポートしており、ラムダ式や関数を連結して出力をサニタイズすることができます。これにより、コードの複雑さを減らし、簡単に連結を書くだけで、大きな関数を書く必要がなくなります。
ステップ5:VectorDBsを使用する
ベクトルデータベース(VectorDBs)は、高次元ベクトル(LLMによって生成されるテキスト埋め込みなど)を格納、管理、効率的に検索します。ここでは、人気のあるオプションを比較します:
Qdrant
利点: 高性能、統合が容易、活発なコミュニティ。
欠点: 重大なものはなし。
ミルブス
利点: 複数の距離尺度、データ可視化ツール。
欠点: 習得に時間がかかる。
クロマ
利点: Python、APIは使いやすく、モジュール設計。
欠点: 比較的新しく、コミュニティのサポートが限られている。
PGVector
利点: PostgreSQLの機能を活用し、SQLベースのクエリを実行。
欠点: 高次元ベクトル検索においてパフォーマンスが低い。
FAISS
利点: 高性能検索、GPU対応。
欠点: 他のデータベースとの統合が必要。
Qdrantのスケーラビリティ、統合の容易さ、そして活発な開発は、我々のAI駆動型ソリューションにとって適切な選択肢となっています。
VectorDBsを堅牢なIRソリューションとして活用する
情報検索(IR)ソリューションを作成するには、VectorDBsを使用します。
- テキスト前処理: 生データデータをクリーンアップし、前処理する。
- テキスト埋め込み生成: 前処理されたテキストをLLMを使用して高次元ベクトルに変換する。
- VectorDBに埋め込みを格納: 効率的な検索のためにインデックス埋め込み。
- クエリ処理: ユーザーのクエリを前処理し、エンベディングに変換する。
- 類似検索: VectorDBで関連する埋め込みを検索します。
- ランキングと結果の表示: 取得した埋め込みベクトルをランク付けし、テキストに変換して表示します。
このプロセスに従い、VectorDBsを活用することで、効率的かつ効果的なIRシステムを構築することができます。