از توابع راه دور BigQuery برای پرسیدن سؤالات به Vertex AI Visual Question Answering (VQA) در پرس و جوی SQL استفاده کنید.

۱. مقدمه

نمای کلی

توابع از راه دور BigQuery به شما امکان می‌دهد یک تابع را به زبان‌هایی غیر از SQL و جاوا اسکریپت یا با کتابخانه‌ها و سرویس‌هایی که در توابع تعریف‌شده توسط کاربر 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 Visual Question Answering (VQA) به سوالی در مورد تصاویر ذخیره شده در Cloud Storage پاسخ دهید. کوئری SQL شما یک URI برای یک تصویر از یک جدول در BigQuery بازیابی می‌کند. سپس با استفاده از یک تابع از راه دور BigQuery، URI تصویر را به یک تابع Cloud Run ارسال می‌کنید که با پاسخ‌های VQA در مورد تصویر پاسخ می‌دهد.

تصویرسازی

۵۸۳۲۰۲۰۱۸۴ccf2b2.png

از دیدگاه توسعه، مراحلی که در این آزمایشگاه کد انجام خواهید داد عبارتند از:

  1. ایجاد نقطه پایانی HTTP در توابع Cloud Run
  2. یک اتصال از نوع CLOUD_RESOURCE ایجاد کنید
  3. یک جدول شیء BigQuery برای مخزن ذخیره‌سازی ابری ایجاد کنید
  4. ایجاد تابع از راه دور
  5. درست مانند سایر توابع تعریف شده توسط کاربر، از تابع remote در یک پرس و جو استفاده کنید

آنچه یاد خواهید گرفت

۲. تنظیمات و الزامات

پیش‌نیازها

فعال کردن پوسته ابری

  1. از کنسول ابری، روی فعال کردن پوسته ابری کلیک کنید d1264ca30785e435.png .

cb81e7c8e34bc8d.png

اگر این اولین باری است که Cloud Shell را اجرا می‌کنید، یک صفحه میانی برای توضیح آن به شما نمایش داده می‌شود. اگر با یک صفحه میانی مواجه شدید، روی ادامه کلیک کنید.

d95252b003979716.png

آماده‌سازی و اتصال به Cloud Shell فقط چند لحظه طول می‌کشد.

7833d5e1c5d18f54.png

این ماشین مجازی مجهز به تمام ابزارهای توسعه مورد نیاز است. این ماشین یک دایرکتوری خانگی پایدار ۵ گیگابایتی ارائه می‌دهد و در فضای ابری گوگل اجرا می‌شود که عملکرد شبکه و احراز هویت را تا حد زیادی افزایش می‌دهد. بخش عمده‌ای از کار شما در این آزمایشگاه کد، اگر نگوییم همه، را می‌توان با یک مرورگر انجام داد.

پس از اتصال به 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].

۳. تنظیم متغیرهای محیطی محلی

در این کد، شما چند متغیر محیطی ایجاد خواهید کرد تا خوانایی دستورات 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"

۴. تابع Cloud Run را ایجاد کنید

برای ایجاد یک تابع از راه دور BigQuery، ابتدا باید با استفاده از تابع Cloud Run یک نقطه پایانی HTTP ایجاد کنید. نقطه پایانی باید بتواند دسته‌ای از ردیف‌ها را در یک درخواست HTTP POST واحد پردازش کند و نتایج را برای دسته به عنوان پاسخ HTTP برگرداند.

این تابع Cloud Run، آدرس اینترنتی (URI) مربوط به فضای ذخیره‌سازی تصویر و اعلان سوال را به عنوان ورودی از کوئری SQL شما دریافت می‌کند و پاسخ را از Visual Question Answering (VQA) برمی‌گرداند.

این آزمایشگاه کد از یک مثال برای زمان اجرای python311 با استفاده از Vertex AI SDK برای پایتون استفاده می‌کند.

کد منبع تابع را ایجاد کنید

ابتدا یک دایرکتوری ایجاد کنید و با دستور cd به آن دایرکتوری بروید.

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

اگر ترجیح می‌دهید به عنوان یک Cloud Functions نسل دوم مستقر شوید، از دستور زیر استفاده کنید:

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

