google cloud のセマンティック検索を使ってみたい
詳しい内容は google cloud の 動画から www.youtube.com
テキスト検索ではなく、ベクトル検索になるので、いい感じで検索結果をかえしてくれるらしい また、マルチモーダルのため画像、音声なども扱える。 今回は 画像を google cloud storage に置き、セマンティック検索を試してみたい。
まずは、画像データの準備から
機械学習の無料のサンプルデータセットを利用した。 ここには 30枚の部屋の写真がのっている。 それぞれ、雰囲気や映しているものも異なる。 ローカルに一度保存。
cloud storage に 画像アップロード
これを google cloud storage に配置する。 ちなみに、google cloud のアカウントは最初に無料枠として $300 が使えるため、 どれくらい費用としてかかるのかも見てみたい。 バケットを作成し、準備した画像をアップロード
次に、Bigquery に オブジェクトテーブルを作成する
これ以降は google cloud のチュートリアルを参考にした。 https://cloud.google.com/blog/products/data-analytics/bigquery-multimodal-embeddings-generation/?hl=en
まずは画像データを扱う為のオブジェクトテーブルを作る。 オブジェクトテーブルとは非構造化データを扱う為の、読み取り専用テーブル https://cloud.google.com/bigquery/docs/object-table-introduction?hl=ja
チュートリアルには書かれていないが、コンソールから コネクションの作成が必要。
下記を参考にして、コネクションを作成する。 bk mk --connection コマンドで作るらしい。 zenn.dev
コネクション作成後、適宜下記の内容を書き換えて、create。 connectionId は先程作ったものを指定する。
CREATE OR REPLACE EXTERNAL TABLE `bqml_tutorial.met_images` WITH CONNECTION `Location.ConnectionID` OPTIONS ( object_metadata = 'SIMPLE', uris = ['gs://gcs-public-data--met/*'] );
無事、テーブルは作成できたが、select が permission denied のエラー storage.objects.list の権限がなさそう。
Bigquery の サービスアカウントに対して、IAM と管理の画面から プリンシパルに Bigquery のサービスアカウント、ロールに、Storage オブジェクト閲覧者を付与して再実行。
無事、見えてきた。
モデルを作成する。
※これ以降のソースコードはサンプルをそのまま貼り付けている。 適宜、プロジェクト名など変更する必要があり。
CREATE OR REPLACE MODEL bqml_tutorial.multimodal_embedding_model REMOTE WITH CONNECTION `LOCATION.CONNNECTION_ID` OPTIONS (endpoint = 'multimodalembedding@001')
マルチモーダルだと、endpoint は 上記を使うらしい?
エンベディングを生成する
CREATE OR REPLACE TABLE `bqml_tutorial.met_image_embeddings` AS SELECT * FROM ML.GENERATE_EMBEDDING( MODEL `bqml_tutorial.multimodal_embedding_model`, TABLE `bqml_tutorial.met_images`) WHERE content_type = 'image/jpeg' Limit 10000
作った、テーブルとモデルを使用して、エンベディングをつくる。 また権限のエラー
gserviceaccount.com does not have the permission to access resources used by ML.GENERATE_EMBEDDING.
エラーメッセージで下記を参照して、権限付与しろとのこと Vertex AI ユーザーを付与すればよさそう → ダメだった。よくわらないかつ面倒なので vertex AI の 管理者ロールを与えた。 最小権限の原則とかから本来は調べるべき。実行できた ok https://cloud.google.com/bigquery/docs/generate-text-tutorial?hl=ja
生成されたエンベディングにベクトルインデックスを作成する
CREATE OR REPLACE VECTOR INDEX `met_images_index` ON bqml_tutorial.met_image_embeddings(ml_generate_embedding_result) OPTIONS(index_type = 'IVF', distance_type = 'COSINE')
どうやら合計行数は最低でも 5000 行必要らしい。 まぁ、ベクトルインデックスは、オプションらしいので今回はとばす。
テキストから画像への (クロスモダリティ) 検索に埋め込みを使用する
-- embed search string CREATE OR REPLACE TABLE `bqml_tutorial.search_embedding` AS SELECT * FROM ML.GENERATE_EMBEDDING( MODEL `bqml_tutorial.multimodal_embedding_model`, ( SELECT "pictures of white or cream colored dress from victorian era" AS content ) )
これで、埋め込まれた検索文字列を使用して、 類似した埋め込みを検索できるようになった。
-- use the embedded search string to search for images CREATE OR REPLACE TABLE `bqml_tutorial.vector_search_results` AS SELECT base.uri AS gcs_uri, distance FROM VECTOR_SEARCH( TABLE `bqml_tutorial.met_image_embeddings`, "ml_generate_embedding_result", TABLE `bqml_tutorial.search_embedding`, "ml_generate_embedding_result", top_k => 5)
ちなみに、自分は 部屋の写真を読み込み、
CREATE OR REPLACE TABLE `first-study-project-414006.bgml_turorial.room_search_embeddings` AS SELECT * FROM ML.GENERATE_EMBEDDING( MODEL `first-study-project-414006.bgml_turorial.room_model`, ( SELECT "A natural room with a white base and sofa" AS content ) )
このような埋め込みを使用した。 create されたテーブルはこのように、embedding された結果が格納されている。
-- use the embedded search string to search for images CREATE OR REPLACE TABLE `first-study-project-414006.bgml_turorial.room_search_results` AS SELECT base.uri AS gcs_uri, distance FROM VECTOR_SEARCH( TABLE `first-study-project-414006.bgml_turorial.room_embeddings`, "ml_generate_embedding_result", TABLE `first-study-project-414006.bgml_turorial.room_search_embeddings`, "ml_generate_embedding_result", top_k => 5)
結果と cloud storage に格納されている画像見てみましたが、 だいぶ良さそうでした。もう少し調べてみます。