1. Introduzione
Panoramica
Le funzioni remote di BigQuery ti consentono di implementare una funzione in linguaggi diversi da SQL e JavaScript o con le librerie e i servizi non consentiti nelle funzioni definite dall'utente di BigQuery. Le funzioni remote di BigQuery forniscono un'integrazione diretta con le funzioni di Cloud Run e Cloud Run. Puoi richiamare una funzione remota di BigQuery all'interno di una query SQL prendendo una o più colonne come input e restituendo un singolo valore come output.
Le funzioni Cloud Run sono una soluzione di calcolo leggera che consente agli sviluppatori di creare funzioni autonome a uso specifico che possono essere attivate tramite HTTPS o rispondere a CloudEvents senza dover gestire un ambiente server o di runtime. Le funzioni Cloud Run supportano Node.js, Python, Go, Java, .NET, Ruby e PHP.
In questo codelab imparerai a creare una funzione remota BigQuery per ottenere risposte a una domanda sulle immagini archiviate in Cloud Storage utilizzando Visual Question Answering (VQA) di Vertex AI. La query SQL recupererà un URI per un'immagine da una tabella in BigQuery. Quindi, utilizzando una funzione remota di BigQuery, invierai l'URI dell'immagine a una funzione Cloud Run che risponderà con le risposte di VQA sull'immagine.
Illustrazione
Dal punto di vista dello sviluppo, questi sono i passaggi che dovrai completare in questo codelab:
- Crea l'endpoint HTTP nelle funzioni di Cloud Run
- Crea una connessione di tipo CLOUD_RESOURCE
- crea una tabella di oggetti BigQuery per il bucket Cloud Storage
- Crea la funzione remota
- Utilizza la funzione remota in una query come qualsiasi altra funzione definita dall'utente
Cosa imparerai a fare
- Creare una funzione Cloud Run HTTP in Python
- Come creare e utilizzare una funzione remota BigQuery all'interno di una query SQL
- Come creare una tabella di oggetti BigQuery
- Utilizzare l'SDK Vertex AI per Python per utilizzare la risposta alle domande visive (VQA)
2. Configurazione e requisiti
Prerequisiti
- Hai eseguito l'accesso alla console Cloud.
- Hai già eseguito il deployment di una funzione Cloud Run HTTP. Consulta la guida rapida di Python.
- Hai già creato un bucket in Cloud Storage. Consulta la guida rapida di Cloud Storage.
- Devi disporre dei ruoli appropriati per creare un set di dati, una tabella e una funzione remota in BigQuery. Consulta la guida introduttiva Caricare ed eseguire query sui dati in BigQuery.
Attiva Cloud Shell
- Nella console Cloud, fai clic su Attiva Cloud Shell .
Se è la prima volta che avvii Cloud Shell, viene visualizzata una schermata intermedia che descrive di cosa si tratta. Se viene visualizzata una schermata intermedia, fai clic su Continua.
Dovrebbero bastare pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.
Questa macchina virtuale viene caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte, se non tutto, del lavoro in questo codelab può essere svolto con un browser.
Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è già autenticato e il progetto è già impostato sul tuo ID progetto.
- Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list
Output comando
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Esegui il seguente comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project
Output comando
[core] project = <PROJECT_ID>
In caso contrario, puoi impostarlo con questo comando:
gcloud config set project <PROJECT_ID>
Output comando
Updated property [core/project].
3. Configura le variabili di ambiente locale
In questo codice, creerai alcune variabili di ambiente per migliorare la leggibilità dei comandi gcloud
utilizzati in questo codelab.
PROJECT_ID=$(gcloud config get-value project) # Cloud Function variables FUNCTION_NAME="imagen-vqa" FUNCTION_REGION="us-central1" # Cloud Function variables BUCKET_NAME=$PROJECT_ID-imagen-vqa # BigQuery variables DATASET_ID="remote_function_codelab" TABLE_NAME="images" BQ_REGION="US" CONNECTION_ID="imagen_vqa_connection"
4. Crea la funzione Cloud Run
Per creare una funzione remota BigQuery, devi prima creare un endpoint HTTP utilizzando la funzione Cloud Run. L'endpoint deve essere in grado di elaborare un batch di righe in una singola richiesta POST HTTP e restituire i risultati del batch come risposta HTTP.
Questa funzione Cloud Run riceverà l'URI di archiviazione delle immagini e il prompt della domanda come input dalla query SQL e restituirà la risposta dalla Visual Question Answering (VQA).
Questo codelab utilizza un esempio per l'ambiente di runtime python311 che utilizza l'SDK Vertex AI per Python.
Crea il codice sorgente della funzione
Innanzitutto, crea una directory e accedi tramite cd.
mkdir imagen-vqa && cd $_
Poi, crea un file requirements.txt
.
google-cloud-aiplatform[preview] google-cloud-storage functions-framework==3.*
Successivamente, crea un file di origine main.py
.
from vertexai.preview.vision_models import ImageQnAModel from vertexai.preview.vision_models import Image from flask import jsonify from google.cloud import storage from urllib.parse import urlparse import functions_framework # This is the entry point for the cloud function @functions_framework.http def imagen_vqa(request): try: # See if you can parse the incoming JSON return_value = [] request_json = request.get_json() # This grabs the input into the function as called from the SQL function calls = request_json['calls'] for call in calls: # We call the VQA function here in another function defined below ai_result = vqa(call) # The result to BigQuery is in the order it was prepared in return_value.append(ai_result[0]) # Prepare the response back to BigQuery return_json = jsonify( { "replies": return_value } ) return return_json except Exception as e: return jsonify( { "errorMessage": str(e) } ), 400 # Helper function to split apart the GCS URI def decode_gcs_url(url): # Read the URI and parse it p = urlparse(url) bucket = p.netloc file_path = p.path[0:].split('/', 1) # Return the relevant objects (bucket, path to object) return bucket, file_path[1] # We can't use the image load from local file since it expects a local path # We use a GCS URL and get the bytes of the image def read_file(object_path): # Parse the path bucket, file_path = decode_gcs_url(object_path) storage_client = storage.Client() bucket = storage_client.bucket(bucket) blob = bucket.blob(file_path) # Return the object as bytes return blob.download_as_bytes() # This is the function that calls the VQA function def vqa (parameters): # This is the model we want to use image_qna_model = ImageQnAModel.from_pretrained("imagetext@001") # The location is the first parameter image_loc = parameters[0] # Get the bytes image_bytes = read_file(image_loc) # Load the bytes into the Image handler input_image = Image(image_bytes) # Ask the VQA the question results = image_qna_model.ask_question( image=input_image, # The prompt was the second parameter question=parameters[1], number_of_results=1 ) return results
Esegui il deployment della funzione Cloud Run
Ora puoi eseguire il deployment della funzione Cloud Run per il runtime python311.
Per eseguire il deployment di una funzione Cloud Run direttamente su Cloud Run, esegui il seguente comando:
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function imagen_vqa \ --region $FUNCTION_REGION \ --no-allow-unauthenticated
Se preferisci eseguire il deployment come Cloud Functions (2a gen), utilizza il seguente comando:
gcloud functions deploy $FUNCTION_NAME \ --gen2 \ --region=$FUNCTION_REGION \ --runtime=python311 \ --trigger-http \ --source=. \ --no-allow-unauthenticated
e poi salvare l'URL della funzione come variabile di ambiente da utilizzare in seguito.
ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"
5. Crea il bucket Cloud Storage
Per prima cosa, crea un bucket Cloud Storage per archiviare le immagini.
gcloud storage buckets create gs://$BUCKET_NAME
Successivamente, carica un'immagine da utilizzare per la VQA. Questo codelab utilizza l'immagine di esempio della documentazione di VQA.
Puoi utilizzare la console Cloud per Cloud Storage per caricare l'immagine direttamente nel tuo bucket. In alternativa, puoi eseguire i seguenti comandi per scaricare l'immagine di esempio nella directory Cloud Shell corrente
wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true
e poi caricalo nel tuo bucket Cloud Storage.
gcloud storage cp image.jpg gs://$BUCKET_NAME
6. Crea una connessione a una risorsa cloud per BigQuery
BigQuery utilizza una connessione CLOUD_RESOURCE per interagire con la funzione Cloud Functions. Esegui questo comando per creare questa connessione.
bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \ --connection_type=CLOUD_RESOURCE $CONNECTION_ID
A questo punto, vengono visualizzati i dettagli della nuova connessione BigQuery.
bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID
Salva il nome dell'account di servizio della connessione BigQuery in una variabile, come mostrato.
CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"
Concedi all'account di servizio l'accesso al bucket Cloud Storage.
gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME
7. Creare una tabella di oggetti BigQuery
Le tabelle di oggetti BigQuery sono tabelle di sola lettura su oggetti di dati non strutturati che risiedono in Cloud Storage.
Le tabelle di oggetti ti consentono di analizzare i dati non strutturati in Cloud Storage. Puoi eseguire analisi con le funzioni remote e unire i risultati di queste operazioni con il resto dei dati strutturati in BigQuery.
Per prima cosa, crea un set di dati.
bq --location=$BQ_REGION mk \ --dataset \ $DATASET_ID
Il seguente comando crea una tabella di oggetti basata sul bucket di immagini Cloud Storage. La tabella risultante conterrà gli URI di tutte le immagini nel bucket.
bq mk --table \ --external_table_definition=gs://$BUCKET_NAME/*@$BQ_REGION.$CONNECTION_ID \ --object_metadata=SIMPLE \ $PROJECT_ID:$DATASET_ID.$TABLE_NAME
8. Crea la funzione remota BigQuery
L'ultimo passaggio consiste nel configurare la funzione remota BigQuery.
Innanzitutto, concedi all'account di servizio della connessione BigQuery le autorizzazioni per richiamare la funzione Cloud Run. Non è consigliabile consentire l'invocazione non autenticata per il servizio di funzioni Cloud Run.
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --member=serviceAccount:$CONNECTION_SA \ --role="roles/run.invoker" \ --region $FUNCTION_REGION
Poi, salva la query SQL in una variabile.
SQL_CREATE_FUNCTION="CREATE FUNCTION \`$PROJECT_ID.$DATASET_ID\`.vqa(uri STRING, image_prompt STRING) RETURNS STRING REMOTE WITH CONNECTION \`$PROJECT_ID.$BQ_REGION.$CONNECTION_ID\` OPTIONS ( endpoint = '$ENDPOINT_URL' )"
Ora esegui la query.
bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION
Dopo aver eseguito la query per creare la funzione remota, vedrai Created <your-project-id>.remote_function_codelab.vqa
9. Chiamare la funzione remota di BigQuery in una query SQL
Hai completato i passaggi di sviluppo per la creazione della funzione remota. Ora puoi chiamare la funzione Cloud Run da una query SQL.
Innanzitutto, salva la domanda e la query SQL in una variabile. Questo codelab utilizza l'esempio riportato nella documentazione di Visual Question Answering. Questa query utilizza l'immagine più recente aggiunta al bucket di archiviazione.
export SQL_QUERY="DECLARE question STRING DEFAULT 'What objects are in the image?'; SELECT uri, image_prompt ,\`$DATASET_ID\`.vqa(uri, image_prompt) as result FROM ( SELECT *, dense_rank() over (order by updated) as rnk , question as image_prompt FROM \`$PROJECT_ID.$DATASET_ID.images\`) as innertable WHERE rnk = 1; "
Quindi esegui la query SQL per mostrare la risposta del servizio Vertex AI Visual Question Answering (VQA).
bq query --nouse_legacy_sql $SQL_QUERY
I risultati dovrebbero essere simili all'output di esempio seguente:
+---------------------------------+--------------------------------+----------+ | uri | image_prompt | result | +---------------------------------+--------------------------------+----------+ | gs://<YOUR_BUCKET>/image.jpg | What objects are in the image? | marbles | +---------------------------------+--------------------------------+----------+
10. Risoluzione dei problemi
Durante la creazione della tabella BigQuery, se ricevi un errore BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME
, assicurati di aver incluso il percorso /*
dopo $BUCKET_NAME
nel comando.
Quando esegui la query SQL, se ricevi un errore Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint>
, prova ad attendere circa 1-2 minuti affinché la concessione dell'autorizzazione del ruolo Invoker di funzione cloud venga propagata all'account di servizio di connessione BigQuery prima di riprovare.
11. Complimenti!
Complimenti per aver completato il codelab.
Ti consigliamo di consultare la documentazione sulle funzioni remote di BigQuery e sulla risposta alle domande visive (VQA).
Argomenti trattati
- Come configurare l'autenticazione in una funzione Cloud Run e verificare che sia stata configurata correttamente
- Esegui una chiamata a una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
- Come creare un account di servizio e concedergli il ruolo appropriato per richiamare una funzione
- Come impersonare un servizio da un ambiente di sviluppo locale che dispone dei ruoli appropriati per richiamare una funzione
12. Esegui la pulizia
Per evitare addebiti involontari, ad esempio se questa funzione Cloud Run viene richiamata inavvertitamente più volte rispetto all'allocazione mensile dei richiami della funzione Cloud Run nel livello senza costi, puoi eliminare la funzione Cloud Functions o eliminare il progetto che hai creato nel passaggio 2.
Per eliminare la funzione Cloud Run, vai alla console Cloud Run all'indirizzo https://console.cloud.google.com/functions/ ed elimina la funzione imagen-vqa (o $FUNCTION_NAME se hai utilizzato un nome diverso).
Se scegli di eliminare l'intero progetto, puoi andare all'indirizzo https://console.cloud.google.com/cloud-resource-manager, selezionare il progetto che hai creato nel passaggio 2 e scegliere Elimina. Se elimini il progetto, dovrai modificare i progetti nel tuo Cloud SDK. Puoi visualizzare l'elenco di tutti i progetti disponibili eseguendo gcloud projects list
.