Analizza i dati multimodali con SQL e Python
Questo tutorial mostra come analizzare i dati multimodali utilizzando le query SQL e le funzioni definite dall'utente (UDF) di Python.
Questo tutorial utilizza il catalogo dei prodotti del set di dati pubblico del negozio di animali Cymbal.
Obiettivi
- Utilizza
i valori
ObjectRef
per archiviare i dati delle immagini insieme ai dati strutturati in una tabella standard BigQuery. - Genera testo in base ai dati delle immagini di una tabella standard utilizzando la
funzione
AI.GENERATE_TABLE
. - Trasforma le immagini esistenti per crearne di nuove utilizzando un UDF Python.
- Suddividi i PDF per sottoporli ad ulteriore analisi utilizzando una UDF di Python.
- Utilizza un modello Gemini e la funzione
ML.GENERATE_TEXT
per analizzare i dati PDF suddivisi in blocchi. - Genera embedding basati sui dati delle immagini di una tabella standard utilizzando la
funzione
ML.GENERATE_EMBEDDING
. - Elabora dati multimodali ordinati utilizzando array di valori
ObjectRef
.
Costi
In questo documento utilizzi i seguenti componenti fatturabili di 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.
Per generare una stima dei costi in base all'utilizzo previsto,
utilizza il Calcolatore prezzi.
Per ulteriori informazioni, consulta le seguenti pagine dei prezzi:
- Prezzi di BigQuery
- Prezzi delle funzioni UDF di Python di BigQuery
- Prezzi di Cloud Storage
- Prezzi di Vertex AI
Prima di iniziare
-
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.
Ruoli obbligatori
Per ottenere le autorizzazioni necessarie per completare questo tutorial, chiedi all'amministratore di concederti i seguenti ruoli IAM:
-
Crea una connessione:
Amministratore connessione BigQuery (
roles/bigquery.connectionAdmin
) -
Concedi le autorizzazioni all'account di servizio della connessione:
Amministratore IAM del progetto (
roles/resourcemanager.projectIamAdmin
) -
Crea un bucket Cloud Storage:
Amministrazione archiviazione (
roles/storage.admin
) -
Crea set di dati, modelli, funzioni UDF e tabelle ed esegui job BigQuery:
BigQuery Admin (
roles/bigquery.admin
) -
Crea URL che ti consentano di leggere e modificare gli oggetti Cloud Storage:
BigQuery ObjectRef Admin (
roles/bigquery.objectRefAdmin
)
Per saperne di più sulla concessione dei ruoli, consulta Gestire l'accesso a progetti, cartelle e organizzazioni.
Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.
Configura
In questa sezione crei il set di dati, la connessione, le tabelle e i modelli utilizzati in questo tutorial.
Crea un set di dati
Crea un set di dati BigQuery per contenere gli oggetti che crei in questo tutorial:
Nella console Google Cloud , vai alla pagina BigQuery.
Nel riquadro Explorer, seleziona il progetto.
Espandi l'opzione
Azioni e fai clic su Crea set di dati. Viene visualizzato il riquadro Crea set di dati.In ID set di dati, digita
cymbal_pets
.Fai clic su Crea set di dati.
Crea un bucket
Crea un bucket Cloud Storage per archiviare gli oggetti trasformati:
Vai alla pagina Bucket.
Fai clic su
Crea.Nella pagina Crea un bucket, nella sezione Inizia, inserisci un nome univoco a livello globale che soddisfi i requisiti per i nomi dei bucket.
Fai clic su Crea.
Crea una connessione
Crea una connessione a una risorsa Cloud e recupera il account di servizio della connessione. BigQuery utilizza la connessione per accedere agli oggetti in Cloud Storage:
Vai alla pagina BigQuery.
Nel riquadro Explorer, fai clic su
Aggiungi dati.Viene visualizzata la finestra di dialogo Aggiungi dati.
Nel riquadro Filtra per, seleziona Applicazioni aziendali nella sezione Tipo di origine dati.
In alternativa, nel campo Cerca origini dati, puoi inserire
Vertex AI
.Nella sezione Origini dati in primo piano, fai clic su Vertex AI.
Fai clic sulla scheda della soluzione Modelli Vertex AI: federazione BigQuery.
Nell'elenco Tipo di connessione, seleziona Modelli remoti di Vertex AI, funzioni remote e BigLake (risorsa Cloud).
Nel campo ID connessione, digita
cymbal_conn
.Fai clic su Crea connessione.
Fai clic su Vai alla connessione.
Nel riquadro Informazioni sulla connessione, copia l'ID account di servizio da utilizzare in un passaggio successivo.
Concedi le autorizzazioni all'account di servizio della connessione
Concedi all'account di servizio della connessione i ruoli appropriati per accedere ad altri servizi. Devi concedere questi ruoli nello stesso progetto che hai creato o selezionato nella sezione Prima di iniziare. La concessione dei ruoli in un progetto diverso genera l'errore bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com
does not have the permission to access resource
.
Concedi le autorizzazioni per il bucket Cloud Storage
Concedi all'account di servizio l'accesso per utilizzare gli oggetti nel bucket che hai creato:
Vai alla pagina Bucket.
Fai clic sul nome del bucket che hai creato.
Fai clic su Autorizzazioni.
Fai clic su
Concedi l'accesso. Viene visualizzata la finestra di dialogo Concedi l'accesso.Nel campo Nuove entità, inserisci l'ID account di servizio che hai copiato in precedenza.
Nel campo Seleziona un ruolo, scegli Cloud Storage e poi Utente oggetto Storage.
Fai clic su Salva.
Concedi le autorizzazioni per utilizzare i modelli Vertex AI
Concedi all'account di servizio l'accesso per utilizzare i modelli Vertex AI:
Vai alla pagina IAM e amministrazione.
Fai clic su
Concedi l'accesso. Viene visualizzata la finestra di dialogo Concedi l'accesso.Nel campo Nuove entità, inserisci l'ID account di servizio che hai copiato in precedenza.
Nel campo Seleziona un ruolo, seleziona Vertex AI e poi Utente Vertex AI.
Fai clic su Salva.
Crea le tabelle di dati di esempio
Crea tabelle per archiviare le informazioni sui prodotti Cymbal per animali domestici.
Crea la tabella products
Crea una tabella standard contenente le informazioni sui prodotti Cymbal per animali domestici:
Nella console Google Cloud , vai alla pagina BigQuery.
Nell'editor di query, esegui la seguente query per creare la tabella
products
:LOAD DATA OVERWRITE cymbal_pets.products FROM FILES( format = 'avro', uris = [ 'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/tables/products/products_*.avro']);
Crea la tabella product_images
Crea una tabella di oggetti contenente le immagini dei prodotti Cymbal per animali domestici:
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la tabella
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);
Crea la tabella product_manuals
Crea una tabella di oggetti contenente i manuali dei prodotti Cymbal per animali domestici:
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la tabella
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']);
Creare un modello di generazione di testo
Crea un modello remoto BigQuery ML che rappresenti un modello Gemini di Vertex AI:
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare il modello remoto:
CREATE OR REPLACE MODEL `cymbal_pets.gemini` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'gemini-2.0-flash');
Crea un modello di generazione di embedding
Crea un modello remoto BigQuery ML che rappresenti un modello di embedding multimodale di Vertex AI:
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare il modello remoto:
CREATE OR REPLACE MODEL `cymbal_pets.embedding_model` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'multimodalembedding@001');
Creare una tabella products_mm
con dati multimodali
Crea una tabella products_mm
contenente una colonna image
compilata con le immagini dei prodotti della tabella degli oggetti product_images
. La colonna image
che viene creata è una colonna STRUCT
che utilizza il formato ObjectRef
.
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la tabella
products_mm
e compilare la colonnaimage
: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;
Nell'editor di query della pagina BigQuery, esegui la seguente query per visualizzare i dati della colonna
image
:SELECT product_name, image FROM cymbal_pets.products_mm`
I risultati sono simili ai seguenti:
+--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | 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}} | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | ... | ... | ... | | ... | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
Generare informazioni sui prodotti utilizzando un modello Gemini
Utilizza un modello Gemini per generare i seguenti dati per i prodotti del negozio di animali domestici:
- Aggiungi una colonna
image_description
alla tabellaproducts_mm
. - Compila le colonne
animal_type
,search_keywords
esubcategory
della tabellaproducts_mm
. - Esegui una query che restituisca una descrizione di ogni brand di prodotto e anche un conto del numero di prodotti di quel brand. La descrizione del brand viene generata analizzando le informazioni sui prodotti di tutti i prodotti del brand, incluse le immagini dei prodotti.
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare e compilare la colonna
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));
Nell'editor di query della pagina BigQuery, esegui la seguente query per aggiornare le colonne
animal_type
,search_keywords
esubcategory
con i dati generati: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;
Nell'editor di query della pagina BigQuery, esegui la seguente query per visualizzare i dati generati:
SELECT product_name, image_description, animal_type, search_keywords, subcategory, FROM cymbal_pets.products_mm;
I risultati sono simili ai seguenti:
+--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | 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 | | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | ... | ... | ... | ... | ... | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
Nell'editor di query della pagina BigQuery, esegui la seguente query per generare una descrizione di ogni brand di prodotto e anche un conteggio del numero di prodotti del brand:
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;
I risultati sono simili ai seguenti:
+--------------+-------------------------------------+-----+ | 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.. | | +--------------+-------------------------------------+-----+ | ... | ... |... | +--------------+-------------------------------------+-----+
Creare una UDF Python per trasformare le immagini prodotto
Crea una UDF Python per convertire le immagini dei prodotti in scala di grigi.
La UDF Python utilizza librerie open source e anche l'esecuzione parallela per trasformare più immagini contemporaneamente.
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la UDF
to_grayscale
: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 """;
Trasformare le immagini prodotto
Crea la tabella products_grayscale
con una colonna ObjectRef
contenente
i percorsi di destinazione e gli autori per le immagini in scala di grigi. Il percorso di destinazione viene ricavato dal percorso dell'immagine originale.
Dopo aver creato la tabella, esegui la funzione to_grayscale
per creare le immagini in scala di grigi, scrivili in un bucket Cloud Storage e poi restituisce i valori ObjectRefRuntime
contenenti gli URL di accesso e i metadati per le immagini in scala di grigi.
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la tabella
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;
Sostituisci
BUCKET
con il nome del bucket che hai creato.Nell'editor di query della pagina BigQuery, esegui la seguente query per creare le immagini in scala di grigi, scriverle in un bucket Cloud Storage e restituire i valori
ObjectRefRuntime
contenenti gli URL di accesso e i metadati per le immagini in scala di grigi: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;
I risultati sono simili ai seguenti:
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 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"}} | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Creare una UDF Python per suddividere i dati PDF
Crea un UDF Python per suddividere gli oggetti PDF che contengono i manuali dei prodotti Cymbal per animali domestici in più parti.
I PDF sono spesso molto grandi e potrebbero non rientrare in una singola chiamata a un modello di AI generativa. Se suddividi i PDF in blocchi, puoi archiviare i dati in un formato adatto per i modelli per facilitare l'analisi.
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la UDF
chunk_pdf
:-- 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 """;
Analizzare i dati PDF
Esegui la funzione chunk_pdf
per suddividere i dati PDF nella tabellaproduct_manuals
, quindi crea una tabella product_manual_chunk_strings
contenente un frammento di PDF per riga. Utilizza un modello Gemini sui dati di product_manual_chunk_strings
per
riassumere le informazioni legali riportate nei manuali dei prodotti.
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la tabella
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;
Nell'editor di query della pagina BigQuery, esegui la seguente query per analizzare i dati PDF utilizzando un modello Gemini:
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));
I risultati sono simili ai seguenti:
+-------------------------------------------------------------------------------------------------------------------------------------------+ | 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:** | +-------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-------------------------------------------------------------------------------------------------------------------------------------------+
Genera embedding ed esegui una ricerca vettoriale
Genera gli embedding dai dati delle immagini, quindi utilizzali per restituire immagini simili utilizzando la ricerca vettoriale.
In uno scenario di produzione, ti consigliamo di creare un indice di vettori prima di eseguire una ricerca di vettori. Un indice vettoriale consente di eseguire la ricerca vettoriale più rapidamente, con il compromesso di ridurre il richiamo e quindi restituire risultati più approssimativi.
Nell'editor di query della pagina BigQuery, esegui la seguente query per creare la tabella
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 () );
Nell'editor di query della pagina BigQuery, esegui la seguente query per eseguire una ricerca vettoriale e restituire le immagini prodotto simili all'immagine di input specificata:
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) )) );
I risultati sono simili ai seguenti:
+-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | 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--------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | ... | ... | ... | ... | ... | ... | ... | ... | +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
Elaborare dati multimodali ordinati utilizzando array di valori ObjectRef
Questa sezione illustra come completare le seguenti attività:
- Ricrea la tabella
product_manuals
in modo che contenga sia un file PDF per il manuale del prodottoCrittercuisine 5000
sia file PDF per ogni pagina del manuale. - Crea una tabella che mappa il manuale ai relativi chunk. Il valore
ObjectRef
che rappresenta il manuale completo è archiviato in una colonnaSTRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
. I valoriObjectRef
che rappresentano le pagine del manuale vengono memorizzati in una colonnaARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
. - Analizza insieme un array di valori
ObjectRef
per restituire un singolo valore generato. - Analizza separatamente un array di valori
ObjectRef
e restituisce un valore generato per ogni valore dell'array.
Nell'ambito delle attività di analisi, converti l'array di valori ObjectRef
in un elenco ordinato di valori ObjectRefRuntime
e poi lo passi a un modello Gemini, specificando i valori ObjectRefRuntime
all'interno del prompt. I valori ObjectRefRuntime
forniscono gli URL firmati che il modello utilizza per accedere alle informazioni sull'oggetto in Cloud Storage.
Per elaborare i dati multimodali ordinati utilizzando
array di valori ObjectRef
:
Vai alla pagina BigQuery.
Nell'editor di query, esegui la seguente query per ricreare la tabella
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']);
Nell'editor di query, esegui la seguente query per scrivere i dati PDF nella tabella
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;
Nell'editor di query, esegui la seguente query per visualizzare i dati PDF nella tabella
map_manual_to_chunks
:SELECT * FROM cymbal_pets.map_manual_to_chunks;
I risultati sono simili ai seguenti:
+-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | 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}} | | | | | +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | | | | | ... | ... | ... | ... | +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
Nell'editor di query, esegui la seguente query per generare una singola risposta da un modello Gemini in base all'analisi di un array di valori
ObjectRef
: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));
I risultati sono simili ai seguenti:
+-------------------------------------------+ | 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. | +-------------------------------------------+
Nell'editor di query, esegui la seguente query per generare più risposte da un modello Gemini in base all'analisi di un array di valori
ObjectRef
: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));
I risultati sono simili ai seguenti:
+-----------------------------------------------+-------------------------------------------+----------------------------------------------------+ | 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. | +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
Esegui la pulizia
- 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.