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

1. نظرة عامة

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

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

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

  • إنشاء DeploymentResourcePool
  • نشر النماذج في غضون DeploymentResourcePool

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

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

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

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

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

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

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

توفّر ميزة إتاحة نموذج الاستضافة المشتركة مفهوم "مجموعة موارد النشر" التي تُجمِّع النماذج معًا لمشاركة الموارد ضمن جهاز افتراضي. يمكن للنماذج مشاركة جهاز افتراضي (VM) إذا كانت يتشارك في نقطة نهاية، وأيضًا في حال نشرها في نقاط نهاية مختلفة. في الوقت الحالي، يجب أن تحتوي النماذج في مجموعة الموارد نفسها على صورة الحاوية نفسها، بما في ذلك إصدار إطار العمل للحاويات المُنشأة مسبقًا في 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

من وحدة التحكّم الطرفية، نفِّذ ما يلي لتحديد متغيّر env لمشروعك، مع الحرص على استبدال 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 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 في نقطة نهاية مختلفة ضمن مجموعة الموارد نفسها.

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

بعد ذلك، يمكنك استدعاء دالة التنبؤ في نقطة النهاية التي ستُظهر تنبؤًا من أحد النماذج المنشورة في نقطة النهاية.

endpoint.predict(instances=x_test)

🎉 تهانينا. 🎉

لقد تعلّمت كيفية استخدام Vertex AI لتنفيذ ما يلي:

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

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

7- تنظيف

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

undeploy_model

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

إيقاف المثيل

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

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