Используйте удаленные функции BigQuery, чтобы задавать вопросы Vertex AI Visual Question Answering (VQA) в SQL-запросе.

1. Введение

Обзор

Удаленные функции BigQuery позволяют реализовать функцию на языках, отличных от SQL и JavaScript, или с помощью библиотек и сервисов, которые не разрешены в пользовательских функциях BigQuery. Удаленные функции BigQuery обеспечивают прямую интеграцию с функциями Cloud Run и Cloud Run . Вы можете вызвать удаленную функцию BigQuery в запросе SQL, приняв один или несколько столбцов в качестве входных данных, а затем вернув одно значение в качестве выходных данных.

Функции Cloud Run — это легкое вычислительное решение, позволяющее разработчикам создавать одноцелевые автономные функции, которые можно запускать с помощью HTTPS или реагировать на CloudEvents без необходимости управлять сервером или средой выполнения. Функции Cloud Run поддерживают Node.js, Python, Go, Java, .NET, Ruby и PHP.

В этой лабораторной работе вы узнаете, как создать удаленную функцию BigQuery для получения ответов на вопросы об изображениях, хранящихся в облачном хранилище, с помощью визуальных ответов на вопросы Vertex AI (VQA) . Ваш SQL-запрос получит URI для изображения из таблицы в BigQuery. Затем, используя удаленную функцию BigQuery, вы отправите URI изображения в функцию Cloud Run, которая ответит ответами от VQA об изображении.

Иллюстрация

5832020184ccf2b2.png

С точки зрения разработки, в этой лаборатории кода вы выполните следующие шаги:

  1. Создайте конечную точку HTTP в функциях Cloud Run.
  2. Создайте соединение типа CLOUD_RESOURCE.
  3. Создайте таблицу объектов BigQuery для сегмента Cloud Storage.
  4. Создайте удаленную функцию
  5. Используйте удаленную функцию в запросе так же, как и любые другие пользовательские функции.

Что вы узнаете

2. Настройка и требования

Предварительные условия

Активировать Cloud Shell

  1. В Cloud Console нажмите «Активировать Cloud Shell». d1264ca30785e435.png .

cb81e7c8e34bc8d.png

Если вы запускаете Cloud Shell впервые, вы увидите промежуточный экран с описанием того, что это такое. Если вам был представлен промежуточный экран, нажмите «Продолжить» .

d95252b003979716.png

Подготовка и подключение к Cloud Shell займет всего несколько минут.

7833d5e1c5d18f54.png

Эта виртуальная машина загружена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Большую часть, если не всю, работу в этой лаборатории кода можно выполнить с помощью браузера.

После подключения к Cloud Shell вы увидите, что вы прошли аутентификацию и что для проекта установлен идентификатор вашего проекта.

  1. Выполните следующую команду в Cloud Shell, чтобы подтвердить, что вы прошли аутентификацию:
gcloud auth list

Вывод команды

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

Вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить его с помощью этой команды:

gcloud config set project <PROJECT_ID>

Вывод команды

Updated property [core/project].

3. Настройте локальные переменные среды.

В этом коде вы создадите несколько переменных среды, чтобы улучшить читаемость команд gcloud используемых в этой лаборатории кода.

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. Создайте функцию Cloud Run.

Чтобы создать удаленную функцию BigQuery, сначала необходимо создать конечную точку HTTP с помощью функции Cloud Run. Конечная точка должна иметь возможность обрабатывать пакет строк в одном запросе HTTP POST и возвращать результаты пакета в виде ответа HTTP.

Эта функция Cloud Run получит URI хранилища изображений и запрос на вопрос в качестве входных данных из вашего SQL-запроса и вернет ответ из визуального ответа на вопрос (VQA).

В этой кодовой лаборатории используется пример среды выполнения python311 с использованием Vertex AI SDK для Python .

Создайте исходный код функции

Сначала создайте каталог и перейдите в него.

mkdir imagen-vqa && cd $_

Затем создайте файл requirements.txt .

google-cloud-aiplatform[preview]
google-cloud-storage
functions-framework==3.*

Затем создайте исходный файл 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

Развертывание функции Cloud Run

Теперь вы можете развернуть функцию Cloud Run для среды выполнения python311.

Чтобы развернуть функцию Cloud Run непосредственно в Cloud Run, выполните следующую команду:

gcloud beta run deploy $FUNCTION_NAME \
      --source . \
      --function imagen_vqa \
      --region $FUNCTION_REGION \
      --no-allow-unauthenticated

Если вы предпочитаете развертывать облачные функции 2-го поколения, используйте следующую команду:

gcloud functions deploy $FUNCTION_NAME \
--gen2 \
--region=$FUNCTION_REGION \
--runtime=python311 \
--trigger-http \
--source=. \
--no-allow-unauthenticated

а затем вы можете сохранить URL-адрес функции как переменную среды, чтобы использовать ее позже.

ENDPOINT_URL="$(gcloud beta run services describe $FUNCTION_NAME --region $FUNCTION_REGION --format='value(status.url)')"

5. Создайте сегмент облачного хранилища.

Сначала создайте корзину Cloud Storage для хранения ваших изображений.

gcloud storage buckets create gs://$BUCKET_NAME

Затем загрузите изображение для использования VQA. В этой кодовой лаборатории используется пример изображения из документации VQA .

Вы можете использовать облачную консоль для облачного хранилища, чтобы загрузить изображение непосредственно в корзину. Или вы можете запустить следующие команды, чтобы загрузить пример изображения в текущий каталог Cloud Shell.

wget -O image.jpg -o /dev/null https://unsplash.com/photos/QqN25A3iF9w/download?ixid=M3wxMjA3fDB8MXxhbGx8fHx8fHx8fHwxNjk1NzYxMjY2fA&force=true

