RAGを用いる業務が増えてきたのでメモとして残しておきます。
LlamaIndex v0.10主な変更点
- Llama-index-coreを作成、Integrationを個別パッケージに分離
- LlamaHubでIntegrationを管理
- ServiceContextが非推奨に
①Llama-index-coreに移行
過去のバージョンでllama_indexからインポートしていたものは、基本的にllama_index.coreからインポート
# from llama_index import VectorStoreIndex →
from llama_index.core import VectorStoreIndex
# from llama_index import SimpleDirectoryReader →
from llama_index.core import SimpleDirectoryReader
② サードパーティ「Integration」には主に以下のカテゴリが含まれる
- llms
- embeddings
- multi_modal_llms
- readers
- tools
- vector_stores
③ ServiceContextは非推奨に
v0.10.以前ではServiceContext上で使用するLLMや埋め込みモデル、コールバックなどを指定するために使用していた。
非推奨になったのは主に
①OpenAIをデフォルトで用いることからローカルLLMを使用する場合でもapiキーが必要になること
②カスタムモデルを用いる場合すべてのモジュールにservice_contextを渡す必要があること
の2点が原因らしい。
ServiceContextの代わりにSettingsを使用する
from llama_index.embedding.openai import OpneAIEmbedding
from llama_index.llm.openai import OpenAI
from llama_index.core.callbacks import CallbackManager
from llama_index.core.settings import Settings
#テキストのエンベディングモデルの指定
Settings.embed_model=OpenAIEmbedding()
#LLMモデルの指定
Settings.llm=OpenAI()
#コールバックマネージャーの指定
Settings.callback_manager=CallbackManager()
LlamaIndex v0.10. 使用例
(1) LlamaIndexのインストール
!pip install llama-index
(2) 環境変数の準備
openaiにアクセスするために環境変数"OPENAI_API_KEY"にapiキーを設定する
from os
from google.colab import userdata
#openai api_keyを環境変数に設定
os.environ["OPENAI_API_KEY"]=userdata.get("OPENAI_API_KEY")
# Google Driveと接続
from google.colab import drive
drive.mount('/content/drive')
from google.colab import drive
drive.mount('/content/drive')
(3)データの用意
今回の場合は"data"ディレクトリ配下にデータを用意する。今回はwikipediaから参照したテキストを .txtとして保存しました。
root/
├ data/
│ └starwars_ep4.txt
│ └starwars_ep5.txt
│ └starwars_ep6.txt
└ rag.py
(4) ドキュメントのLoading
from llama_index.core import SimpleDirectoryReader
#documents配下のドキュメント読み込み
documents=SimpleDirectoryReader("data").load_data()
(5) Indexing
(3)でロードしたドキュメントからインデックスの作成を行う。
今回はVectoreStoreIndexを用いて、ドキュメントをチャンクという単位に分割し、チャンク毎にベクトルに変換し保存している。
from llama_index.core import VectorStoreIndex
#インデックスの作成
index = VectorStoreIndex.from_documents(documents)
(6) Querying
クエリエンジンによってユーザーの入力するクエリと関連する情報を(4)で作成したインデックスより検索する。
query_engine = index.as_query_engine()
print(query_engine.query("ジャバについて教えてください。"))
ジャバは犯罪王であり、惑星タトゥイーンに根城を構える存在です。彼は炭素冷凍されたハン・ソロを囚われており、賞金稼ぎやレイアらを捕らえるなど、悪事を働いています。ジャバは自身の宮殿を拠点とし、様々な犯罪行為を行っています
一部誤りがあるものの、テキストの内容から検索して文章を生成していることがわかる。
精度を上げるための調整方法
LlamaIndexにおいて精度を上げるため、Indexingでは主に
①Embeddingモデルの変更
② チャンクサイズの変更
があげられる。
①Embeddingモデルの変更はSettings.embed_modelから行う
from llama_index.embedding.openai import OpneAIEmbedding
from llama_index.core import Settings
Settings.embed_mdodel=OpenAIEmbedding(model="text-embedding-ada-002")
②チャンクサイズの変更はSentenceSplitterで行う。
from llama_index.core import Settings
from llama_index.core.node_parser import SentenceSplitter
#テキストスプリッターの設定
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
)
・separator : 単語の区切り文字 (default:" ")
・chunk_size : 各チャンクのトークン数 (default:1024)
・chunk_overlap : 分割時の各チャンクのトークンの重なり (default:20)
・paragraph_separator : 段落間の区切り文字 (default:"\n\n\n")
・secondary_chunking_regex : 文の区切り文字の正規表現 (default:">[^,.;。]+[,.;。]?")
・chunking_tokenizer_fn : テキストを文章に分割する関数 (default:nltk.sent_tokenize)
・callback_manager : コールバックマネージャ
・tokenizer : トークナイザー
Embbedingモデル比較
今回はEmbeddingモデルをtext-embedding-ada-002"と"text-embedding-3-small"とした時のQuerying結果から上位10件を表示する。
#model= を変更する
Settings.embed_mdodel=OpenAIEmbedding(model="text-embedding-ada-002")
retriever=VectorIndexRetriever(
index=index,
similarity_top_k=10)
nodes=retriever.retrieve("ジャバについて日本語で教えてください。")
for n in nodes:
print("Score: {}\nText: {}".format(n.get_score(),n.get_content().replace("\n",""+"...")))
print("len :{}".format(len(n.get_content())))
Score: 0.7947975656350409
Text: ルークにジェダイに相応しい忍耐力があるかを試していたヨーダは、年齢を重ねすぎており、辛抱強さのないルークの指導をためらうが、オビ=ワンの説得によりやっと修行を始める。しかしジェダイとしての意識が低いル
len :1383
Score: 0.7930118632174142
...前作より1年ほどの月日が流れた。ルーク・スカイウォーカーの使者として惑星タトゥイーンに根城を構える犯罪王ジャバ・ザ・ハットの宮殿へ遣わされた2体のドロイ
len :1771
Score: 0.7858297954692173
...ヤヴィンの戦いから3年。デス・スターを反乱同盟軍に破壊された銀河帝国軍の反撃は激烈を極めた[4]。反乱軍は帝国軍の攻撃によりヤヴィン第4衛星の基地から撤
len :1697
Score: 0.778847222481473
...そんな中、銀河帝国の支配に抵抗す
len :1695
Score: 0.7656718280522846
Text: その後、R2の解析により、レイアがここに監禁され、処刑を待っていることが分かり、ルークはソロとチューバッカを説得し救出に向かう。帝国軍の猛追を受けながらも、3人はレイアの救出に成功し、ファルコンへと急
len :1153
Score: 0.7576013788521982
...激戦の果てに、
len :875
Score: 0.1274102592472926
Text: ルークにジェダイに相応しい忍耐力があるかを試していたヨーダは、年齢を重ねすぎており、辛抱強さのないルークの指導をためらうが、オビ=ワンの説得によりやっと修行を始める。しかしジェダイとしての意識が低いル
len :1383
Score: 0.11958097504967838
...前作より1年ほどの月日が流れた。ルーク・スカイウォーカーの使者として惑星タトゥイーンに根城を構える犯罪王ジャバ・ザ・ハットの宮殿へ遣わされた2体のドロイ
len :1771
Score: 0.10637537265803704
...ヤヴィンの戦いから3年。デス・スターを反乱同盟軍に破壊された銀河帝国軍の反撃は激烈を極めた[4]。反乱軍は帝国軍の攻撃によりヤヴィン第4衛星の基地から撤
len :1697
Score: 0.08226115775394001
Text: その後、R2の解析により、レイアがここに監禁され、処刑を待っていることが分かり、ルークはソロとチューバッカを説得し救出に向かう。帝国軍の猛追を受けながらも、3人はレイアの救出に成功し、ファルコンへと急
len :1153
Score: 0.07853515867038942
...そんな中、銀河帝国の支配に抵抗す
len :1695
Score: 0.07484458060546172
...激戦の果てに、
len :875
今回は参照テキストが3つと少なかったため検索結果の順位に大きな差はでなかったが、スコア値が変化していることがわかる。
まとめ
今回はLlamaIndexの使い方をメモした。
次は細かな設定を学んでいきたい。
参考文献
こちらのサイトを参考にさせていただきました
LlamaIndex v0.10 クイックスタートガイド - Python版