どっかのエンジニアの備忘録

読んで本や心に留めておきたい言葉をまとめたいと思ってます

google cloud セマンティック検索

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 に格納されている画像見てみましたが、 だいぶ良さそうでした。もう少し調べてみます。