目次
はじめに
こんにちは!
株式会社エクス、アドバンスドテクノロジー部所属のクスノキです!
この会社に入社して丸二年が経ちました。お陰さまで、社内の様々な方と関わりを持つことができ、ようやく会社に馴染めたかなぁ…とか思ってます。
最近は AI 分野の進化が凄まじいので、それを追いかけるのに精一杯です。例えば、OpenAI が GPT-4 Turbo や GPT-4 Turbo with vision を発表したかと思えば、Google が Gemini を発表したり…と、生成 AI の激しい競争が続いていますね。そんな世の中の変化もありますが、このブログでのんびりと役に立つ情報を提供していけたらと思っていますので、引き続きよろしくお願いします!
さて本編
余談はここまでにして、今回の本題に参りましょう。
前回の RAG 解説編では、言語モデルを Fine-tuning する方法と RAG を使用する方法のメリット、デメリットについてそれぞれ紹介しました。特に、RAG は下記のようなメリットがあることを紹介しました。
- 更新される頻度の多いデータに対応できる
- クローズドな情報が外部に漏れない
- GPU リソースなどの高額なマシンを必要としない
今回は、RAG の仕組みを構築するために、環境構築時に使用する dockerfile の設定などについて、紹介していきたいと思います!!!
なお、前回の RAG 解説編を読んでいなくても理解できる内容にはなっていますが、読むとより分かりやすい内容になっていますので、そちらも是非読んでみてください!!!(そもそも RAG 忘れたよ!という方も一読いただけるとありがたいです!)
RAG の環境構築
では、実際に RAG の仕組みを構築していきます。今回は、下記のような構成にしてみました。
フロントエンド
Slack API を使用していますので、詳しくはこちらの URL をご参照ください。また、開発用のフレームワークとして、Slack アプリ専用のフレームワークである Bolt を使用しています。クスノキは、Web アプリケーションの開発の経験がそんなに多くないですが、簡単にイベント通知などを実装できるとのことで、こちらを採用しました。
バックエンド
ローカル環境にて、実行用の docker container を立てています。また、docker イメージには、python:3.11-slim-bookworm をベースに langchain というライブラリを使用しています。
langchain は LLM を使ったアプリケーションを簡単に作成できるように設計されたフレームワークで、python や JavaScript で使用することができます。langchain は言語モデルの呼び出しにも利用することができ、OpenAI の GPT や Google Cloud の Vertex AI PaLM API などの様々な API を利用することができます。他にも本当に多くのサービスと連携するための仕組みが用意されているので、是非ご確認ください。
データベース
Qdrant というベクトルデータベースを使用しています。このサービスはベクトルや文章データを保存する機能の他、ベクトル検索を高速に実行するアルゴリズムを提供するサービスです。
Qdrant はクラウドサービスでも提供されており、こちらで料金の計算をすることができます。蛇足ですが、1536 次元のベクトルデータを 10 万件保存し、3 つのレプリケーションを作成してもたった 8.54 ドルなので、運用環境においてもかなりお手頃な値段かなと思います。
更に、公式の Docker イメージも用意されています。つまり、
- 開発環境を Docker で構築
- 運用環境をクラウドサービスで構築
なんてことも可能です。今回は、デモ的に使用しているだけなので、Qdrant の公式コンテナを用意したいと思います。
LLM
Google が提供している Vertex AI の PaLM 2 for Text の text-bison@001 を使用しています。他に使われているLLMとして、OpenAI が提供している GPT-4 や GPT-3.5turbo が広く知られており、いずれも従量課金制です。
今回 PaLM 2 for Text を使用した理由は、OpenAI はトークン単位での従量課金なのに対し、VertexAI は文字数単位での従量課金だからです。今回は、日本語でのプロンプトを用いる予定ですので、料金的に有利な VertexAI を使用しました。
Embedding Model
前回の概要説明編でも説明したように、RAG の仕組みを構築するにはチャンクのベクトル埋め込み表現を取得する必要があります。日本語に対応したベクトル埋め込みモデルは様々ありますが、今回は Hugging Face にある oshizo/sbert-jsnli-luke-japanese-base-lite というモデルを使用したいと思います。もし他のベクトル埋め込みモデルに興味があれば、こちらが参考になると思いますので、よろしければ確認してみてください。
ドキュメント
今回の RAG を用いた Chat Bot で答えてほしいドキュメントとして、弊社の社内規定を利用することにしました。pdf 形式のファイルで合計 49 個あります。社内規定なので詳しくはお教えできませんが、図や表はあまり使われておらず、文章が淡々と書かれているドキュメントです。(恐らく、皆さんが各会社で提供されている社内規定文章とそれほど大きくは違わないかと思います。)弊社の社内規定を利用した理由としては、図や表はチャンクに切り分けることが難しいため、RAG の仕組み的には不向きなためです。
以上の内容をまとめたのが、下記のような図になります。(大雑把な図でごめんなさい…)
![RAGのアーキテクチャ図](https://www.xeex-ti.jp/rndblog/wp-content/uploads/2023/10/image-2-1024x708.png)
環境準備
上記の内容を元に、環境構築をしていきましょう。
フォルダ構成
まずは全体のフォルダ構成です。今回は docker コンテナを用いて環境構築を行うため、下記のようになりました。app の main.py に実際の処理を記述して実行するイメージです。
├─app_rag_test
│ ├─Dockerfile
│ ├─requirements.txt
│ └─app
│ └─main.py
├─.env
└─docker-compose.yml
Dockerfile
次に Dockerfile の紹介です。おまじないのようなコードを使用していますので、一部の人には馴染みのあるコードかと思います。
FROM python:3.11-slim-bookworm as builder
COPY requirements.txt /tmp
WORKDIR /tmp
# install packages
RUN apt-get update && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# pip install (python library)
RUN pip3 install --no-cache-dir -U pip setuptools wheel && \
pip3 install --no-cache-dir -r requirements.txt
WORKDIR /app
CMD ["python", "main.py"]
requirement.txt
requirement.txt は python で取得したいライブラリの一式を記述するテキストファイルのことです。
- Google Cloud の Vertex AI を使用するための google-cloud-aiplatform
- slack API を使用するための slack_bolt
- Qdrant を使用するための qdrant-client
などを取得しています。
accelerate==0.23.0
bitsandbytes==0.41.1
google-cloud-aiplatform==1.34.0
langchain==0.0.309
pandas==2.1.1
slack_bolt==1.18.0
sentence_transformers==2.2.2
transformers==4.34.0
tiktoken==0.5.1
qdrant-client==1.5.0
unstructured[pdf]==0.10.18
docker-compose.yml
docker-compose.yml は docker compose コマンドで実行される、コンテナの構築方法の定義を記述したファイルです。app_rag_test: 以下には RAG の実行環境を構築するための定義が記述されています。
後半に書かれている db: 以下には、Qdrant の実行環境を構築するための定義が記述されています。このように docker-compose.yml を記述することによって、複数のコンテナやその関係を構築することが可能です。
services:
app_rag_test:
image: app_rag_test
container_name: app_rag_test
env_file: ./.env
environment:
- SLACK_APP_TOKEN
- SLACK_BOT_TOKEN
- NVIDIA_VISIBLE_DEVICES
- NVIDIA_DRIVER_CAPABILITIES
- CUDA_MODULE_LOADING
- APPDATA = ${APPDATA}
- HOME
- GOOGLE_APPLICATION_CREDENTIALS
- MODEL_PATH
- MODEL_NAME
build:
context: ./app_rag_test
dockerfile: Dockerfile
volumes:
- type: bind
source: ./app_rag_test/app
target: /app
- type: bind
source: ./common
target: /app/common
- type: bind
source: ${APPDATA}/gcloud
target: ${HOME}/.config/gcloud
- type: volume
source: model
target: ${MODEL_PATH}
ports:
- "8000:8000"
depends_on:
- db
networks:
rag:
ipv4_address: 172.20.0.3
deploy:
resources:
reservations:
devices:
- driver: nvidia
capabilities: [gpu]
db:
image: qdrant/qdrant:v1.5.1
container_name: qdrant
ports:
- "6333:6333"
- "6334:6334"
networks:
rag:
ipv4_address: 172.20.0.2
networks:
rag:
name: rag
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
.env
env ファイルには環境変数を設定します。今回の例において
- GOOGLE_APPLICATION_CREDENTIALS
- SLACK_BOT_TOKEN
- SLACK_APP_TOKEN
には、機微な情報を設定する必要があります。外部に漏れてしまうと悪用されてしまう可能性がありますので、各自扱いには十分ご注意ください。
HOME = /home
MODEL_PATH = /app/model
MODEL_NAME = oshizo/sbert-jsnli-luke-japanese-base-lite
SLACK_APP_TOKEN = "[Your App-Level Token]"
SLACK_BOT_TOKEN = "[Your Bot User OAuth Token]"
NVIDIA_VISIBLE_DEVICES = all
NVIDIA_DRIVER_CAPABILITIES = utility,compute
CUDA_MODULE_LOADING = LAZY
GOOGLE_APPLICATION_CREDENTIALS = "[Your service account key].json"
GOOGLE_APPLICATION_CREDENTIALS には、Google Cloud サービスアカウントのキー情報が書かれた json ファイルの保存先を記述します。今回はデモ的な環境構築のため、サービスアカウントキーをダウンロードする方法を用いますが、Google Cloud では Workload Identity 連携を使用することが推奨されています。もし、セキュリティの観点からサービスアカウントキーをダウンロードする方法が使用したくない場合、Workload Identity 連携を考慮に入れてみてください。
Google Cloud
今回の RAG の開発環境構築において、Google Cloud を使用するためには下記の設定が必要になります。しかし、今回のテーマの主旨と少し離れてきますので今回は省略したいと思います。(後々、RAG の外伝編としてお伝えできればと思っています。)
- サービスアカウントの作成
- Vertex AI API の有効化
Slack API
slack Bot の作成方法も、今回のテーマの主旨と少し離れてきますので今回は省略したいと思います。(後々、RAG の外伝編としてお伝えできればと思っています。)
終わりに
ブログの文章が長くなってきたので、今回はここまでにしたいと思います。思ったよりブログに書きたいことが多く、中々 RAG の動作をお見せすることができず申し訳ないです…。最終的には必ずお見せできるようにしたいと思います!!!
先に記載した通り、次回は python を使って実装していきたいと思います。次回も是非読んでいただければ幸いです!
次回はこちら
後日投稿予定…
コメント
Comments are closed.