Analise dados multimodais com SQL e UDFs Python
Este tutorial mostra como analisar dados multimodais usando consultas SQL e funções definidas pelo utilizador (FDUs) do Python.
Este tutorial usa o catálogo de produtos do conjunto de dados público da loja de animais Cymbal.
Objetivos
- Use valores
ObjectRef
para armazenar dados de imagens juntamente com dados estruturados numa tabela padrão do BigQuery . - Gere texto com base em dados de imagens de uma tabela padrão através da função
AI.GENERATE_TABLE
. - Transforme imagens existentes para criar novas imagens através de uma UDF do Python.
- Divida PDFs em partes para análise mais detalhada através de uma FDU do Python.
- Use um modelo do Gemini e a função
ML.GENERATE_TEXT
para analisar os dados de PDF divididos em blocos. - Gere incorporações com base em dados de imagens de uma tabela padrão através da função
ML.GENERATE_EMBEDDING
. - Processar dados multimodais ordenados através de matrizes de valores
ObjectRef
.
Custos
Neste documento, usa os seguintes componentes faturáveis do 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.
Para mais informações, consulte as seguintes páginas de preços:
Antes de começar
-
In the Trusted Cloud console, on the project selector page, select or create a Trusted Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator
(
roles/resourcemanager.projectCreator
), which contains theresourcemanager.projects.create
permission. Learn how to grant roles.
-
Verify that billing is enabled for your Trusted Cloud project.
-
Enable the BigQuery, BigQuery Connection, Cloud Storage, and Vertex AI APIs.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin
), which contains theserviceusage.services.enable
permission. Learn how to grant roles.
Funções necessárias
Para receber as autorizações de que precisa para concluir este tutorial, peça ao seu administrador que lhe conceda as seguintes funções do IAM:
-
Crie uma associação:
Administrador da associação do BigQuery (
roles/bigquery.connectionAdmin
) -
Conceda autorizações à conta de serviço da associação:
Administrador de IAM do projeto (
roles/resourcemanager.projectIamAdmin
) -
Crie um contentor do Cloud Storage:
Administrador de armazenamento (
roles/storage.admin
) -
Criar conjuntos de dados, modelos, UDFs e tabelas, e executar tarefas do BigQuery:
Administrador do BigQuery (
roles/bigquery.admin
) -
Crie URLs que lhe permitam ler e modificar objetos do Cloud Storage:
Administrador de ObjectRef do BigQuery (
roles/bigquery.objectRefAdmin
)
Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.
Também pode conseguir as autorizações necessárias através de funções personalizadas ou outras funções predefinidas.
Configurar
Nesta secção, cria o conjunto de dados, a associação, as tabelas e os modelos usados neste tutorial.
Crie um conjunto de dados
Crie um conjunto de dados do BigQuery para conter os objetos que criar neste tutorial:
Na Trusted Cloud consola, aceda à página BigQuery.
No painel Explorador, selecione o seu projeto.
Expanda a opção
Ações e clique em Criar conjunto de dados. É aberto o painel Criar conjunto de dados.Para ID do conjunto de dados, escreva
cymbal_pets
.Clique em Criar conjunto de dados.
Crie um contentor
Crie um contentor do Cloud Storage para armazenar objetos transformados:
Aceda à página Recipientes.
Clique em
Criar.Na página Criar um contentor, na secção Começar, introduza um nome globalmente exclusivo que cumpra os requisitos do nome do contentor.
Clique em Criar.
Crie uma associação
Crie uma associação de recursos do Google Cloud e obtenha a conta de serviço da associação. O BigQuery usa a ligação para aceder a objetos no Cloud Storage:
Aceda à página do BigQuery.
No painel Explorador, clique em
Adicionar dados.É apresentada a caixa de diálogo Adicionar dados.
No painel Filtrar por, na secção Tipo de origem de dados, selecione Aplicações empresariais.
Em alternativa, no campo Pesquisar origens de dados, pode introduzir
Vertex AI
.Na secção Origens de dados em destaque, clique em Vertex AI.
Clique no cartão da solução Modelos da Vertex AI: federação do BigQuery.
Na lista Tipo de ligação, selecione Modelos remotos, funções remotas e BigLake (recurso da nuvem) da Vertex AI.
No campo ID de associação, escreva
cymbal_conn
.Clique em Criar associação.
Clique em Aceder à associação.
No painel Informações de associação, copie o ID da conta de serviço para utilização num passo seguinte.
Conceda autorizações à conta de serviço da associação
Conceda à conta de serviço da associação as funções adequadas para aceder a outros serviços. Tem de conceder estas funções no mesmo projeto que criou ou
selecionou na secção Antes de começar. A concessão das funções num projeto diferente resulta no erro bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.s3ns.iam.gserviceaccount.com
does not have the permission to access resource
.
Conceda autorizações no contentor do Cloud Storage
Conceda à conta de serviço acesso à utilização de objetos no contentor que criou:
Aceda à página Recipientes.
Clique no nome do depósito que criou.
Clique em Autorizações.
Clique em
Conceder acesso. É apresentada a caixa de diálogo Conceder acesso.No campo Novos membros, introduza o ID da conta de serviço que copiou anteriormente.
No campo Selecionar uma função, escolha Cloud Storage e, de seguida, selecione Utilizador de objetos de armazenamento.
Clique em Guardar.
Conceda autorizações para usar os modelos da Vertex AI
Conceda à conta de serviço acesso para usar os modelos da Vertex AI:
Aceda à página IAM e administrador.
Clique em
Conceder acesso. É apresentada a caixa de diálogo Conceder acesso.No campo Novos membros, introduza o ID da conta de serviço que copiou anteriormente.
No campo Selecionar uma função, selecione Vertex AI e, de seguida, selecione Utilizador da Vertex AI.
Clique em Guardar.
Crie as tabelas de dados de exemplo
Crie tabelas para armazenar as informações do produto Cymbal pets.
Crie a tabela products
Crie uma tabela padrão que contenha as informações do produto Cymbal pets:
Na Trusted Cloud consola, aceda à página BigQuery.
No editor de consultas, execute a seguinte consulta para criar a tabela
products
:LOAD DATA OVERWRITE cymbal_pets.products FROM FILES( format = 'avro', uris = [ 'gs://cloud-samples-data/bigquery/tutorials/cymbal-pets/tables/products/products_*.avro']);
Crie a tabela product_images
Cria uma tabela de objetos que contenha as imagens dos produtos de animais de estimação da Cymbal:
No editor de consultas da página BigQuery, execute a seguinte consulta para criar a tabela
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);
Crie a tabela product_manuals
Cria uma tabela de objetos que contenha os manuais dos produtos de animais de estimação Cymbal:
No editor de consultas da página BigQuery, execute a seguinte consulta para criar a tabela
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']);
Crie um modelo de geração de texto
Crie um modelo remoto do BigQuery ML que represente um modelo do Vertex AI Gemini:
No editor de consultas da página BigQuery, execute a seguinte consulta para criar o modelo remoto:
CREATE OR REPLACE MODEL `cymbal_pets.gemini` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'gemini-2.0-flash');
Crie um modelo de geração de incorporações
Crie um modelo remoto do BigQuery ML que represente um modelo de incorporação multimodal do Vertex AI:
No editor de consultas da página BigQuery, execute a seguinte consulta para criar o modelo remoto:
CREATE OR REPLACE MODEL `cymbal_pets.embedding_model` REMOTE WITH CONNECTION `us.cymbal_conn` OPTIONS (ENDPOINT = 'multimodalembedding@001');
Crie uma products_mm
tabela com dados multimodais
Crie uma tabela products_mm
que contenha uma coluna image
preenchida com imagens de produtos da tabela de objetos product_images
. A coluna image
criada é uma coluna STRUCT
que usa o formato ObjectRef
.
No editor de consultas da página BigQuery, execute a seguinte consulta para criar a tabela
products_mm
e preencher a colunaimage
: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;
No editor de consultas da página BigQuery, execute a seguinte consulta para ver os dados da coluna
image
:SELECT product_name, image FROM cymbal_pets.products_mm
Os resultados têm um aspeto semelhante ao seguinte:
+--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | 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}} | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+ | ... | ... | ... | | ... | +--------------------------------+--------------------------------------+-----------------------------------------------+------------------------------------------------+
Gere informações sobre produtos com um modelo do Gemini
Use um modelo do Gemini para gerar os seguintes dados para os produtos da loja de animais de estimação:
- Adicione uma coluna
image_description
à tabelaproducts_mm
. - Preencha as colunas
animal_type
,search_keywords
esubcategory
da tabelaproducts_mm
. - Execute uma consulta que devolva uma descrição de cada marca de produto e também uma contagem do número de produtos dessa marca. A descrição da marca é gerada através da análise das informações dos produtos de todos os produtos dessa marca, incluindo as imagens dos produtos.
No editor de consultas da página BigQuery, execute a seguinte consulta para criar e preencher a coluna
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));
No editor de consultas da página BigQuery, execute a seguinte consulta para atualizar as colunas
animal_type
,search_keywords
esubcategory
com dados gerados: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;
No editor de consultas da página BigQuery, execute a seguinte consulta para ver os dados gerados:
SELECT product_name, image_description, animal_type, search_keywords, subcategory, FROM cymbal_pets.products_mm;
Os resultados têm um aspeto semelhante ao seguinte:
+--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | 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 | | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+ | ... | ... | ... | ... | ... | +--------------------------------+-------------------------------------+-------------+------------------------+------------------+
No editor de consultas da página BigQuery, execute a seguinte consulta para gerar uma descrição de cada marca de produto e também uma contagem do número de produtos dessa marca:
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;
Os resultados têm um aspeto semelhante ao seguinte:
+--------------+-------------------------------------+-----+ | 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.. | | +--------------+-------------------------------------+-----+ | ... | ... |... | +--------------+-------------------------------------+-----+
Crie uma FDU do Python para transformar imagens de produtos
Crie uma FDU Python para converter imagens de produtos em escala de cinzentos.
A FDU Python usa bibliotecas de código aberto e também usa a execução paralela para transformar várias imagens em simultâneo.
No editor de consultas da página do BigQuery, execute a seguinte consulta para criar a 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 """;
Transforme imagens de produtos
Crie a tabela products_grayscale
com uma coluna ObjectRef
que contenha os caminhos de destino e os autorizadores para imagens a preto e branco. O caminho
de destino é derivado do caminho da imagem original.
Depois de criar a tabela, execute a função to_grayscale
para criar as imagens a cinzento, escrevê-las num contentor do Cloud Storage e, em seguida, devolver valores ObjectRefRuntime
que contêm URLs de acesso e metadados para as imagens a cinzento.
No editor de consultas da página BigQuery, execute a seguinte consulta para criar a tabela
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;
Substitua
BUCKET
pelo nome do recipiente que criou.No editor de consultas da página BigQuery, execute a seguinte consulta para criar as imagens a cinzento, escrevê-las num contentor do Cloud Storage e, em seguida, devolver valores
ObjectRefRuntime
que contêm URLs de acesso e metadados para as imagens a cinzento: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;
Os resultados têm um aspeto semelhante ao seguinte:
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 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"}} | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Crie uma FDU do Python para dividir dados de PDF em partes
Crie uma FUD em Python para dividir os objetos PDF que contêm os manuais dos produtos para animais de estimação Cymbal em várias partes.
Os PDFs são frequentemente muito grandes e podem não caber numa única chamada a um modelo de IA generativa. Ao dividir os PDFs em partes, pode armazenar os dados dos PDFs num formato pronto para o modelo para uma análise mais fácil.
No editor de consultas da página do BigQuery, execute a seguinte consulta para criar a 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 """;
Analise dados de PDFs
Execute a função chunk_pdf
para dividir os dados do PDF na tabela product_manuals
e, de seguida, crie uma tabela product_manual_chunk_strings
que contenha um bloco de PDF por linha. Use um modelo do Gemini nos product_manual_chunk_strings
dados para
resumir as informações legais encontradas nos manuais dos produtos.
No editor de consultas da página BigQuery, execute a seguinte consulta para criar a tabela
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;
No editor de consultas da página BigQuery, execute a seguinte consulta para analisar os dados PDF através de um modelo 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));
Os resultados têm um aspeto semelhante ao seguinte:
+-------------------------------------------------------------------------------------------------------------------------------------------+ | 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:** | +-------------------------------------------------------------------------------------------------------------------------------------------+ | ... | +-------------------------------------------------------------------------------------------------------------------------------------------+
Gere incorporações e faça uma pesquisa vetorial
Gere incorporações a partir de dados de imagens e, em seguida, use as incorporações para devolver imagens semelhantes através da pesquisa vetorial.
Num cenário de produção, recomendamos que crie um índice vetorial antes de executar uma pesquisa vetorial. Um índice vetorial permite-lhe realizar a pesquisa vetorial mais rapidamente, com a desvantagem de reduzir a capacidade de memorização e, por isso, devolver resultados mais aproximados.
No editor de consultas da página BigQuery, execute a seguinte consulta para criar a tabela
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 () );
No editor de consultas da página BigQuery, execute a seguinte consulta para executar uma pesquisa vetorial e devolver imagens de produtos semelhantes à imagem de entrada fornecida:
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) )) );
Os resultados têm um aspeto semelhante ao seguinte:
+-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | 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--------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+ | ... | ... | ... | ... | ... | ... | ... | ... | +-----------------+-----------------+----------------+----------------------------------------------+--------------------+-------------------------------+------------------------------------------------+----------------+
Processar dados multimodais ordenados usando matrizes de valores ObjectRef
Esta secção mostra como concluir as seguintes tarefas:
- Recrie a tabela
product_manuals
para que contenha um ficheiro PDF para o manual do produtoCrittercuisine 5000
e ficheiros PDF para cada página desse manual. - Crie uma tabela que mapeie o manual para os respetivos fragmentos. O valor
ObjectRef
que representa o manual completo é armazenado numa colunaSTRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
. Os valoresObjectRef
que representam as páginas manuais são armazenados numa colunaARRAY<STRUCT<uri STRING, version STRING, authorizer STRING, details JSON>>
. - Analise uma matriz de valores
ObjectRef
em conjunto para devolver um único valor gerado. - Analisa uma matriz de valores
ObjectRef
separadamente e devolve um valor gerado para cada valor da matriz.
Como parte das tarefas de análise, converte a matriz de valores ObjectRef
numa lista ordenada de valores ObjectRefRuntime
e, em seguida, transmite essa lista a um modelo Gemini, especificando os valores ObjectRefRuntime
como parte do comando. Os valores ObjectRefRuntime
fornecem URLs assinados que o modelo usa para aceder às informações do objeto no Cloud Storage.
Siga estes passos para processar dados multimodais ordenados através de matrizes de valores ObjectRef
:
Aceda à página do BigQuery.
No editor de consultas, execute a seguinte consulta para recriar a tabela
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']);
No editor de consultas, execute a seguinte consulta para escrever dados PDF na tabela
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;
No editor de consultas, execute a seguinte consulta para ver os dados do PDF na tabela
map_manual_to_chunks
:SELECT * FROM cymbal_pets.map_manual_to_chunks;
Os resultados têm um aspeto semelhante ao seguinte:
+-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | 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}} | | | | | +-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+ | | | | | ... | ... | ... | ... | +-------------------------------------+--------------------------------+-----------------------------------+------------------------------------------------------+-------------------------------------------+---------------------------------+------------------------------------+-------------------------------------------------------+
No editor de consultas, execute a seguinte consulta para gerar uma única resposta de um modelo Gemini com base na análise de uma matriz de valores
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));
Os resultados têm um aspeto semelhante ao seguinte:
+-------------------------------------------+ | 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. | +-------------------------------------------+
No editor de consultas, execute a seguinte consulta para gerar várias respostas de um modelo Gemini com base na análise de uma matriz de valores
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));
Os resultados têm um aspeto semelhante ao seguinte:
+-----------------------------------------------+-------------------------------------------+----------------------------------------------------+ | 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. | +-----------------------------------------------+-------------------------------------------+----------------------------------------------------+
Limpar
- 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.