LlamaIndex v0.10 クイックスタートガイド - Python版
Python版の「LlamaIndex」のクイックスタートガイドをまとめました。
1. LlamaIndex
「LlamaIndex」は、プライベートやドメイン固有の知識を必要とする専門知識を必要とする質問応答チャットボットを簡単に作成できるライブラリです。
v0.10 では大規模アップデートがありました。
2. LlamaIndexの5つのステージ
「LlamaIndex」には、5つのステージがあります。
2-1. Loading
データソース (テキストファイル、PDF、Webサイト、データベース、APIなど) からデータを読み込みます。
「Loading」の主要コンポーネントは、次のとおりです。
2-2. Indexing
データのクエリを可能にするデータ構造「インデックス」を作成します。
「Indexing」の主要コンポーネントは、次のとおりです。
2-3. Storing
インデックスを作成した後、インデックスと他のメタデータを保存することで、再作成する必要がなくなります。
2-4. Querying
インデックスから関連データをクエリします。
「Querying」の主要コンポーネントは、次のとおりです。
2-3. Evaluation
クエリに対するレスポンスがどの程度正確、忠実、迅速であるかを客観的に測定します。
3. ドキュメントの準備
今回は、マンガペディアの「ぼっち・ざ・ろっく!」のドキュメントを用意しました。
・bocchi.txt
4. 質問応答
Google Colabでの質問応答の実行手順は、次のとおりです。
(1) パッケージのインストール。
# パッケージのインストール
!pip install llama-index==0.10.4
「llama-index」はスタートバンドルで、以下のパッケージをインストールしています。
(2) 環境変数の準備。
左端の鍵アイコンで「OPENAI_API_KEY」を設定してからセルを実行してください。
# 環境変数の準備 (左端の鍵アイコンでOPENAI_API_KEYを設定)
import os
from google.colab import userdata
os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")
(3) ログレベルの設定。
import logging
import sys
# ログレベルの設定
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)
(4) Colabにdataフォルダを作成してドキュメントを配置。
左端のフォルダアイコンでファイル一覧を表示し、右クリック「新しいフォルダ」でdataフォルダを作成し、ドキュメントをドラッグ&ドロップします。
(5) ドキュメントの読み込み。
from llama_index.core import SimpleDirectoryReader
# ドキュメントの読み込み
documents = SimpleDirectoryReader("data").load_data()
(6) インデックスの作成。
「インデックス」は、データのクエリを可能にするデータ構造を保持するコンポーネントです。ドキュメントをチャンクに分割し、チャンク毎に埋め込みに変換して保持します。
チャンクは類似検索の対象となるデータ単位になります。
from llama_index.core import VectorStoreIndex
# インデックスの作成
index = VectorStoreIndex.from_documents(documents)
DEBUG:llama_index.node_parser.node_utils:> Adding chunk: 結束バンド 後藤ひとりは友達を作れない陰キャでいつも一人で過ごしていたが、中学時代にテレビのイ...
DEBUG:llama_index.node_parser.node_utils:> Adding chunk: 文化祭ライブ 夏休みに入り、後藤ひとりは知り合いも増えていたが、自分から遊びに誘うことができず...
DEBUG:llama_index.node_parser.node_utils:> Adding chunk: ひねくれ者なヨヨコは、結束バンドをライバル視しながらも、彼女たちにアドバイスを送り、ファンたち...
:
(7) クエリエンジンの作成。
「クエリエンジン」は、ユーザー入力(クエリ)と関連する情報をインデックスから取得し、それをもとに応答を生成するモジュールです。
# クエリエンジンの作成
query_engine = index.as_query_engine()
(8) 質問応答。
# 質問応答
print(query_engine.query("ぼっちちゃんの得意な楽器は?"))
後藤ひとりの得意な楽器はギターです。
ログを確認すると、以下のコンテキストを取得していることがわかります。
[Similarity score: 0.832151] 自分には何の取り柄もないのを痛感していたため、中学の頃に暗い性格の人間がバンドをやって人気者になったインタビューを読んで、ギターを始める。毎日練習したお陰でギターの腕前はプロ級になったが、結局、...
[Similarity score: 0.829139] 変わり者で一人でいるのが好きだが、後藤ひとりと違って特にコミュ障というわけではない。音楽に関しては独自の価値観を持っており、流行(はや)りに流されるのを嫌い、バンドの個性を重視している。そのため...
OpenAI APIの通信内容も確認できます。Unicodeエスケープシーケンスを日本語に戻してます。
Context information is below.
---------------------
自分には何の取り柄もないのを痛感していたため、中学の頃に暗い性格の人間がバンドをやって人気者になったインタビューを読んで、ギターを始める。毎日練習したお陰でギターの腕前はプロ級になったが、結局、...
変わり者で一人でいるのが好きだが、後藤ひとりと違って特にコミュ障というわけではない。音楽に関しては独自の価値観を持っており、流行(はや)りに流されるのを嫌い、バンドの個性を重視している。そのため...
---------------------
Given the context information and not prior knowledge, answer the question. If the answer is not in the context, inform the user that you can't answer the question.
Question: ぼっちちゃんの得意な楽器は?
Answer:
5. インデックスの保存
作成したインデックスは保存しておくと、次回に再作成する必要がなくなります。
(1) インデックスの保存。
# インデックスの保存
index.storage_context.persist()
(2) インデックスの読み込み。
from llama_index.core import StorageContext, load_index_from_storage
# インデックスの読み込み
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)
6. カスタマイズ
6-1. LLMの設定
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
# LLMの設定
Settings.llm = OpenAI(
model="gpt-3.5-turbo",
temperature=0.1
)
LLMの主なパラメータは、次のとおりです。
6-2. 埋め込みの設定
from llama_index.core import Settings
from llama_index.embeddings.openai import OpenAIEmbedding
# 埋め込みの設定
Settings.embed_model = OpenAIEmbedding(
model="text-embedding-3-small",
)
Embeddingの主なパラメータは、次のとおりです。
6-3. テキストスプリッターの設定
from llama_index.core import Settings
from llama_index.core.node_parser import SentenceSplitter
import tiktoken
# テキストスプリッターの設定
Settings.text_splitter = SentenceSplitter(
separator=" ",
chunk_size=1024,
chunk_overlap=20,
paragraph_separator="\n\n\n",
secondary_chunking_regex="[^,.;。]+[,.;。]?",
tokenizer=tiktoken.encoding_for_model("gpt-3.5-turbo").encode
)
SentenceSplitterのパラメータは、次のとおりです。
チャンクサイズとチャンクオーバーラップは、テキストスプリッターを設定せず、個別に設定することも可能です。
# チャンクサイズとチャンクオーバーラップの設定
Settings.chunk_size = 512
Settings.chunk_overlap = 20
6-4. トークナイザーの設定
from llama_index.core import Settings
import tiktoken
# トークナイザーの設定
Settings.tokenizer = tiktoken.encoding_for_model("gpt-3.5-turbo").encode
6-5. コールバックの設定
from llama_index.core.callbacks import TokenCountingHandler, CallbackManager
from llama_index.core import Settings
# コールバックの設定
token_counter = TokenCountingHandler()
Settings.callback_manager = CallbackManager([token_counter])
6-6. プロンプトヘルパーの設定
通常、LLMの属性を使用して自動的に設定されますが、特別な場合は上書きできます。
from llama_index.core import Settings
# プロンプトヘルパーの設定
Settings.context_window = 4096
Settings.num_output = 256
6-7. クエリエンジンの設定
ベクトル検索で取得するチャンク数は、クエリエンジンのsimilarity_top_kで指定します。
# クエリエンジンの準備
query_engine = index.as_query_engine(
similarity_top_k=10,
)
6-8. Rerankerの設定
「Reranker」は、クエリエンジンのnode_postprocessorsで設定します。
# パッケージのインストール
!pip install llama-index-postprocessor-flag-embedding-reranker
!pip install FlagEmbedding
from llama_index.postprocessor.flag_embedding_reranker import FlagEmbeddingReranker
# Rerankerの準備
rerank = FlagEmbeddingReranker(
model="BAAI/bge-reranker-v2-m3",
use_fp16=True,
top_n=5
)
# クエリエンジンの準備
query_engine = index.as_query_engine(
similarity_top_k=10,
node_postprocessors=[rerank]
)
6-9. トランスフォーメーションの設定
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core import Settings
# トランスフォーメーションの設定
Settings.transformations = [SentenceSplitter(chunk_size=1024)]
7. LlamaHub
「LLM」「埋め込み」「ローダー」「ツール」「ベクトルストア」など、「LlamaIndex」の「Integration」はすべて「LlamaHub」で管理します。
ただし「LlamaHub」への移行はまだ作業中です。 数週間以内にサイトを更新します。それまでの間は、Notionパッケージレジストリを利用します。
今回は、「llama-index-readers-web」の「SimpleWebPageReader」を使って、Webページの情報に基づいて「LlamaIndex」に質問してみます。
(1) パッケージのインストール。
# パッケージのインストール
!pip install llama-index-readers-web
(2) 「SimpleWebPageReader」でURLからドキュメントを生成。
Wikipediaのぼっち・ざ・ろっくのページを読み込みました。
from llama_index.readers.web import SimpleWebPageReader
# リーダーの準備
reader = SimpleWebPageReader(html_to_text=True)
documents = reader.load_data(urls=["https://ja.wikipedia.org/wiki/%E3%81%BC%E3%81%A3%E3%81%A1%E3%83%BB%E3%81%96%E3%83%BB%E3%82%8D%E3%81%A3%E3%81%8F!"])
(3) 質問応答。
# 質問応答
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("結束バンドとは?")
print(response)
この記事が気に入ったらサポートをしてみませんか?