الوحدة 6 — سجلّ النماذج والإصدارات
النموذج المُدرَّب في الوحدة 5 يعيش الآن كملفّ model.bst على Cloud Storage. هذا الملفّ مجرَّد بيانات؛ لا يعرف من دَرَّبه، على أيّ بيانات، ولا كيف يُقاس أداؤه. Model Registry هو الطبقة الفاصلة التي تُحوِّل الملفّ إلى مورد تُدار حياته: يحمل اسمًا، إصدارات، اسمًا مستعارًا للنشر، تقييمًا مرفقًا، ولسانيّة كاملة إلى وظيفة التدريب التي أنتجته. بدونه، النشر يمرّ سنة كاملة قبل أن نحتاج إلى «العودة إلى إصدار الأسبوع الماضي»، فنكتشف أنّه اختفى.
المفاهيم في ثلاث دقائق
- Model (
نموذج): كيان منطقيّ يحمل اسمًا خالدًا، مثلًاfraud-xgb. لا يتغيّر اسمه أبدًا. - Model Version (
إصدار): نسخة محدَّدة تحت هذا الاسم، تحمل رقمًا (1,2, ...) وملفّات مرتبطة (النموذج، الحاوية المُخدِّمة، ما وراء البيانات). - Alias (
اسم مستعار): بطاقة قابلة للتحريك تُشير إلى إصدار. الأكثر استعمالًا:default(إذا لم تُحدَّد نسخة، هذه هي). لغتنا اليوميّة: «انقل الاسم المستعارproductionإلى الإصدار 4».
الفكرة الأساس: رمز النشر يستهدف الاسم المستعار، لا رقم الإصدار. تغيير الإنتاج يتمّ بتحريك الاسم المستعار، لا بإعادة كتابة الرمز.
تسجيل النموذج
سكريبت الوحدة 4 مرَّر model_display_name="xgb-fraud" إلى job.run(...)، ما يعني أنّ Vertex سجَّل النموذج تلقائيًّا عند نجاح التدريب. لنرَ كيف نُسجِّل صراحةً:
from google.cloud import aiplatform
aiplatform.init(project="fraud-detection-lab", location="europe-west1")
model = aiplatform.Model.upload(
display_name="fraud-xgb",
artifact_uri="gs://fraud-models-lab/xgb-fraud-2026-09-05/model",
serving_container_image_uri=(
"europe-docker.pkg.dev/vertex-ai/prediction/xgboost-cpu.1-6:latest"
),
labels={
"framework": "xgboost",
"usecase": "fraud",
"trained_on": "2026-09-05",
},
version_aliases=["default"],
version_description="tuning Vizier round 12, val AUC-PR 0.72",
)
print(model.resource_name, "version_id=", model.version_id)
يحدث خلف الكواليس:
- إن كان اسم
fraud-xgbجديدًا: يُنشَأ الكيان، يُخزَّن ملفّ النموذج، ويُعيَّن الإصدار الأوّل1. - إن كان الاسم موجودًا: يُنشَأ إصدار جديد (
2,3, ...)، ويحمل الأسماء المستعارة المُطلَبة.
labels تُشير إلى وسوم قابلة للفلترة على الواجهة والـAPI. تجنّب البيانات الحسّاسة (لا مفاتيح، لا معرِّفات عملاء).
الأسماء المستعارة في الاستعمال
يمكن أن تحمل الإصدارات أسماء مستعارة متعدّدة: default, production, canary, stable. القاعدة الشائعة:
default: الإصدار الذي يُنشَر إن لم يُحدَّد شيءproduction: الإصدار الذي يستقبل حركة الإنتاج (traffic)canary: مرشَّح تحت الاختبار قبل الترقية
النقل بسيط:
model_family = aiplatform.Model("fraud-xgb") # يفتح آخر إصدار
model_family.remove_version_aliases(["production"], version="2")
model_family.add_version_aliases(["production"], version="3")
سيناريو الإنتاج: نشر الوحدة 7 يقرأ من الاسم المستعار production. تحريك الاسم من الإصدار 2 إلى 3 يجعل النشر يستعمل النسخة الجديدة عند إعادة تحميل يديّة أو مُجدولة، بلا تعديل كود.
إرفاق التقييم
التقييم بلا نموذج لا يعني شيئًا؛ النموذج بلا تقييم أخطر: يُنشَر بلا حجّة. Vertex يسمح بإرفاق ModelEvaluation إلى إصدار محدَّد:
from google.cloud.aiplatform_v1.types import (
ModelEvaluation, EvaluatedAnnotation,
)
import json
metrics = {
"roc_auc": 0.94,
"aucpr": 0.72,
"precision_at_recall_0.5": 0.31,
"confusion_matrix": {"tp": 152, "fp": 340, "tn": 98214, "fn": 152},
"eval_dataset": "gs://fraud-features-lab/features/2026-09-05/test/*.parquet",
"date": "2026-09-05",
}
eval_ref = model.upload_evaluation(
display_name="test-2026-09-05",
metrics=metrics,
)
print(eval_ref.name)
التقييم يُصبح مرئيًّا في تبويبة «Evaluations» للإصدار، ويظهر في الـAPI عند الاستعلام عن ما وراء بيانات النموذج. الفرق بين نموذجَين مرشَّحَين للنشر يمرّ عبر مقارنة التقييمات المرفقة مباشرة، لا عبر جدول Excel مُشترك يتيه بعد شهر.
اللسانيّة إلى وظيفة التدريب
عندما ينشأ الإصدار من وظيفة تدريب Vertex (وليس رفعًا يدويًّا)، اللسانيّة تُنشَأ تلقائيًّا:
model.gca_resource.metadata["trainingPipelineName"]
# projects/.../trainingPipelines/9876543210
من هذه اللسانيّة، الفريق يستطيع:
- فتح وظيفة التدريب ومطالعة سجلّاتها
- الوصول إلى معاملات التدريب (
hyperparameters) المستعملة - تتبّع مجموعة البيانات المُدخَلة إذا كانت مسجَّلة كـ
Vertex Dataset
في الوحدة 9 سنرى Pipelines تُوسِّع هذه اللسانيّة إلى الرسم البيانيّ كاملًا: التدريب، التقييم، الشرط، النشر. لكن اللسانيّة الأساس (نموذج ⇒ وظيفة تدريب) موجودة منذ التسجيل، بلا Pipeline.
ماذا نضع في الحقول
ثلاث ممارسات تجني نصف قيمة السجلّ:
display_nameوصفيّ:fraud-xgb-euأفضل منmodel1. اسم لا يتغيّر أبدًا، لأنّ كلّ الأنابيب تعتمد عليه.version_descriptionمختصر لكن تشغيليّ: تاريخ التدريب، معاملات مميّزة، مقياس رئيسيّ. سطر واحد يقتصد ساعات لاحقًا.labelsمنظَّمة:framework,usecase,owner,env(prod/lab). الفلترة عليها في الواجهة تسمح لمن يُشرف على 30 نموذجًا أن يجد النموذج المطلوب في ثوانٍ.
الحاوية المُخدِّمة
كلّ إصدار يحمل serving_container_image_uri: صورة الحاوية التي ستُشغَّل عند النشر. لعائلة XGBoost نستعمل الحاوية المُسبَقة الصنع من Vertex. لنموذج مخصّص، نبني صورة بها HTTP endpoint يقبل استدعاء POST /predict.
للحاوية المُسبَقة الصنع تتوقّع بنية ملفّات معيّنة:
- XGBoost:
model.bstتحتartifact_uri - scikit-learn:
model.pklأوmodel.joblib - TensorFlow: نموذج
SavedModelكامل
نسيان هذه القاعدة (تسمية الملفّ booster.bin مثلًا) يجعل النشر يبدأ ثم يفشل عند أوّل استدعاء توقّع: الحاوية تبحث عن اسم لا تجده.
حذف وإلغاء اسم مستعار
النماذج والإصدارات تُبقى ما لم تُحذَف صراحةً. مع الوقت يتراكم عشرات الإصدارات. القاعدة:
- لا نحذف، بل نُلغي الاسم المستعار
productionمن الإصدار القديم. البيانات مرجعيّة تاريخيّة قد نحتاجها لمراجعة تنظيميّة. - بعد سنة، نقلها إلى
nearlineأوarchiveعبر سياسة GCS. - الحذف يبقى لحالتَين: نموذج تجريبيّ اختبَرَ خطأ، أو التزام تنظيميّ بحذف بيانات ما (GDPR).
عند تسجيل إصدار جديد لنموذج موجود، الأسماء المستعارة لا تنتقل تلقائيًّا. default يبقى على الإصدار السابق ما لم تصرّح version_aliases=["default"]. هذا مقصود: إصدار جديد يحلّ محلّ الإنتاج فقط بقرار صريح، لا بتدريب صدفة.
productionقبل تحريك الاسم المستعار production إلى إصدار جديد، تحقّق من تقييمه المرفق ومن نتائجه على نقطة نهاية canary (الوحدة 7). سياسة معتمدة: نموذج جديد يقضي 24 ساعة على 10 % من الحركة قبل الحصول على 100 %.
في الخلاصة
- Model Registry يُحوِّل ملفّ النموذج إلى مورد مُدار: هويّة، إصدارات، أسماء مستعارة، تقييم، لسانيّة.
- الاسم المستعار
productionهو ما يستهدفه رمز النشر، فتحريكه بديل عن تعديل الكود. - إرفاق التقييم يُوثِّق قرار النشر ويسمح بالمقارنة بين المرشَّحين.
- الحاوية المُخدِّمة تُلتَقط عند التسجيل، والحاويات المُسبَقة الصنع تفرض بنية ملفّات محدَّدة.
الوحدة التالية: نشر إصدارَين على نقطة نهاية بتقسيم حركة 90/10، مع مراقبة الاستجابة والسجلّات.