1. סקירה כללית
בשיעור ה-Lab הזה תשתמשו בתכונה של מודל אירוח משותף ב-Vertex AI כדי לארח כמה מודלים באותה VM לצורך חיזוי אונליין.
מה תלמדו
תלמדו איך:
- צור
DeploymentResourcePool
- פריסת מודלים ב-
DeploymentResourcePool
העלות הכוללת להרצת שיעור ה-Lab הזה ב-Google Cloud היא כ-2$.
2. מבוא ל-Vertex AI
במעבדה הזו נעשה שימוש במוצרי ה-AI החדשים ביותר שזמינים ב-Google Cloud. Vertex AI משלבת את חבילות ה-ML ב-Google Cloud לחוויית פיתוח חלקה. בעבר, היה אפשר לגשת למודלים שהותאמו אישית ולמודלים שהותאמו באמצעות AutoML דרך שירותים נפרדים. המוצר החדש משלב את כל ממשקי ה-API האלה בממשק API אחד, לצד מוצרים חדשים אחרים. אפשר גם להעביר פרויקטים קיימים ל-Vertex AI. יש לך משוב? אפשר למצוא אותו בדף התמיכה.
Vertex AI כולל הרבה מוצרים שונים לתמיכה בתהליכי עבודה של למידת מכונה מקצה לקצה. בשיעור ה-Lab הזה נתמקד במוצרים הבאים: Predictions ו-Workbench
3. סקירה כללית של תרחיש לדוגמה
כשפורסים מודלים בשירות החיזוי של Vertex AI, כל מודל מופעל כברירת מחדל במכונה וירטואלית משלו. כדי להוזיל את האירוח, אפשר לארח כמה מודלים באותה מכונה וירטואלית, וכך לנצל טוב יותר את הזיכרון ואת משאבי המחשוב. מספר המודלים שתרצו לפרוס באותה מכונה וירטואלית יהיה תלוי בגדלי המודלים ובדפוסי התנועה, אבל התכונה הזו שימושית במיוחד בתרחישים שבהם יש לכם הרבה מודלים פרוסים עם תנועה דלילה.
תמיכה במודל אירוח משותף מציגה את הקונספט Deployment Resource Pool, שמקבץ מודלים לשיתוף משאבים במכונה וירטואלית. מודלים יכולים לשתף מכונה וירטואלית אם הם משתפים אותה נקודת קצה, וגם אם הם נפרסים בנקודות קצה שונות. נכון לעכשיו, למודלים באותו מאגר משאבים צריכה להיות אותה קובץ אימג' בקונטיינר, כולל גרסת המסגרת של קונטיינרים מוכנים מראש של Vertex Prediction. בנוסף, בגרסת המוצר הזו יש תמיכה רק בקונטיינרים מוכנים מראש של Vertex Prediction עם מסגרת המודל של Tensorflow. עדיין אין תמיכה במסגרות מודל אחרות ובקונטיינרים מותאמים אישית.
4. הגדרת הסביבה
כדי להריץ את הקודלה הזה, צריך פרויקט ב-Google Cloud Platform שבו החיוב מופעל. כדי ליצור פרויקט, פועלים לפי ההוראות שמפורטות כאן.
שלב 1: מפעילים את Compute Engine API
עוברים אל Compute Engine ובוחרים באפשרות Enable (הפעלה) אם היא לא מופעלת.
שלב 2: מפעילים את Vertex AI API
עוברים אל הקטע Vertex AI במסוף Cloud ולוחצים על Enable Vertex AI API.
שלב 3: יצירת מכונה של Vertex AI Workbench
בקטע Vertex AI במסוף Cloud, לוחצים על Workbench:
מפעילים את Notebooks API, אם הוא לא פועל.
לאחר ההפעלה, לוחצים על פנקסי רשימות מנוהלים:
לאחר מכן בוחרים פנקס רשימות חדש.
נותנים שם למחברת, ובקטע Permission בוחרים באפשרות Service account.
בוחרים באפשרות הגדרות מתקדמות.
בקטע אבטחה, בוחרים באפשרות 'הפעלת מסוף' אם היא עדיין לא מופעלת.
אפשר להשאיר את כל שאר ההגדרות המתקדמות כפי שהן.
לאחר מכן, לוחצים על יצירה. הקצאה של המכונה תימשך כמה דקות.
אחרי יצירת המכונה, בוחרים באפשרות OPEN JUPYTERLAB.
5. דגם הרכבת
כדי לנסות את תכונת האירוח הנוסף, קודם אנחנו צריכים לאמן מודל ולאחסן את הארטיפקטים של המודל שנשמרו בקטגוריה של Cloud Storage. נשתמש במבצע של Workbench notebook כדי להפעיל את משימת האימון.
שלב 1: יוצרים קטגוריה של Cloud Storage
אם יש לכם קטגוריה קיימת בפרויקט שבה אתם רוצים להשתמש, אתם יכולים לדלג על השלב הזה. אחרת, פותחים סשן חדש בטרמינל מהמרכז להפעלת אפליקציות.
מריצים את הפקודה הבאה במסוף כדי להגדיר משתנה סביבה לפרויקט. חשוב להחליף את your-cloud-project
במזהה הפרויקט:
PROJECT_ID='your-cloud-project'
בשלב הבא, מריצים את הפקודה הבאה כדי ליצור קטגוריה חדשה בפרויקט.
BUCKET="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET
שלב 2: הפעלת ה-notebook
פותחים מסמך חדש ב-notebook של TensorFlow 2 במרכז האפליקציות של מכונה של Workbench.
הקוד שבהמשך אימון מסווג סנטימנטים בינאריים (חיובי או שלילי) במערך הנתונים של ביקורות על סרטים מ-IMDB. מדביקים את הקוד במחברת.
חשוב להחליף את {YOUR_BUCKET}
בקטגוריה שיצרתם בשלב הקודם (או בקטגוריה אחרת בפרויקט). כאן נשמור את הארטיפקטים של המודל שנשמר, שנצטרך בהמשך כשנעלה את המודל ל-Vertex AI Model Registry.
import numpy as np
import tensorflow_datasets as tfds
import tensorflow as tf
# REPLACE WITH YOUR BUCKET!
OUTPUT_PATH='gs://{YOUR_BUCKET}/model_output'
BUFFER_SIZE = 10000
BATCH_SIZE = 64
VOCAB_SIZE = 1000
# Load data
dataset, info = tfds.load('imdb_reviews', with_info=True,
as_supervised=True)
train_dataset, test_dataset = dataset['train'], dataset['test']
train_dataset = train_dataset.shuffle(BUFFER_SIZE).batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)
test_dataset = test_dataset.batch(BATCH_SIZE).prefetch(tf.data.AUTOTUNE)
# Create text encoder
encoder = tf.keras.layers.TextVectorization(
max_tokens=VOCAB_SIZE)
encoder.adapt(train_dataset.map(lambda text, label: text))
# Create model
model = tf.keras.Sequential([
encoder,
tf.keras.layers.Embedding(
input_dim=len(encoder.get_vocabulary()),
output_dim=64,
# Use masking to handle the variable sequence lengths
mask_zero=True),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(1)
])
# Compile model
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
optimizer=tf.keras.optimizers.Adam(1e-4),
metrics=['accuracy'])
# Fit model
history = model.fit(train_dataset, epochs=10,
validation_data=test_dataset,
validation_steps=30)
# Save model
model.save(OUTPUT_PATH)
לאחר מכן, בוחרים בלחצן Execute.
לאחר מכן מגדירים את הביצועים באופן הבא ולוחצים על שליחה.
בכרטיסייה Executions במסוף אפשר לעקוב אחרי סטטוס משימת האימון.
6. פריסת מודל
שלב 1: מעלים את המודל
בסיום הביצוע, חוזרים ל-notebook ב-Workbench כדי להעלות את המודל. יוצרים מסמך notebook חדש ב-TensorFlow.
קודם כול, מייבאים את Vertex AI Python SDK
from google.cloud import aiplatform
לאחר מכן מעלים את המודל, מחליפים את {YOUR_BUCKET}
בקטגוריה שציינתם בקוד האימון.
# replace {YOUR_BUCKET}
model_1 = aiplatform.Model.upload(display_name='text-model-1',
artifact_uri='gs://{YOUR_BUCKET}/model_output',
serving_container_image_uri='us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest')
למטרות הדגמה, נעלה את המודל הזה פעמיים וניצור שני משאבי מודלים שונים ב-Vertex AI. זאת כדי שנוכל לבדוק פריסה של מספר מודלים בנקודת קצה יחידה בתוך מאגר משאבי פריסה. בתרחיש אמיתי, היו לכם שני מודלים שונים במקום ליצור מודלים מאותם ארטיפקטים שנשמרו, אבל זו קיצור דרך כדי שלא נצטרך להפעיל עוד אימון. בנוסף, אפשר לפרוס את שני המודלים לנקודות קצה שונות באותו מאגר משאבים לפריסה.
# replace {YOUR_BUCKET}
model_2 = aiplatform.Model.upload(display_name='text-model-2',
artifact_uri='gs://{YOUR_BUCKET}/model_output',
serving_container_image_uri='us-docker.pkg.dev/vertex-ai/prediction/tf2-cpu.2-8:latest')
עכשיו אמורים להופיע שני המודלים במרשם המודלים של Vertex AI. סטטוס הפריסה ריק כי עדיין לא פרסנו את המודלים.
שלב 2: יוצרים נקודת קצה
יוצרים נקודת קצה (endpoint). חשוב לזכור שהפעולה הזו שונה מפריסה של מודל לנקודת קצה.
endpoint = aiplatform.Endpoint.create('cohost-endpoint')
כשיוצרים את נקודת הקצה, היא מופיעה במסוף.
שלב 3: יוצרים את DeploymentResourcePool
אפשר ליצור את DeploymentResourcePool באמצעות הפקודה הבאה. חשוב להחליף את {YOUR_PROJECT}
במזהה הפרויקט.
# replace {YOUR_PROJECT}
PROJECT_ID={YOUR_PROJECT}
REGION="us-central1"
VERTEX_API_URL=REGION + "-aiplatform.googleapis.com"
VERTEX_PREDICTION_API_URL=REGION + "-prediction-aiplatform.googleapis.com"
MULTI_MODEL_API_VERSION="v1beta1"
# Give the pool a name
DEPLOYMENT_RESOURCE_POOL_ID="my-resource-pool"
import json
import pprint
pp = pprint.PrettyPrinter(indent=4)
CREATE_RP_PAYLOAD = {
"deployment_resource_pool":{
"dedicated_resources":{
"machine_spec":{
"machine_type":"n1-standard-4"
},
"min_replica_count":1,
"max_replica_count":2
}
},
"deployment_resource_pool_id":DEPLOYMENT_RESOURCE_POOL_ID
}
CREATE_RP_REQUEST=json.dumps(CREATE_RP_PAYLOAD)
pp.pprint("CREATE_RP_REQUEST: " + CREATE_RP_REQUEST)
!curl \
-X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/deploymentResourcePools \
-d '{CREATE_RP_REQUEST}'
אפשר לראות את המאגר על ידי הפעלת
!curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/deploymentResourcePools/{DEPLOYMENT_RESOURCE_POOL_ID}
שלב 4: פורסים את המודלים בנקודת הקצה
עכשיו, אחרי שיצרנו את מאגר המשאבים, אנחנו יכולים לפרוס את המודלים בתוך מאגר המשאבים.
קודם נפרוס את model_1
. חשוב להחליף את MODEL_1_ID
ו-ENDPOINT_ID
במזהים המתאימים.
MODEL_1_ID="{MODEL_1_ID}"
ENDPOINT_ID="{ENDPOINT_ID}"
הפקודה הבאה פורסת את model_1
בנקודת הקצה בתוך מאגר המשאבים.
MODEL_NAME = "projects/{project_id}/locations/{region}/models/{model_id}".format(project_id=PROJECT_ID, region=REGION, model_id=MODEL_1_ID)
SHARED_RESOURCE = "projects/{project_id}/locations/{region}/deploymentResourcePools/{deployment_resource_pool_id}".format(project_id=PROJECT_ID, region=REGION, deployment_resource_pool_id=DEPLOYMENT_RESOURCE_POOL_ID)
DEPLOY_MODEL_PAYLOAD = {
"deployedModel": {
"model": MODEL_NAME,
"shared_resources": SHARED_RESOURCE
},
"trafficSplit": {
"0": 100
}
}
DEPLOY_MODEL_REQUEST=json.dumps(DEPLOY_MODEL_PAYLOAD)
pp.pprint("DEPLOY_MODEL_REQUEST: " + DEPLOY_MODEL_REQUEST)
!curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/endpoints/{ENDPOINT_ID}:deployModel \
-d '{DEPLOY_MODEL_REQUEST}'
הפעולה הזו תימשך כמה דקות, אבל בסיום תראו את המודל שנפרס בנקודת הקצה במסוף.
בשלב הבא אפשר לפרוס את model_2
בתוך אותו מאגר פריסה. נפרוס אותו באותה נקודת קצה כמו model_1
. עם זאת, אפשר גם לפרוס את model_2
לנקודת קצה אחרת באותו מאגר משאבים.
מעדכנים את MODEL_ID
במזהה של model_2
. שוב, אפשר לקבל את המזהה הזה על ידי הפעלת model_2.name
MODEL_2_ID="{MODEL_2_ID}"
לאחר מכן פורסים את model_2
. מכיוון שכבר פרסנו את model_1
בנקודת הקצה, צריך לעדכן את trafficSplit
כך שהתנועה תפוצל בין שני המודלים. לא נצטרך לעדכן את השדה trafficSplit
אם נחליט לפרוס את model_2
בנקודת קצה אחרת בתוך אותו מאגר משאבים.
כדי לעדכן את חלוקת התנועה, צריך להגדיר את מזהה DeployedModel עבור model_1
. חשוב לזכור שהמספר הזה שונה ממספר המודל.
DEPLOYED_MODEL_1_ID = {DEPLOYED_MODEL_1_ID}
לאחר מכן מבצעים את הפקודה הבאה כדי לפרוס את המודל השני.
MODEL_NAME = "projects/{project_id}/locations/{region}/models/{model_id}".format(project_id=PROJECT_ID, region=REGION, model_id=MODEL_2_ID)
SHARED_RESOURCE = "projects/{project_id}/locations/{region}/deploymentResourcePools/{deployment_resource_pool_id}".format(project_id=PROJECT_ID, region=REGION, deployment_resource_pool_id=DEPLOYMENT_RESOURCE_POOL_ID)
#`trafficSplit` is a map from a DeployedModel's ID to the percentage of this Endpoint's traffic that should be forwarded to that DeployedModel.
# The traffic percentage values for an endpoint must add up to 100.
# The key for the model being deployed is "0".
DEPLOY_MODEL_PAYLOAD = {
"deployedModel": {
"model": MODEL_NAME,
"shared_resources": SHARED_RESOURCE
},
"trafficSplit": {
"0": 50,
DEPLOYED_MODEL_1_ID: 50
}
}
DEPLOY_MODEL_REQUEST=json.dumps(DEPLOY_MODEL_PAYLOAD)
pp.pprint("DEPLOY_MODEL_REQUEST: " + DEPLOY_MODEL_REQUEST)
!curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://{VERTEX_API_URL}/{MULTI_MODEL_API_VERSION}/projects/{PROJECT_ID}/locations/{REGION}/endpoints/{ENDPOINT_ID}:deployModel \
-d '{DEPLOY_MODEL_REQUEST}'
שוב, בדוגמה הזו שני המודלים נפרסו באותה נקודת קצה, אבל אפשר גם לארח מודלים באירוח נוסף באותו מאגר משאבים שנפרס בנקודות קצה שונים. במקרה כזה, לא צריך לדאוג לגבי פיצול התנועה.
אחרי הפריסה של המודל השני, שני המודלים יופיעו במסוף.
שלב 5: קבלת תחזיות
בשלב האחרון בודקים את נקודת הקצה ומקבלים חיזויים.
קודם כול, מגדירים את משפט הבדיקה.
x_test=['The movie was cool. The animation and the graphics were out of this world. I would recommend this movie.']
לאחר מכן, קוראים לפונקציה predict בנקודת הקצה, והיא תחזיר חיזוי מאחד מהמודלים שנפרסו בנקודת הקצה.
endpoint.predict(instances=x_test)
🎉 מזל טוב! 🎉
למדתם איך להשתמש ב-Vertex AI כדי:
- אירוח משותף של מודלים באותה מכונה וירטואלית לצורך חיזויים אונליין
כדי לקבל מידע נוסף על החלקים השונים ב-Vertex, אתם יכולים לעיין במסמכי העזרה.
7. הסרת המשאבים
אם אתם לא מתכננים להשתמש במודלים, כדאי לבטל את הפריסה שלהם בנקודת הקצה. אפשר גם למחוק את נקודת הקצה לגמרי. תמיד אפשר לפרוס מחדש את המודל בנקודת קצה במקרה הצורך.
חלוניות של מסמכי Jupyter שמנוהלות על ידי Workbench יפוג הזמן שלהן באופן אוטומטי אחרי 180 דקות של חוסר פעילות, כך שלא תצטרכו לדאוג לכיבוי המכונה. כדי לכבות את המכונה באופן ידני, לוחצים על הלחצן Stop בקטע Vertex AI Workbench במסוף. כדי למחוק את המחברות כולה, לוחצים על הלחצן 'מחיקה'.
כדי למחוק את הקטגוריה של האחסון, עוברים לתפריט הניווט במסוף Cloud, לוחצים על Storage, בוחרים את הקטגוריה ולוחצים על Delete: