LlamaIndexのVectorStore(ChromaDB、Faiss、Qdrant)

LlamaIndexのVectorStore(ChromaDB、Faiss、Qdrant)まとめ

この記事では、LlamaIndexでベクトル検索を行うVectorStoreについて解説しています。

ChromaDB、Faiss、Qdrantといったオープンソースのベクトルストアの違いや使用方法について詳しく説明しています。

ざっくり言うと

  • LlamaIndexのVectorStoreとは
  • ChromaDB、Faiss、Qdrantの違いが分かる
  • ベクトルストアをローカルで構築する方法を解説

12/25開催の無料ウェビナー!

目次

LlamaIndexのVectorStoreとは

見出し画像

LlamaIndexのベクトルストアは、RAGにおいてベクトル検索を活用した効率的な類似性検索を提供します。

これにより、膨大なデータの中から関連性の高い情報を素早く見つけ出すことが可能です。

LlamaIndexは、以下のようなオープンソースのベクトルストアに対応しています。

  • ChromaDB
  • Faiss
  • Qdrant

ChromaDB・Faiss・Qdrantの違い

見出し画像

ChromaDB

ChromaDBは、RAG 向けのオープンソース埋め込みデータベースであり、LLMアプリケーションの開発を簡素化するために設計されています。特に音声関連のユースケースで人気があります。

メリット・デメリット

メリット

  • 柔軟性とスケーラビリティが強みで、クラウド環境やオンプレミスでのデプロイが可能です。
  • 複数のデータ形式やタイプに対応でき、幅広いアプリケーションに適しています。
  • ローカルでの運用が可能で、クラウドやオンプレミスのどちらでも利用可能です。

デメリット

  • 他のデータベースと比べると、特定のケースでパフォーマンスの差が生じることがある。

Faiss

FaissDBは、類似度検索やクラスタリングに特化したオープンソースのベクトル検索ライブラリです。

Facebook AI Researchによって開発され、非常に高速な検索性能が特徴です。

メリット・デメリット

メリット

  • 大規模なデータセットに対して高速な検索が可能で、特に高効率な類似度検索やクラスタリングが必要なタスクに適しています。
  • 研究やプロダクション環境で使われることが多く、さまざまなベクトルベースのアプリケーションで利用されています。

デメリット

  • セットアップやデプロイがやや複雑で、他のベクトルストアと比べて利用には技術的な知識が求められる。
  • ローカルでの運用が前提となっており、クラウドでの使用に関しては他の選択肢と比較して制約がある

Qdrant

Qdrantは、スケーラブルなベクトルデータベースで、ハイブリッド検索(ベクトルとスパースデータを組み合わせた検索)をサポートしています。特に類似検索に強みがあります。

クライアントとサーバーサイドの両方で利用でき、ローカルクラウドやでの展開も可能です。

メリット・デメリット

メリット

  • ハイブリッド検索機能をサポートしており、複雑な検索クエリにも対応可能です。
  • スケーラビリティが高く、大規模なデータセットにも対応でき、クラウドやローカルの両方で運用可能です。
  • APIを通じて簡単に利用でき、モダンなベクトルデータベースの一つとして注目されています。

デメリット

  • ハイブリッド検索が有効でない場合や、特定のユースケースでは他のデータベースに対してパフォーマンスが劣る場合があります。

LlamaIndex VectorStoreの実行環境

見出し画像

この記事で用意した実行環境は以下のとおりです。

  • GPU:NVIDIA A100 80GB
  • GPUメモリ(VRAM):80GB
  • OS :Ubuntu 22.04
  • Docker

Dockerで環境構築

Dockerを使用してLlamaIndexの環境構築をします

Dockerの使い方は以下の記事をご覧ください。

STEP
Dockerfileの作成

Ubuntuのコマンドラインで、Dockerfileを作成します。

mkdir llamaindex_vectorstore
cd llamaindex_vectorstore
nano Dockerfile

Dockerfileに以下の記述を貼り付けます。

# ベースイメージ(CUDA)の指定
FROM nvidia/cuda:12.1.0-cudnn8-devel-ubuntu22.04

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y python3-pip python3-venv git nano curl

RUN curl -fsSL https://ollama.com/install.sh | sh

# 作業ディレクトリを設定
WORKDIR /app

# アプリケーションコードをコピー
COPY . /app

# Python仮想環境の作成
RUN python3 -m venv /app/.venv

# 仮想環境をアクティベートするコマンドを.bashrcに追加
RUN echo "source /app/.venv/bin/activate" >> /root/.bashrc

# JupyterLabのインストール
RUN /app/.venv/bin/pip install Jupyter jupyterlab

# LlamaIndex関連のインストール
RUN /app/.venv/bin/pip install ollama llama-index llama-index-core llama-index-llms-ollama llama-index-embeddings-huggingface llama-index-readers-web llama-index-readers-file chromadb llama-index-vector-stores-chroma llama-index-vector-stores-faiss faiss-gpu llama-index-vector-stores-qdrant qdrant_client

# コンテナの起動時にbashを実行
CMD ["/bin/bash"]

[Ctrl + S]キーで変更内容を保存し、[Ctrl + X]キーで編集モードから抜けます。

コマンドの説明

FROM nvidia/cuda:12.1.0-cudnn8-devel-ubuntu22.04

CUDA12.1のベースイメージを指定しています。

RUN apt-get update && apt-get install -y python3-pip python3-venv git nano curl

必要なパッケージをインストールしています。

RUN curl -fsSL https://ollama.com/install.sh | sh

Linux版のOllamaをインストールしています。PythonでOllamaを動かす際にもLinux版Ollamaのインストールが必要になりますのでご注意ください。

RUN /app/.venv/bin/pip install Jupyter jupyterlab

JupyterLabをインストールしています。

RUN /app/.venv/bin/pip install ollama llama-index llama-index-core llama-index-readers-file llama-index-llms-ollama llama-index-embeddings-huggingface llama-index-readers-web

LlamaIndexとOllama関連のパッケージをインストールしています。

LLMはOllamaのライブラリを使って動かしますので、PyTorchやTransformerは別途インストール不要です。

STEP
docker-compose.ymlファイルの作成

docker-compose.ymlでDockerコンテナの設定をします。

docker-compose.ymlのYAMLファイルを作成して開きます。

nano docker-compose.yml

以下のコードをコピーして、YAMLファイルに貼り付けます。

services:
  llamaindex_vectorstore:
    build:
      context: .
      dockerfile: Dockerfile
    image: llamaindex_vectorstore
    runtime: nvidia
    container_name: llamaindex_vectorstore
    ports:
      - "8888:8888"
    volumes:
      - .:/app/llamaindex_vectorstore
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities: [gpu]
    command: >
      bash -c '/usr/local/bin/ollama serve & /app/.venv/bin/jupyter lab --ip="*" --port=8888 --NotebookApp.token="" --NotebookApp.password="" --no-browser --allow-root'

[Ctrl + S]キーで変更内容を保存し、[Ctrl + X]キーで編集モードから抜けます。

コマンドの説明

bash -c ‘/usr/local/bin/ollama serve & /app/.venv/bin/jupyter lab –ip=”*” –port=8888 –NotebookApp.token=”” –NotebookApp.password=”” –no-browser –allow-root’

bash -c '/usr/local/bin/ollama serve

Ollama Serverを起動しています。PythonのOllamaを使用する際に、Ollama Serverを起動しておく必要がありますので、ご注意ください。

& /app/.venv/bin/jupyter lab --ip="*" --port=8888 --NotebookApp.token="" --NotebookApp.password="" --no-browser --allow-root'

JupyterLabを8888番ポートで起動しています。

STEP
Dockerコンテナを起動

Dockerfileからビルドしてコンテナを起動します。   

docker compose up

 

Dockerの起動後にブラウザの検索窓に”localhost:8888″を入力すると、Jupyter Labをブラウザで表示できます。

localhost:8888

事前準備

見出し画像

Dockerコンテナで起動したJupyter Lab上でRAGの実装をします。

STEP
LLMの設定

日本語LLMモデル「Llama-3-ELYZA-JP-8B-q4_k_m.gguf」をダウンロードします。

!curl -L -o Llama-3-ELYZA-JP-8B-q4_k_m.gguf "https://huggingface.co/elyza/Llama-3-ELYZA-JP-8B-GGUF/resolve/main/Llama-3-ELYZA-JP-8B-q4_k_m.gguf?download=true"

Llama-3-ELYZA-JPについては、別記事で詳しく解説しています。

LLMの実行にはOllamaを使用します。

LLMのモデルがOllama使えるようにプロンプトテンプレートを指定して、モデルを作成します。

import ollama
from llama_index.core import Settings
from llama_index.llms.ollama import Ollama

modelfile='''
FROM ./Llama-3-ELYZA-JP-8B-q4_k_m.gguf
TEMPLATE """{{ if .System }}<|start_header_id|>system<|end_header_id|>

{{ .System }}<|eot_id|>{{ end }}{{ if .Prompt }}<|start_header_id|>user<|end_header_id|>

{{ .Prompt }}<|eot_id|>{{ end }}<|start_header_id|>assistant<|end_header_id|>

{{ .Response }}<|eot_id|>"""
PARAMETER stop "<|start_header_id|>"
PARAMETER stop "<|end_header_id|>"
PARAMETER stop "<|eot_id|>"
PARAMETER stop "<|reserved_special_token"
'''

ollama.create(model='elyza8b', modelfile=modelfile)
Settings.llm = Ollama(model="elyza8b", request_timeout=360.0)
コードの説明

FROM ./Llama-3-ELYZA-JP-8B-q4_k_m.gguf

ダウンロードしたモデルのパスが入ります。

TEMPLATE “””{{ if .System }}<|start_header_id|>system<|end_header_id|>…

モデルで使用するプロンプトテンプレートが入ります。

ollama.create(model=’elyza8b’, modelfile=modelfile)

モデルとプロンプトテンプレートを使ってOllama用のモデルを作成します。modelにはOllamaで呼び出す際に使用する名前をつけられます。

Settings.llm = Ollama(model=”elyza8b”, request_timeout=360.0)

Settings.llm は、LlamaIndexにおけるLLMをグローバルに設定しています。LlamaIndexでLLMを使用する際に、自動的にグローバルに設定したLLMが使用されます。

Ollama(model="elyza8b", request_timeout=360.0)

Ollamaのモデルを指定しています。またリクエストのタイムアウト時間を360秒に設定しています。

Ollamaの詳しい使い方は、別の記事で解説しています。

STEP
埋め込みモデルの設定

テキストをベクトル表現に変換する埋め込みモデルを読み込みます。

日本語性能が高く、無料で使える埋め込みモデル「intfloat/multilingual-e5-large」を指定しています。

from llama_index.embeddings.huggingface import HuggingFaceEmbedding

Settings.embed_model = HuggingFaceEmbedding(model_name="intfloat/multilingual-e5-large")
コードの説明

Settings.embed_model

埋め込みモデルをグローバルに設定しています。LlamaIndexでインデックス作成時に埋め込みモデルが自動的に使用されます。

STEP
Wikipediaからテキストを抽出

Wikipediaからテキストデータを抽出して、読み込みます。

Wikipediaの『宮部みゆきの小説』に関するページを指定しています。

from llama_index.readers.web import SimpleWebPageReader
documents = SimpleWebPageReader(html_to_text=True).load_data(
    ["https://ja.wikipedia.org/wiki/%E7%81%AB%E8%BB%8A_(%E5%B0%8F%E8%AA%AC)",
    "https://ja.wikipedia.org/wiki/%E7%90%86%E7%94%B1_(%E5%B0%8F%E8%AA%AC)",
    "https://ja.wikipedia.org/wiki/%E5%90%8D%E3%82%82%E3%81%AA%E3%81%8D%E6%AF%92",
    "https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%AD%E3%83%A2%E3%83%B3%E3%81%AE%E5%81%BD%E8%A8%BC"]
)
コードの説明

SimpleWebPageReader(html_to_text=True).load_data()

指定したWebページから取得したHTMLデータをテキスト形式で読み込みます。

STEP
テキストをチャンクに分割

読み込んだデータをチャンクに分割し、各チャンクをノードとして処理します。

ノードは効率的な検索やクエリ処理をサポートするため、メタデータや関係情報を含む単位です。

from llama_index.core.node_parser import TokenTextSplitter

splitter = TokenTextSplitter(
    chunk_size=1000,
    chunk_overlap=100,
    separator=" ",
)
nodes = splitter.get_nodes_from_documents(documents)
nodes[10:13]
コードの説明

splitter = TokenTextSplitter(…

  • chunk_size=1000: 1つのチャンクに含まれるトークンの最大数を1000トークンに設定しています。これにより、テキストが1000トークンずつ分割されます。
  • chunk_overlap=100: 隣接するチャンク間で100トークンの重複が設定されています。これにより、文脈の連続性を保つことができ、モデルがより意味を理解しやすくなります。
  • separator=" ": トークンを分割する際の区切り文字として、スペース(" ")を使用しています。これは、一般的に単語の区切りを意味します。

nodes = splitter.get_nodes_from_documents(documents)

指定したdocumentsをトークン単位で分割し、それぞれをノードに変換します。ノードはテキストの一部分を保持し、後でモデルに入力するためのチャンクとなります。

確認のため、分割したノードを3つ表示しています。

[TextNode(id_='20bcf4cd-92fc-42a8-9757-f5cbd6d4777c', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={<NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='https://ja.wikipedia.org/wiki/%E7%81%AB%E8%BB%8A_(%E5%B0%8F%E8%AA%AC)', node_type=<ObjectType.DOCUMENT: '4'>, metadata={}, hash='956de29d6407704bc945d1ff9f843ad814ca357e032b0d19e2b86c40d6754fe9'), <NodeRelationship.PREVIOUS: '2'>: RelatedNodeInfo(node_id='2caab499-b5e6-4d7c-97fd-a758b7182667', node_type=<ObjectType.TEXT: '1'>, metadata={}, hash='b1e3b12cf2dec27dee38ac9f925d7110a4cd9213fb3584c076fd00010c3c533d'), <NodeRelationship.NEXT: '3'>: RelatedNodeInfo(node_id='46f36a51-8730-445d-9510-1ef7a5834351', node_type=<ObjectType.TEXT: '1'>, metadata={}, hash='0b109e7390b9935d93de686a7ca2c39197f64842a4b6d3cd4741e1a0002ed341')}, text='## あらすじ\n\n[[編集](/w/index.php?title=%E7%81%AB%E8%BB%8A_\\(%E5%B0%8F%E8%AA%AC\\)&action=edit&section=2\n"節を編集: あらすじ")]\n\n刑事・本間俊介は、犯人確保時に負った傷のために休職していた。そんな彼に、亡くなった妻・千鶴子の親戚で銀行員の栗坂和也が意外な事を頼み込む。謎の失踪を遂げた和也の婚約者・関根彰子を探し出して欲しいという。\n\n和也の話によれば、クレジットカードを持っていないという彰子にカード作成を薦めたところ、審査の段階で彼女が自己破産経験者だということが判明した。事の真偽を問い詰められた彰子は、翌日には職場からも住まいからも姿を消していたとの事だった。\n\n休職中で警察手帳も使えない本間は、彰子の親戚や雑誌記者を装って捜査を開始する。最初に彰子の勤め先を訪ね、社長から彰子の履歴書を見せられた本間は、写真を見て彼女の美貌に驚く。美しいながら、夜の仕事には染まらない清楚な雰囲気が漂っていた。次に、彰子の自己破産手続きに関わった弁護士を訪ねたところ、「関根彰子」は会社勤めの傍ら水商売に手を出しており、容貌の特徴は大きな八重歯だという。勤め先での関根彰子と自己破産した関根彰子は、名前が同じながら容貌も性格も素行も一致しないのだ。\n\n本間は和也の婚約者だった「関根彰子」は、本物の関根彰子に成りすました偽者ではないのかと言う疑念がわく。\n\n調べを進める本間は、都会での1人暮らしの夢からカード破産に陥る女性や、無理なマイホーム購入で離散に陥った一家、実家の借金が原因で追い詰められ、婚家を去らざるを得なかった女性など、借金に翻弄される人生を目の当たりにする。\n\n## 登場人物\n\n[[編集](/w/index.php?title=%E7%81%AB%E8%BB%8A_\\(%E5%B0%8F%E8%AA%AC\\)&action=edit&section=3\n"節を編集: 登場人物")]\n\n本間 俊介\n\n    42歳。捜査一課刑事。休職中\n本間 智\n\n    10歳。俊介の息子\n本間 千鶴子\n\n    俊介の妻。故人\n井坂 恒男\n\n    本間家の隣人\nカッちゃん', mimetype='text/plain', start_char_idx=11862, end_char_idx=12802, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n'),
 TextNode(id_='46f36a51-8730-445d-9510-1ef7a5834351', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={<NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='https://ja.wikipedia.org/wiki/%E7%81%AB%E8%BB%8A_(%E5%B0%8F%E8%AA%AC)', node_type=<ObjectType.DOCUMENT: '4'>, metadata={}, hash='956de29d6407704bc945d1ff9f843ad814ca357e032b0d19e2b86c40d6754fe9'), <NodeRelationship.PREVIOUS: '2'>: RelatedNodeInfo(node_id='20bcf4cd-92fc-42a8-9757-f5cbd6d4777c', node_type=<ObjectType.TEXT: '1'>, metadata={}, hash='a5977d98668d2593e22ab29fb494a46132835e241159732d9418462574bdd54f'), <NodeRelationship.NEXT: '3'>: RelatedNodeInfo(node_id='f96c3089-226f-4a13-a706-2a5e86b5a923', node_type=<ObjectType.TEXT: '1'>, metadata={}, hash='db5e608fed56cc45a77a1f7149021b786a8964035fcdcdf17e618e99300facd9')}, text='42歳。捜査一課刑事。休職中\n本間 智\n\n    10歳。俊介の息子\n本間 千鶴子\n\n    俊介の妻。故人\n井坂 恒男\n\n    本間家の隣人\nカッちゃん\n\n    智の同級生\n栗坂 和也\n\n    29歳。千鶴子のいとこの息子。銀行員\n碇 貞夫\n\n    42歳。俊介の同僚\n関根 彰子\n\n    本物の関根彰子。スナックに勤務したことがあり、自己破産した経歴があった。\n新城 喬子\n\n    偽の関根彰子。婚約者を残し失踪した。自身は父親が遺した借金によって取り立て屋に苦しめられ、売春の強要をされた。悪状況から脱却するため自分と近い境遇の人間に成りすまそうとしていた。\n野村 一恵\n\n    本物の彰子の同級生\n本多 保\n\n    本物の彰子の幼なじみ\n本多 郁美\n\n    保の妻\n関根 淑子\n\n    彰子の母、故人。宇都宮市に在住していたが転落死した。\n溝口 悟郎\n\n    関根彰子の破産手続きをした弁護士\n今井 四郎\n\n    今井事務機の社長\nみっちゃん\n\n    今井事務機の事務員\n澤木\n\n    溝口・高田弁護士事務所の事務員\n青年\n\n    溝口・高田弁護士事務所の事務員\n井坂 久恵\n\n    43歳、恒男の妻、デザイナー\n片瀬 秀樹\n\n    下着通販会社ローズライン管理課課長補佐。新城喬子と交際していたが、新城喬子の他人に成りすますという野望のため体よく利用されていただけだった。\n須藤 薫\n\n    喬子の友人\n木村 こずえ\n\n    22歳。フリーター\n倉田 康司\n\n    喬子の別れた夫\n市木 かおり\n\n    喬子の元同居人\n雑誌記者\n\n    本間の知人\n宮城 富美江\n\n    彰子の知人\n紺野\n\n    喫茶バッカスの店主\n紺野 明美\n\n    紺野の娘\n紺野 信子\n\n    紺野の妻。コーポ川口の大家\n宮田 かなえ\n\n    美容室ロレアルサロンの従業員\nママ\n\n    ライハマのママ\n菊池\n\n    ライハマのバーテン\nマキ', mimetype='text/plain', start_char_idx=12724, end_char_idx=13566, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n'),
 TextNode(id_='f96c3089-226f-4a13-a706-2a5e86b5a923', embedding=None, metadata={}, excluded_embed_metadata_keys=[], excluded_llm_metadata_keys=[], relationships={<NodeRelationship.SOURCE: '1'>: RelatedNodeInfo(node_id='https://ja.wikipedia.org/wiki/%E7%81%AB%E8%BB%8A_(%E5%B0%8F%E8%AA%AC)', node_type=<ObjectType.DOCUMENT: '4'>, metadata={}, hash='956de29d6407704bc945d1ff9f843ad814ca357e032b0d19e2b86c40d6754fe9'), <NodeRelationship.PREVIOUS: '2'>: RelatedNodeInfo(node_id='46f36a51-8730-445d-9510-1ef7a5834351', node_type=<ObjectType.TEXT: '1'>, metadata={}, hash='0b109e7390b9935d93de686a7ca2c39197f64842a4b6d3cd4741e1a0002ed341'), <NodeRelationship.NEXT: '3'>: RelatedNodeInfo(node_id='3ec6b5c7-5d2a-4598-84ad-eadb436669fc', node_type=<ObjectType.TEXT: '1'>, metadata={}, hash='4508fa37c97fe2b086c790e51f4c45f23d99e5bee0de3f253c363501e0d92b17')}, text='紺野の妻。コーポ川口の大家\n宮田 かなえ\n\n    美容室ロレアルサロンの従業員\nママ\n\n    ライハマのママ\n菊池\n\n    ライハマのバーテン\nマキ\n\n    ライハマの店員\n北村 真知子\n\n    理学療法士\n境\n\n    宇都宮署の刑事\n加藤\n\n    倉田不動産社員\n\n## 書誌情報\n\n[[編集](/w/index.php?title=%E7%81%AB%E8%BB%8A_\\(%E5%B0%8F%E8%AA%AC\\)&action=edit&section=4\n"節を編集: 書誌情報")]\n\n  * 単行本:1992年7月1日発売、[双葉社](/wiki/%E5%8F%8C%E8%91%89%E7%A4%BE "双葉社")、[ISBN 978-4-5752-3117-5](/wiki/%E7%89%B9%E5%88%A5:%E6%96%87%E7%8C%AE%E8%B3%87%E6%96%99/9784575231175)\n  * 文庫本:1998年1月30日発売、[新潮文庫](/wiki/%E6%96%B0%E6%BD%AE%E6%96%87%E5%BA%AB "新潮文庫")、[ISBN 978-4-1013-6918-1](/wiki/%E7%89%B9%E5%88%A5:%E6%96%87%E7%8C%AE%E8%B3%87%E6%96%99/9784101369181)\n  * Audible版: 2019年8月15日配信、朗読:[三浦友和](/wiki/%E4%B8%89%E6%B5%A6%E5%8F%8B%E5%92%8C "三浦友和") 15時間35分\n\n## テレビドラマ\n\n[[編集](/w/index.php?title=%E7%81%AB%E8%BB%8A_\\(%E5%B0%8F%E8%AA%AC\\)&action=edit&section=5\n"節を編集: テレビドラマ")]\n\n### 1994年版\n\n[[編集](/w/index.php?title=%E7%81%AB%E8%BB%8A_\\(%E5%B0%8F%E8%AA%AC\\)&action=edit&section=6\n"節を編集: 1994年版")]\n\n[1994年](/wiki/1994%E5%B9%B4 "1994年")(平成6年)[2月5日](/wiki/2%E6%9C%885%E6%97%A5\n"2月5日")に[土曜ワイド劇場](/wiki/%E5%9C%9F%E6%9B%9C%E3%83%AF%E3%82%A4%E3%83%89%E5%8A%87%E5%A0%B4\n"土曜ワイド劇場")枠で『**火車 カード破産の女!** 』というタイトルでドラマ化された。\n\n映画でも高い実績を持つベテラン池広一夫が演出し、クライマックス一場面だけのために大きな喫茶店セットを組むなどの特徴がある。\n\n####', mimetype='text/plain', start_char_idx=13489, end_char_idx=14707, text_template='{metadata_str}\n\n{content}', metadata_template='{key}: {value}', metadata_seperator='\n')]

LlamaIndexのVectorStoreの構築

見出し画像

LlamaIndexで用意されているシンプルなVectorStoreの構築について解説していきます。

必要なパッケージをインストールします。

pip install llama-index llama-index-core

Dockerコンテナの構築時にすでにインストールされている場合は、スキップしてください。

VectorStoreIndexクラスを使って、ベクトルストアのインデックスを作成します。

from llama_index.core import VectorStoreIndex

index = VectorStoreIndex(nodes, show_progress=True)

インデックスをもとにクエリエンジンを作成します。

query_engine = index.as_query_engine(similarity_top_k=3)
response = query_engine.query("火車の概要を教えて下さい")
print(response)
火車は、宮部みゆきによるミステリー小説であり、社会問題としての消費者金融のありかたをテーマに、サラリーマン金融やカード破産などの借財と多重債務をめぐる取り立てに翻弄される女の生き様を、彼女のことを追い求める刑事の視点から描く。
コードの説明

query_engine = index.as_query_engine(similarity_top_k=3)

  • as_query_engine:インデックスもとにユーザーの質問に対して回答を生成するクエリエンジンを構築します。
  • similarity_top_k=3:類似度に基づいて上位3つの関連性の高い結果を取得するように指定しています。

インデックスのIDを設定し、指定したディレクトリに保存します。

index.set_index_id("miyabe_miyuki")
index.storage_context.persist("./storage/simple_vs")
コードの説明

index.set_index_id(“miyabe_miyuki”)

  • indexに対して、IDとして "miyabe_miyuki" を設定しています。インデックスIDは、インデックスを一意に識別するためのもので、後でインデックスをロードしたり、クエリを実行したりする際に役立ちます。

index.storage_context.persist(“./storage/simple_vs”)

データの保存や管理を行う部分(storage_context)を指定されたディレクトリ("./storage/simple_vs")に保存しています。このディレクトリにインデックスのデータが保存され、次回以降の使用時に再インデックスすることなく、同じデータをすぐに利用できるようになります。

保存されたインデックスをストレージからロードして再利用します。

from llama_index.core import StorageContext, load_index_from_storage

storage_context = StorageContext.from_defaults(persist_dir="./storage/simple_vs")

simple_vc_index = load_index_from_storage(storage_context, index_id="miyabe_miyuki")
コードの説明

storage_context = StorageContext.from_defaults(persist_dir=”./storage/simple_vs”)

  • ここでは、"./storage/simple_vs" というディレクトリにある保存済みデータを扱うための StorageContext を作成しています。

simple_vc_index = load_index_from_storage(storage_context, index_id=”miyabe_miyuki”)

  • storage_contextindex_id="miyabe_miyuki" を使って、ストレージからインデックスをロードしています。
  • index_id="miyabe_miyuki" は、保存したインデックスに設定された一意のIDです。このIDを指定することで、その特定のインデックスをロードしています。これにより、以前に保存したインデックスを再構築することなく、再度使用できるようになります。

ChromaDBの構築

見出し画像

ChromaDBを使用してベクトルストアを保存および再利用する方法を示しています。

必要なパッケージをインストールします。

pip install chromadb llama-index-vector-stores-chroma

Dockerコンテナの構築時にすでにインストールされている場合は、スキップしてください。

ChromaDBを使用してベクトルストアのインデックスを作成します。

import chromadb
from llama_index.core import VectorStoreIndex
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import StorageContext

chroma_client = chromadb.EphemeralClient()
chroma_collection = chroma_client.create_collection("miyabe_miyuki")

vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)

chroma_index = VectorStoreIndex(nodes, storage_context=storage_context)
コードの説明

chroma_client = chromadb.EphemeralClient()

ChromaDBのエフェメラル(短期間の)クライアントを作成します。これは、データを一時的に保存し、サーバーが終了すると削除されるメモリ内のデータベースを意味します。

chroma_collection = chroma_client.create_collection(“miyabe_miyuki”)

chroma_clientを使用して、新しいコレクション(データのコンテナ)を作成しています。ここではコレクション名を"miyabe_miyuki"として指定しています。

vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

ChromaVectorStoreを使って、ChromaDB内のコレクション(chroma_collection)をベクトルストアとして扱うためのオブジェクトを作成しています。これにより、コレクション内のデータに対してベクトル検索を行えるようになります。

storage_context = StorageContext.from_defaults(vector_store=vector_store)

StorageContextは、データの保存や管理を行うためのオブジェクトです。ここでは、先に作成したvector_store(ChromaDBベースのベクトルストア)をStorageContextにセットして、データ管理を行えるようにしています。

chroma_index = VectorStoreIndex(nodes, storage_context=storage_context)

VectorStoreIndexクラスを使って、nodesをベクトル検索用のインデックスとして作成しています。storage_contextを指定しているため、このインデックスはChromaDBをバックエンドとして使って検索が行われます。

