Closed6

LlamaIndex v0.10.1を試す

kun432kun432

サラッとColaboratoryで流してみる。

インストール

https://docs.llamaindex.ai/en/stable/getting_started/installation.html

!pip install llama-index

新しいパッケージの構成を確認してみる。

!pip freeze | grep "llama-"
llama-index==0.10.6
llama-index-agent-openai==0.1.1
llama-index-core==0.10.6.post1
llama-index-embeddings-openai==0.1.1
llama-index-legacy==0.9.48
llama-index-llms-openai==0.1.2
llama-index-multi-modal-llms-openai==0.1.1
llama-index-program-openai==0.1.2
llama-index-question-gen-openai==0.1.1
llama-index-readers-file==0.1.3

んー、なるほど、この感じだとLLMにCohere使いたい、ベクトルDBにQdrant使いたい、みたいな場合は追加でパッケージのインストールが必要になりそう。

今のところのパッケージ構成は一時的にNotionに記載されているけど、最終的にはインテグレーション系はLlamaHubに集約されるのかな?

https://pretty-sodium-5e0.notion.site/ce81b247649a44e4b6b35dfb24af28a6?v=53b3c2ced7bb4c9996b81b83c9f01139

PyPIを見てみると山ほどあるな。でもまあ必要なパッケージだけ追加できるほうがイメージ作ったりする場合には極力コンパクトにできそう

https://pypi.org/search/?q=llama-index-&o=

例えばこんな感じでカスタムに必要なものだけインストールできるみたい。

!pip install llama-index-core llama-index-llms-cohere llama-index-embeddings-cohere llama-index postprocessor-cohere-rerank llama-index-vector-stores-qdrant
kun432kun432

チュートリアル

https://docs.llamaindex.ai/en/stable/getting_started/starter_example.html

OpenAI APIキーをセット

import os
from google.colab import userdata

os.environ["OPENAI_API_KEY"] = userdata.get("OPENAI_API_KEY")

ファイルを用意する。

from pathlib import Path
import requests

# Wikipediaからのデータ読み込み
wiki_titles = ["イクイノックス", "ドウデュース"]
for title in wiki_titles:
    response = requests.get(
        "https://ja.wikipedia.org/w/api.php",
        params={
            "action": "query",
            "format": "json",
            "titles": title,
            "prop": "extracts",
            # 'exintro': True,
            "explaintext": True,
        },
    ).json()
    page = next(iter(response["query"]["pages"].values()))
    wiki_text = page["extract"]

    data_path = Path("data")
    if not data_path.exists():
        Path.mkdir(data_path)

    with open(data_path / f"{title}.txt", "w") as fp:
        fp.write(wiki_text)

ファイルからインデックス作成してクエリまで。

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()

response = query_engine.query("ドウデュースの主な勝ち鞍は?")
print(response)
GIを含む重賞3勝目、日本ダービー、京都記念

ここまではそんなに違いは感じない。

kun432kun432

https://blog.llamaindex.ai/llamaindex-v0-10-838e735948f8

https://pretty-sodium-5e0.notion.site/v0-10-0-Migration-Guide-6ede431dcb8841b09ea171e7f133bd77

変更点を見ている中でコード的に影響ありそうなのはここ

LlamaIndex v0.10 contains some major updates:

(snip)

  1. ServiceContext is deprecated: Every LlamaIndex user is familiar with ServiceContext, which over time has become a clunky, unneeded abstraction for managing LLMs, embeddings, chunk sizes, callbacks, and more. As a result we are completely deprecating it; you can now either directly specify arguments or set a default.

DeepL訳

LlamaIndex v0.10にはいくつかの大きなアップデートが含まれています:

(snip)

  1. ServiceContextは廃止されました: LlamaIndexのユーザーなら誰もがServiceContextを使い慣れていると思いますが、LLMやエンベッディング、チャンクサイズ、コールバックなどを管理するための抽象化された不要なものでした。現在では、引数を直接指定するか、デフォルトを設定することができます。

Service Contextのマイグレーションガイドがあった。

https://github.com/run-llama/llama_index/blob/main/docs/module_guides/supporting_modules/service_context_migration.md

今までだとこんな感じになってたと思う。実際にこれで動くかはおいといて適当。

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.llms.openai import OpenAI
from llama_index.core import ServiceContext, set_global_service_context

service_context = ServiceContext.from_defaults(
    llm=OpenAI(model="gpt-3.5-turbo"),
    embed_model=OpenAIEmbedding(model="text-embedding-3-small"),
    node_parser=SentenceSplitter(chunk_size=512, chunk_overlap=20),
    num_output=512,
    context_window=3900,
)
set_global_service_context(service_context)

documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()

response = query_engine.query("ドウデュースの主な勝ち鞍は?")
print(response)

自分はset_global_service_contextをあまり使わない、というかなんかうまく動かなかった印象を持っているので、いろんなモジュールの初期化時にservice contextを個別に設定することが多かった気がする。

今後はこんな感じ?

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.node_parser import SentenceSplitter
from llama_index.llms.openai import OpenAI
from llama_index.core import Settings

Settings.llm = OpenAI(model="gpt-3.5-turbo-0125")
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.node_parser = SentenceSplitter()
Settings.num_output = 512
Settings.chunk_size = 400
Settings.chunk_overlap = 100
Settings.context_window = 4096
Settings.num_output = 256

documents = SimpleDirectoryReader("data").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()

response = query_engine.query("ドウデュースの主な勝ち鞍は?")
print(response)

もしくは個別に設定する。

んー、Service ContextがSettingsになって劇的に変わったって感じはあまりしないかなぁ。

個人的に思うのは、上記のようにLLMモジュールとかEmbeddingモジュールというようなモジュールレベルのものとチャンクサイズとみたいなモジュールのパラメータレベルのものが同列に並んでいるというのがわかりにくさを生んでいるような気がするのだよね。。。

自分が使う場合はモジュールだけ設定して、パラメータはモジュール側に設定することにしそう。デフォルトのモジュール設定だけしておいて、変えたい場合は都度引数で指定する、もしくは、全部都度指定する、かな。

kun432kun432

とりあえずコードを書く上では、

  • 必要なパッケージを必要に応じて追加する
  • Service Context/Settingsあたりは少し使ってみて考える

かな。それ以外はそんなに気にしなくて良さそう。

まあLangChainもパッケージ分割されているし、これ自体は正しい流れじゃないかな。

このスクラップは3ヶ月前にクローズされました