Closed4

LlamaIndex on Vertex AI for RAGを試す

kun432kun432

https://twitter.com/llama_index/status/1790768330099580940

https://cloud.google.com/vertex-ai/generative-ai/docs/llamaindex-on-vertexai

ドキュメント斜め読みした感じだと、LlamaIndexからVertex AIを使う、というよりは、Vertex AIにLlamaIndexが組み込まれている、という感じに読める。

LangChainについても、LlamaIndexとは少しやり方は異なるようだけど、どうやらSDKに組み込まれているような感がある。

https://cloud.google.com/vertex-ai/generative-ai/docs/reasoning-engine/overview?hl=ja

フレームワークにロックインされるか、プラットフォームにロックインされるか、の違いかな。個人的には今の状況だとフレームワークにロックインされるほうがマシかなぁという感を持っているのだけど、それはそれとしてフレームワークを組み込むというアプローチはちょっと新鮮ではある。

少し触ってみる。

kun432kun432

Colaboratoryでざっと試してみた。結論から言うと、今回のお試しでは以下がうまく行かなかった。

  • retrieval単体で動かした場合に検索でチャンクが得られない
  • よって、最終回答もおそらくコンテキストがない状態での回答(つまりLLM単体の回答)だと思われる

原因はわからない。何かが足りないのか、間違っているのかもしれないけど、一旦やったことだけまとめておく。途中でつまづきまくっていろいろやっていたので、もしかすると不要なものがあるかもしれない。


事前準備

  • プロジェクトでVertex AI APIを有効にする
  • コンテキストとなるドキュメントはCloud StorageもしくはGoogleドライブ
    • Cloud Storage
      • バケットを作成してドキュメントをアップロードしておく
      • サービスアカウント"Vertex AI RAG データ サービス エージェント"にバケットへの参照権を付与しておく
    • Googleドライブ
      • 該当のファイル(フォルダでもいいかもしれない)の共有設定で、上記サービスアカウントからの参照を許可しておく

Colaboratory

Cloud SDKをインストール。Colaboratoryには予めCloud SDKが入っているけども、最初うまくいかなかったので、バージョンが古いのかも、ということで、入れ直した。ただ、ここは本当にそうなのかは不明。

!apt-get update
!apt-get install apt-transport-https ca
!curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
!echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
!apt-get update
!apt-get install google-cloud-cli

gcloudコマンドのパスを確認

!which gcloud

デフォルトのものは/toolsみたいなところに入っていたはず。以下のように/usr/binになっていれば上記でインストールしたものが使用される。

/usr/bin/gcloud

Vertex AI SDKのインストール

!pip install --upgrade google-cloud-aiplatform

GCPの認証。以下は予めGCPアカウントとプロジェクトをColaboratoryのSecretに登録している前提。認証するとURLが表示されるので、アクセスしてトークンをコピー、Colaboratory側に入力する。

from google.colab import userdata

GCP_ACCOUNT = userdata.get('GCP_ACCOUNT')
GCP_PROJECT = userdata.get('GCP_PROJECT')

!gcloud config set account {GCP_ACCOUNT} --quiet
!gcloud config set project {GCP_PROJECT} --quiet
!gcloud auth application-default login

Quota project "XXXXXX" was added to ADC which can be used by Google client libraries for billing and quota. Note that some services may still bill the project owning the resource.

みたいになればOKだと思う。

ではサンプルコードを動かす。設定が必要なのは以下。

  • プロジェクトID
  • RagCopus(Vertex AI上ではRAGのインデックスのことをこう呼ぶみたい)につける名前
  • ドキュメントへのパス(Cloud Storage and/or Googleドライブ)
project_id="XXXXXXXXXX"     # プロジェクトID
display_name="doduece"      # RAGのコンテキストに付ける名前、何でも良さそう
paths = ["https://drive.google.com/file/d/XXXXXXXXXXXXXXXXXX", "gs://XXXXXXX"]

まずRagCorpusを作成してドキュメントをインポート。

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

# Vertex AI API初期化、なお東京は非対応だった
vertexai.init(project=project_id, location="us-central1")

# RagCorpusの作成
rag_corpus = rag.create_corpus(display_name=display_name,)

この作成でまず躓いた。なぜかエラーになる。で色々調べて、冒頭のCloudSDKのインストールに至った次第。ただそれが原因だったかは不明。

RagCorpusが作成できたらドキュメントをインポート

