استخدِم دوال 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 للحصول على إجابات عن أسئلة حول الصور المخزّنة في Cloud Storage باستخدام ميزة الإجابة المرئية على الأسئلة (VQA) في Vertex AI. سيسترد طلب بحث 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 هذه معرّف الموارد المنتظم لتخزين الصور وطلب السؤال كمدخل من طلب بحث SQL، وستعرض الإجابة من ميزة "الإجابة المرئية على الأسئلة" (VQA).

يستخدم هذا الدرس التطبيقي حول الترميز مثالاً لوقت التشغيل python311 باستخدام Vertex AI SDK for 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

إذا كنت تفضّل النشر كـ "الجيل الثاني من Cloud Functions"، استخدِم الأمر التالي:

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

أولاً، أنشئ حزمة في Cloud Storage لتخزين صورك.

gcloud storage buckets create gs://$BUCKET_NAME

بعد ذلك، حمِّل صورة لاستخدامها في VQA. يستخدم هذا الدرس التطبيقي حول الترميز الصورة النموذجية من مستندات VQA.

يمكنك استخدام Cloud Console لخدمة Cloud Storage من أجل تحميل الصورة مباشرةً إلى حزمتك. أو يمكنك تنفيذ الأوامر التالية لتنزيل الصورة النموذجية إلى دليل 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 Cloud

يستخدم BigQuery عملية ربط CLOUD_RESOURCE للتفاعل مع Cloud Function. نفِّذ الأمر التالي لإنشاء عملية الربط هذه.

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. سيتضمّن الجدول الناتج معرّفات الموارد الموحّدة لجميع الصور في هذا الحزمة.

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 لعرض الردّ من خدمة "الإجابة المرئية على الأسئلة" (VQA) ضمن Vertex AI.

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>، حاوِل الانتظار لمدة دقيقة أو دقيقتَين تقريبًا إلى أن يتم نشر إذن دور Cloud Function Invoker إلى حساب خدمة ربط BigQuery قبل إعادة المحاولة.

11. تهانينا!

تهانينا على إكمال هذا الدرس العملي.

ننصحك بمراجعة المستندات حول وظائف BigQuery عن بُعد والإجابة المرئية على الأسئلة (VQA).

المواضيع التي تناولناها

  • كيفية ضبط المصادقة على إحدى دوال Cloud Run والتأكّد من ضبطها بشكلٍ سليم
  • استدعاء دالة مصادَق عليها من بيئة تطوير محلية من خلال تقديم الرمز المميز لهوية gcloud
  • كيفية إنشاء حساب خدمة ومنحه الدور المناسب لتنفيذ وظيفة
  • كيفية انتحال هوية خدمة من بيئة تطوير محلية تتضمّن الأدوار المناسبة لاستدعاء دالة

12. تَنظيم

لتجنُّب الرسوم غير المقصودة (على سبيل المثال، إذا تم استدعاء دالة Cloud Run هذه بشكل غير مقصود مرات أكثر من عدد مرات استدعاء دالة Cloud Run المخصّصة لك شهريًا في الطبقة المجانية)، يمكنك إما حذف دالة Cloud أو حذف المشروع الذي أنشأته في الخطوة 2.

لحذف وظيفة Cloud Run، انتقِل إلى Cloud Run Cloud Console على https://console.cloud.google.com/functions/ واحذف وظيفة imagen-vqa (أو $FUNCTION_NAME إذا كنت قد استخدمت اسمًا مختلفًا).

إذا اخترت حذف المشروع بأكمله، يمكنك الانتقال إلى https://console.cloud.google.com/cloud-resource-manager، واختيار المشروع الذي أنشأته في الخطوة 2، ثم النقر على "حذف". إذا حذفت المشروع، عليك تغيير المشاريع في Cloud SDK. يمكنك الاطّلاع على قائمة بجميع المشاريع المتاحة من خلال تنفيذ gcloud projects list.