1. Introduzione
Panoramica
Le funzioni remote di BigQuery 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 Cloud Run Functions 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.
Cloud Run Functions è una soluzione di calcolo leggera che consente agli sviluppatori di creare funzioni autonome a uso specifico, che possono essere attivate utilizzando HTTPS o rispondere a CloudEvents senza la necessità di gestire un ambiente server o di runtime. Cloud Run Functions supporta Node.js, Python, Go, Java, .NET, Ruby e PHP.
In questo codelab imparerai a creare una funzione remota di 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. Poi, 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 completerai in questo codelab:
- Crea l'endpoint HTTP in Cloud Run Functions
- 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
- Come creare una funzione Cloud Run HTTP in Python
- Come creare e utilizzare una funzione remota di BigQuery all'interno di una query SQL
- Come creare una tabella di oggetti BigQuery
- Come utilizzare l' SDK Vertex AI per Python per utilizzare Visual Question Answering (VQA)
2. Configurazione e requisiti
Prerequisiti
- Hai eseguito l'accesso alla console Cloud.
- In precedenza hai eseguito il deployment di una funzione Cloud Run HTTP. Consulta la guida rapida di Python.
- In precedenza hai creato un bucket in Cloud Storage. Consulta la guida rapida di Cloud Storage.
- Disponi dei ruoli appropriati per creare un set di dati, una tabella e una funzione remota in BigQuery. Consulta la guida rapida 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 ne descrive le funzionalità. Se hai visualizzato una schermata intermedia, fai clic su Continua.

Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.

Questa macchina virtuale è caricata con tutti gli strumenti di sviluppo necessari. Offre una home directory persistente di 5 GB ed è in esecuzione in Google Cloud, migliorando notevolmente le prestazioni di rete e l'autenticazione. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto con un browser.
Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è autenticato e il progetto è 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 questo 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 locali
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 di BigQuery, devi prima creare un endpoint HTTP utilizzando una funzione Cloud Run. L'endpoint deve essere in grado di elaborare un batch di righe in una singola richiesta HTTP POST e restituire i risultati per il batch come risposta HTTP.
Questa funzione Cloud Run riceverà l'URI di archiviazione dell'immagine e la richiesta di domanda come input dalla query SQL e restituirà la risposta da Visual Question Answering (VQA).
Questo codelab utilizza un esempio per il runtime python311 utilizzando l' SDK Vertex AI per Python.
Crea il codice sorgente per la funzione
Per prima cosa, crea una directory e spostati al suo interno.
mkdir imagen-vqa && cd $_
Poi, crea un file requirements.txt.
google-cloud-aiplatform[preview] google-cloud-storage functions-framework==3.*
Quindi, crea un file sorgente 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 (2nd gen), utilizza il seguente comando:
gcloud functions deploy $FUNCTION_NAME \ --gen2 \ --region=$FUNCTION_REGION \ --runtime=python311 \ --trigger-http \ --source=. \ --no-allow-unauthenticated
e poi puoi salvare l'URL della funzione come variabile di ambiente da utilizzare in un secondo momento.
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
Poi, carica un'immagine da utilizzare per VQA. Questo codelab utilizza l' immagine di esempio dalla documentazione di VQA.
Puoi utilizzare la console Cloud per Cloud Storage per caricare l'immagine direttamente nel 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 caricarla nel bucket Cloud Storage.
gcloud storage cp image.jpg gs://$BUCKET_NAME
6. Crea una connessione alle risorse Cloud BigQuery
BigQuery utilizza una connessione CLOUD_RESOURCE per interagire con Cloud Functions. Esegui il seguente comando per creare questa connessione.
bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \ --connection_type=CLOUD_RESOURCE $CONNECTION_ID
Poi, visualizza i dettagli della nuova connessione BigQuery.
bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID
Salva il nome del service account di connessione BigQuery in una variabile, come mostrato.
CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"
Concedi al service account l'accesso al bucket Cloud Storage.
gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME
7. Crea 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 consentono di analizzare i dati non strutturati in Cloud Storage. Puoi eseguire l'analisi con le funzioni remote e poi 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 di Cloud Storage. La tabella risultante conterrà gli URI di tutte le immagini in quel 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 di BigQuery
L'ultimo passaggio consiste nel configurare la funzione remota di BigQuery.
Per prima cosa, concedi al service account di connessione BigQuery le autorizzazioni per richiamare la funzione Cloud Run. Non è consigliabile consentire la chiamata 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' )"
E 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. Chiama la funzione remota di BigQuery in una query SQL
Ora hai completato i passaggi di sviluppo per la creazione della funzione remota. Ora puoi chiamare la funzione Cloud Run da una query SQL.
Per prima cosa, salva la domanda e la query SQL in una variabile. Questo codelab utilizza l' esempio della documentazione di Visual Question Answering. Questa query utilizza l'ultima immagine 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; "
Poi, esegui la query SQL per visualizzare la risposta del servizio Visual Question Answering (VQA) di Vertex AI.
bq query --nouse_legacy_sql $SQL_QUERY
I risultati dovrebbero essere simili all'output di esempio riportato di seguito:
+---------------------------------+--------------------------------+----------+ | uri | image_prompt | result | +---------------------------------+--------------------------------+----------+ | gs://<YOUR_BUCKET>/image.jpg | What objects are in the image? | marbles | +---------------------------------+--------------------------------+----------+
10. Risoluzione dei problemi
Quando crei la 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 prima che la concessione dell'autorizzazione del ruolo Invoker di Cloud Functions si propaghi al service account di connessione BigQuery prima di riprovare.
11. Complimenti!
Complimenti per aver completato il codelab.
Ti consigliamo di consultare la documentazione su funzioni remote di BigQuery e su Visual Question Answering (VQA).
Argomenti trattati
- Come configurare l'autenticazione su una funzione Cloud Run e verificare che sia stata configurata correttamente
- Richiamare una funzione autenticata da un ambiente di sviluppo locale fornendo il token per la tua identità gcloud
- Come creare un service account e concedergli il ruolo appropriato per richiamare una funzione
- Come simulare l'identità di un servizio da un ambiente di sviluppo locale che dispone dei ruoli appropriati per richiamare una funzione
12. Libera spazio
Per evitare addebiti involontari (ad esempio, se questa funzione Cloud Run viene richiamata inavvertitamente più volte di quanto consentito dalla quota di chiamate mensili di Cloud Run Functions nel Livello senza costi), puoi eliminare la funzione Cloud Functions o il progetto 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 creato nel passaggio 2 e scegliere Elimina. Se elimini il progetto, dovrai cambiare progetto in Cloud SDK. Puoi visualizzare l'elenco di tutti i progetti disponibili eseguendo gcloud projects list.