OSS版EmbeddingモデルをRAG型社内チャットボットで使う

背景や目的


RAG(Retrieval-Augmented Generation)システムでは、Embeddingモデルが必要です。
性能やコストの観点から「有利であればOSSモデルを使うのもアリでは?」と考え、以前の記事で良さそうなモデルを選び試してみました。(→OSS版EmbeddingモデルをAWSで試用した例)
その結果が意外と良く、今回はそのOSSモデルを本番のRAG型チャットボットシステムに組み込んでみました。
本記事では、そのAPI化した部分等の手順も含めて具体的にご紹介します。RAG構築の一例としてご参考になれば幸いです。

実現したい事


アプリとしては、AI社内チャットボットです。

社内情報をRAGで回答させるチャットボット画面を提供します。

アーキテクチャ図としては以下の通りです。

上の赤枠部を中心に紹介します。

構築手順サマリー


手順のサマリーとしては以下の通りです。

1.VPC構築
2.S3にEmbeddingモデル一式を配置
3.コンテナ環境の作成
4.API用のapp.pyを作成 ★今回の話題★
5.コンテナイメージ作成とECRに登録
6.コンテナをLambda関数にセット

順番に紹介してゆきます。

構築1)VPC構築


セキュリティー対応としてVPCの設定をします。メインVPCとサブネットを定義し、それらにLambda関数が属するようなネットワーク設定をします。

手順は以前の記事(→RAG型社内チャットボットのVPC構築例)にありますので、必要な場合はそちらを参照してください。

構築2)S3にEmbeddingモデル一式を配置


OSS版EmbeddingモデルをHugging Faceからダウンロードし、AWS上のS3へアップします。
実際にはモデルはGluCoSEを使用しました。

手順は以前の記事(→OSS版EmbeddingモデルをAWSで試用した例)の「AWSで構築:モデルをS3に設置」内にあります。必要な場合はそちらを参照してください。

構築3)コンテナ環境の作成


ベクトル生成処理用のコンテナイメージを作成するために、ビルド環境を準備します。
dockerをインストールして使えるようにしておきます。

手順は以前の記事(→OSS版EmbeddingモデルをAWSで試用した例)の「AWSで構築:コンテナ環境の作成」にあります。必要な場合はそちらを参照してください。

構築4)API用のapp.pyを作成


実際のベクトル生成処理が下記のコードです。app.pyとして保存します。

app.py (API化版)
import json
from sentence_transformers import SentenceTransformer
import boto3
import os

bucket_name = "ctcrag-embed-model" # S3バケット名
model_prefix = "GLuCoSE-base-ja-v2-model"

def lambda_handler(event, context):
  # Lambdaの一時フォルダにダウンロード
    local_model_dir = "/tmp/model/"
    snapshot_dir = os.path.join(local_model_dir, model_prefix)
    os.makedirs(local_model_dir, exist_ok=True)
    # S3からモデル全体をコピー
    s3_client = boto3.client("s3")
    if not os.path.exists(snapshot_dir):
        for obj in s3_client.list_objects_v2(Bucket=bucket_name, Prefix=model_prefix)["Contents"]:
            download_path = os.path.join(local_model_dir, obj["Key"])
            os.makedirs(os.path.dirname(download_path), exist_ok=True)
            s3_client.download_file(bucket_name, obj["Key"], download_path)
    # モデルのロード        
    model = SentenceTransformer(snapshot_dir)

    # API化部分
    try:
        body = json.loads(event["body"])
        sentences = body.get("sentences", [])
        if not isinstance(sentences, list) or not all(isinstance(s, str) for s in sentences):
            raise ValueError
    except (KeyError, ValueError):
        return {
            "statusCode": 400,
            "body": json.dumps({"error": "Invalid input. Provide a list of strings."})
        }

    # ベクター値作成
    embeddings = model.encode(sentences, convert_to_tensor=True).tolist()
    return {
        "statusCode": 200,
        "body": json.dumps({"embeddings": embeddings})
    }

ここでは、S3からGluCoSEをダウンロードしてロードする処理と、受け取った文章リストに対してベクトル値を生成しAPIとして返す処理の、2つの機能を提供しています。

これで、他のLambda関数などから呼び出してベクトルを生成・取得できるAPIとして利用可能になりました。

構築5)コンテナイメージ作成とECRに登録


先ほど作成したapp.pyを含むコンテナイメージをローカルでビルドし、AWS上のECRリポジトリにプッシュします。

その手順は以前の記事(→OSS版EmbeddingモデルをAWSで試用した例)「AWSで構築:コンテナイメージ作成とECR登録」にあるので、必要に応じてそちらを参照してください。

構築6)コンテナをLambda関数にセット


ECRのコンテナイメージURIを指定したLambda関数を作成します。動作させるためには、設定値(メモリ、タイムアウト、等)の調整も必要です。

手順は以前の記事(→OSS版EmbeddingモデルをAWSで試用した例)「AWSで構築:コンテナをLambdaにセット」内にあります。参考にしてください。

試用してみましょう!


本番システムでは、このAPIを他のLambda関数から呼び出していますが、ここではColab上でセルの実行をしてみました。結果は以下のとおりです。

モデルに入力文を与えて、その結果のベクトル値が生成されました。OKです。

最後に、性能について少し紹介します。
以下は、チャットボットでベクトルデータベース検索がされた時の結果です。チャットボットは今回のAPIを使用して開発しています。

質問文検索結果
サクラエディタをインストールしたいです。       1. ID: F64, Score: 0.6876
Doc: 以下は、「ソフトウェアインストール時」に関するルール情報です。 以下に含まれるソフトウェアをインストールしたい。 Skype for Business,SKYSEA Client View,サクラエディタ…

2. ID: F63, Score: 0.6752
Doc: 以下は、「ソフトウェアインストール時」に関するルール情報です。 以下に含まれるソフトウェアをインストールしたい。 NginX,nkf,Node.jp,Node.js,NoEditor,Nomad,N…

3. ID: F62, Score: 0.6737
Doc: 以下は、「ソフトウェアインストール時」に関するルール情報です。 以下に含まれるソフトウェアをインストールしたい。 IM-BPM for Accel Platform,indent-rainbow f…

「インストール」「サクラエディタ」を含んだ質問をし、ソフト名まで一致したデータの方が1位になっています(Scoreは類似度です)。ソフト名以外が全く同じ内容のデータをいくつかセットしてあり、それらは2位、3位、となりました。
差が小さくても期待したデータが上位になっている例であり、今後も色々と活用できそうです。

まとめ


OSS版EmbeddingモデルをAWS上に設置し、APIとして利用可能な形に整えました。

本編で記載しませんでしたが、ベクトルデータベースを作る時に次元数には気をつけてください。今回のモデルは768でした。

本番用でもOSS版モデルでの検索が十分利用できる事がわかりました。良かったです。
ಲೇಖನದಲ್ಲಿರುವ ಮಾಹಿತಿಯು ಸಹಾಯಕವಾಗಿದೆ ಎಂದು ನಾನು ಭಾವಿಸುತ್ತೇನೆ.
(記事内の情報がお役に立てば幸いです)

ご連絡フォーム


フィードバックを是非お願いします。
本記事の方法での問題点や、よりよい方法のアイデアを頂けると大変助かります。

・この記事に関して

・その他のご連絡

DevAIsをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む