# RagCorpusにドキュメントをインポート
response = rag.import_files(
    rag_corpus.name,
    paths,
    chunk_size=512,  # Optional
    chunk_overlap=100,  # Optional
)

reponseを見るとファイルはインポートされた模様

response
imported_rag_files_count: 1

retrieval単体で実施するも回答なし。。。

response = rag.retrieval_query(
    text="名前の由来は?",
    rag_corpora=[rag_corpus.name]
)
response

登録されていないのかな?ということで、いろいろインタフェース調べてると以下の様なものがあった。

rag.list_files(
    corpus_name=rag_corpus.name
)
ListRagFilesPager<rag_files {
  name: "projects/XXXXXXXXXX/locations/us-central1/ragCorpora/XXXXXXXXXXXXXXXXXXXX/ragFiles/XXXXXXXXXXXXXXXXXXXX"
  display_name: "XXXXX.txt"
  create_time {
    seconds: 1715888362
    nanos: 380013000
  }
  update_time {
    seconds: 1715888362
    nanos: 380013000
  }
  gcs_source {
    uris: "gs://XXXXXXXXX/XXXXX.txt"
  }
}
rag_files {
  name: "projects/XXXXXXXXXX/locations/us-central1/ragCorpora/XXXXXXXXXXXXXXXXXXXX/ragFiles/XXXXXXXXXXXXXXXXXXXX"
  display_name: "XXXXX.txt"
  create_time {
    seconds: 1715888660
    nanos: 291426000
  }
  update_time {
    seconds: 1715888660
    nanos: 291426000
  }
  google_drive_source {
    resource_ids {
      resource_type: RESOURCE_TYPE_FILE
      resource_id: "XXXXXXXXXXXXXXXXXXXX"
    }
  }
}

これを見る限りは登録されているように見えるんだけどな。。。

LLMで呼び出し。色々つまづいてたので気づいてなかったけど、今これを改めて見ると、ツール呼び出しっぽい感じだな。そもそもツールとして呼び出されていないという気もする(とはいえretrieval単体でアレなので、、、)

rag_retrieval_tool = Tool.from_retrieval(
    retrieval=rag.Retrieval(
        source=rag.VertexRagStore(
            rag_corpora=[rag_corpus.name],  # Currently only 1 corpus is allowed.
            similarity_top_k=3,  # Optional
        ),
    )
)

rag_model = GenerativeModel(
    model_name="gemini-1.0-pro-002", tools=[rag_retrieval_tool]
)

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

結果

candidates {
  content {
    role: "model"
    parts {
      text: "Doudice\'s main wins are the Prix du Muguet, Prix Greffulhe, Prix Jean-Luc Lagard\303\250re, Poule d\'Essai des Poulains, Prix d\'Ispahan."
    }
  }
  finish_reason: STOP
  safety_ratings {
    category: HARM_CATEGORY_HATE_SPEECH
    probability: NEGLIGIBLE
    probability_score: 0.08035746961832047
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.07668380439281464
  }
  safety_ratings {
    category: HARM_CATEGORY_DANGEROUS_CONTENT
    probability: NEGLIGIBLE
    probability_score: 0.10894504189491272
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.07185126841068268
  }
  safety_ratings {
    category: HARM_CATEGORY_HARASSMENT
    probability: NEGLIGIBLE
    probability_score: 0.08632347732782364
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.08756384253501892
  }
  safety_ratings {
    category: HARM_CATEGORY_SEXUALLY_EXPLICIT
    probability: NEGLIGIBLE
    probability_score: 0.07640768587589264
    severity: HARM_SEVERITY_NEGLIGIBLE
    severity_score: 0.04208773002028465
  }
  grounding_metadata {
  }
}
usage_metadata {
  prompt_token_count: 9
  candidates_token_count: 45
  total_token_count: 54
}

なるほど、コンテンツフィルタ的なものがあるっぽい。

んでもって回答は間違っているのだけど、それはまあ置いといて、おそらくRAGが正しく動くならば、grounding_metadataってのに何かしら入ってきそうではある。

kun432kun432

とりあえずGCP久々すぎてつまづきまくったのだけど、個人的には、慣れたLlamaIndexの書き方をあえてVertex AIに合わせて変えるまでのモチベーションはあまりないかな。他のモデル使えないし。メリットとしては、

  • GCPの各リソースと連携・管理ができる
  • コンテンツフィルタが使える

あたりになるんだろうか。

このスクラップは2024/05/17にクローズされました