Amazon SageMaker JumpStart、Llama 2、Amazon OpenSearch Serverless と Vector Engine を使用して金融サービス用のコンテキストチャットボットを構築する | アマゾン ウェブ サービス

Amazon SageMaker JumpStart、Llama 2、Amazon OpenSearch Serverless と Vector Engine を使用して金融サービス用のコンテキストチャットボットを構築する | アマゾン ウェブ サービス

金融サービス (FinServ) 業界には、ドメイン固有のデータ、データ セキュリティ、規制管理、業界のコンプライアンス標準に関連する独自の生成 AI 要件があります。 さらに、顧客は、最もパフォーマンスが高くコスト効率の高い機械学習 (ML) モデルを選択する選択肢と、ビジネス ユース ケースに合わせて必要なカスタマイズ (微調整) を実行する機能を求めています。 Amazon SageMaker ジャンプスタート は、必要なデータ セキュリティ制御を提供し、コンプライアンス標準要件を満たしているため、FinServ 顧客の生成 AI ユースケースに最適です。

この投稿では、単純な金融ドメインのユースケースを使用して、SageMaker JumpStart の大規模言語モデル (LLM) を使用した検索拡張生成 (RAG) ベースのアプローチを使用した質問応答タスクを示します。 RAG は、LLM と情報検索 (IR) システムを組み合わせることにより、テキスト生成の品質を向上させるためのフレームワークです。 LLM がテキストを生成し、IR システムが知識ベースから関連情報を取得します。 取得された情報は、LLM の入力を補強するために使用されます。これは、モデルが生成したテキストの精度と関連性を向上させるのに役立ちます。 RAG は、質問応答や要約など、さまざまなテキスト生成タスクに効果的であることがわかっています。 これは、テキスト生成モデルの品質と精度を向上させるための有望なアプローチです。

SageMaker JumpStart を使用する利点

SageMaker JumpStart を使用すると、ML 実践者は、コンテンツ作成、画像生成、コード生成、質問応答、コピーライティング、要約、分類、情報検索などのユースケースに合わせた最先端のモデルを幅広い選択肢から選択できます。 ML 実践者は基礎モデルを専用のモデルにデプロイできます。 アマゾンセージメーカー ネットワーク分離環境からインスタンスを抽出し、モデルのトレーニングとデプロイメントに SageMaker を使用してモデルをカスタマイズします。

SageMaker JumpStart は以下を提供するため、FinServ 顧客の生成 AI ユースケースに最適です。

  • カスタマイズ機能 – SageMaker JumpStart は、基礎モデルのドメイン適応に関するステップバイステップのガイダンスのためのサンプル ノートブックと詳細な投稿を提供します。 これらのリソースに従って、基礎モデルの微調整、ドメイン適応、指示を行ったり、RAG ベースのアプリケーションを構築したりできます。
  • データセキュリティ – 推論ペイロード データのセキュリティを確保することが最も重要です。 SageMaker JumpStart を使用すると、シングル テナンシーのエンドポイント プロビジョニングを使用して、ネットワークを分離してモデルをデプロイできます。 さらに、プライベート モデル ハブ機能を通じて、個別のセキュリティ要件に合わせて、選択したモデルへのアクセス制御を管理できます。
  • 規制管理とコンプライアンス – HIPAA BAA、SOC123、PCI、HITRUST CSF などの標準への準拠は SageMaker の中核機能であり、金融​​セクターの厳格な規制状況との整合性を確保します。
  • モデルの選択 – SageMaker JumpStart は、業界で認められた HELM ベンチマークで常にトップにランクされる最先端の ML モデルのセレクションを提供します。 これらには、Llama 2、Falcon 40B、AI21 J2 Ultra、AI21 Summarize、Hugging Face MiniLM、および BGE モデルが含まれますが、これらに限定されません。

この投稿では、Llama 2 基盤モデルと ハグフェイス GPTJ-6B-FP16 埋め込みモデル。どちらも SageMaker JumpStart で利用できます。 私たちも使っています ベクトルエンジン for Amazon OpenSearch サーバーレス (現在プレビュー中) 埋め込みを保存するベクター データ ストアとして。

大規模な言語モデルの制限

