1. Introduction
Présentation
Les fonctions distantes BigQuery vous permettent d'implémenter une fonction dans d'autres langages que SQL et JavaScript, ou avec les bibliothèques et les services qui ne sont pas autorisés dans les fonctions définies par l'utilisateur de BigQuery. Les fonctions distantes BigQuery s'intègrent directement aux fonctions Cloud Run et à Cloud Run. Vous pouvez appeler une fonction à distance BigQuery dans une requête SQL en prenant une ou plusieurs colonnes en entrée, puis en renvoyant une seule valeur en sortie.
Cloud Run Functions est une solution de calcul légère permettant aux développeurs de créer des fonctions autonomes à usage unique qui peuvent être déclenchées à l'aide d'HTTPS ou qui répondent aux CloudEvents sans avoir à gérer de serveur ni d'environnement d'exécution. Les fonctions Cloud Run sont compatibles avec Node.js, Python, Go, Java, .NET, Ruby et PHP.
Dans cet atelier de programmation, vous allez apprendre à créer une fonction distante BigQuery pour obtenir des réponses à une question sur des images stockées dans Cloud Storage à l'aide de la fonctionnalité Visual Question Answering (VQA) (Répondre à des questions visuelles) de Vertex AI. Votre requête SQL récupère un URI pour une image à partir d'une table dans BigQuery. Ensuite, à l'aide d'une fonction distante BigQuery, vous enverrez l'URI de l'image à une fonction Cloud Run qui vous répondra avec les réponses de VQA sur l'image.
Illustration
Du point de vue du développement, voici les étapes que vous allez suivre dans cet atelier de programmation:
- Créer le point de terminaison HTTP dans les fonctions Cloud Run
- Créer une connexion de type CLOUD_RESOURCE
- Créer une table d'objets BigQuery pour le bucket Cloud Storage
- Créer la fonction distante
- Utilisez la fonction distante dans une requête comme n'importe quelle autre fonction définie par l'utilisateur.
Points abordés
- Créer une fonction Cloud Run HTTP en Python
- Créer et utiliser une fonction distante BigQuery dans une requête SQL
- Créer une table d'objets BigQuery
- Utiliser le SDK Vertex AI pour Python pour utiliser la résolution de questions visuelles (VQA)
2. Préparation
Prérequis
- Vous êtes connecté à Cloud Console.
- Vous avez déjà déployé une fonction Cloud Run HTTP. Consultez le guide de démarrage rapide pour Python.
- Vous avez déjà créé un bucket dans Cloud Storage. Consultez le guide de démarrage rapide de Cloud Storage.
- Vous disposez des rôles appropriés pour créer un ensemble de données, une table et une fonction distante dans BigQuery. Consultez le guide de démarrage rapide sur le chargement et l'interrogation de données dans BigQuery.
Activer Cloud Shell
- Dans Cloud Console, cliquez sur Activer Cloud Shell
.
Si vous démarrez Cloud Shell pour la première fois, un écran intermédiaire s'affiche. Si un écran intermédiaire vous a été présenté, cliquez sur Continuer.
Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.
Cette machine virtuelle contient tous les outils de développement nécessaires. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute dans Google Cloud, ce qui améliore considérablement les performances du réseau et l'authentification. Une grande partie, voire la totalité, de votre travail dans cet atelier de programmation peut être effectué dans un navigateur.
Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est défini avec votre ID de projet.
- Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list
Résultat de la commande
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project
Résultat de la commande
[core] project = <PROJECT_ID>
Si vous obtenez un résultat différent, exécutez cette commande :
gcloud config set project <PROJECT_ID>
Résultat de la commande
Updated property [core/project].
3. Configurer des variables d'environnement locales
Dans ce code, vous allez créer quelques variables d'environnement pour améliorer la lisibilité des commandes gcloud
utilisées dans cet atelier de programmation.
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. Créer la fonction Cloud Run
Pour créer une fonction distante BigQuery, vous devez d'abord créer un point de terminaison HTTP à l'aide de la fonction Cloud Run. Le point de terminaison doit pouvoir traiter un lot de lignes dans une seule requête HTTP POST et renvoyer les résultats du lot sous forme de réponse HTTP.
Cette fonction Cloud Run recevra l'URI de stockage d'images et l'invite à la question en tant qu'entrée de votre requête SQL, et renverra la réponse du système de questions-réponses visuelles (VQA).
Cet atelier de programmation utilise un exemple d'environnement d'exécution Python 311 utilisant le SDK Vertex AI pour Python.
Créer le code source de la fonction
Commencez par créer un répertoire et utilisez la commande cd pour y accéder.
mkdir imagen-vqa && cd $_
Ensuite, créez un fichier requirements.txt
.
google-cloud-aiplatform[preview] google-cloud-storage functions-framework==3.*
Ensuite, créez un fichier source 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
Déployer la fonction Cloud Run
Vous pouvez maintenant déployer votre fonction Cloud Run pour l'environnement d'exécution python311.
Pour déployer une fonction Cloud Run directement sur Cloud Run, exécutez la commande suivante:
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function imagen_vqa \ --region $FUNCTION_REGION \ --no-allow-unauthenticated
Si vous préférez déployer en tant que Cloud Functions (2e génération), utilisez la commande suivante:
gcloud functions deploy $FUNCTION_NAME \ --gen2 \ --region=$FUNCTION_REGION \ --runtime=python311 \ --trigger-http \ --source=. \ --no-allow-unauthenticated
Vous pouvez ensuite enregistrer l'URL de la fonction en tant que variable d'environnement pour l'utiliser ultérieurement.
ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"
5. Créer le bucket Cloud Storage
Commencez par créer un bucket Cloud Storage pour stocker vos images.
gcloud storage buckets create gs://$BUCKET_NAME
Ensuite, importez une image que VQA pourra utiliser. Cet atelier de programmation utilise l'exemple d'image de la documentation sur la VQA.
Vous pouvez utiliser la console Cloud pour Cloud Storage pour importer l'image directement dans votre bucket. Vous pouvez également exécuter les commandes suivantes pour télécharger l'exemple d'image dans votre répertoire Cloud Shell actuel :
wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true
puis importez-le dans votre bucket Cloud Storage.
gcloud storage cp image.jpg gs://$BUCKET_NAME
6. Créer une connexion à une ressource cloud BigQuery
BigQuery utilise une connexion CLOUD_RESOURCE pour interagir avec votre fonction Cloud. Exécutez la commande suivante pour créer cette connexion.
bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \ --connection_type=CLOUD_RESOURCE $CONNECTION_ID
Affichez ensuite les détails de la nouvelle connexion BigQuery.
bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID
Enregistrez le nom du compte de service de connexion BigQuery dans une variable, comme indiqué.
CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"
Accordez au compte de service l'accès à votre bucket Cloud Storage.
gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME
7. Créer une table d'objets BigQuery
Les tables d'objets BigQuery sont des tables en lecture seule sur des objets de données non structurés stockés dans Cloud Storage.
Les tables d'objets vous permettent d'analyser des données non structurées dans Cloud Storage. Vous pouvez effectuer une analyse avec des fonctions à distance, puis joindre les résultats de ces opérations aux autres données structurées dans BigQuery.
Commencez par créer un ensemble de données.
bq --location=$BQ_REGION mk \ --dataset \ $DATASET_ID
La commande suivante crée une table d'objets basée sur votre bucket d'images Cloud Storage. La table générée contient les URI de toutes les images de ce bucket.
bq mk --table \ --external_table_definition=gs://$BUCKET_NAME/*@$BQ_REGION.$CONNECTION_ID \ --object_metadata=SIMPLE \ $PROJECT_ID:$DATASET_ID.$TABLE_NAME
8. Créer la fonction distante BigQuery
La dernière étape consiste à configurer la fonction distante BigQuery.
Commencez par accorder au compte de service de connexion BigQuery les autorisations nécessaires pour appeler la fonction Cloud Run. Il n'est pas recommandé d'autoriser les appels non authentifiés pour votre service de fonction Cloud Run.
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --member=serviceAccount:$CONNECTION_SA \ --role="roles/run.invoker" \ --region $FUNCTION_REGION
Enregistrez ensuite la requête SQL dans une variable.
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' )"
Maintenant, exécutez la requête.
bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION
Après avoir exécuté la requête permettant de créer la fonction distante, le message Created <your-project-id>.remote_function_codelab.vqa
s'affiche.
9. Appeler la fonction distante BigQuery dans une requête SQL
Vous avez maintenant terminé les étapes de développement pour créer la fonction distante. Vous pouvez désormais appeler votre fonction Cloud Run à partir d'une requête SQL.
Commencez par enregistrer votre question et votre requête SQL dans une variable. Cet atelier de programmation utilise l'exemple de la documentation Visual Question Answering. Cette requête utilise la dernière image ajoutée à votre bucket de stockage.
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; "
Exécutez ensuite la requête SQL pour afficher la réponse du service de réponse visuelle (VQA) de Vertex AI.
bq query --nouse_legacy_sql $SQL_QUERY
Les résultats doivent ressembler à l'exemple ci-dessous:
+---------------------------------+--------------------------------+----------+ | uri | image_prompt | result | +---------------------------------+--------------------------------+----------+ | gs://<YOUR_BUCKET>/image.jpg | What objects are in the image? | marbles | +---------------------------------+--------------------------------+----------+
10. Dépannage
Lorsque vous créez la table BigQuery, si vous recevez une erreur BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME
, assurez-vous d'avoir inclus le chemin d'accès /*
après $BUCKET_NAME
dans la commande.
Lorsque vous exécutez votre requête SQL, si vous obtenez une erreur Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint>
, essayez d'attendre environ une à deux minutes pour que l'autorisation de rôle d'appelant de fonction Cloud se propage au compte de service de connexion BigQuery avant de réessayer.
11. Félicitations !
Félicitations, vous avez terminé l'atelier de programmation.
Nous vous recommandons de consulter la documentation sur les fonctions distantes BigQuery et la résolution de questions visuelles (VQA).
Points abordés
- Configurer l'authentification sur une fonction Cloud Run et vérifier qu'elle a été correctement configurée
- Appeler une fonction authentifiée à partir d'un environnement de développement local en fournissant le jeton de votre identité gcloud
- Créer un compte de service et lui attribuer le rôle approprié pour appeler une fonction
- usurper l'identité d'un service à partir d'un environnement de développement local disposant des rôles appropriés pour appeler une fonction.
12. Effectuer un nettoyage
Pour éviter les frais involontaires (par exemple, si cette fonction Cloud Run est appelée par inadvertance plus de fois que votre quota mensuel d'appels de fonctions Cloud Run dans le niveau sans frais), vous pouvez supprimer la fonction Cloud ou le projet que vous avez créé à l'étape 2.
Pour supprimer la fonction Cloud Run, accédez à la console Cloud Run à l'adresse https://console.cloud.google.com/functions/, puis supprimez la fonction imagen-vqa (ou $FUNCTION_NAME si vous avez utilisé un autre nom).
Si vous choisissez de supprimer l'ensemble du projet, accédez à https://console.cloud.google.com/cloud-resource-manager, sélectionnez le projet que vous avez créé à l'étape 2, puis choisissez "Supprimer". Si vous supprimez le projet, vous devrez le modifier dans Cloud SDK. Vous pouvez afficher la liste de tous les projets disponibles en exécutant gcloud projects list
.