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.
ב-Codelab הזה נסביר איך ליצור פונקציה מרוחקת ב-BigQuery כדי לקבל תשובות לשאלה לגבי תמונות שמאוחסנות ב-Cloud Storage באמצעות מענה לשאלות על תמונות (VQA) ב-Vertex AI. שאילתת ה-SQL שלכם תאחזר URI של תמונה מטבלה ב-BigQuery. לאחר מכן, באמצעות פונקציה מרוחקת של BigQuery, תשלחו את ה-URI של התמונה לפונקציית Cloud Run שתחזיר תשובות מ-VQA לגבי התמונה.
איור

מבחינת פיתוח, אלה השלבים שתבצעו ב-codelab הזה:
- יצירת נקודת קצה של HTTP בפונקציות Cloud Run
- יצירת חיבור מסוג CLOUD_RESOURCE
- יצירת טבלת אובייקטים ב-BigQuery לקטגוריה של Cloud Storage
- יצירת הפונקציה המרוחקת
- משתמשים בפונקציה המרוחקת באילתא בדיוק כמו בכל פונקציה אחרת בהגדרת המשתמש
מה תלמדו
- איך יוצרים פונקציית Cloud Run מסוג HTTP ב-Python
- איך ליצור ולהשתמש בפונקציה מרוחקת של BigQuery בתוך שאילתת SQL
- איך יוצרים טבלת אובייקטים ב-BigQuery
- איך משתמשים ב-Vertex AI SDK ל-Python כדי להשתמש ב-Visual Question Answering (VQA)
2. הגדרה ודרישות
דרישות מוקדמות
- אתם מחוברים ל-Cloud Console.
- פרסתם בעבר פונקציית Cloud Run מסוג HTTP. מדריך למתחילים ב-Python
- כבר יצרתם קטגוריה ב-Cloud Storage. מדריך למתחילים בנושא Cloud Storage
- יש לכם את התפקידים המתאימים ליצירת קבוצת נתונים, טבלה ופונקציה מרוחקת ב-BigQuery. ראו את המדריך למתחילים בנושא טעינה ושליחת שאילתות על נתונים ב-BigQuery.
הפעלת Cloud Shell
- ב-Cloud Console, לוחצים על Activate Cloud Shell
.

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים עם תיאור של השירות. אם הוצג לכם מסך ביניים, לוחצים על המשך.

הקצאת המשאבים והחיבור ל-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. ב-Codelab הזה נעשה שימוש בתמונה לדוגמה ממסמכי ה-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. יצירת קישור למשאבים ב-Cloud ב-BigQuery
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 במשתנה. ב-Codelab הזה נעשה שימוש בדוגמה מתוך מסמכי 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 | +---------------------------------+--------------------------------+----------+
10. פתרון בעיות
אם מופיעה השגיאה BigQuery error in mk operation: Source URI must be a Google Cloud Storage location: gs://$BUCKET_NAME כשיוצרים את הטבלה ב-BigQuery, צריך לוודא שכללתם את הנתיב /* אחרי $BUCKET_NAME בפקודה.
כשמריצים את שאילתת ה-SQL, אם מקבלים את השגיאה Access Denied: BigQuery BigQuery: Received response code 403 from endpoint <your-function-endpoint>, כדאי לחכות כדקה או שתיים עד שהרשאת התפקיד Cloud Function 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 וללחוץ על 'מחיקה'. אם תמחקו את הפרויקט, תצטרכו לשנות את הפרויקטים ב-Cloud SDK. כדי לראות את רשימת כל הפרויקטים הזמינים, מריצים את הפקודה gcloud projects list.