1. Introducción
Descripción general
Las funciones remotas de BigQuery te permiten implementar una función en lenguajes distintos de SQL y JavaScript, o con bibliotecas y servicios no permitidos en las funciones definidas por el usuario de BigQuery. Las funciones remotas de BigQuery proporcionan una integración directa con las funciones de Cloud Run y Cloud Run. Para invocar una función remota de BigQuery dentro de una consulta SQL, toma una o más columnas como entrada y, luego, muestra un solo valor como resultado.
Las funciones de Cloud Run son una solución de procesamiento ligera que permite a los desarrolladores crear funciones independientes y de un solo propósito que se pueden activar con HTTPS o responder a CloudEvents sin necesidad de administrar un servidor o entorno de ejecución. Las funciones de Cloud Run son compatibles con Node.js, Python, Go, Java, .NET, Ruby y PHP.
En este codelab, aprenderás a crear una función remota de BigQuery para obtener respuestas a una pregunta sobre imágenes almacenadas en Cloud Storage con Visual Question Answering (VQA) de Vertex AI. Tu consulta en SQL recuperará un URI para una imagen de una tabla en BigQuery. Luego, con una función remota de BigQuery, enviarás el URI de la imagen a una función de Cloud Run que responderá con respuestas de VQA sobre la imagen.
Ilustración
Desde una perspectiva de desarrollo, estos son los pasos que completarás en este codelab:
- Crea el extremo HTTP en las funciones de Cloud Run
- Crea una conexión del tipo CLOUD_RESOURCE
- Crea una tabla de objetos de BigQuery para el bucket de Cloud Storage
- Crea la función remota
- Usa la función remota en una consulta como cualquier otra función definida por el usuario
Qué aprenderás
- Cómo crear una función de HTTP de Cloud Run en Python
- Cómo crear y usar una función remota de BigQuery en una consulta de SQL
- Cómo crear una tabla de objetos de BigQuery
- Cómo usar el SDK de Vertex AI para Python para usar la búsqueda de respuestas visuales (VQA)
2. Configuración y requisitos
Requisitos previos
- Accediste a la consola de Cloud.
- Ya implementaste una función HTTP de Cloud Run. Consulta la guía de inicio rápido de Python.
- Ya creaste un bucket en Cloud Storage. Consulta la guía de inicio rápido de Cloud Storage.
- Tienes los roles adecuados para crear un conjunto de datos, una tabla y una función remota en BigQuery. Consulta la guía de inicio rápido Cargar y consultar datos en BigQuery.
Activar Cloud Shell
- En la consola de Cloud, haz clic en Activar Cloud Shell.
Si es la primera vez que inicias Cloud Shell, aparecerá una pantalla intermedia en la que se describe qué es. Si aparece una pantalla intermedia, haz clic en Continuar.
El aprovisionamiento y la conexión a Cloud Shell solo tomará unos minutos.
Esta máquina virtual está cargada con todas las herramientas de desarrollo necesarias. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que mejora considerablemente el rendimiento de la red y la autenticación. Gran parte de tu trabajo en este codelab, si no todo, se puede hacer con un navegador.
Una vez que te conectes a Cloud Shell, deberías ver que se te autenticó y que el proyecto se configuró con tu ID de proyecto.
- En Cloud Shell, ejecuta el siguiente comando para confirmar que tienes la autenticación:
gcloud auth list
Resultado del comando
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- En Cloud Shell, ejecuta el siguiente comando para confirmar que el comando gcloud conoce tu proyecto:
gcloud config list project
Resultado del comando
[core] project = <PROJECT_ID>
De lo contrario, puedes configurarlo con el siguiente comando:
gcloud config set project <PROJECT_ID>
Resultado del comando
Updated property [core/project].
3. Configura variables de entorno local
En este código, crearás algunas variables de entorno para mejorar la legibilidad de los comandos gcloud
que se usan en este 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 función de Cloud Run
Para crear una función remota de BigQuery, primero debes crear un extremo HTTP con la función de Cloud Run. El extremo debe poder procesar un lote de filas en una sola solicitud POST HTTP y mostrar los resultados para el lote como una respuesta HTTP.
Esta función de Cloud Run recibirá el URI de almacenamiento de imágenes y la instrucción de la pregunta como entrada de tu consulta de SQL, y mostrará la respuesta de la respuesta visual de preguntas (VQA).
En este codelab, se usa un ejemplo del entorno de ejecución de python311 con el SDK de Vertex AI para Python.
Crea el código fuente de la función
Primero, crea un directorio y ábrelo con el comando cd.
mkdir imagen-vqa && cd $_
Luego, crea un archivo requirements.txt
.
google-cloud-aiplatform[preview] google-cloud-storage functions-framework==3.*
A continuación, crea un archivo fuente 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
Implementa la función de Cloud Run
Ahora puedes implementar tu función de Cloud Run para el entorno de ejecución python311.
Para implementar una función de Cloud Run directamente en Cloud Run, ejecuta el siguiente comando:
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function imagen_vqa \ --region $FUNCTION_REGION \ --no-allow-unauthenticated
Si prefieres implementarla como una función de Cloud Functions de 2ª gen., usa el siguiente comando:
gcloud functions deploy $FUNCTION_NAME \ --gen2 \ --region=$FUNCTION_REGION \ --runtime=python311 \ --trigger-http \ --source=. \ --no-allow-unauthenticated
y, luego, puedes guardar la URL de la función como una variable de entorno para usarla más adelante.
ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"
5. Crea el bucket de Cloud Storage
Primero, crea un bucket de Cloud Storage para almacenar tus imágenes.
gcloud storage buckets create gs://$BUCKET_NAME
A continuación, sube una imagen para que la use VQA. En este codelab, se usa la imagen de ejemplo de la documentación de VQA.
Puedes usar la consola de Cloud Storage para subir la imagen directamente a tu bucket. También puedes ejecutar los siguientes comandos para descargar la imagen de ejemplo en tu directorio actual de Cloud Shell.
wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true
y, luego, subirlo a tu bucket de Cloud Storage.
gcloud storage cp image.jpg gs://$BUCKET_NAME
6. Crea una conexión de recursos de Cloud de BigQuery
BigQuery usa una conexión CLOUD_RESOURCE para interactuar con tu Cloud Function. Ejecuta el siguiente comando para crear esta conexión.
bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \ --connection_type=CLOUD_RESOURCE $CONNECTION_ID
A continuación, muestra los detalles de la nueva conexión de BigQuery.
bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID
Guarda el nombre de la cuenta de servicio de conexión de BigQuery en una variable, como se muestra.
CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"
Otorga acceso a la cuenta de servicio para acceder a tu bucket de Cloud Storage.
gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME
7. Crea una tabla de objetos de BigQuery
Las tablas de objetos de BigQuery son tablas de solo lectura sobre objetos de datos no estructurados que residen en Cloud Storage.
Las tablas de objetos te permiten analizar datos no estructurados en Cloud Storage. Puedes realizar análisis con funciones remotas y, luego, unir los resultados de estas operaciones con el resto de tus datos estructurados en BigQuery.
Primero, crea un conjunto de datos.
bq --location=$BQ_REGION mk \ --dataset \ $DATASET_ID
El siguiente comando crea una tabla de objetos basada en tu bucket de imágenes de Cloud Storage. La tabla resultante contendrá los URIs de todas las imágenes de ese 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 función remota de BigQuery
El último paso es configurar la función remota de BigQuery.
Primero, otorga permisos a la cuenta de servicio de conexión de BigQuery para invocar la función de Cloud Run. No se recomienda permitir la invocación no autenticada para el servicio de funciones de Cloud Run.
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --member=serviceAccount:$CONNECTION_SA \ --role="roles/run.invoker" \ --region $FUNCTION_REGION
A continuación, guarda la consulta de SQL en una 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' )"
Ahora, ejecuta la consulta.
bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION
Después de ejecutar la consulta para crear la función remota, verás Created <your-project-id>.remote_function_codelab.vqa
.
9. Cómo llamar a la función remota de BigQuery en una consulta SQL
Acabas de completar los pasos de desarrollo para crear la función remota. Ahora puedes llamar a tu función de Cloud Run desde una consulta SQL.
Primero, guarda tu pregunta y tu consulta en SQL en una variable. En este codelab, se usa el ejemplo de la documentación de la Búsqueda de respuestas visuales. Esta consulta usa la imagen más reciente que se agregó a tu bucket de almacenamiento.
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; "
Luego, ejecuta la consulta de SQL para mostrar la respuesta del servicio de búsqueda de respuestas visuales (VQA) de Vertex AI.
bq query --nouse_legacy_sql $SQL_QUERY
Los resultados deberían ser similares al resultado de ejemplo a continuación:
+---------------------------------+--------------------------------+----------+ | uri | image_prompt | result | +---------------------------------+--------------------------------+----------+ | gs://<YOUR_BUCKET>/image.jpg | What objects are in the image? | marbles | +---------------------------------+--------------------------------+----------+
10. Solución de problemas
Cuando crees la tabla de BigQuery, si recibes un error BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME
, asegúrate de haber incluido la ruta de acceso /*
después de $BUCKET_NAME
en el comando.
Cuando ejecutes tu consulta SQL, si recibes un error Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint>
, espera entre 1 y 2 minutos para que se propague el permiso de rol de invocador de Cloud Function a la cuenta de servicio de conexión de BigQuery antes de volver a intentarlo.
11. ¡Felicitaciones!
¡Felicitaciones por completar el codelab!
Te recomendamos que revises la documentación sobre las funciones remotas de BigQuery y la búsqueda de respuestas visuales (VQA).
Temas abordados
- Cómo configurar la autenticación en una función de Cloud Run y verificar que se haya configurado correctamente
- Proporciona el token de tu identidad de gcloud para invocar una función autenticada desde un entorno de desarrollo local
- Cómo crear una cuenta de servicio y otorgarle el rol adecuado para invocar una función
- Cómo suplantar la identidad de un servicio desde un entorno de desarrollo local que tenga los roles adecuados para invocar una función
12. Limpia
Para evitar cargos involuntarios (por ejemplo, si esta función de Cloud Run se invoca de forma involuntaria más veces que la asignación mensual de invocación de funciones de Cloud Run en el nivel gratuito), puedes borrar la Cloud Function o borrar el proyecto que creaste en el paso 2.
Para borrar la función de Cloud Run, ve a la consola de Cloud Run en https://console.cloud.google.com/functions/ y borra la función imagen-vqa (o $FUNCTION_NAME en caso de que hayas usado un nombre diferente).
Si decides borrar el proyecto completo, puedes ir a https://console.cloud.google.com/cloud-resource-manager, seleccionar el proyecto que creaste en el paso 2 y elegir Borrar. Si borras el proyecto, deberás cambiar los proyectos en tu SDK de Cloud. Para ver la lista de todos los proyectos disponibles, ejecuta gcloud projects list
.