フォーム読み込み中
2024年12月27日掲載
現在、生成AIおよびRAGを使ったサービスがホットになっています。RAGは(Retrieval Augmented Generation)の略称で、生成AIを使いながら前のデータを整理し、ユーザーが自然言語による文章ベースで質問をついでに、応じて関連する文章を検索・滞在し、質問文に対する回答文を生成し放棄する技術です。このRAGは生成AI - LLMが登場するよりずっと前からメタ社による自然言語処理技術として展開されていますが、LLMの登場により大いに普及しています。
現在、Alibaba Cloudを含めPublic Cloud上でRAGによるサービスの作り方はかなり普及していますが、今回はMinIOというAWS S3と互換性のあるオブジェクトストレージが構築できる便利なオープンソースの紹介もあわせて、オブジェクトストレージを使ったシンプルなRAGアプリケーションの作り方を解説します。
生成AI - RAGアプリケーション構築フレームワークとして、オープンソースのLangChainがサポートするデータソース一覧をみてみました。その結果、Alibaba Cloudは現状MaxComputeのみサポートという状況です(2024/7/24時点)
ベンダー/クラウド名 | データベース | 分析基盤 | ストレージ | AI | ユーティリティ |
|---|---|---|---|---|---|
Google AlloyDB for PostgreSQL, Google Cloud SQL for SQL server, Google Cloud SQL for MySQL, Google Cloud SQL for PostgreSQL, Google Firestore in Datastore Mode, Google Firestore (Native Mode), Google Memorystore for Redis, Google Spanner | Google BigQuery, Google Bigtable | Google Cloud Storage Directory, Google Cloud Storage File, Google Drive | Google Speech-to-Text Audio Transcripts | Google El Carro for Oracle Workloads | |
Alibaba Cloud | Alibaba Cloud MaxCompute | ||||
Amazon | Athena | AWS S3 Directory, AWS S3 File | Amazon Textract | ||
Microsoft | Azure Blob Storage Container, Azure Blob Storage File | Azure AI Data | Azure AI Document Intelligence | ||
Tencent | Tencent COS Directory, Tencent COS File | ||||
Oracle | Oracle Autonomous Database, Oracle AI Vector Search: Document Processing | ||||
Huawei | Huawei OBS Directory, Huawei OBS File | ||||
Airtable | Airtable | ||||
AssemblyAI | AssemblyAI Audio Transcripts | ||||
AstraDB | AstraDB | ||||
ArcGIS | ArcGIS | ||||
Apify | Apify Dataset | ||||
Cube | Cube Semantic Layer | ||||
Datadog | Datadog Logs | ||||
Dropbox | Dropbox | ||||
Git | Git, GitBook, GitHub | ||||
Notion | Notion DB 1/2, Notion DB 2/2 | ||||
Rockset | Rockset | ||||
Slack | |||||
Snowflake | Snowflake | ||||
SurrealDB | SurrealDB |
Alibaba CloudでLangChainによる生成AIアプリケーション開発は難しそうですね。一方AWS S3はサポートしているようです。なので、それをカバーするために今回はAWS S3と互換性のあるオープンソースのMinIOをAlibaba Cloudに立ち上げながら、Alibaba Cloud内でS3とのRAGによる生成AIアプリケーションを構築してみます。
※補足として、Alibaba CloudはLangChainをサポートしていない、というわけではなく、バージョンによってはサポートしているものもあります。例えば今のLangChainバージョンv2.0ではAnalyticDB for PostgreSQLをサポートしていませんが、バージョンv0.1 ではAnalyticDB for PostgreSQLをサポートしています。そういう意味ではLangChainのバージョンによってサポート有無が変わるので、詳しくはLangChain公式サイトを参照してください。
MinIOはAWS S3と互換性のあるオブジェクトストレージをどこでも立ち上げることが出来るオープンソースです。その功績が評価され、MinIOはCNCF(Cloud Native Computing Foundation)ことクラウドネイティブに関連するミドルウェアのオープンソースとして登録されています。
Alibaba Cloud上でMinIOを立ち上げる方法は色々ありますが、今回はシンプルにECSこと仮想コンピューティング3台で立ち上げます。MinIOはHA構成として構築もできるので、ECS1台でも100台でも問題ないです。もちろんAlibabaCloudのFunctionComputeやContainer Service for Kubernetes (ACK)でMinIOを立ち上げることもできます。ECSでMinIOによるオブジェクトストレージを立ち上げたあと、その1つのECSにLangChain+Pythonによるアプリケーションを配置し、実行するだけです。今回はテックブログ用にクイックなDemoなので、かなり簡略化した手順となりますがご了承ください。
MinIOは Kubernetes、Linux、dockerなど様々な方法でインストールすることができます。今回はECS Ubuntu上で構築するため、 minio.debらパッケージファイルを入手し、立ち上げます。
※事前にECSのSecurity groupでPort 9000、9001を解放しておく必要があります。
SSHでログイン後、 minio.debらパッケージファイルを入手し、立ち上げます。
wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio_20240716234641.0.0_amd64.deb -O minio.deb
dpkg -i minio.deb
MinIOサービスファイルを作成します。
tee /etc/systemd/system/minio.service <<EOF
[Unit]
Description=MinIO
Documentation=https://min.io/docs/minio/linux/index.html
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
WorkingDirectory=/usr/local
User=minio-user
Group=minio-user
ProtectProc=invisible
EnvironmentFile=-/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
Restart=always
LimitNOFILE=65536
TasksMax=infinity
TimeoutStopSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
EOF
MinIOユーザーとグループを作成します。
groupadd -r minio-user
useradd -M -r -g minio-user minio-user
mkdir -p /mnt/disk{1..4}
chown minio-user:minio-user /mnt/disk{1..4}
MinIO環境ファイルを作成します。
tee /etc/default/minio <<EOF
MINIO_VOLUMES="http://10.2.0.29:9000/mnt/disk{1..4}/minio http://10.2.0.28:9000/mnt/disk{1..4}/minio http://10.2.0.27:9000/mnt/disk{1..4}/minio"
MINIO_OPTS="--console-address :9001"
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minio-secret-key-CHANGE-ME
EOF
これで導入は完了です。しかし、異なるVM間で連結できているかlsblkとmountを試したところ、その出力結果から、マウントポイントが設定されていないことが判明します。
root@iZ6wea00iajgu2rabxroi9Z:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
loop0 7:0 0 61.9M 1 loop /snap/core20/1405
loop1 7:1 0 79.9M 1 loop /snap/lxd/22923
loop3 7:3 0 38.8M 1 loop /snap/snapd/21759
loop4 7:4 0 63.9M 1 loop /snap/core20/2318
loop5 7:5 0 87M 1 loop /snap/lxd/29351
vda 252:0 0 100G 0 disk
├─vda1 252:1 0 1M 0 part
├─vda2 252:2 0 200M 0 part /boot/efi
└─vda3 252:3 0 99.8G 0 part /
root@iZ6wea00iajgu2rabxroi9Z:~#
root@iZ6wea00iajgu2rabxroi9Z:~# mount | grep /mnt
root@iZ6wea00iajgu2rabxroi9Z:~#
なので、マウントポイントの作成、設定を行います。
mkdir -p /mnt/disk{1..4}
dd if=/dev/zero of=/mnt/disk1/disk.img bs=1M count=1024
dd if=/dev/zero of=/mnt/disk2/disk.img bs=1M count=1024
dd if=/dev/zero of=/mnt/disk3/disk.img bs=1M count=1024
dd if=/dev/zero of=/mnt/disk4/disk.img bs=1M count=1024
mkfs.ext4 /mnt/disk1/disk.img sudo mkfs.ext4 /mnt/disk2/disk.img
mkfs.ext4 /mnt/disk3/disk.img sudo mkfs.ext4 /mnt/disk4/disk.img
mount -o loop /mnt/disk1/disk.img /mnt/disk1
mount -o loop /mnt/disk2/disk.img /mnt/disk2
mount -o loop /mnt/disk3/disk.img /mnt/disk3
mount -o loop /mnt/disk4/disk.img /mnt/disk4
マウントポイントの作成、設定が終われば、MinIOサービスを再起動します。
sudo systemctl daemon-reload
systemctl restart minio.service
これで、ブラウザからMinIOコンソールにアクセスで操作できるようになります。
ログイン情報はcat /etc/default/minio で見れます。
MinIO からAccess Keyを発行し、セキュリティ対策を図ることもできます。
うまくいきました。ここからMinIOと疎通テストをしてみます。
import boto3
import os
from datasets import load_dataset
s3_resource = boto3.resource(
's3',
endpoint_url='http://47.xx.xxx.244:9000',
aws_access_key_id='kFSxFDn1QFN1GxvrMK0o',
aws_secret_access_key='xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
)
s3_resource.create_bucket(Bucket="rag-service")
MinIOのObjectStorageができたら、早速RAGアプリケーションを試してみます。
今回は、huggingface の wiki ダンプ データセットを使用します。このデータセットをダウンロードし、アップロードしておきます。
# Hugging Faceのデータセットをロード
dataset = load_dataset("AhmedSSabir/Japanese-wiki-dump-sentence-dataset")
# データセットを一時的にローカル保存し、MinIOへアップロード
for split in dataset.keys():
split_dataset = dataset[split]
local_file_path = f"/tmp/{split}.jsonl"
split_dataset.to_json(local_file_path, orient='records', lines=True)
s3_resource.Bucket(bucket_name).upload_file(local_file_path, f"{split}.jsonl")
os.remove(local_file_path)
あとは以下のPythonコードにてendpoint_url、aws_access_key_id、aws_secret_access_keyを入力し実行するだけです(テックブログ用の簡易なコードなのでチューニングや最適化はしていません)
なお LangChain の Repo でS3処理Class コードには S3接続設定はそこまで厳密に求めているわけではないようです。
import openai
import chromadb
import os
import sys
from langchain_community.document_loaders import S3DirectoryLoader
from langchain.chains import ConversationalRetrievalChain, RetrievalQA
from langchain_community.chat_models import ChatOpenAI
from langchain_community.llms import OpenAI
from langchain.text_splitter import CharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain.indexes.vectorstore import VectorStoreIndexWrapper
from langchain_openai import OpenAIEmbeddings
# OpenAI APIキーの設定
os.environ["OPENAI_API_KEY"] = ""
query = sys.argv[1] if len(sys.argv) > 1 else None
# S3バケットからドキュメントをロード
s3_loader = S3DirectoryLoader(
"s3",
endpoint_url="http://47.xx.xxx.244:9000",
aws_access_key_id="kFSxFDn1QFN1GxvrMK0o",
aws_secret_access_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
docs = s3_loader.load()
splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
split_texts = splitter.split_documents(docs)
# ドキュメントのベクトル化と検索
embeddings = OpenAIEmbeddings()
vector_store = Chroma.from_documents(split_texts, embeddings)
# QAオブジェクトの作成
qa_system = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=vector_store.as_retriever())
# 会話型検索チェーンの作成
conv_chain = ConversationalRetrievalChain.from_llm(
llm=ChatOpenAI(model="gpt-3.5-turbo"),
retriever=vector_store.as_retriever(search_kwargs={"k": 1}),
)
chat_history = []
while True:
if not query:
query = input("プロンプト: ")
if query in ['quit', 'q', 'exit']:
sys.exit()
result = conv_chain({"question": query, "chat_history": chat_history})
print(result['answer'])
chat_history.append((query, result['answer']))
query = None
学生の夏休みがうらやましいですね。
本記事ではクイックにS3互換性のあるオブジェクトストレージとLangChainによるRAGサービスの構築方法を紹介しました。MinIOはどのクラウド、オンプレミスでも立ち上げることが出来ますので、気になる方は試してみてください。
Alibaba Cloudは中国国内でのクラウド利用はもちろん、日本-中国間のネットワークの不安定さの解消、中国サイバーセキュリティ法への対策など、中国進出に際する課題を解消できるパブリッククラウドサービスです。
MSP(Managed Service Provider)サービスは、お客さまのパブリッククラウドの導入から運用までをトータルでご提供するマネージドサービスです。
条件に該当するページがございません