و سپس می‌توانید آدرس تابع (Function URL) را به عنوان یک متغیر محیطی ذخیره کنید تا بعداً از آن استفاده کنید.

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

۵. ایجاد سطل ذخیره‌سازی ابری

ابتدا، یک فضای ذخیره‌سازی ابری برای ذخیره تصاویر خود ایجاد کنید.

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

و سپس در فضای ذخیره‌سازی ابری خود آپلود کنید.

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

۶. یک اتصال BigQuery Cloud Resource ایجاد کنید

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"

برای دسترسی به فضای ذخیره‌سازی ابری خود، به حساب سرویس دسترسی بدهید.

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

۷. یک جدول شیء BigQuery ایجاد کنید

جداول شیء BigQuery، جداول فقط خواندنی روی اشیاء داده بدون ساختار هستند که در Cloud Storage قرار دارند.

جداول شیء به شما امکان می‌دهند داده‌های بدون ساختار را در فضای ذخیره‌سازی ابری تجزیه و تحلیل کنید. می‌توانید تجزیه و تحلیل را با توابع از راه دور انجام دهید و سپس نتایج این عملیات را با بقیه داده‌های ساختار یافته خود در BigQuery ترکیب کنید.

ابتدا، یک مجموعه داده ایجاد کنید.

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

دستور زیر یک جدول شیء بر اساس مجموعه تصاویر فضای ابری شما ایجاد می‌کند. جدول حاصل شامل URI های مربوط به تمام تصاویر موجود در آن مجموعه خواهد بود.

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

۸. تابع BigQuery Remote را ایجاد کنید

آخرین مرحله پیکربندی تابع BigQuery Remote است.

ابتدا، مجوزهای حساب سرویس اتصال 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 Query را در یک متغیر ذخیره کنید.

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 مشاهده خواهید کرد.

۹. تابع BigQuery Remote را در یک کوئری SQL فراخوانی کنید

اکنون مراحل توسعه برای ایجاد تابع از راه دور را تکمیل کرده‌اید. اکنون می‌توانید تابع Cloud Run خود را از درون یک کوئری SQL فراخوانی کنید.

ابتدا، سوال و کوئری SQL خود را در یک متغیر ذخیره کنید. این آزمایشگاه کد از مثال موجود در مستندات Visual Question Answering استفاده می‌کند. این کوئری از آخرین تصویر اضافه شده به مخزن ذخیره‌سازی شما استفاده می‌کند.

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 |
+---------------------------------+--------------------------------+----------+

۱۰. عیب‌یابی

هنگام ایجاد جدول 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> ، حدود ۱ تا ۲ دقیقه صبر کنید تا مجوز نقش Cloud Function Invoker به حساب سرویس اتصال BigQuery منتقل شود و سپس دوباره امتحان کنید.

۱۱. تبریک می‌گویم!

تبریک می‌گویم که آزمایشگاه کد را تمام کردید!

توصیه می‌کنیم مستندات مربوط به BigQuery Remote Functions و Visual Question Answering (VQA) را مطالعه کنید.

آنچه ما پوشش داده‌ایم

  • نحوه پیکربندی احراز هویت در عملکرد Cloud Run و تأیید صحت پیکربندی احراز هویت
  • با ارائه توکن برای هویت gcloud خود، یک تابع احراز هویت شده را از یک محیط توسعه محلی فراخوانی کنید.
  • نحوه ایجاد یک حساب کاربری سرویس و اعطای نقش مناسب برای فراخوانی یک تابع به آن
  • نحوه جعل هویت یک سرویس از یک محیط توسعه محلی که نقش‌های مناسبی برای فراخوانی یک تابع دارد

۱۲. تمیز کردن

برای جلوگیری از هزینه‌های ناخواسته، (برای مثال، اگر این تابع 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 بروید، پروژه‌ای را که در مرحله ۲ ایجاد کرده‌اید انتخاب کنید و گزینه Delete را انتخاب کنید. اگر پروژه را حذف کنید، باید پروژه‌ها را در Cloud SDK خود تغییر دهید. می‌توانید با اجرای gcloud projects list لیست تمام پروژه‌های موجود را مشاهده کنید.