LLM は膨大な量の非構造化データについてトレーニングを受けており、一般的なテキスト生成に優れています。 このトレーニングを通じて、LLM は事実の知識を取得し、蓄積します。 ただし、既製の LLM には次のような制限があります。

  • 彼らはオフラインでトレーニングしているため、最新の情報を知ることができません。
  • 主に一般化されたデータに関するトレーニングでは、ドメイン固有のタスクにおける効率が低下します。 たとえば、金融会社は、Q&A ボットが最新の内部文書から回答を取得し、正確さとビジネス ルールへの準拠を確保することを好む場合があります。
  • 埋め込まれた情報に依存すると、解釈可能性が損なわれます。

LLM で特定のデータを使用するには、次の XNUMX つの一般的な方法があります。

  • モデル プロンプト内にデータを埋め込むと、出力生成中にこのコンテキストを利用できるようになります。 これは、ゼロショット (例なし)、少数ショット (限られた例)、または多ショット (豊富な例) のいずれかになります。 このような状況に応じたプロンプトは、モデルをより微妙な結果に向けて導きます。
  • プロンプトと補完のペアを使用してモデルを微調整します。
  • RAG は、外部データ (ノンパラメトリック) を取得し、このデータをプロンプトに統合して、コンテキストを強化します。

ただし、最初の方法はコンテキスト サイズに関するモデルの制約に対処するため、長いドキュメントの入力が困難になり、コストが増加する可能性があります。 微調整アプローチは強力ではありますが、特に進化し続ける外部データの場合、リソースを大量に消費するため、展開の遅れやコストの増加につながります。 RAG と LLM を組み合わせることで、前述の制限に対する解決策が提供されます。

検索拡張生成

RAG は外部データ (ノンパラメトリック) を取得し、このデータを ML プロンプトに統合して、コンテキストを強化します。 ルイスら。 は 2020 年に RAG モデルを導入し、事前トレーニングされたシーケンス間モデル (パラメトリック メモリ) とニューラル リトリーバーを介してアクセスされる Wikipedia の高密度ベクトル インデックス (ノンパラメトリック メモリ) の融合として概念化しました。

RAG の動作方法は次のとおりです。

  • データソース – RAG は、ドキュメント リポジトリ、データベース、API などのさまざまなデータ ソースから取得できます。
  • データのフォーマット – ユーザーのクエリとドキュメントの両方が、関連性の比較に適した形式に変換されます。
  • 埋め込み – この比較を容易にするために、クエリとドキュメント コレクション (またはナレッジ ライブラリ) は、言語モデルを使用して数値埋め込みに変換されます。 これらの埋め込みは、テキストの概念を数値的にカプセル化します。
  • 関連性検索 – ユーザー クエリの埋め込みがドキュメント コレクションの埋め込みと比較され、埋め込み空間での類似性検索を通じて関連テキストが特定されます。
  • コンテキストの強化 – 識別された関連テキストがユーザーの元のプロンプトに追加されるため、そのコンテキストが強化されます。
  • LLM処理 – 強化されたコンテキストを使用して、プロンプトが LLM に供給され、関連する外部データが含まれるため、関連性のある正確な出力が生成されます。
  • 非同期更新 – 参照ドキュメントを最新の状態に保つために、埋め込み表現とともに参照ドキュメントを非同期的に更新できます。 これにより、将来のモデル応答が最新の情報に基づいて作成され、精度が保証されます。

基本的に、RAG は LLM にリアルタイムの関連情報を注入する動的な方法を提供し、正確かつタイムリーな出力の生成を保証します。

次の図は、LLM で RAG を使用する概念的なフローを示しています。

Build a contextual chatbot for financial services using Amazon SageMaker JumpStart, Llama 2 and Amazon OpenSearch Serverless with Vector Engine | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.

ソリューションの概要