а затем загрузить в корзину Cloud Storage.

gcloud storage cp image.jpg gs://$BUCKET_NAME

6. Создайте подключение к облачному ресурсу BigQuery.

BigQuery использует соединение CLOUD_RESOURCE для взаимодействия с вашей облачной функцией. Выполните следующую команду, чтобы создать это соединение.

bq mk --connection --location=$BQ_REGION --project_id=$PROJECT_ID \
--connection_type=CLOUD_RESOURCE $CONNECTION_ID

Затем отобразите сведения о новом подключении к BigQuery.

bq show --connection $PROJECT_ID.$BQ_REGION.$CONNECTION_ID

Сохраните имя учетной записи службы подключения BigQuery в переменную, как показано.

CONNECTION_SA="<YOUR-SERVICE-ACCOUNT-ID>@gcp-sa-bigquery-condel.iam.gserviceaccount.com"

Предоставьте доступ к сервисному аккаунту для доступа к вашему сегменту Cloud Storage.

gsutil iam ch serviceAccount:$CONNECTION_SA:objectAdmin gs://$BUCKET_NAME

7. Создайте таблицу объектов BigQuery.

Таблицы объектов BigQuery – это таблицы, доступные только для чтения, для объектов неструктурированных данных, находящихся в Cloud Storage.

Таблицы объектов позволяют анализировать неструктурированные данные в Cloud Storage. Вы можете выполнить анализ с помощью удаленных функций, а затем объединить результаты этих операций с остальными структурированными данными в BigQuery.

Сначала создайте набор данных.

bq --location=$BQ_REGION mk \
    --dataset \
    $DATASET_ID

Следующая команда создает таблицу объектов на основе корзины образов Cloud Storage. Результирующая таблица будет содержать URI для всех изображений в этом сегменте.

bq mk --table \
--external_table_definition=gs://$BUCKET_NAME/*@$BQ_REGION.$CONNECTION_ID \
--object_metadata=SIMPLE \
$PROJECT_ID:$DATASET_ID.$TABLE_NAME

8. Создайте удаленную функцию BigQuery.

Последний шаг — настроить удаленную функцию BigQuery.

Сначала предоставьте учетной записи службы подключений BigQuery разрешения на вызов функции Cloud Run. Не рекомендуется разрешать вызов функции Cloud Run без аутентификации.

gcloud run services add-iam-policy-binding $FUNCTION_NAME \
 --member=serviceAccount:$CONNECTION_SA \
 --role="roles/run.invoker" \
 --region $FUNCTION_REGION

Затем сохраните SQL-запрос в переменной.

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'
)"

А теперь запустите запрос.

bq query --nouse_legacy_sql $SQL_CREATE_FUNCTION

После выполнения запроса на создание удаленной функции вы увидите Created <your-project-id>.remote_function_codelab.vqa

9. Вызов удаленной функции BigQuery в SQL-запросе.

Вы завершили этапы разработки для создания удаленной функции. Теперь вы можете вызывать функцию Cloud Run из запроса SQL.

Сначала сохраните свой вопрос и SQL-запрос в переменной. В этой кодовой лаборатории используется пример из документации по визуальным ответам на вопросы. В этом запросе используется последнее изображение, добавленное в ваш сегмент хранилища.

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;
"

Затем запустите SQL-запрос, чтобы просмотреть ответ от службы визуальных ответов на вопросы Vertex AI (VQA).

bq query --nouse_legacy_sql $SQL_QUERY

Результаты должны выглядеть примерно так, как показано в примере ниже:

+---------------------------------+--------------------------------+----------+
|               uri               |    image_prompt                |  result  |
+---------------------------------+--------------------------------+----------+
| gs://<YOUR_BUCKET>/image.jpg    | What objects are in the image? |  marbles |
+---------------------------------+--------------------------------+----------+

10. Устранение неполадок

Если при создании таблицы BigQuery вы получаете сообщение об ошибке BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME , убедитесь, что вы включили путь /* после $BUCKET_NAME в команду.

Если при выполнении SQL-запроса вы получаете сообщение об ошибке Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint> , попробуйте подождать около 1–2 минут, чтобы разрешение роли Cloud Function Invoker распространилось на BigQuery. учетную запись службы подключения перед повторной попыткой.

11. Поздравляем!

Поздравляем с завершением работы над кодом!

Рекомендуем просмотреть документацию по удаленным функциям BigQuery и визуальным ответам на вопросы (VQA) .

Что мы рассмотрели

  • Как настроить аутентификацию в функции Cloud Run и убедиться, что аутентификация настроена правильно
  • Вызовите аутентифицированную функцию из локальной среды разработки, предоставив токен для вашего удостоверения gcloud.
  • Как создать учетную запись службы и предоставить ей соответствующую роль для вызова функции
  • Как олицетворять службу из локальной среды разработки, имеющую соответствующие роли для вызова функции

12. Очистка

Чтобы избежать непреднамеренных расходов (например, если эта функция Cloud Run случайно вызывается больше раз, чем ежемесячно выделено количество вызовов функции Cloud Run на уровне бесплатного пользования ), вы можете либо удалить функцию Cloud, либо удалить проект, созданный на шаге 2.

Чтобы удалить функцию Cloud Run, перейдите в облачную консоль Cloud Run по адресу https://console.cloud.google.com/functions/ и удалите функцию imagen-vqa (или $FUNCTION_NAME, если вы использовали другое имя).

Если вы решите удалить весь проект, вы можете перейти на https://console.cloud.google.com/cloud-resource-manager , выбрать проект, созданный на шаге 2, и нажать «Удалить». Если вы удалите проект, вам придется изменить проекты в Cloud SDK. Вы можете просмотреть список всех доступных проектов, запустив gcloud projects list .