SQL と Python を使用してマルチモーダル データを分析する
このチュートリアルでは、SQL クエリと Python ユーザー定義関数(UDF)を使用してマルチモーダル データを分析する方法について説明します。
このチュートリアルでは、一般公開されている Cymbal ペットショップ データセットの商品カタログを使用します。
目標
ObjectRef
値を使用して、BigQuery の標準テーブルに構造化データとともに画像データを保存します。AI.GENERATE_TABLE
関数を使用して、標準テーブルの画像データに基づいてテキストを生成します。- Python UDF を使用して既存の画像を変換し、新しい画像を作成します。
- Python UDF を使用して PDF をチャンク化し、詳細な分析を行います。
- Gemini モデルと
ML.GENERATE_TEXT
関数を使用して、チャンク化された PDF データを分析します。 ML.GENERATE_EMBEDDING
関数を使用して、標準テーブルの画像データに基づいてエンベディングを生成します。ObjectRef
値の配列を使用して、順序付きマルチモーダル データを処理します。
料金
このドキュメントでは、課金対象である次の Trusted Cloud by S3NSコンポーネントを使用します。
- BigQuery: you incur costs for the data that you process in BigQuery.
- BigQuery Python UDFs: you incur costs for using Python UDFs.
- Cloud Storage: you incur costs for the objects stored in Cloud Storage.
- Vertex AI: you incur costs for calls to Vertex AI models.
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
詳細については、次の料金ページをご覧ください。
始める前に
-
In the Trusted Cloud console, on the project selector page, select or create a Trusted Cloud project.
-
Make sure that billing is enabled for your Trusted Cloud project.
-
Enable the BigQuery, BigQuery Connection, Cloud Storage, and Vertex AI APIs.
必要なロール
このチュートリアルを完了するために必要な権限を取得するには、管理者に次の IAM ロールを付与するよう依頼してください。
-
接続を作成します。
BigQuery 接続管理者 (
roles/bigquery.connectionAdmin
) -
接続のサービス アカウントに権限を付与する: プロジェクト IAM 管理者 (
roles/resourcemanager.projectIamAdmin
) -
Cloud Storage バケットを作成します。
ストレージ管理者 (
roles/storage.admin
) -
データセット、モデル、UDF、テーブルを作成し、BigQuery ジョブを実行する:
BigQuery 管理者 (
roles/bigquery.admin
) -
Cloud Storage オブジェクトの読み取りと変更を許可する URL を作成します。
BigQuery ObjectRef 管理者 (
roles/bigquery.objectRefAdmin
)
ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
設定
このセクションでは、このチュートリアルで使用するデータセット、接続、テーブル、モデルを作成します。
データセットを作成する
このチュートリアルで作成するオブジェクトを含む BigQuery データセットを作成します。
Trusted Cloud コンソールで、[BigQuery] ページに移動します。
[エクスプローラ] ペインでプロジェクトを選択します。
[
アクション] オプションを開き、[データセットを作成] をクリックします。[データセットを作成] ペインが開きます。[データセット ID] に「
cymbal_pets
」と入力します。[データセットを作成] をクリックします。
バケットの作成
変換されたオブジェクトを保存する Cloud Storage バケットを作成します。
[バケット] ページに移動します。
[
作成] をクリックします。[バケットの作成] ページの [始める] セクションで、バケット名の要件を満たすグローバルに一意の名前を入力します。
[作成] をクリックします。
接続を作成する
クラウド リソース接続を作成し、接続のサービス アカウントを取得します。BigQuery は、この接続を使用して Cloud Storage 内のオブジェクトにアクセスします。
[BigQuery] ページに移動します。
[エクスプローラ] ペインで、
[データを追加] をクリックします。[データを追加] ダイアログが開きます。
[フィルタ条件] ペインの [データソースのタイプ] セクションで、[ビジネス アプリケーション] を選択します。
または、[データソースを検索] フィールドに「
Vertex AI
」と入力します。[特徴量データソース] セクションで、[Vertex AI] をクリックします。
[Vertex AI モデル: BigQuery フェデレーション] ソリューション カードをクリックします。
[接続タイプ] リストで、[Vertex AI リモートモデル、リモート関数、BigLake(Cloud リソース)] を選択します。
[接続 ID] フィールドに「
cymbal_conn
」と入力します。[接続を作成] をクリックします。
[接続へ移動] をクリックします。
[接続情報] ペインで、次の手順で使用するサービス アカウント ID をコピーします。
接続のサービス アカウントに権限を付与する
他のサービスにアクセスするために、接続のサービス アカウントに適切なロールを付与します。これらのロールは、始める前にで作成または選択したプロジェクトで付与する必要があります。別のプロジェクトでロールを付与すると、bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.s3ns-system.iam.gserviceaccount.com
does not have the permission to access resource
エラーが発生します。
Cloud Storage バケットに対する権限を付与する
作成したバケット内のオブジェクトを使用するためのアクセス権をサービス アカウントに付与します。
[バケット] ページに移動します。
作成したバケットの名前をクリックします。
[権限] をクリックします。
[
アクセスを許可] をクリックします。[アクセス権を付与] ダイアログが開きます。[新しいプリンシパル] フィールドに、前の手順でコピーしたサービス アカウント ID を入力します。
[ロールを選択] フィールドで、[Cloud Storage] を選択し、[Storage オブジェクト ユーザー] を選択します。
[保存] をクリックします。
Vertex AI モデルを使用する権限を付与する
Vertex AI モデルを使用するアクセス権をサービス アカウントに付与します。
[IAM と管理] ページに移動します。
[
アクセスを許可] をクリックします。[アクセス権を付与] ダイアログが開きます。[新しいプリンシパル] フィールドに、前の手順でコピーしたサービス アカウント ID を入力します。
[ロールを選択] フィールドで、[Vertex AI] を選択し、[Vertex AI ユーザー] を選択します。
[保存] をクリックします。
サンプルデータのテーブルを作成する
Cymbal ペット商品情報を格納するテーブルを作成します。
products
テーブルを作成する
Cymbal ペット商品情報を含む標準テーブルを作成します。
Trusted Cloud コンソールで、[BigQuery] ページに移動します。
クエリエディタで、次のクエリを実行して
products
テーブルを作成します。LOAD DATA OVERWRITE cymbal_pets.products FROM FILES( format = 'avro', uris = [ 'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/tables/products/products_*.avro']);
product_images
テーブルを作成する
Cymbal ペット商品の画像を含むオブジェクト テーブルを作成します。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
product_images
テーブルを作成します。CREATE OR REPLACE EXTERNAL TABLE cymbal_pets.product_images WITH CONNECTION `us.cymbal_conn` OPTIONS ( object_metadata = 'SIMPLE', uris = ['gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/images/*.png'], max_staleness = INTERVAL 30 MINUTE, metadata_cache_mode = AUTOMATIC);
product_manuals
テーブルを作成する
Cymbal ペット製品のマニュアルを含むオブジェクト テーブルを作成します。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
product_manuals
テーブルを作成します。CREATE OR REPLACE EXTERNAL TABLE cymbal_pets.product_manuals WITH CONNECTION `us.cymbal_conn` OPTIONS ( object_metadata = 'SIMPLE', uris = ['gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/documents/*.pdf']);
テキスト生成モデルを作成する
Vertex AI Gemini モデルを表す BigQuery ML リモートモデルを作成します。
[BigQuery] ページのクエリエディタで、次のクエリを実行してリモートモデルを作成します。
CREATE OR REPLACE MODEL `cymbal_pets.gemini` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'gemini-2.0-flash');
エンベディング生成モデルを作成する
Vertex AI マルチモーダル エンベディング モデルを表す BigQuery ML リモートモデルを作成します。
[BigQuery] ページのクエリエディタで、次のクエリを実行してリモートモデルを作成します。
CREATE OR REPLACE MODEL `cymbal_pets.embedding_model` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'multimodalembedding@001');
マルチモーダル データを含む products_mm
テーブルを作成する
product_images
オブジェクト テーブルの商品画像が入力された image
列を含む products_mm
テーブルを作成します。作成される image
列は、ObjectRef
形式を使用する STRUCT
列です。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
products_mm
テーブルを作成し、image
列にデータを入力します。CREATE OR REPLACE TABLE cymbal_pets.products_mm AS SELECT products.* EXCEPT (uri), ot.ref AS image FROM cymbal_pets.products INNER JOIN cymbal_pets.product_images ot ON ot.uri = products.uri;
[BigQuery] ページのクエリエディタで、次のクエリを実行して
image
列データを表示します。SELECT product_name, image FROM cymbal_pets.products_mm`
結果は次のようになります。
+--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | product_name | image.uri | image.version | image.authorizer | image.details | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | AquaClear Aquarium Background | gs://cloud-samples-data/bigquery/ | 1234567891011 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"image/png", | | | tutorials/cymbal-pets/images/ | | | "md5_hash":"494f63b9b137975ff3e7a11b060edb1d", | | | aquaclear-aquarium-background.png | | | "size":1282805,"updated":1742492680017000}} | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | AquaClear Aquarium | gs://cloud-samples-data/bigquery/ | 2345678910112 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"image/png", | | Gravel Vacuum | tutorials/cymbal-pets/images/ | | | "md5_hash":"b7bfc2e2641a77a402a1937bcf0003fd", | | | aquaclear-aquarium-gravel-vacuum.png | | | "size":820254,"updated":1742492682411000}} | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | ... | ... | ... | | ... | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
Gemini モデルを使用して商品情報を生成する
Gemini モデルを使用して、ペットショップの商品に関する次のデータを生成します。
products_mm
テーブルにimage_description
列を追加します。products_mm
テーブルのanimal_type
、search_keywords
、subcategory
列にデータを入力します。- 各商品ブランドの説明と、そのブランドの商品数を返すクエリを実行します。ブランドの説明は、そのブランドのすべての商品の商品情報(商品画像を含む)を分析して生成されます。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
image_description
列を作成してデータを入力します。CREATE OR REPLACE TABLE cymbal_pets.products_mm AS SELECT product_id, product_name, brand, category, subcategory, animal_type, search_keywords, price, description, inventory_level, supplier_id, average_rating, image, image_description FROM AI.GENERATE_TABLE( MODEL `cymbal_pets.gemini`, ( SELECT ('Can you describe the following image?', OBJ.GET_ACCESS_URL(image, 'r')) AS prompt, * FROM cymbal_pets.products_mm ), STRUCT('image_description STRING' AS output_schema));
[BigQuery] ページのクエリ エディタで、次のクエリを実行して、
animal_type
、search_keywords
、subcategory
列を生成するデータで更新します。UPDATE cymbal_pets.products_mm p SET p.animal_type = s.animal_type, p.search_keywords = s.search_keywords, p.subcategory = s.subcategory FROM ( SELECT animal_type, search_keywords, subcategory, uri FROM AI.GENERATE_TABLE( MODEL `cymbal_pets.gemini`, ( SELECT ( 'For the image of a pet product, concisely generate the following metadata.' '1) animal_type and 2) 5 SEO search keywords, and 3) product subcategory', OBJ.GET_ACCESS_URL(image, 'r'), description) AS prompt, image.uri AS uri, FROM cymbal_pets.products_mm ), STRUCT( 'animal_type STRING, search_keywords ARRAY<STRING>, subcategory STRING' AS output_schema, 100 AS max_output_tokens)) ) s WHERE p.image.uri = s.uri;
[BigQuery] ページのクエリエディタで、次のクエリを実行して生成されたデータを表示します。
SELECT product_name, image_description, animal_type, search_keywords, subcategory, FROM cymbal_pets.products_mm;
結果は次のようになります。
+--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | product_name | image.description | animal_type | search_keywords | subcategory | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | AquaClear Aquarium Background | The image shows a colorful coral | fish | aquarium background | aquarium decor | | | reef backdrop. The background is a | | fish tank backdrop | | | | blue ocean with a bright light... | | coral reef decor | | | | | | underwater scenery | | | | | | aquarium decoration | | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | AquaClear Aquarium | The image shows a long, clear | fish | aquarium gravel vacuum | aquarium | | Gravel Vacuum | plastic tube with a green hose | | aquarium cleaning | cleaning | | | attached to one end. The tube... | | aquarium maintenance | | | | | | fish tank cleaning | | | | | | gravel siphon | | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | ... | ... | ... | ... | ... | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
[BigQuery] ページのクエリエディタで、次のクエリを実行して、各商品ブランドの説明と、そのブランドの商品数を生成します。
SELECT brand, brand_description, cnt FROM AI.GENERATE_TABLE( MODEL `cymbal_pets.gemini`, ( SELECT brand, COUNT(*) AS cnt, ( 'Use the images and text to give one concise brand description for a website brand page.' 'Return the description only.', ARRAY_AGG(OBJ.GET_ACCESS_URL(image, 'r')), ARRAY_AGG(description), ARRAY_AGG(category), ARRAY_AGG(subcategory)) AS prompt FROM cymbal_pets.products_mm GROUP BY brand ), STRUCT('brand_description STRING' AS output_schema)) ORDER BY cnt DESC;
結果は次のようになります。
+--------------+-------------------------------------+-----+ | brand | brand.description | cnt | +--------------+-------------------------------------+-----+ | AquaClear | AquaClear is a brand of aquarium | 33 | | | and pond care products that offer | | | | a wide range of solutions for... | | +--------------+-------------------------------------+-----+ | Ocean | Ocean Bites is a brand of cat food | 28 | | Bites | that offers a variety of recipes | | | | and formulas to meet the specific.. | | +--------------+-------------------------------------+-----+ | ... | ... |... | +--------------+-------------------------------------+-----+
Python UDF を作成して商品画像を変換する
Python UDF を作成して、商品画像をグレースケールに変換します。
Python UDF はオープンソース ライブラリを使用し、また並列実行を使用して複数の画像を同時に変換します。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
to_grayscale
UDF を作成します。CREATE OR REPLACE FUNCTION cymbal_pets.to_grayscale(src_json STRING, dst_json STRING) RETURNS STRING LANGUAGE python WITH CONNECTION `us.cymbal_conn` OPTIONS (entry_point='to_grayscale', runtime_version='python-3.11', packages=['numpy', 'opencv-python']) AS """ import cv2 as cv import numpy as np from urllib.request import urlopen, Request import json # Transform the image to grayscale. def to_grayscale(src_ref, dst_ref): src_json = json.loads(src_ref) srcUrl = src_json["access_urls"]["read_url"] dst_json = json.loads(dst_ref) dstUrl = dst_json["access_urls"]["write_url"] req = urlopen(srcUrl) arr = np.asarray(bytearray(req.read()), dtype=np.uint8) img = cv.imdecode(arr, -1) # 'Load it as it is' # Convert the image to grayscale gray_image = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # Send POST request to the URL _, img_encoded = cv.imencode('.png', gray_image) req = Request(url=dstUrl, data=img_encoded.tobytes(), method='PUT', headers = { "Content-Type": "image/png", }) with urlopen(req) as f: pass return dst_ref """;
商品画像を変換する
グレースケール画像の宛先パスと認証情報を格納する ObjectRef
列を持つ products_grayscale
テーブルを作成します。宛先パスは元のイメージパスから派生します。
テーブルを作成したら、to_grayscale
関数を実行してグレースケール画像を作成し、Cloud Storage バケットに書き込みます。次に、グレースケール画像のアクセス URL とメタデータを含む ObjectRefRuntime
値を返します。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
products_grayscale
テーブルを作成します。CREATE OR REPLACE TABLE cymbal_pets.products_grayscale AS SELECT product_id, product_name, image, OBJ.MAKE_REF( CONCAT('gs://BUCKET/cymbal-pets-images/grayscale/', REGEXP_EXTRACT(image.uri, r'([^/]+)$')), 'us.cymbal_conn') AS gray_image FROM cymbal_pets.products_mm;
BUCKET
は、作成したバケットの名前に置き換えます。[BigQuery] ページのクエリエディタで、次のクエリを実行してグレースケール画像を作成し、Cloud Storage バケットに書き込みます。次に、グレースケール画像のアクセス URL とメタデータを含む
ObjectRefRuntime
値を返します。SELECT cymbal_pets.to_grayscale( TO_JSON_STRING(OBJ.GET_ACCESS_URL(image, 'r')), TO_JSON_STRING(OBJ.GET_ACCESS_URL(gray_image, 'rw'))) FROM cymbal_pets.products_grayscale;
結果は次のようになります。
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | f0 | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | {"access_urls":{"expiry_time":"2025-04-26T03:00:48Z", | | "read_url":"https://storage.googleapis.com/mybucket/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_read URL_information", | | "write_url":"https://storage.googleapis.com/myproject/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_write URL_information"}, | | "objectref":{"authorizer":"myproject.region.myconnection","uri":"gs://myproject/cymbal-pets-images/grayscale/ocean-bites-salmon-&-tuna-cat-food.png"}} | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | {"access_urls":{"expiry_time":"2025-04-26T03:00:48Z", | | "read_url":"https://storage.googleapis.com/mybucket/cymbal-pets-images%2Fgrayscale%2Ffluffy-buns-guinea-pig-tunnel.png?additional _read URL_information", | | "write_url":"https://storage.googleapis.com/myproject/cymbal-pets-images%2Fgrayscale%2Focean-bites-salmon-%26-tuna-cat-food.png?additional_write_URL_information"}, | | "objectref":{"authorizer":"myproject.region.myconnection","uri":"gs://myproject/cymbal-pets-images%2Fgrayscale%2Ffluffy-buns-guinea-pig-tunnel.png"}} | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Python UDF を作成して PDF データをチャンク化する
Python UDF を作成して、Cymbal ペット製品のマニュアルを含む PDF オブジェクトを複数のパートに分割します。
PDF は非常に大きい場合が多く、生成 AI モデルへの単一の呼び出しに収まらない可能性があります。PDF をチャンク化することで、PDF データをモデル対応の形式で保存し、分析を容易にできます。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
chunk_pdf
UDF を作成します。-- This function chunks the product manual PDF into multiple parts. -- The function accepts an ObjectRefRuntime value for the PDF file and the chunk size. -- It then parses the PDF, chunks the contents, and returns an array of chunked text. CREATE OR REPLACE FUNCTION cymbal_pets.chunk_pdf(src_json STRING, chunk_size INT64, overlap_size INT64) RETURNS ARRAY<STRING> LANGUAGE python WITH CONNECTION `us.cymbal_conn` OPTIONS (entry_point='chunk_pdf', runtime_version='python-3.11', packages=['pypdf']) AS """ import io import json from pypdf import PdfReader # type: ignore from urllib.request import urlopen, Request def chunk_pdf(src_ref: str, chunk_size: int, overlap_size: int) -> str: src_json = json.loads(src_ref) srcUrl = src_json["access_urls"]["read_url"] req = urlopen(srcUrl) pdf_file = io.BytesIO(bytearray(req.read())) reader = PdfReader(pdf_file, strict=False) # extract and chunk text simultaneously all_text_chunks = [] curr_chunk = "" for page in reader.pages: page_text = page.extract_text() if page_text: curr_chunk += page_text # split the accumulated text into chunks of a specific size with overlaop # this loop implements a sliding window approach to create chunks while len(curr_chunk) >= chunk_size: split_idx = curr_chunk.rfind(" ", 0, chunk_size) if split_idx == -1: split_idx = chunk_size actual_chunk = curr_chunk[:split_idx] all_text_chunks.append(actual_chunk) overlap = curr_chunk[split_idx + 1 : split_idx + 1 + overlap_size] curr_chunk = overlap + curr_chunk[split_idx + 1 + overlap_size :] if curr_chunk: all_text_chunks.append(curr_chunk) return all_text_chunks """;
PDF データを分析する
chunk_pdf
関数を実行して product_manuals
テーブルの PDF データをチャンクに分割し、行ごとに 1 つの PDF チャンクを含む product_manual_chunk_strings
テーブルを作成します。product_manual_chunk_strings
データに Gemini モデルを使用して、製品マニュアルに記載されている法的情報を要約します。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
product_manual_chunk_strings
テーブルを作成します。CREATE OR REPLACE TABLE cymbal_pets.product_manual_chunk_strings AS SELECT chunked FROM cymbal_pets.product_manuals, UNNEST (cymbal_pets.chunk_pdf( TO_JSON_STRING( OBJ.GET_ACCESS_URL(OBJ.MAKE_REF(uri, 'us.cymbal_conn'), 'r')), 1000, 100 )) as chunked;
[BigQuery] ページのクエリエディタで、次のクエリを実行して Gemini モデルを使用して PDF データを分析します。
SELECT ml_generate_text_llm_result FROM ML.GENERATE_TEXT( MODEL `cymbal_pets.gemini`, ( SELECT ( 'Can you summarize the product manual as bullet points? Highlight the legal clauses', chunked) AS prompt, FROM cymbal_pets.product_manual_chunk_strings ), STRUCT( TRUE AS FLATTEN_JSON_OUTPUT));
結果は次のようになります。
+-------------------------------------------------------------------------------------------------------------------------------------------+ | ml_generate_text_llm_result | +-------------------------------------------------------------------------------------------------------------------------------------------+ | ## CritterCuisine Pro 5000 Automatic Pet Feeder Manual Summary: | | | | **Safety:** | | | | * **Stability:** Place feeder on a level, stable surface to prevent tipping. | | * **Power Supply:** Only use the included AC adapter. Using an incompatible adapter can damage the unit and void the warranty. | | * **Cord Safety:** Keep the power cord out of reach of pets to prevent chewing or entanglement. | | * **Children:** Supervise children around the feeder. This is not a toy. | | * **Pet Health:** Consult your veterinarian before using an automatic feeder if your pet has special dietary needs, health conditions, or | +-------------------------------------------------------------------------------------------------------------------------------------------+ | ## Product Manual Summary: | | | | **6.3 Manual Feeding:** | | | | * Press MANUAL button to dispense a single portion (Meal 1 size). **(Meal Enabled)** | | | | **6.4 Recording a Voice Message:** | | | | * Press and hold VOICE button. | | * Speak clearly into the microphone (up to 10 seconds). | | * Release VOICE button to finish recording. | | * Briefly press VOICE button to play back the recording. | | * To disable the voice message, record a blank message (hold VOICE button for 10 seconds without speaking). **(Meal Enabled)** | | | | **6.5 Low Food Level Indicator:** | +-------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-------------------------------------------------------------------------------------------------------------------------------------------+
エンベディングを生成し、ベクトル検索を実行する
画像データからエンベディングを生成し、エンベディングを使用してベクトル検索で類似画像を返します。
本番環境のシナリオでは、ベクトル検索を実行する前にベクトル インデックスを作成することをおすすめします。ベクトル インデックスを使用すると、ベクトル検索をより迅速に実行できますが、再現率が低下するため、より近似的な結果が返されます。
[BigQuery] ページのクエリエディタで、次のクエリを実行して
products_embeddings
テーブルを作成します。CREATE OR REPLACE TABLE cymbal_pets.products_embedding AS SELECT product_id, ml_generate_embedding_result as embedding, content as image FROM ML.GENERATE_EMBEDDING( MODEL `cymbal_pets.embedding_model`, ( SELECT OBJ.GET_ACCESS_URL(image, 'r') as content, image, product_id FROM cymbal_pets.products_mm ), STRUCT () );
[BigQuery] ページのクエリエディタで、次のクエリを実行してベクトル検索を実行し、指定された入力画像に類似した商品画像を返します。
SELECT * FROM VECTOR_SEARCH( TABLE cymbal_pets.products_embedding, 'embedding', (SELECT ml_generate_embedding_result as embedding FROM ML.GENERATE_EMBEDDING( MODEL `cymbal_pets.embedding_model`, (SELECT OBJ.FETCH_METADATA(OBJ.MAKE_REF('gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/images/cozy-naps-cat-scratching-post-with-condo.png', 'us.cymbal_conn')) as content) )) );
結果は次のようになります。
+-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | query.embedding | base.product_id | base.embedding | base.image.uri | base.image.version | base.image.authorizer | base.image.details | distance | +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | -0.0112330541 | 181 | -0.0112330541 | gs://cloud-samples-data/bigquery/ | 12345678910 | myproject.region.myconnection | {"gcs_metadata":{"content_type": | 0.0 | | 0.0142525584 | | 0.0142525584 | tutorials/cymbal-pets/images/ | | | "image/png","md5_hash":"21234567hst16555w60j", | | | 0.0135886827 | | 0.0135886827 | cozy-naps-cat-scratching-post-with-condo.png | | | "size":828318,"updated":1742492688982000}} | | | 0.0149955815 | | 0.0149955815 | | | | | | | ... | | ... | | | | | | | | | | | | | | | | | | | | | | | | +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | -0.0112330541 | 187 | -0.0190353896 | gs://cloud-samples-data/bigquery/ | 23456789101 | myproject.region.myconnection | {"gcs_metadata":{"content_type": | 0.4216330832.. | | 0.0142525584 | | 0.0116206668 | tutorials/cymbal-pets/images/ | | | "image/png","md5_hash":"7328728fhakd9937djo4", | | | 0.0135886827 | | 0.0136198215 | cozy-naps-cat-scratching-post-with-bed.png | | | "size":860113,"updated":1742492688774000}} | | | 0.0149955815 | | 0.0173457414 | | | | | | | ... | | ... | | | | | | | | | | | | | | | | | | | | | | | | +---------C--------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | ... | ... | ... | ... | ... | ... | ... | ... | +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
ObjectRef
値の配列を使用して順序付きマルチモーダル データを処理する
このセクションでは、次のタスクを行う方法を説明します。
product_manuals
テーブルを再作成して、Crittercuisine 5000
製品マニュアルの PDF ファイルと、そのマニュアルの各ページの PDF ファイルの両方が含まれるようにします。- マニュアルをチャンクにマッピングするテーブルを作成します。マニュアル全体を表す
ObjectRef
値は、STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
列に保存されます。マニュアル ページを表すObjectRef
値は、ARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
列に格納されます。 ObjectRef
値の配列をまとめて分析し、生成された単一の値を返します。ObjectRef
値の配列を個別に分析し、配列値ごとに生成された値を返します。
分析タスクの一環として、ObjectRef
値の配列を ObjectRefRuntime
値の順序付きリストに変換し、そのリストを Gemini モデルに渡して、プロンプトの一部として ObjectRefRuntime
値を指定します。ObjectRefRuntime
値は、モデルが Cloud Storage 内のオブジェクト情報にアクセスするために使用する署名付き URL を提供します。
ObjectRef
値の配列を使用して順序付きマルチモーダル データを処理する手順は次のとおりです。
[BigQuery] ページに移動します。
クエリエディタで、次のクエリを実行して
product_manuals
テーブルを再作成します。CREATE OR REPLACE EXTERNAL TABLE `cymbal_pets.product_manuals` WITH CONNECTION `us.cymbal_conn` OPTIONS ( object_metadata = 'SIMPLE', uris = [ 'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/documents/*.pdf', 'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/document_chunks/*.pdf']);
クエリエディタで次のクエリを実行して、PDF データを
map_manual_to_chunks
テーブルに書き込みます。-- Extract the file and chunks into a single table. -- Store the chunks in the chunks column as array of ObjectRefs (ordered by page number) CREATE OR REPLACE TABLE cymbal_pets.map_manual_to_chunks AS SELECT ARRAY_AGG(m1.ref)[0] manual, ARRAY_AGG(m2.ref ORDER BY m2.ref.uri) chunks FROM cymbal_pets.product_manuals m1 JOIN cymbal_pets.product_manuals m2 ON REGEXP_EXTRACT(m1.uri, r'.*/([^.]*).[^/]+') = REGEXP_EXTRACT(m2.uri, r'.*/([^.]*)_page[0-9]+.[^/]+') GROUP BY m1.uri;
クエリエディタで次のクエリを実行して、
map_manual_to_chunks
テーブルの PDF データを表示します。SELECT * FROM cymbal_pets.map_manual_to_chunks;
結果は次のようになります。
+-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | manual.uri | manual.version | manual.authorizer | manual.details | chunks.uri | chunks.version | chunks.authorizer | chunks.details | +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | gs://cloud-samples-data/bigquery/ | 1742492785900455 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"application/pef", | gs://cloud-samples-data/bigquery/ | 1745875761227129 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"application/pdf", | | tutorials/cymbal-pets/documents/ | | | "md5_hash":"c9032b037693d15a33210d638c763d0e", | tutorials/cymbal-pets/documents/ | | | "md5_hash":"5a1116cce4978ec1b094d8e8b49a1d7c", | | crittercuisine_5000_user_manual.pdf | | | "size":566105,"updated":1742492785941000}} | crittercuisine_5000_user_manual_page1.pdf | | | "size":504583,"updated":1745875761266000}} | | | | | +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | | | | | crittercuisine_5000_user_manual_page1.pdf | 1745875760613874 | myproject.region.myconnection | {"gcs_metadata":{"content_type":"application/pdf", | | | | | | tutorials/cymbal-pets/documents/ | | | "md5_hash":"94d03ec65d28b173bc87eac7e587b325", | | | | | | crittercuisine_5000_user_manual_page2.pdf | | | "size":94622,"updated":1745875760649000}} | | | | | +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | | | | | ... | ... | ... | ... | +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
クエリエディタで次のクエリを実行して、
ObjectRef
値の配列の分析に基づいて Gemini モデルから単一のレスポンスを生成します。WITH manuals AS ( SELECT OBJ.GET_ACCESS_URL(manual, 'r') AS manual, ARRAY( SELECT OBJ.GET_ACCESS_URL(chunk, 'r') AS chunk FROM UNNEST(m1.chunks) AS chunk WITH OFFSET AS idx ORDER BY idx ) AS chunks FROM cymbal_pets.map_manual_to_chunks AS m1 ) SELECT ml_generate_text_llm_result AS Response FROM ML.GENERATE_TEXT( MODEL `cymbal_pets.gemini`, ( SELECT ( 'Can you provide a page by page summary for the first 3 pages of the attached manual? Only write one line for each page. The pages are provided in serial order', manuals.chunks) AS prompt, FROM manuals ), STRUCT(TRUE AS FLATTEN_JSON_OUTPUT));
結果は次のようになります。
+-------------------------------------------+ | Response | +-------------------------------------------+ | Page 1: This manual is for the | | CritterCuisine Pro 5000 automatic | | pet feeder. | | Page 2: The manual covers safety | | precautions, what's included, | | and product overview. | | Page 3: The manual covers assembly, | | initial setup, and programming the clock. | +-------------------------------------------+
クエリエディタで次のクエリを実行して、
ObjectRef
値の配列の分析に基づいて Gemini モデルから複数のレスポンスを生成します。WITH input_chunked_objrefs AS ( SELECT row_id, offset, chunk_ref FROM ( SELECT ROW_NUMBER() OVER () AS row_id, * FROM `cymbal_pets.map_manual_to_chunks` ) AS indexed_table LEFT JOIN UNNEST(indexed_table.chunks) AS chunk_ref WITH OFFSET ), get_access_urls AS ( SELECT row_id, offset, chunk_ref, OBJ.GET_ACCESS_URL(chunk_ref, 'r') AS ObjectRefRuntime FROM input_chunked_objrefs ), valid_get_access_urls AS ( SELECT * FROM get_access_urls WHERE ObjectRefRuntime['runtime_errors'] IS NULL ), ordered_output_objrefruntime_array AS ( SELECT ARRAY_AGG(ObjectRefRuntime ORDER BY offset) AS ObjectRefRuntimeArray FROM valid_get_access_urls GROUP BY row_id ) SELECT page1_summary, page2_summary, page3_summary FROM AI.GENERATE_TABLE( MODEL `cymbal_pets.gemini`, ( SELECT ( 'Can you provide a page by page summary for the first 3 pages of the attached manual? Only write one line for each page. The pages are provided in serial order', ObjectRefRuntimeArray) AS prompt, FROM ordered_output_objrefruntime_array ), STRUCT( 'page1_summary STRING, page2_summary STRING, page3_summary STRING' AS output_schema));
結果は次のようになります。
+-----------------------------------------------+-------------------------------------------+----------------------------------------------------+ | page1_summary | page2_summary | page3_summary | +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+ | This manual provides an overview of the | This section explains how to program | This page covers connecting the feeder to Wi-Fi | | CritterCuisine Pro 5000 automatic pet feeder, | the feeder's clock, set feeding | using the CritterCuisine Connect app, remote | | including its features, safety precautions, | schedules, copy and delete meal settings, | feeding, managing feeding schedules, viewing | | assembly instructions, and initial setup. | manually feed your pet, record | feeding logs, receiving low food alerts, | | | a voice message, and understand | updating firmware, creating multiple pet profiles, | | | the low food level indicator. | sharing access with other users, and cleaning | | | | and maintaining the feeder. | +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
クリーンアップ
- In the Trusted Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.