Vertex AI: نماذج المضيف المشارك على الجهاز الافتراضي نفسه لعرض التوقّعات

1. نظرة عامة

في هذا الدرس التطبيقي، ستستخدم ميزة "نموذج الاستضافة المشتركة" في Vertex AI لاستضافة نماذج متعددة على الجهاز الافتراضي نفسه لإجراء التوقّعات على الإنترنت.

المواضيع التي ستتعرّف عليها

ستتعرّف على كيفية:

  • إنشاء DeploymentResourcePool
  • نشر النماذج ضِمن DeploymentResourcePool

تبلغ التكلفة الإجمالية لتشغيل هذا الدرس التطبيقي على Google Cloud حوالي دولارَين أمريكيَين.

2. مقدّمة عن Vertex AI

يستخدم هذا الدرس التطبيقي أحدث عروض منتجات الذكاء الاصطناعي المتاحة على Google Cloud. تدمج منصة Vertex AI عروض تعلُّم الآلة على Google Cloud في تجربة تطوير سلسة. في السابق، كان يمكن الوصول إلى النماذج التي تم تدريبها باستخدام AutoML والنماذج المخصّصة من خلال خدمات منفصلة. يجمع العرض الجديد بينهما في واجهة برمجة تطبيقات واحدة، بالإضافة إلى منتجات جديدة أخرى. يمكنك أيضًا نقل المشاريع الحالية إلى Vertex AI. إذا كان لديك أي ملاحظات، يُرجى الاطّلاع على صفحة الدعم.

تتضمّن Vertex AI العديد من المنتجات المختلفة لدعم مهام سير عمل تعلُّم الآلة المتكاملة. سيركّز هذا الدرس التطبيقي على المنتجات المميّزة أدناه: التوقّعات و‫Workbench

نظرة عامة على منتجات Vertex

3. نظرة عامة على حالة الاستخدام

عند نشر النماذج في خدمة التوقّعات في Vertex AI، يتم تلقائيًا نشر كل نموذج على جهاز افتراضي خاص به. لجعل الاستضافة أكثر فعالية من حيث التكلفة، يمكنك استضافة نماذج متعددة على الجهاز الافتراضي نفسه، ما يؤدي إلى تحسين استخدام الذاكرة والموارد الحسابية. يعتمد عدد النماذج التي تختار نشرها على الجهاز الافتراضي نفسه على أحجام النماذج وأنماط الزيارات، ولكن هذه الميزة مفيدة بشكل خاص في السيناريوهات التي تتضمّن العديد من النماذج المنشورة التي تتلقّى زيارات متفرقة.

يقدّم دعم نموذج الاستضافة المشتركة مفهوم "مجموعة موارد النشر"، الذي يجمع النماذج معًا لمشاركة الموارد ضِمن جهاز افتراضي. يمكن للنماذج مشاركة جهاز افتراضي إذا كانت تشارك نقطة نهاية، وأيضًا إذا تم نشرها في نقاط نهاية مختلفة. في الوقت الحالي، يجب أن تحتوي النماذج في مجموعة الموارد نفسها على صورة الحاوية نفسها، بما في ذلك إصدار إطار العمل للحاويات الجاهزة للاستخدام في Vertex Prediction. بالإضافة إلى ذلك، لا يتم في هذا الإصدار سوى دعم الحاويات الجاهزة للاستخدام في Vertex Prediction التي تتضمّن إطار عمل نموذج TensorFlow، ولا يتم بعد دعم أُطر عمل النماذج الأخرى والحاويات المخصّصة.

deployment_pool

4. إعداد البيئة

ستحتاج إلى مشروع على Google Cloud Platform مفعّلة فيه الفوترة لتشغيل هذا الدرس البرمجي. لإنشاء مشروع، اتّبِع الـ تعليمات الواردة هنا.

الخطوة 1: تفعيل Compute Engine API

انتقِل إلى Compute Engine وانقر على تفعيل إذا لم تكن الخدمة مفعّلة بعد.

الخطوة 2: تفعيل Vertex AI API

انتقِل إلى قسم Vertex AI في Cloud Console وانقر على تفعيل Vertex AI API.

لوحة بيانات Vertex AI

الخطوة 3: إنشاء مثيل Vertex AI Workbench

من قسم Vertex AI في Cloud Console، انقر على Workbench:

قائمة Vertex AI

فعِّل Notebooks API إذا لم تكن مفعّلة بعد.

Notebook_api

بعد تفعيلها، انقر على دفاتر الملاحظات المُدارة:

Notebooks_UI

بعد ذلك، انقر على دفتر ملاحظات جديد.

new_notebook

امنح دفتر الملاحظات اسمًا، وضِمن الإذن ، انقر على حساب الخدمة

create_notebook

انقر على الإعدادات المتقدّمة.

ضِمن الأمان ، انقر على "تفعيل الوحدة الطرفية" إذا لم تكن مفعّلة بعد.

enable_terminal

يمكنك ترك جميع الإعدادات المتقدّمة الأخرى كما هي.

بعد ذلك، انقر على إنشاء. سيستغرق توفير المثيل بضع دقائق.

بعد إنشاء المثيل، انقر على فتح JupyterLab.

open_jupyterlab

5. تدريب النموذج

قبل أن نتمكّن من تجربة ميزة الاستضافة المشتركة، علينا أولاً تدريب نموذج وتخزين بيانات النموذج المحفوظة في حزمة على Cloud Storage. سنستخدم أداة تنفيذ دفتر ملاحظات Workbench لتشغيل مهمة التدريب.

الخطوة 1: إنشاء حزمة على Cloud Storage

إذا كانت لديك حزمة حالية في مشروعك تريد استخدامها، يمكنك تخطّي هذه الخطوة. بخلاف ذلك، افتح جلسة طرفية جديدة من المشغّل.

launcher_terminal

من الوحدة الطرفية، نفِّذ الأمر التالي لتعريف متغيّر بيئة لمشروعك، مع الحرص على استبدال your-cloud-project برقم تعريف مشروعك:

PROJECT_ID='your-cloud-project'

بعد ذلك، نفِّذ الأمر التالي لإنشاء حزمة جديدة في مشروعك.

BUCKET="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET

الخطوة 2: تشغيل تنفيذ دفتر الملاحظات

من مشغّل مثيل Workbench، افتح دفتر ملاحظات TensorFlow 2 جديدًا.

launcher_tf2

يدرّب الرمز أدناه مصنّفًا ثنائيًا للانطباعات (إيجابية أو سلبية) على مجموعة بيانات مراجعات الأفلام في IMDB. ألصِق الرمز في دفتر الملاحظات.

احرص على استبدال {YOUR_BUCKET} بالحزمة التي أنشأتها في الخطوة السابقة (أو حزمة أخرى في مشروعك). هذا هو المكان الذي سنخزّن فيه بيانات النموذج المحفوظة، والتي سنحتاج إليها لاحقًا عند تحميل النموذج إلى سجلّ نماذج Vertex AI.

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_nb

بعد ذلك، اضبط عملية التنفيذ على النحو التالي وانقر على إرسال

execution_config

من علامة التبويب "عمليات التنفيذ" في وحدة التحكّم، يمكنك تتبُّع حالة مهمة التدريب.

execution_status

6. نشر نموذج

الخطوة 1: تحميل النموذج

عند اكتمال عملية التنفيذ، ارجع إلى دفتر ملاحظات Workbench لتحميل النموذج. أنشئ دفتر ملاحظات TensorFlow جديدًا.

tf_nb

أولاً، استورِد حزمة تطوير البرامج (SDK) في Python الخاصة بمنصة Vertex AI.

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، من المفترض أن يظهر الآن كلا النموذجَين. تكون حالة النشر فارغة لأنّنا لم ننشر النماذج بعد.

model_registry

الخطوة 2: إنشاء نقطة نهاية

أنشئ نقطة نهاية. يُرجى العِلم أنّ هذه العملية تختلف عن نشر نموذج في نقطة نهاية.

endpoint = aiplatform.Endpoint.create('cohost-endpoint')

بعد إنشاء نقطة النهاية، ستظهر في وحدة التحكّم.

console_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_1_endpoint

بعد ذلك، يمكننا تفعيل 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}'

في هذا المثال، تم نشر النموذجَين في نقطة النهاية نفسها، ولكن يمكنك أيضًا استضافة نماذج بشكل مشترك في مجموعة الموارد نفسها التي يتم نشرها في نقطتَي نهاية مختلفتَين. في هذه الحالة، لن تقلق بشأن تقسيم الزيارات.

بعد نشر النموذج الثاني، سيظهر كلاهما في وحدة التحكّم.

deployed_models

الخطوة 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. تنظيف

عليك إلغاء نشر النماذج من نقطة النهاية إذا كنت لا تخطط لاستخدامها. يمكنك أيضًا حذف نقطة النهاية بالكامل. يمكنك إعادة نشر نموذج في نقطة نهاية في أي وقت إذا احتجت إلى ذلك.

undeploy_model

تنتهي مهلة دفاتر الملاحظات المُدارة في Workbench تلقائيًا بعد 180 دقيقة من عدم النشاط، لذا لا داعي للقلق بشأن إيقاف المثيل. إذا أردت إيقاف المثيل يدويًا، انقر على الزر "إيقاف" في قسم Vertex AI Workbench في وحدة التحكّم. إذا أردت حذف دفتر الملاحظات بالكامل، انقر على الزر "حذف".

إيقاف الجهاز الافتراضي

لحذف حزمة التخزين، استخدِم قائمة التنقّل في Cloud Console، وانتقِل إلى "مساحة التخزين"، ثم اختَر حزمتك وانقر على "حذف":

حذف مساحة التخزين