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 באמצעות Visual Question Answering (VQA) של Vertex AI. שאילתת ה-SQL תאחזר מזהה URI של תמונה מטבלה ב-BigQuery. לאחר מכן, באמצעות הפונקציה המרוחקת של BigQuery, תשלחו את ה-URI של התמונה לפונקציה של Cloud Run שתחזיר תשובות מ-VQA לגבי התמונה.
איור
מבחינת פיתוח, השלבים הבאים שתבצעו ב-Codelab הזה:
- יצירת נקודת הקצה מסוג HTTP בפונקציות של Cloud Run
- יצירת חיבור מסוג CLOUD_RESOURCE
- יצירת טבלת אובייקטים ב-BigQuery לקטגוריה של Cloud Storage
- יצירת הפונקציה מרחוק
- משתמשים בפונקציה מרחוק בשאילתה כמו בכל פונקציה אחרת בהגדרת המשתמש
מה תלמדו
- איך יוצרים פונקציית HTTP ב-Cloud Run ב-Python
- איך יוצרים פונקציה מרוחקת ב-BigQuery ומשתמשים בה בתוך שאילתת SQL
- איך יוצרים טבלת אובייקטים ב-BigQuery
- איך משתמשים ב-Vertex AI SDK ל-Python כדי להשתמש ב-Visual Question Answering (VQA)
2. הגדרה ודרישות
דרישות מוקדמות
- אתם מחוברים למסוף Cloud.
- פרסתם בעבר פונקציית HTTP ב-Cloud Run. מעבר למדריך למתחילים ב-Python
- יצרתם בעבר קטגוריה ב-Cloud Storage. עיינו במדריך למתחילים של Cloud Storage.
- יש לכם את התפקידים המתאימים ליצירת מערך נתונים, טבלה ופונקציה מרוחקת ב-BigQuery. מידע נוסף זמין במדריך למתחילים בנושא טעינת נתונים והרצת שאילתות ב-BigQuery.
הפעלת Cloud Shell
- במסוף Cloud, לוחצים על Activate Cloud Shell .
אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג מסך ביניים עם תיאור של השירות. אם יוצג מסך ביניים, לוחצים על Continue (המשך).
תהליך ההקצאה וההתחברות ל-Cloud Shell אמור להימשך רק כמה רגעים.
המכונה הווירטואלית הזו כוללת את כל הכלים הנדרשים לפיתוח. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, משפרת מאוד את הביצועים והאימות של הרשת. אפשר לבצע את רוב העבודה ב-codelab הזה, אם לא את כולה, באמצעות דפדפן.
אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שהפרויקט מאומת ושהפרויקט מוגדר לפי מזהה הפרויקט שלכם.
- מריצים את הפקודה הבאה ב-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`
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה gcloud מכירה את הפרויקט:
gcloud config list project
פלט הפקודה
[core] project = <PROJECT_ID>
אם היא לא נמצאת שם, תוכלו להגדיר אותה באמצעות הפקודה הבאה:
gcloud config set project <PROJECT_ID>
פלט הפקודה
Updated property [core/project].
3. הגדרת משתני סביבה מקומיים
בקוד הזה תיצורו כמה משתני סביבה כדי לשפר את הקריאוּת של הפקודות gcloud
שבהן נעשה שימוש ב-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. יצירת הפונקציה ב-Cloud Run
כדי ליצור פונקציה מרוחקת ב-BigQuery, קודם צריך ליצור נקודת קצה מסוג HTTP באמצעות פונקציית Cloud Run. נקודת הקצה חייבת להיות מסוגלת לעבד קבוצה של שורות בבקשת HTTP POST יחידה ולהחזיר את התוצאות של האצווה כתגובת HTTP.
הפונקציה הזו ב-Cloud Run תקבל את ה-URI של אחסון התמונה ואת הנחיית השאלה כקלט משאילתת ה-SQL, ותחזיר את התשובה מ-Visual Question Answering (VQA).
בשיעור ה-Codelab הזה נעשה שימוש בדוגמה לסביבת זמן ריצה של python311 באמצעות Vertex AI SDK ל-Python.
יצירת קוד המקור של הפונקציה
קודם יוצרים ספרייה ומעבירים את נתיב העבודה (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
לאחר מכן אפשר לשמור את כתובת ה-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 Storage ב-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 Resource
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. הטבלה שתתקבל תכיל את מזהי ה-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 כדי להציג את התשובה משירות ה-VQA (Visual Question Answering) של 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>
, צריך להמתין כ-1-2 דקות עד שהרשאת התפקיד של Cloud Functions Invoker תתעדכן בחשבון השירות של החיבור ל-BigQuery, לפני הניסיון הבא.
11. מעולה!
כל הכבוד על השלמת ה-Codelab!
מומלץ לעיין במסמכי העזרה בנושא פונקציות מרוחקות של BigQuery ומענה על שאלות חזותיות (VQA).
מה עסקנו בו
- איך להגדיר אימות בפונקציית Cloud Run ולוודא שהאימות הוגדר כראוי
- הפעלת פונקציה מאומתת מסביבת פיתוח מקומית באמצעות מתן האסימון לזהות שלכם ב-gcloud
- איך יוצרים חשבון שירות ומעניקים לו את התפקיד המתאים להפעלת פונקציה
- איך מתחזים לשירות מסביבת פיתוח מקומית שיש לה את התפקידים המתאימים להפעלת פונקציה
12. הסרת המשאבים
כדי להימנע מחיובים לא מכוונים (לדוגמה, אם הפונקציה של Cloud Run הופעלה בטעות יותר פעמים מההקצאה החודשית של הפונקציה של Cloud Run בתוכנית ללא תשלום), אפשר למחוק את הפונקציה של Cloud Functions או למחוק את הפרויקט שיצרתם בשלב 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 ולבחור באפשרות Delete (מחיקה). אם תמחקו את הפרויקט, תצטרכו לשנות את הפרויקטים ב-Cloud SDK. כדי להציג את רשימת כל הפרויקטים הזמינים, מריצים את הפקודה gcloud projects list
.