金融サービス アプリケーション用のコンテキストに応じた質問応答チャットボットを作成するには、次の手順が必要です。

  1. SageMaker JumpStart GPT-J-6B 埋め込みモデルを使用して、 Amazon シンプル ストレージ サービス (Amazon S3) アップロードディレクトリ。
  2. 次の手順を使用して、関連するドキュメントを特定します。
    • 同じモデルを使用してユーザーのクエリの埋め込みを生成します。
    • OpenSearch Serverless とベクトル エンジン機能を使用して、埋め込みスペース内で最も関連性の高い上位 K 個のドキュメント インデックスを検索します。
    • 識別されたインデックスを使用して、対応するドキュメントを取得します。
  3. 取得したドキュメントをコンテキストとしてユーザーのプロンプトや質問と組み合わせます。 これを SageMaker LLM に転送して応答を生成します。

このプロセスを調整するために、人気のあるフレームワークである LangChain を採用しています。 LangChain は、LLM を利用したアプリケーションを強化するように特別に設計されており、さまざまな LLM にユニバーサル インターフェイスを提供します。 複数の LLM の統合を合理化し、呼び出し間のシームレスな状態の永続性を確保します。 さらに、カスタマイズ可能なプロンプト テンプレート、包括的なアプリケーション構築エージェント、検索と取得に特化したインデックスなどの機能により、開発者の効率が向上します。 より深く理解するには、を参照してください。 ラングチェーンのドキュメント.

前提条件

コンテキスト認識型チャットボットを構築するには、次の前提条件が必要です。

OpenSearch サーバーレス ベクトル エンジンのセットアップ方法については、以下を参照してください。 Amazon OpenSearch サーバーレス用のベクター エンジンの紹介、現在プレビュー中.

次のソリューションの包括的なチュートリアルについては、 GitHubレポ を参照してください Jupyterノートブック。

SageMaker JumpStart を使用して ML モデルをデプロイする

ML モデルをデプロイするには、次の手順を実行します。

  1. SageMaker JumpStart から Llama 2 LLM をデプロイします。
    from sagemaker.jumpstart.model import JumpStartModel
    llm_model = JumpStartModel(model_id = "meta-textgeneration-llama-2-7b-f")
    llm_predictor = llm_model.deploy()
    llm_endpoint_name = llm_predictor.endpoint_name

  2. GPT-J 埋め込みモデルをデプロイします。
    embeddings_model = JumpStartModel(model_id = "huggingface-textembedding-gpt-j-6b-fp16")
    embed_predictor = embeddings_model.deploy()
    embeddings_endpoint_name = embed_predictor.endpoint_name
    

データをチャンク化してドキュメント埋め込みオブジェクトを作成する

このセクションでは、データを小さなドキュメントに分割します。 チャンク化は、大きなテキストを小さなチャンクに分割する技術です。 これは、RAG モデルに対する検索クエリの関連性を最適化し、チャットボットの品質を向上させるため、重要なステップです。 チャンク サイズは、ドキュメントの種類や使用されるモデルなどの要因によって異なります。 これが段落のおおよそのサイズであるため、チャンク chunk_size=1600 が選択されています。 モデルが改良されると、コンテキスト ウィンドウのサイズが増加し、より大きなチャンク サイズが可能になります。

