Multimodale Daten mit SQL und Python analysieren
In dieser Anleitung erfahren Sie, wie Sie multimodale Daten mit SQL-Abfragen und benutzerdefinierten Python-Funktionen (UDFs) analysieren.
In dieser Anleitung wird der Produktkatalog aus dem öffentlichen Dataset des Cymbal-Zoofachgeschäfts verwendet.
Lernziele
- Verwenden Sie
ObjectRef
-Werte, um Bilddaten zusammen mit strukturierten Daten in einer BigQuery-Standardtabelle zu speichern. - Mit der
AI.GENERATE_TABLE
-Funktion können Sie Text basierend auf Bilddaten aus einer Standardtabelle generieren. - Mit einem Python-UDF vorhandene Bilder in neue Bilder umwandeln
- Mithilfe eines Python-UDF können Sie PDFs in kleinere Teile für die weitere Analyse aufteilen.
- Verwenden Sie ein Gemini-Modell und die
ML.GENERATE_TEXT
-Funktion, um die gechunkten PDF-Daten zu analysieren. - Mit der
ML.GENERATE_EMBEDDING
-Funktion können Sie Einbettungen basierend auf Bilddaten aus einer Standardtabelle generieren. - Verarbeiten Sie geordnete multimodale Daten mit Arrays von
ObjectRef
-Werten.
Kosten
In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:
- 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.
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.
Weitere Informationen finden Sie auf den folgenden Preisseiten:
Hinweise
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the BigQuery, BigQuery Connection, Cloud Storage, and Vertex AI APIs.
Erforderliche Rollen
Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Ausführen dieser Anleitung benötigen:
-
Verbindung erstellen:
BigQuery-Verbindungsadministrator (
roles/bigquery.connectionAdmin
) -
Gewähren Sie dem Dienstkonto der Verbindung Berechtigungen:
Projekt-IAM-Administrator (
roles/resourcemanager.projectIamAdmin
) -
Cloud Storage-Bucket erstellen:
Storage-Administrator (
roles/storage.admin
) -
Datasets, Modelle, UDFs und Tabellen erstellen und BigQuery-Jobs ausführen:
BigQuery-Administrator (
roles/bigquery.admin
) -
URLs erstellen, mit denen Sie Cloud Storage-Objekte lesen und ändern können:
BigQuery ObjectRef Admin (
roles/bigquery.objectRefAdmin
)
Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.
Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.
Einrichten
In diesem Abschnitt erstellen Sie das Dataset, die Verbindung, die Tabellen und die Modelle, die in dieser Anleitung verwendet werden.
Dataset erstellen
Erstellen Sie ein BigQuery-Dataset, das die Objekte enthält, die Sie in dieser Anleitung erstellen:
Rufen Sie in der Google Cloud Console die Seite BigQuery auf.
Wählen Sie im Bereich Explorer Ihr Projekt aus.
Maximieren Sie die Option
Aktionen und klicken Sie auf Dataset erstellen. Der Bereich Dataset erstellen wird geöffnet.Geben Sie als Dataset-ID den String
cymbal_pets
ein.Klicken Sie auf Dataset erstellen.
Bucket erstellen
Erstellen Sie einen Cloud Storage-Bucket zum Speichern der umgewandelten Objekte:
Rufen Sie die Seite Buckets auf.
Klicken Sie auf
Erstellen.Geben Sie auf der Seite Bucket erstellen im Bereich Einstieg einen global eindeutigen Namen ein, der den Anforderungen für Bucket-Namen entspricht.
Klicken Sie auf Erstellen.
Verbindung herstellen
Erstellen Sie eine Cloud-Ressourcenverbindung und rufen Sie das Dienstkonto der Verbindung ab. BigQuery verwendet die Verbindung, um auf Objekte in Cloud Storage zuzugreifen:
Rufen Sie die Seite BigQuery auf.
Klicken Sie im Bereich Explorer auf
Daten hinzufügen.Das Dialogfeld Daten hinzufügen wird geöffnet.
Wählen Sie im Bereich Nach im Abschnitt Datenquellentyp die Option Geschäftsanwendungen aus.
Alternativ können Sie im Feld Nach Datenquellen suchen den Wert
Vertex AI
eingeben.Klicken Sie im Bereich Empfohlene Datenquellen auf Vertex AI.
Klicken Sie auf die Lösungskarte Vertex AI-Modelle: BigQuery-Verknüpfung.
Wählen Sie in der Liste Verbindungstyp die Option Vertex AI-Remote-Modelle, Remote-Funktionen und BigLake (Cloud-Ressource) aus.
Geben Sie im Feld Verbindungs-ID
cymbal_conn
ein.Klicken Sie auf Verbindung erstellen.
Klicken Sie auf Zur Verbindung.
Kopieren Sie im Bereich Verbindungsinformationen die Dienstkonto-ID zur Verwendung in einem folgenden Schritt.
Dem Dienstkonto der Verbindung Berechtigungen gewähren
Weisen Sie dem Dienstkonto der Verbindung die entsprechenden Rollen für den Zugriff auf andere Dienste zu. Sie müssen diese Rollen in demselben Projekt gewähren, das Sie im Abschnitt Vorbereitung erstellt oder ausgewählt haben. Die Zuweisung der Rollen in einem anderen Projekt führt zu dem Fehler bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com
does not have the permission to access resource
.
Berechtigungen für den Cloud Storage-Bucket gewähren
Gewähren Sie dem Dienstkonto Zugriff auf die Objekte im von Ihnen erstellten Bucket:
Rufen Sie die Seite Buckets auf.
Klicken Sie auf den Namen des von Ihnen erstellten Buckets.
Klicken Sie auf Berechtigungen.
Klicken Sie auf
Zugriff erlauben. Das Dialogfeld Zugriff erlauben wird geöffnet.Geben Sie im Feld Neue Hauptkonten die Dienstkonto-ID ein, die Sie zuvor kopiert haben.
Wählen Sie im Feld Rolle auswählen die Option Cloud Storage und dann Storage Object User aus.
Klicken Sie auf Speichern.
Berechtigungen zur Verwendung von Vertex AI-Modellen erteilen
Gewähren Sie dem Dienstkonto Zugriff auf die Verwendung von Vertex AI-Modellen:
Zur Seite IAM & Verwaltung.
Klicken Sie auf
Zugriff erlauben. Das Dialogfeld Zugriff erlauben wird geöffnet.Geben Sie im Feld Neue Hauptkonten die Dienstkonto-ID ein, die Sie zuvor kopiert haben.
Wählen Sie im Feld Rolle auswählen die Option Vertex AI und dann Vertex AI-Nutzer aus.
Klicken Sie auf Speichern.
Tabellen mit Beispieldaten erstellen
Erstellen Sie Tabellen zum Speichern der Produktinformationen von Cymbal Pets.
Tabelle products
erstellen
Erstellen Sie eine Standardtabelle mit den Produktinformationen von Cymbal Pets:
Rufen Sie in der Google Cloud Console die Seite BigQuery auf.
Führen Sie im Abfrageeditor die folgende Abfrage aus, um die Tabelle
products
zu erstellen:LOAD DATA OVERWRITE cymbal_pets.products FROM FILES( format = 'avro', uris = [ 'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/tables/products/products_*.avro']);
Tabelle product_images
erstellen
Erstellen Sie eine Objekttabelle mit den Produktbildern von Cymbal Pets:
Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle
product_images
zu erstellen: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);
Tabelle product_manuals
erstellen
Erstellen Sie eine Objekttabelle mit den Produkthandbüchern von Cymbal Pets:
Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle
product_manuals
zu erstellen: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']);
Textgenerierungsmodell erstellen
BigQuery ML-Remote-Modell erstellen, das ein Vertex AI Gemini-Modell darstellt:
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um das Remote-Modell zu erstellen:
CREATE OR REPLACE MODEL `cymbal_pets.gemini` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'gemini-2.0-flash');
Modell für die Generierung von Einbettungen erstellen
Erstellen Sie ein BigQuery ML-Remote-Modell, das ein multimodales Vertex AI-Embedding-Modell darstellt:
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um das Remote-Modell zu erstellen:
CREATE OR REPLACE MODEL `cymbal_pets.embedding_model` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'multimodalembedding@001');
products_mm
-Tabelle mit multimodalen Daten erstellen
Erstellen Sie eine products_mm
-Tabelle mit einer image
-Spalte, die mit Produktbildern aus der Objekttabelle product_images
ausgefüllt ist. Die erstellte Spalte image
ist eine STRUCT
-Spalte mit dem Format ObjectRef
.
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Tabelle
products_mm
zu erstellen und die Spalteimage
zu füllen: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;
Führen Sie auf der Seite BigQuery im Abfrageeditor die folgende Abfrage aus, um die Daten der Spalte
image
aufzurufen:SELECT product_name, image FROM cymbal_pets.products_mm`
Die Ergebnisse sehen in etwa so aus:
+--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | 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}} | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | ... | ... | ... | | ... | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
Produktinformationen mit einem Gemini-Modell generieren
Verwenden Sie ein Gemini-Modell, um die folgenden Daten für die Produkte im Tiergeschäft zu generieren:
- Fügen Sie der Tabelle
products_mm
die Spalteimage_description
hinzu. - Fülle die Spalten
animal_type
,search_keywords
undsubcategory
der Tabelleproducts_mm
aus. - Führen Sie eine Abfrage aus, die eine Beschreibung jeder Produktmarke und die Anzahl der Produkte dieser Marke zurückgibt. Die Markenbeschreibung wird durch die Analyse der Produktinformationen aller Produkte dieser Marke generiert, einschließlich Produktbilder.
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Spalte
image_description
zu erstellen und zu befüllen: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));
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Spalten
animal_type
,search_keywords
undsubcategory
mit generierten Daten zu aktualisieren: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;
Führen Sie auf der Seite BigQuery im Abfrageeditor die folgende Abfrage aus, um die generierten Daten aufzurufen:
SELECT product_name, image_description, animal_type, search_keywords, subcategory, FROM cymbal_pets.products_mm;
Die Ergebnisse sehen in etwa so aus:
+--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | 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 | | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | ... | ... | ... | ... | ... | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um eine Beschreibung jeder Produktmarke und eine Zählung der Anzahl der Produkte dieser Marke zu generieren:
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;
Die Ergebnisse sehen in etwa so aus:
+--------------+-------------------------------------+-----+ | 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 zum Transformieren von Produktbildern erstellen
Erstellen Sie eine Python-UDF, um Produktbilder in Graustufen umzuwandeln.
Die Python-UDF verwendet Open-Source-Bibliotheken und die parallele Ausführung , um mehrere Bilder gleichzeitig zu transformieren.
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die benutzerdefinierte Funktion
to_grayscale
zu erstellen: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 """;
Produktbilder optimieren
Erstelle die Tabelle products_grayscale
mit einer Spalte ObjectRef
, die die Zielpfade und Autorisierungen für Graustufenbilder enthält. Der Zielpfad wird aus dem Pfad des Originalbilds abgeleitet.
Nachdem Sie die Tabelle erstellt haben, führen Sie die Funktion to_grayscale
aus, um die Graustufenbilder zu erstellen, sie in einen Cloud Storage-Bucket zu schreiben und dann ObjectRefRuntime
-Werte mit Zugriffs-URLs und Metadaten für die Graustufenbilder zurückzugeben.
Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle
products_grayscale
zu erstellen: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;
Ersetzen Sie
BUCKET
durch den Namen des von Ihnen erstellten Buckets.Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die Graustufenbilder zu erstellen, in einen Cloud Storage-Bucket zu schreiben und dann
ObjectRefRuntime
-Werte mit Zugriffs-URLs und Metadaten für die Graustufenbilder zurückzugeben: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;
Die Ergebnisse sehen in etwa so aus:
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 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 zum Aufteilen von PDF-Daten erstellen
Erstellen Sie eine Python-UDF, um die PDF-Objekte mit den Produkthandbüchern von Cymbal Pets in mehrere Teile aufzuteilen.
PDFs sind oft sehr groß und passen möglicherweise nicht in einen einzelnen Aufruf eines generativen KI-Modells. Wenn Sie die PDFs in kleinere Teile aufteilen, können Sie die PDF-Daten in einem für die Modellierung geeigneten Format speichern, um sie leichter analysieren zu können.
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die benutzerdefinierte Funktion
chunk_pdf
zu erstellen:-- 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-Daten analysieren
Führen Sie die Funktion chunk_pdf
aus, um die PDF-Daten in der Tabelle product_manuals
in kleinere Teile zu zerlegen, und erstellen Sie dann eine product_manual_chunk_strings
-Tabelle mit einem PDF-Chunk pro Zeile. Verwenden Sie ein Gemini-Modell auf den product_manual_chunk_strings
-Daten, um die rechtlichen Hinweise in den Produkthandbüchern zusammenzufassen.
Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle
product_manual_chunk_strings
zu erstellen: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;
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um die PDF-Daten mit einem Gemini-Modell zu analysieren:
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));
Die Ergebnisse sehen in etwa so aus:
+-------------------------------------------------------------------------------------------------------------------------------------------+ | 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:** | +-------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-------------------------------------------------------------------------------------------------------------------------------------------+
Einbettungen generieren und eine Vektorsuche ausführen
Generieren Sie Einbettungen aus Bilddaten und verwenden Sie die Einbettungen dann, um mithilfe der Vektorsuche ähnliche Bilder zurückzugeben.
In einem Produktionsszenario empfehlen wir, vor der Durchführung einer Vektorsuche einen Vektorindex zu erstellen. Mit einem Vektorindex können Sie die Vektorsuche schneller ausführen. Der Nachteil ist, dass die Trefferquote reduziert wird und Sie so ungefähre Ergebnisse erhalten.
Führen Sie im Abfrageeditor auf der Seite BigQuery die folgende Abfrage aus, um die Tabelle
products_embeddings
zu erstellen: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 () );
Führen Sie im Abfrageeditor der Seite BigQuery die folgende Abfrage aus, um eine Vektorsuche auszuführen und Produktbilder zurückzugeben, die dem angegebenen Eingabebild ähneln:
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) )) );
Die Ergebnisse sehen in etwa so aus:
+-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | 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--------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | ... | ... | ... | ... | ... | ... | ... | ... | +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
Sortierte multimodale Daten mit Arrays von ObjectRef
-Werten verarbeiten
In diesem Abschnitt werden die folgenden Aufgaben erläutert:
- Erstellen Sie die Tabelle
product_manuals
neu, sodass sie sowohl eine PDF-Datei für dasCrittercuisine 5000
-Produkthandbuch als auch PDF-Dateien für jede Seite dieses Handbuchs enthält. - Erstellen Sie eine Tabelle, in der die einzelnen Abschnitte des Handbuchs zugeordnet sind. Der Wert
ObjectRef
, der das vollständige Handbuch darstellt, wird in einer Spalte vom TypSTRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
gespeichert. DieObjectRef
-Werte, die die manuellen Seiten darstellen, werden in einerARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
-Spalte gespeichert. - Analysieren Sie ein Array von
ObjectRef
-Werten, um einen einzelnen generierten Wert zurückzugeben. - Ein Array von
ObjectRef
-Werten wird einzeln analysiert und für jeden Arraywert wird ein generierter Wert zurückgegeben.
Im Rahmen der Analyseaufgaben wandeln Sie das Array der ObjectRef
-Werte in eine sortierte Liste von ObjectRefRuntime
-Werten um und übergeben diese Liste dann an ein Gemini-Modell. Dabei geben Sie die ObjectRefRuntime
-Werte als Teil des Prompts an. Die ObjectRefRuntime
-Werte enthalten signierte URLs, über die das Modell auf die Objektinformationen in Cloud Storage zugreift.
So verarbeiten Sie sortierte multimodale Daten mit Arrays von ObjectRef
-Werten:
Rufen Sie die Seite BigQuery auf.
Führen Sie im Abfrageeditor die folgende Abfrage aus, um die Tabelle
product_manuals
neu zu erstellen: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']);
Führen Sie im Abfrageeditor die folgende Abfrage aus, um PDF-Daten in die Tabelle
map_manual_to_chunks
zu schreiben:-- 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;
Führen Sie im Abfrageeditor die folgende Abfrage aus, um die PDF-Daten in der Tabelle
map_manual_to_chunks
aufzurufen:SELECT * FROM cymbal_pets.map_manual_to_chunks;
Die Ergebnisse sehen in etwa so aus:
+-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | 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}} | | | | | +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | | | | | ... | ... | ... | ... | +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
Führen Sie im Abfrageeditor die folgende Abfrage aus, um eine einzelne Antwort aus einem Gemini-Modell zu generieren, die auf der Analyse eines Arrays von
ObjectRef
-Werten basiert: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));
Die Ergebnisse sehen in etwa so aus:
+-------------------------------------------+ | 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. | +-------------------------------------------+
Führen Sie im Abfrageeditor die folgende Abfrage aus, um mehrere Antworten aus einem Gemini-Modell zu generieren, die auf der Analyse eines Arrays von
ObjectRef
-Werten basieren: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));
Die Ergebnisse sehen in etwa so aus:
+-----------------------------------------------+-------------------------------------------+----------------------------------------------------+ | 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. | +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
Bereinigen
- In the Google 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.