🦙

Google CloudとRAG | LlamaIndex on Vertex AI編

2024/09/09に公開

はじめに

Google I/O 2024 のタイミングで発表された LlamaIndex on Vertex AI について解説します。

最初にお断りですが、以下の個人的な考えから、この記事では LlamaIndex 自体の説明はしません。

  • LlamaIndex on Vertex AI をさわるうえで、知らなくても問題ない
  • LlamaIndex を知らない人はそもそも LlamaIndex on Vertex AI には興味を持たない

LlamaIndex on Vertex AI とは?

端的に表現すると、RAG における Retrieval の部分を担当してくれるツールです。
以下画像の通り、Google Cloud で RAG を実装する際の選択肢が増えてきています。

Vertex AIでのRAGの構築

以下、ざっくりとした特徴です。

  • チャンク作成、エンベディング生成、インデックスの作成、保存のステージを良い感じにやってくれる。
  • 対応しているファイル形式は HTML や Markdown、Google ドキュメントや Google スライド、パワポなど。
  • 対応しているデータソースは単一ファイルのアップロード、Cloud Storage、Google ドライブ、Slack、Jira
  • Vertex AI の Gemini や embedding モデルの多くが使用可能

公式ドキュメントには料金が書いておらず、また今回は小さいデータで検証していたため、
LlamaIndex on Vertex AI に特有の課金が存在するか、正直わかりませんでした。
Vertex AI Vector Search の料金から類推すると、
corpus(インデックス)の作成時には課金されている可能性があります。
一方、corpusを作成して放置しても、インデックスがデプロイされている扱いにはなっていないようでした。
※これは LlamaIndex on Vertex AI 特有の課金のお話で、モデルの利用や Cloud Storage には課金されます。

以下、各種ドキュメントです。

他の Retriever との比較

LlamaIndex on Vertex AI と以下 2 つを、独断と偏見で比較してみます。

  • LlamaIndex
  • Vertex AI Search

3 つの観点から見ていきます。

  • Retrieve や Index など、RAG の各ステージにおけるカスタマイズ性
  • 使用できるモデル
  • 対応しているデータソース

検索や生成の精度の比較は大変なので今回はやりません。

LlamaIndex との比較

  • Retrieve や Index など、RAG の各ステージにおけるカスタマイズ性

    • LlamaIndex の方がもちろん高い

    • 2024/9/9 時点で、LlamaIndex on Vertex AI は chunking の際のチャンクサイズ、前後のチャンクのオーバーラップ、retrieve の際のtop_kvector_distance_thresholdくらいしかカスタマイズできない

      • カスタマイズができない分、構築はかなりラク
  • 使用できるモデル

    • LlamaIndex は OpenAI や Anthropic 提供のもの含め、様々なモデルを使える
    • LlamaIndex on Vertex AI は、Vertex AI のモデルにほぼ限定される
  • 対応しているデータソース

    • LlamaIndex はLlamaHubから様々なデータソースとのコネクタを使用できる
    • LlamaIndex on Vertex AI は 限定される

Vertex AI Search との比較

  • Retrieve や Index など、RAG の各ステージにおけるカスタマイズ性

  • 使用できるモデル

    • LlamaIndex on Vertex AI は embedding モデルもコントロールできる
  • 対応しているデータソース

    • Vertex AI Search の方が様々なデータソースに対応している

触ってみた

以下 2 つの使い方をそれぞれ紹介していきます。

  • Retriever 単体
  • Gemini の retrieval tool

共通で必要な準備からしていきます。

準備

  • Cloud Storage のバケットを作成し、ファイルを格納
  • ライブラリをインストール
pip install --upgrade google-cloud-aiplatform

Retriever 単体

チャンクされたドキュメントをとってくるためのものです。回答は生成しません。
先に解説しますと、corpusはインデックスのこと指します。
corporacorpusの複数形なので、複数のインデックスのことです。

import vertexai
from vertexai.preview import rag
from vertexai.preview.generative_models import GenerativeModel, Tool

project_id = "YOUR_PROJECT_ID"
display_name = "sample_corpus"  # 任意の名前

paths = [
    # "https://drive.google.com/file/d/123",
    "gs://your_bucket/",
]  # Cloud StorageもしくはGoogle Driveのリンクのみ対応