インデックスをもとにクエリエンジンを作成します。

query_engine = chroma_index.as_query_engine()
response = query_engine.query("『理由』で事件のあったマンション名を教えて下さい。")
print(response)
ヴァンダール千住北ニューシティ
コードの説明

query_engine = chroma_index.as_query_engine()

  • as_query_engine:インデックスもとにユーザーの質問に対して回答を生成するクエリエンジンを構築します。

インデックスのIDを設定し、指定したディレクトリに保存します。

db = chromadb.PersistentClient(path="./storage/chroma")
chroma_collection = db.get_or_create_collection("miyabe_miyuki")
vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
chroma_index = VectorStoreIndex(nodes, storage_context=storage_context, show_progress=True)
コードの説明

db = chromadb.PersistentClient(path=”./storage/chroma”)

  • PersistentClientを作成し、path="./storage/chroma"という指定されたディレクトリにデータを永続化します。

chroma_collection = db.get_or_create_collection(“miyabe_miyuki”)

  • get_or_create_collectionメソッドは、”miyabe_miyuki”という名前のコレクションを取得するか、存在しない場合は新しく作成します。

vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

  • ChromaVectorStoreを作成し、先ほど作成したchroma_collectionをベクトルストアとして使用します。

storage_context = StorageContext.from_defaults(vector_store=vector_store)

  • StorageContextを作成し、vector_storeをその一部として設定します。

chroma_index = VectorStoreIndex(nodes, storage_context=storage_context, show_progress=True)

  • VectorStoreIndexを作成し、nodesstorage_contextをもとにインデックスを構築します。
  • VectorStoreIndexは、ベクトル検索用のインデックスを作成し、指定されたnodesをインデックス化します。
  • show_progress=Trueは、インデックス作成中に進行状況を表示するオプションで、インデックスの構築が進んでいるかを確認できます。

保存されたインデックスをストレージからロードして再利用します。

db = chromadb.PersistentClient(path="./storage/chroma")
chroma_collection = db.get_or_create_collection("miyabe_miyuki")
chroma_vector_store = ChromaVectorStore(chroma_collection=chroma_collection)
chroma_index = VectorStoreIndex.from_vector_store(vector_store=chroma_vector_store)
コードの説明

chroma_collection = db.get_or_create_collection(“miyabe_miyuki”)

PersistentClientを使って、以前保存したChromaDBのデータベースを再利用するための接続を行います。pathで指定したディレクトリ (./storage/chroma) に保存されたデータベースを読み込み、再利用します。

chroma_vector_store = ChromaVectorStore(chroma_collection=chroma_collection)

すでに保存されている "miyabe_miyuki" という名前のコレクションを取得します。get_or_create_collectionは、もしコレクションが存在しない場合に新たに作成しますが、ここでは既存のコレクションを再利用しています。

chroma_index = VectorStoreIndex.from_vector_store(vector_store=chroma_vector_store)

取得したコレクションを元にChromaVectorStoreを読み込み、保存されたベクトルストアを再利用します。これにより、新規にベクトルストアを構築することなく、保存済みのベクトルデータをそのまま利用することができます。