Job Status ページの下部にある Jupyter Notebook 完全なソリューションについては、GitHub リポジトリを参照してください。

  1. ラングチェーンを拡張する SageMakerEndpointEmbeddings クラスを使用して、(埋め込みモデルの採用の一部として) 前に作成した gpt-j-6b-fp16 SageMaker エンドポイントを使用するカスタム埋め込み関数を作成します。
    from langchain.embeddings import SagemakerEndpointEmbeddings
    from langchain.embeddings.sagemaker_endpoint import EmbeddingsContentHandler logger = logging.getLogger(__name__) # extend the SagemakerEndpointEmbeddings class from langchain to provide a custom embedding function
    class SagemakerEndpointEmbeddingsJumpStart(SagemakerEndpointEmbeddings): def embed_documents( self, texts: List[str], chunk_size: int = 1 ) → List[List[float]]: """Compute doc embeddings using a SageMaker Inference Endpoint. Args: texts: The list of texts to embed. chunk_size: The chunk size defines how many input texts will be grouped together as request. If None, will use the chunk size specified by the class. Returns: List of embeddings, one for each text. """ results = [] _chunk_size = len(texts) if chunk_size > len(texts) else chunk_size st = time.time() for i in range(0, len(texts), _chunk_size): response = self._embedding_func(texts[i : i + _chunk_size]) results.extend(response) time_taken = time.time() - st logger.info( f"got results for {len(texts)} in {time_taken}s, length of embeddings list is {len(results)}" ) print( f"got results for {len(texts)} in {time_taken}s, length of embeddings list is {len(results)}" ) return results # class for serializing/deserializing requests/responses to/from the embeddings model
    class ContentHandler(EmbeddingsContentHandler): content_type = "application/json" accepts = "application/json" def transform_input(self, prompt: str, model_kwargs={}) → bytes: input_str = json.dumps({"text_inputs": prompt, **model_kwargs}) return input_str.encode("utf-8") def transform_output(self, output: bytes) → str: response_json = json.loads(output.read().decode("utf-8")) embeddings = response_json["embedding"] if len(embeddings) == 1: return [embeddings[0]] return embeddings def create_sagemaker_embeddings_from_js_model( embeddings_endpoint_name: str, aws_region: str
    ) → SagemakerEndpointEmbeddingsJumpStart: content_handler = ContentHandler() embeddings = SagemakerEndpointEmbeddingsJumpStart( endpoint_name=embeddings_endpoint_name, region_name=aws_region, content_handler=content_handler, ) return embeddings 

  2. embeddings オブジェクトを作成し、ドキュメントの埋め込みの作成をバッチ処理します。
    embeddings = create_sagemaker_embeddings_from_js_model(embeddings_endpoint_name, aws_region)

  3. これらの埋め込みは、LangChain を使用してベクトル エンジンに保存されます。 OpenSearchVectorSearch。 これらの埋め込みは次のセクションで保存します。 OpenSearch Serverless に埋め込まれたドキュメントを保存します。 これで、チャンク化されたドキュメントを反復処理し、埋め込みを作成し、これらの埋め込みをベクトル検索コレクション内に作成された OpenSearch サーバーレス ベクトル インデックスに保存する準備が整いました。 次のコードを参照してください。
    docsearch = OpenSearchVectorSearch.from_texts(
    texts = [d.page_content for d in docs],
    embedding=embeddings,
    opensearch_url=[{'host': _aoss_host, 'port': 443}],
    http_auth=awsauth,
    timeout = 300,
    use_ssl = True,
    verify_certs = True,
    connection_class = RequestsHttpConnection,
    index_name=_aos_index
    )

書類上の質疑応答

ここまでは、大きなドキュメントを小さなドキュメントに分割し、ベクトル埋め込みを作成して、ベクトル エンジンに保存しました。 この文書データに関する質問に回答できるようになります。 データに対してインデックスを作成したため、セマンティック検索を実行できます。 このようにして、質問に答えるために必要な最も関連性の高い文書のみが、プロンプトを介して LLM に渡されます。 これにより、関連するドキュメントのみを LLM に渡すだけで時間と費用を節約できます。 ドキュメント チェーンの使用方法の詳細については、次を参照してください。 資料.

ドキュメントを使用して質問に答えるには、次の手順を実行します。

  1. LangChain で SageMaker LLM エンドポイントを使用するには、次を使用します。 langchain.llms.sagemaker_endpoint.SagemakerEndpoint、SageMaker LLM エンドポイントを抽象化します。 LangChain SageMaker 統合の次のコードに示すように、リクエストとレスポンスのペイロードの変換を実行します。 content_type に基づいて ContentHandler のコードを調整する必要がある場合があり、使用することを選択した LLM モデルの形式を受け入れることに注意してください。
    content_type = "application/json"
    accepts = "application/json"
    def transform_input(self, prompt: str, model_kwargs: dict) → bytes: payload = { "inputs": [ [ { "role": "system", "content": prompt, }, {"role": "user", "content": prompt}, ], ], "parameters": { "max_new_tokens": 1000, "top_p": 0.9, "temperature": 0.6, }, } input_str = json.dumps( payload, ) return input_str.encode("utf-8") def transform_output(self, output: bytes) → str: response_json = json.loads(output.read().decode("utf-8")) content = response_json[0]["generation"]["content"] return content content_handler = ContentHandler() sm_jumpstart_llm=SagemakerEndpoint( endpoint_name=llm_endpoint_name, region_name=aws_region, model_kwargs={"max_new_tokens": 300}, endpoint_kwargs={"CustomAttributes": "accept_eula=true"}, content_handler=content_handler, )

