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

1. نظرة عامة

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

المعلومات التي تطّلع عليها

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

  • إنشاء DeploymentResourcePool
  • نشر نماذج في DeploymentResourcePool

تبلغ التكلفة الإجمالية لتشغيل هذا التمرين على Google Cloud حوالي $2.

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

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

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

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

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

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

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

deployment_pool

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

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

الخطوة 1: تفعيل واجهة برمجة تطبيقات Compute Engine

انتقِل إلى 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

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

PROJECT_ID='your-cloud-project'

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

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

الخطوة 2: بدء تنفيذ ورقة الملاحظات

افتح ورقة ملاحظات جديدة من TensorFlow 2 من مشغِّل تطبيقات Workbench.

launcher_tf2

يدرّب الرمز أدناه مصنِّفًا ثنائيًا (موجب أو سالب) على مجموعة بيانات مراجعات أفلام 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_nb

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

execution_config

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

execution_status

6- نشر النموذج

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

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

tf_nb

أولاً، عليك استيراد حزمة تطوير البرامج (SDK) الخاصة بـ Vertex AI Python

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 إلى نقطة نهاية مختلفة ضمن مجموعة الموارد نفسها.

لتعديل تقسيم عدد الزيارات، عليك تحديد رقم تعريف DeploymentedModel ID في 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.']

ثم استدعِ التنبؤ على نقطة النهاية التي ستعرض توقعًا من أحد النماذج المنشورة إلى نقطة النهاية.

endpoint.predict(instances=x_test)

🎉 تهانينا. 🎉

لقد تعلمت كيفية استخدام Vertex AI لإجراء ما يلي:

  • نماذج المضيف المشارك على الجهاز الافتراضي نفسه لتوقّعات البحث على الإنترنت

لمزيد من المعلومات حول أجزاء مختلفة من Vertex، يمكنك الاطّلاع على المستندات.

7. تنظيف

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

undeploy_model

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

إيقاف المثيل

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

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