def main():
    # Vertex AI APIの初期化
    vertexai.init(project=project_id, location="us-central1")

    # embeddingモデルの設定
    embedding_model_config = rag.EmbeddingModelConfig(
        publisher_model="publishers/google/models/textembedding-gecko-multilingual@001"
    )

    # corpus(インデックス)の作成
    rag_corpus = rag.create_corpus(
        display_name=display_name,
        embedding_model_config=embedding_model_config,
    )

    # corpusへのファイルインポート(チャンク化、エンベディング、保存)
    response = rag.import_files(
        rag_corpus.name,
        paths,
        chunk_size=512,  # Optional
        chunk_overlap=100,  # Optional
        max_embedding_requests_per_min=900,  # Optional
    )
    query = "Society5.0とはなんですか?"

    # コンテキストの検索
    response = rag.retrieval_query(
        rag_resources=[
            rag.RagResource(
                rag_corpus=rag_corpus.name,
        ],
        text=query,
        similarity_top_k=2,  # Optional
        vector_distance_threshold=0.5,  # Optional
    )
    print(response)

以下のように出力されます。
similarity_top_k を 2 に指定したので、取ってきてくれるチャンクは 2 つです。

contexts {
  contexts {
    source_uri: "gs://llamaindex-test/AI事業者ガイドライン(テスト用スモール版).pdf"
    text: "また近年台頭してきた対話型の生成 AI によ\r\nって「AI の民主化」が起こり、多くの人が「対話」 によって AI を様々な用途へ容易に活用できるようになった。これ\r\nにより、企業では、ビジネスプロセスに AI を組み込むだけではなく、AI が創出する価値を踏まえてビジネスモデル\r\n自体を再構築することにも取り組ん でいる。また、個人においても自らの知識を AI に反映させ、自身の生産性を\r\n拡大させる取組が加速している 。我が国では、従来から Society 5.0 として、サイバー空間とフィジカル空間を高\r\n度に融合させたシステム(CPS : サイバー・フィジカルシステム)による経済発展と社会的課題の解決を両立す\r\nる人間中心の社会という コンセプトを掲げてきた。このコンセプトを実現するにあたり、AI が社会に受け入れられ適\r\n正に利用されるため、2019 年 3 月に「人間中心の AI 社会原則」が策定された。一方で、AI 技術の利用範囲\r\n及び利用者の拡大に伴い、リスクも増大している。"
    distance: 0.22105848934715033
  }
  contexts {
    source_uri: "gs://llamaindex-test/AI事業者ガイドライン(テスト用スモール版).pdf"
    text: "このような認識のもと、これまでに総務省主導で「国際的な議論のための AI 開発ガイドライン案」、「AI 利活\r\n用ガイドライン~AI 利活用のためのプラクティカルリファレンス~」及び経済産業省主導で「AI 原則実践のための\r\nガバナンス・ガイドライン Ver. 1.1」を策定・公表してきた。そして、このたび 3 つのガイ ドラインを統合・見直しし\r\nて、この数年でさらに発展した AI 技術の特徴及び国内外における AI の社会実装 に係る議論を反映し、事業\r\n者が AI の社会実装及びガバナンスを共に実践するためのガイドライン(非拘束的 なソフトロー)として新たに策3\r\n定した(「図 1."
    distance: 0.30341481972702355
  }
}

以下のコードで作成済みの corpus の名前などが取得できます。

project_id = "YOUR_PROJECT_ID"

def main():
    vertexai.init(project=project_id, location="us-central1")

    corpora = rag.list_corpora()
    print(corpora)

以下が出力結果の例です。

ListRagCorporaPager<rag_corpora {
  name: "projects/{project_id}/locations/us-central1/ragCorpora/1234567891011121314"
  display_name: "test_corpus"
  rag_embedding_model_config {
    vertex_prediction_endpoint {
      endpoint: "projects/{project_id}/locations/us-central1/publishers/google/models/textembedding-gecko-multilingual@001"
    }
  }
  create_time {
    seconds: 1720859931
    nanos: 913186000
  }
  update_time {
    seconds: 1720859931
    nanos: 913186000
  }
}

nameの以下が呼び出す際に必要なcorpus_nameです。

"projects/{project_id}/locations/us-central1/ragCorpora/1234567891011121314"

Gemini の retrieval tool

Gemini に Tool として持たせ、Grounding された回答を生成させます。

import vertexai
from vertexai.preview import rag
from vertexai.preview.generative_models import GenerativeModel, Tool

project_id = "YOUR_PROJECT_ID"
display_name = "sample_corpus"  # 任意の名前
corpus_name = f"projects/{project_id}/locations/us-central1/ragCorpora/1234567891011121314"

paths = [
    "gs://your_bucket/",
]

def main():
    rag_retrieval_tool = Tool.from_retrieval(
        retrieval=rag.Retrieval(
            source=rag.VertexRagStore(
                rag_resources=[
                    rag.RagResource(
                        rag_corpus=corpus_name,  # 現在は1つのcorpusのみ指定可能
                    )
                ],
                similarity_top_k=2,  # Optional
                vector_distance_threshold=0.5,  # Optional
            ),
        )
    )
    rag_model = GenerativeModel(
        model_name="gemini-1.5-flash-001", tools=[rag_retrieval_tool]
    )

    response = rag_model.generate_content(query)
    print(response.text)

出力は以下の通りです。

Society5.0は、サイバー空間とフィジカル空間を高度に融合させたシステム(CPS)による経済発展と社会的課題の解決を両立する人間中心の社会というコンセプトです。

corpus の削除

作成したcorpusを削除します。

project_id = "YOUR_PROJECT_ID"
corpus_name = (
    f"projects/{project_id}/locations/us-central1/ragCorpora/1234567891011121314"
)

def main():
    vertexai.init(project=project_id, location="us-central1")
    rag.delete_corpus(name=corpus_name)

    corpora = rag.list_corpora()
    print(corpora)
    # 空のListRagCorporaPagerが出力されば、すべて削除されている
    # ListRagCorporaPager<>

まとめ

LlamaIndex on Vertex AI を使うと、
Cloud Storage や Google ドライブにあるデータでお手軽に RAG ができることがわかりました。

2 か月ぶりくらいに確認してみると公式ドキュメントのリンクが変わっていたり、
Weaviateというベクトル DB が使えるようになっていたりして驚きました。
変化が速い、、。

Discussion