これで、財務書類を操作する準備が整いました。

  1. ドキュメントに関する質問をするには、次のクエリとプロンプト テンプレートを使用します。
    from langchain import PromptTemplate, SagemakerEndpoint
    from langchain.llms.sagemaker_endpoint import LLMContentHandler query = "Summarize the earnings report and also what year is the report for"
    prompt_template = """Only use context to answer the question at the end. {context} Question: {question}
    Answer:""" prompt = PromptTemplate( template=prompt_template, input_variables=["context", "question"]
    ) class ContentHandler(LLMContentHandler): content_type = "application/json" accepts = "application/json" def transform_input(self, prompt: str, model_kwargs: dict) → bytes: payload = { "inputs": [ [ { "role": "system", "content": prompt, }, {"role": "user", "content": prompt}, ], ], "parameters": { "max_new_tokens": 1000, "top_p": 0.9, "temperature": 0.6, }, } input_str = json.dumps( payload, ) return input_str.encode("utf-8") def transform_output(self, output: bytes) → str: response_json = json.loads(output.read().decode("utf-8")) content = response_json[0]["generation"]["content"] return content content_handler = ContentHandler() chain = load_qa_chain( llm=SagemakerEndpoint( endpoint_name=llm_endpoint_name, region_name=aws_region, model_kwargs={"max_new_tokens": 300}, endpoint_kwargs={"CustomAttributes": "accept_eula=true"}, content_handler=content_handler, ), prompt=prompt,
    )
    sim_docs = docsearch.similarity_search(query, include_metadata=False)
    chain({"input_documents": sim_docs, "question": query}, return_only_outputs=True)
    

掃除

将来のコストの発生を避けるために、このノートブックで作成した SageMaker 推論エンドポイントを削除してください。 これを行うには、SageMaker Studio ノートブックで次のコマンドを実行します。

# Delete LLM
llm_predictor.delete_model()
llm_predictor.delete_predictor(delete_endpoint_config=True) # Delete Embeddings Model
embed_predictor.delete_model()
embed_predictor.delete_predictor(delete_endpoint_config=True)

この例用に OpenSearch サーバーレス コレクションを作成し、不要になった場合は、OpenSearch サーバーレス コンソールから削除できます。

まとめ

この投稿では、ドメイン固有のコンテキストを LLM に提供するアプローチとして RAG を使用することについて説明しました。 SageMaker JumpStart を使用して、ベクトル データ ストアとしてベクトル エンジンを備えた Llama 2 と OpenSearch Serverless を使用する金融サービス組織向けに、RAG ベースのコンテキスト チャットボットを構築する方法を示しました。 この方法では、関連するコンテキストを動的に取得することで、Llama 2 を使用したテキスト生成を改良します。 カスタム データを持ち込み、SageMaker JumpStart でこの RAG ベースの戦略を革新できることを楽しみにしています。


著者について

Build a contextual chatbot for financial services using Amazon SageMaker JumpStart, Llama 2 and Amazon OpenSearch Serverless with Vector Engine | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.スニル・パドマナバン AWSのスタートアップソリューションアーキテクトです。 元スタートアップの創設者兼CTOとして、彼は機械学習に情熱を注いでおり、スタートアップがビジネスの成果のためにAI / MLを活用し、ML/AIソリューションを大規模に設計および展開できるよう支援することに注力しています。

Build a contextual chatbot for financial services using Amazon SageMaker JumpStart, Llama 2 and Amazon OpenSearch Serverless with Vector Engine | Amazon Web Services PlatoBlockchain Data Intelligence. Vertical Search. Ai.スレマン・パテル アマゾン ウェブ サービス (AWS) のシニア ソリューション アーキテクトであり、特に機械学習と最新化に重点を置いています。 ビジネスとテクノロジーの両方における専門知識を活用して、Suleman は、顧客が現実のビジネス上の問題に取り組むソリューションの設計と構築を支援します。 仕事に没頭していないときは、Suleman さんはアウトドアを探索したり、ドライブ旅行に出かけたり、キッチンでおいしい料理を作ったりするのが大好きです。

タイムスタンプ:

より多くの AWS機械学習