chroma_index = VectorStoreIndex.from_vector_store(vector_store=chroma_vector_store)

from_vector_storeメソッドを使って、保存されたベクトルストア (chroma_vector_store) を元にVectorStoreIndexを再利用します。

FaissDBの構築

見出し画像

FaissDBを使用してベクトルストアを保存および再利用する方法を示しています。

必要なパッケージをインストールします。

pip install llama-index-vector-stores-faiss faiss-gpu

Dockerコンテナの構築時にすでにインストールされている場合は、スキップしてください。

ベクトル検索に使用する次元数を設定します。

import faiss

d = 1024
faiss_index = faiss.IndexFlatL2(d)
コードの説明

d = 1024

ベクトル検索に使用する次元数(d)を設定しています。ここでは、1024次元のベクトルを扱うことを示しています。

ベクトル検索に使用する次元数は、埋め込みベクトル(この記事では、intfloat/multilingual-e5-large)の次元数と合わせる必要があります。

faiss_index = faiss.IndexFlatL2(d)

1024次元のベクトルに対して、L2距離を使ったインデックスを作成しています。このインデックスは、類似検索(例えば、与えられたベクトルに最も近いベクトルを見つける)に使用されます。

ChromaDBを使用してベクトルストアのインデックスを作成します。

from llama_index.core import (VectorStoreIndex,StorageContext,)
from llama_index.vector_stores.faiss import FaissVectorStore

faiss_vector_store = FaissVectorStore(faiss_index=faiss_index)
storage_context = StorageContext.from_defaults(vector_store=faiss_vector_store)
faiss_index = VectorStoreIndex(nodes, storage_context=storage_context, show_progress=True)
コードの説明

faiss_vector_store = FaissVectorStore(faiss_index=faiss_index)

事前に作成したFaissインデックス(faiss_index)を使用して、FaissVectorStore を初期化しています。

storage_context = StorageContext.from_defaults(vector_store=faiss_vector_store)

デフォルト設定でストレージコンテキストを作成しています。このコンテキストは、ベクトルデータを保存・管理するために使用します。

faiss_index = VectorStoreIndex(nodes, storage_context=storage_context, show_progress=True)

VectorStoreIndex を使って、ベクトルインデックスを作成しています。

インデックスをもとにクエリエンジンを作成します。

query_engine = faiss_index.as_query_engine()
response = query_engine.query("杉村三郎の所属を教えて下さい")
print(response)
杉村三郎は今多コンツェルン会長の娘婿で、同コンツェルングループ広報室に所属しています。
コードの説明

query_engine = faiss_index.as_query_engine()

  • as_query_engine:インデックスもとにユーザーの質問に対して回答を生成するクエリエンジンを構築します。

インデックスのIDを設定し、指定したディレクトリに保存します。

faiss_index.storage_context.persist(persist_dir="./storage/faiss")
コードの説明

faiss_index.storage_context.persist(persist_dir=”./storage/faiss”)

  • persist() は、faiss_index 内で使用されているストレージコンテキストをディスクに保存するためのメソッドです。これにより、次回の使用時に同じインデックスを読み込むことができます。
  • faiss_index.storage_context は、faiss_index のストレージに関する設定やコンテキストを保持しています。

保存されたインデックスをストレージからロードして再利用します。

vector_store = FaissVectorStore.from_persist_dir("./storage/faiss")
storage_context = StorageContext.from_defaults(
    vector_store=vector_store, persist_dir="./storage/faiss"
)
faiss_index = load_index_from_storage(storage_context=storage_context)
コードの説明

vector_store = FaissVectorStore.from_persist_dir(“./storage/faiss”)

指定したディレクトリに保存されているFaissのベクトルストアをロードしています。

storage_context = StorageContext.from_defaults(vector_store=vector_store,persist_dir=”./storage/faiss”)

  • StorageContext.from_defaults() は、ベクトルストアを基にして、ストレージコンテキストを構築するためのメソッドです。
  • persist_dir="./storage/faiss" では、永続化ディレクトリとして ./storage/faiss を指定しています。これにより、今後の保存や読み込みで同じディレクトリが使用されます。
  • vector_store=vector_store では、上で読み込んだFaissのベクトルストアを使用して、ストレージコンテキストを作成しています。

faiss_index = load_index_from_storage(storage_context=storage_context)

  • load_index_from_storage() は、ストレージコンテキストからベクトルインデックスをロードするための関数です。
  • storage_context=storage_context では、前のステップで作成した storage_context を指定し、その中に含まれるベクトルストアや関連情報を使用してインデックスを読み込みます。
  • これにより、保存されていたFaissのベクトルインデックスが再度ロードされ、使用可能な状態になります。

Qdrant VectorStoreの構築

見出し画像

Qdrantを使用してベクトルストアを保存および再利用する方法を示しています。

必要なパッケージをインストールします。

pip install llama-index-vector-stores-qdrant qdrant_client

Dockerコンテナの構築時にすでにインストールされている場合は、スキップしてください。

Qdrantを使用してベクトルストアのインデックスを作成します。

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.qdrant import QdrantVectorStore
from qdrant_client import QdrantClient

client = QdrantClient(path="./storage/qdrant")
qdrant_vector_store = QdrantVectorStore(
    client=client, 
    collection_name="miyabe_miyuki", 
    enable_hybrid=False,
)
storage_context = StorageContext.from_defaults(vector_store=qdrant_vector_store)
qdrant_index = VectorStoreIndex(nodes, storage_context=storage_context)
コードの説明

