清水理史の「イニシャルB」
NAS+ChatGPTで、共有フォルダーの文書をもとに回答するAIチャットを作る
2023年10月16日 06:00
企業などの大規模言語モデル活用例のひとつに、社内文書をもとに質問に答えるチャットAI(AIチャットボット)が、よく挙げられる。これを、一般的なNASで使えるようにしてみよう。NASの共有フォルダーに保存した社内の業務ルールや各種手続きの方法など、自社の情報のみを知識として回答してくれるAIチャットを構築できる。今回はQNAPのNASを使って実現してみた。
NASの共有フォルダーに置いた情報をデータベース化し、AIの知識とする
ChatGPTが話題になりはじめた頃から、自宅内でも実現したいと考えてきたNAS用QAチャットAIが、何とかかたちになってきた。
具体的には、以下のような構成だ。NAS上で、LangChainのGUI開発環境であるFlowise、およびベクトルデータベースのChromaDBをインストールし、共有フォルダーの文書をベクトルデータベースであるChromaに保存して、その情報をもとにOpenAIのAPIを使って会話できるようにしている。
今回は、大規模言語モデルとしてOpenAIのAPIを利用したが、完全ローカルにこだわるのであれば、前回の本コラムで紹介したAPIアクセス可能にしたELYZAを利用することで実現できる。ただし、そのためにはELYZAが動作可能なGPUを搭載したPCを別途用意しなければならないので、今回は、よりハードルが低いであろう方法として、外部の言語モデルを利用している。
構築の手間は利用するNAS次第だが、QNAPのNASはDockerの扱いが楽なので、これを利用すれば、初めてでも難しくはないだろう。
なお、先にお断りしておくが、本稿で解決する方法にはまだ欠点があり、現状ではフォルダーにファイルを追加した場合でも、チャット側にリアルタイムに追加した文書の情報を反映することができない(手動更新が必要)。このため、例えば社内規定や業務マニュアルなど、ある程度、固定されたデータを知識ベースにすることを、現時点では想定している。
また、構築方法は、2023年9月26日時点の情報をもとにしている。ソフトウェアやサービスのバージョンが変わると方法も変わる可能性もあるので、あくまでも参考情報と考えてほしい。
ChromaDBとFlowiseをNASで動かす
それでは早速、構築例を紹介していこう。
まずは必要なアプリケーションをNAS上で動かす。利用したNASは、筆者宅で古くから稼働し続けているQNAPのTS-453Aだ。
QNAPのNASには、Container Stationと呼ばれるコンテナ管理用アプリが搭載されており、これを利用するとdocker-composeでコンテナを簡単に起動できる。以下のSTEP 1-1から、ChromaDBとFlowiseを稼働させていこう。
ちなみに、同様の構成はSynologyのNAS(DS916+)でも検証した。動作は問題ないが、SynologyのNASの場合、docker-composeをSSH経由のコマンドでしか実行できない。Dockerの基本的な操作に慣れている場合は、Synologyでも問題ないだろう。
STEP 1-1:ChromaDBを稼働させる
まずは、文書をベクトルデータとして保存するChromaDBを稼働させる。Container Stationの「アプリケーション」から「作成」をクリックすると、docker-compose用のYAMLコードの入力欄が表示される。
docker-composeは、YAMLで定義された情報に基づいてコンテナを作成する機能だ。ここに以下のコードをコピーして貼り付け、アプリケーション名を「chromadb」などとしてコンテナの作成を開始する。
version: '3.9'
networks:
net:
name: chroma_net
driver: bridge
services:
server:
image: ghcr.io/chroma-core/chroma:latest
restart: always
volumes:
# Default configuration for persist_directory in chromadb/config.py
# Currently it's located in "/chroma/chroma/"
- ./chroma:/chroma/chroma/
ports:
- 8000:8000
networks:
- net
上記の例は、GitHubのchroma-core/chromaのページで公開されている「docker-compose.server.example.yml」ファイルをベースに、データベースの保存先をNASの「/Conatainer/container-station-data/application/chroma/chroma」に変更したものだ。これにより、通常のNASのバックアップなどを利用して、Chromaのデータも保護できる。
完成したら、ブラウザーで「http://NASのIPアドレス:8000/api/v1/version」にアクセスして稼働を確認しておく。
STEP 1-2:Flowiseを稼働させる
続いて、GUIでLLMアプリを構築できるFlowiseを稼働させる。同様に、Container Stationで、以下のYAMLコードを使ってアプリを作成する。これも上記と同様、GitHubのchroma-core/chromaのページで公開されている「docker/docker-compose.yml」を、NAS向けに少し書き換えたものだ。
version: '3.1'
services:
flowise:
image: flowiseai/flowise:1.3.4
restart: always
environment:
- PORT=3000
- DATABASE_PATH=/root/.flowise
- APIKEY_PATH=/root/.flowise
- SECRETKEY_PATH=/root/.flowise
- LOG_PATH=/root/.flowise/logs
ports:
- '3000:3000'
volumes:
- ./flowise:/root/.flowise
- /share/CACHEDEV1_DATA/Public/:/mnt/Public
networks:
- flowise_net
command: /bin/sh -c "sleep 3; flowise start"
networks:
flowise_net:
name: chroma_net
このコードのポイントは3点ある。
1つ目は、「image: flowiseai/flowise:1.3.4」でバージョンを1.3.4に固定している点だ。本稿執筆時点では、1.3.4でないとChromaDBとの接続でエラーが発生してしまう。Githubの修正履歴などを確認し、修正されているようであれば「image: flowiseai/flowise」と「:」以降を削除すれば最新版で利用できる可能性もある。
2つ目はボリュームのマウント先だ。上記コードの「volumes:」の部分で、NAS上の共有フォルダーとコンテナ内部のディレクトリを対応付けしている。
具体的は、2行あるうちの2行目「- /share/CACHEDEV1_DATA/Public/:/mnt/Public」によって、NASの「Public」共有フォルダー(標準で作成済み)を指定している。大規模言語モデルの知識となる文書は、このフォルダー配下に保存することになるので、別の共有フォルダーを利用したい場合は、この部分を書き換えておく必要がある。
3つ目はネットワークの設定だ。FlowiseからChromaDBにアクセスできるようにするために、ChromaDBのコンテナ作成時に指定したネットワーク名でFlowiseもネットワーク接続するように構成する。
FlowiseでQA用フローを作成する
ChromaDBとFlowiseが稼働したら、ブラウザーで「http://192.168.50.171:3000/」にアクセスする。Flowiseが起動するので、「Add new」から以下のようなフローを作成する。あらためて、STEP 2-1から進めていこう。
STEP 2-2:ChatOpenAIを配置する
「Chat Models」の「ChatOpenAI」を配置し、コネクタをRetrieval QA Chainの「Language Model」につなぐ。このノードでOpenAIのAPI経由でgpt-3.5-turboを利用する。つないだら、「Connect Credential」からOpenAIのAPIキーを登録しておく。
STEP 2-3:Chroma Upsert Documentを配置する
「Vector Stores」から「Chroma Upsert Document」を配置し、Retrieval QA Chainの「Vector Store Retriever」につなぐ。これにより、ChromaDBにデータが登録される。つないだら、「Collection Name」に「docqa」などのデータベースに付ける任意の名前を設定し、「Chroma URL」に「http://NASのIPアドレス:8000」を登録しておく。
STEP 2-4:OpenAI Embeddingsを配置する
「Embeddings」から「OpenAI Embeddings」を配置し、コネクタを「Chroma Upsert Document」の「Embeddings」につなぐ。OpenAIのモデルを使って文書をベクトル化する。つないだら「Connect Credential」で2で作成したOpenAIのAPIキーを選択しておく。
STEP 2-5: Folder with Filesを配置する
「Document Loaders」から「Folder with Files」を配置し、コネクタを「Chroma Upsert Document」の「Document」につなぐ。ここで指定したフォルダーからファイルを読み込む。つないだら、「Folder Path」に「/mnt/Public/DOC」など、FlowiseのYAMLで指定したコンテナ側のフォルダー配下を指定する。
STEP 2-6:Recursive Character Text Splitterを配置する
「Text Splitters」から「Recursive Character Text Splitter」を配置し、コネクタを「Folder with Files」につなぐ。これにより、文書が一定サイズに分割されてベクトル化される。つないだら「Chunk Overlap」を「100」などに設定し、分割されても前後関係を保てるようにしておく。
ここまでが全て完了したら、フローに名前を付けて保存しておく。右上の「Chat」ボタンをクリックすると、実際にフローの動作を検証できるので、保存先の文書に記載されている内容についてチャットで質問し、回答されるかどうかを確認しておこう。
ウェブページに埋め込む
フローが完成したら、このフローを利用するためのHTMLコードを取得して、ウェブページに埋め込む。
Flowiseでフローを開いた状態で、右上の「</>」をクリックすると、このフローにアクセスするためのコードが表示される。さまざまな方法が用意されているが、今回は「Embed」の「Popup Html」を利用する。表示されたコードをコピーしておこう。
最後に、コピーしたコードをウェブページに埋め込む。ウェブページは既存のものがあれば、それを利用してかまわないが、今回はQNAPのNASに搭載されているウェブサーバー機能を利用した。コントロールパネルでウェブサーバーを有効化後、「Web」フォルダーを開き、適当なindex.htmlファイルを作成し、そこにコピーしたコードを貼り付ければいい。貼り付ける場所は「</body>」タグの直前などにするといいだろう。
これで、「http://NASのIPアドレス」にアクセスすれば、ウェブページの右下にチャット用のボタンが追加される。ここから、指定したフォルダーのドキュメントに対してチャットが可能になる。
やっていることはシンプル
以上、QNAPのNASを利用して、共有フォルダーに保存されている文書に対してのQAができるチャットAIを実装した。
手順が多く見えるが、やっていることはDockerを使ってChromaDBとFlowiseを起動して、簡単なフローを作成し、ウェブページに埋め込むだけだ。
これを応用すれば、企業が公開しているウェブサーバーや社内向けのイントラネットなどで、同様のチャットAIを簡単に実装できる。手を動かし始めれば意外とスムーズなので、Container Stationが動作するQNAPのNASがある場合は試してみることをお勧めする。