client = QdrantClient(path=”./storage/qdrant”)

QdrantClient を初期化して、./storage/qdrant パスに保存されたQdrantのデータに接続します。このクライアントを通して、Qdrantの操作が行われます。

qdrant_vector_store = QdrantVectorStore()

  • QdrantVectorStore は、QdrantClient を使用して Qdrant 内にコレクション(データの集合体)を管理するクラスです。
  • client=client では、先ほど初期化した QdrantClient を使います。
  • collection_name="miyabe_miyuki" では、コレクションを指定しています。これは、ベクトル検索を行う際のデータの分類や管理に使われます。
  • enable_hybrid=False は、ハイブリッド検索(ベクトル検索とメタデータフィルタリングを組み合わせた検索)を無効にしています。必要に応じて、True にすることで有効化も可能です。

storage_context = StorageContext.from_defaults(vector_store=qdrant_vector_store)

  • StorageContext は、ベクトルストアや他のストレージに関連する情報を管理します。
  • from_defaults(vector_store=qdrant_vector_store) で、先ほど作成した qdrant_vector_store を使って StorageContext を初期化します。
  • これにより、QdrantVectorStore がこのストレージコンテキストの一部となり、データの永続化やインデックス作成に利用されます。

qdrant_index = VectorStoreIndex(nodes, storage_context=storage_context)

  • VectorStoreIndex は、ベクトルストアに基づくドキュメントインデックスを作成します。
  • nodes はインデックスに追加するデータで、ドキュメントや記事などの情報をベクトル化して保存するものです。
  • storage_context=storage_context では、先ほど作成した StorageContext を指定します。これにより、ベクトルデータがQdrantに保存され、ベクトル検索や類似度検索ができるようになります。

インデックスをもとにクエリエンジンを作成します。

query_engine = qdrant_index.as_query_engine()
response = query_engine.query("『ソロモンの偽証』は何部作ですか?")
print(response)
『ソロモンの偽証』は3部作です。
コードの説明

query_engine = qdrant_index.as_query_engine()

  • as_query_engine:インデックスもとにユーザーの質問に対して回答を生成するクエリエンジンを構築します。

保存されたインデックスをストレージからロードして再利用します。

client = QdrantClient(path="./storage/qdrant")
qdrant_vector_store = QdrantVectorStore(client=client, collection_name="miyabe_miyuki")
qdrant_index = VectorStoreIndex.from_vector_store(vector_store=qdrant_vector_store)
コードの説明

client = QdrantClient(path=”./storage/qdrant”)

ローカルストレージに保存されているQdrantデータベースを読み込んでいます。ここでは新しいデータを追加するのではなく、既存のデータベースを再利用しています。

qdrant_vector_store = QdrantVectorStore(client=client, collection_name=”miyabe_miyuki”)

Qdrant内の既存のmiyabe_miyukiコレクションを指定しています。これにより、このコレクションに既に保存されているベクトルデータを再利用する形で、検索インデックスを作成します。

qdrant_index = VectorStoreIndex.from_vector_store(vector_store=qdrant_vector_store)qdrant_vector_store の既存データを基にしてインデックスを作成しています。

生成AI・LLMのコストでお困りなら

GPUのスペック不足で生成AIの開発が思うように進まないことはありませんか?

そんなときには、高性能なGPUをリーズナブルな価格で使えるGPUクラウドサービスがおすすめです!

GPUSOROBAN
GPUSOROBAN

GPUSOROBANは、生成AI・LLM向けの高速GPUを業界最安級の料金で使用することができます。

インターネット環境さえあれば、クラウド環境のGPUサーバーをすぐに利用可能です。

大規模な設備投資の必要がなく、煩雑なサーバー管理からも解放されます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
EdgeHUBロゴ

メールマガジン登録

Stable Diffusion・LLM・RAGに関する最新情報をいち早くお届けします。

無料メルマガの配信をご希望の方は、下記フォームよりご登録ください。

    EdgeHUB編集部からのお知らせ

    無料ウェビナーのお知らせ

    RAG進化のさらに先へ!自立型AIエージェント ウェビナー【12/25無料開催】

    RAG進化のさらに先へ! 大好評につきRAGシリーズ第3弾が開催決定!

    開催日時:
    2024年12月25日(水) 14:00~15:00

    内容:

    • RAGの精度を向上させる「自律型AIエージェント」のデモ
    • 生成AI開発の強い味方「GPUSOROBAN」の活用方法

    このウェビナーでは、オープンソース「LangGraph」で構築したAIエージェントの使い方や、デモを紹介します。

    生成AIに関心のある方、AI技術をビジネスに活かしたい方は、ぜひこの貴重な機会にご参加ください!

    こんな方におすすめ!

    • 自律型AIエージェントに興味がある方
    • RAGの高度化を検討しているエンジニアや開発者
    • 日本語のローカルLLMの利用を検討している方
    • GPUリソースに課題を感じている方

    \簡単1分で申し込み!/

    この記事を書いた人

    EdgeHUBは、NVIDIAクラウドパートナーである株式会社ハイレゾが運営しています。「AIと共にある未来へ繋ぐ」をテーマに、画像生成AI、文章生成AI、動画生成AI、機械学習・LLM、Stable Diffusionなど、最先端の生成AI技術の使い方をわかりやすく紹介します。

    目次