انتقل إلى المحتوى الرئيسي

الوحدة 7 — نقاط النهاية في الوقت الحقيقيّ وبلا خوادم

يخرج النموذج الآن من مرحلة التدريب. الأشيع في الإنتاج أن يُستدعى من تطبيق ويب أو من واجهة برمجيّة تحتاج إلى تنبّؤ بميلي‌ثوانٍ معدودة. الحلّ الرسميّ في SageMaker هو نقطة نهاية (Endpoint): خدمة HTTPS مُدارة تُشغّل نموذجك خلف موازن حمولة. لكن قبل النشر، ثلاثة مكوّنات يجب تمييزها بدقّة.

الثلاثيّة: Model, EndpointConfig, Endpoint

هذه ثلاثة كائنات مستقلّة في SageMaker، ولها دلالات مختلفة:

  • Model: يشير إلى model.tar.gz على S3، ويحدّد صورة الاستدلال (inference image) ودور IAM.
  • EndpointConfig: يقول بأيّ عتاد يُنشر النموذج (نوع المثيل، عدد النسخ، متغيّرات الإنتاج).
  • Endpoint: التنفيذ الفعليّ لهذه التهيئة، مع اسم DNS يستدعيه العميل.

يفصل هذا الترتيب بين «ما النموذج» و«كيف يعمل». ويسمح بنشرين مختلفين لنفس النموذج (تجريبيّ ثمّ إنتاجيّ)، أو بتحديث التهيئة دون إعادة تحميل النموذج.

نشر أوّل نقطة نهاية

من المُقدِّر (estimator) مباشرةً، سطر واحد ينجز الخطوات الثلاث:

predictor = sk_estimator.deploy(
initial_instance_count=1,
instance_type="ml.m5.large",
endpoint_name="churn-rt-v1",
)

زمن الإنشاء: 5-8 دقائق. أثناء ذلك يوفّر SageMaker العتاد، ويسحب صورة الاستدلال، ويحمّل النموذج في الذاكرة. بعدها، كلّ نداء يستغرق ميلي‌ثوانٍ:

sample = valid_df.iloc[[0]]
prediction = predictor.predict(sample.to_dict(orient="records"))

نقطة النهاية تعمل باستمرار، وتُفوتر بالثانية سواء وصلها طلب أم لا. ml.m5.large بـ0.10 دولار/ساعة ≈ 74 دولارًا شهريًّا. اترك ثلاث نقاط نهاية للتجربة دون إغلاق وستكون فاتورة الشهر ضِعف ذلك.

التوسّع التلقائيّ (Auto Scaling)

عندما يتذبذب حجم الطلبات، لا معنى لدفع سعر ثلاث نسخ في الليل. يقدّم SageMaker توسّعًا تلقائيًّا يعتمد على مقياس CloudWatch (عادةً InvocationsPerInstance):

import boto3

client = boto3.client("application-autoscaling")
client.register_scalable_target(
ServiceNamespace="sagemaker",
ResourceId="endpoint/churn-rt-v1/variant/AllTraffic",
ScalableDimension="sagemaker:variant:DesiredInstanceCount",
MinCapacity=1,
MaxCapacity=4,
)
client.put_scaling_policy(
PolicyName="scale-by-invocations",
ServiceNamespace="sagemaker",
ResourceId="endpoint/churn-rt-v1/variant/AllTraffic",
ScalableDimension="sagemaker:variant:DesiredInstanceCount",
PolicyType="TargetTrackingScaling",
TargetTrackingScalingPolicyConfiguration={
"TargetValue": 100.0,
"PredefinedMetricSpecification": {"PredefinedMetricType": "SageMakerVariantInvocationsPerInstance"},
"ScaleInCooldown": 300,
"ScaleOutCooldown": 60,
},
)

قاعدتان تحكميّتان تعالجان أشيع الأخطاء:

  • ScaleInCooldown أطول من ScaleOutCooldown: الاستجابة للحمولة الطارئة سريعة (60 ثانية)، لكنّ الإغلاق يتأنّى (5 دقائق) خشية ذبذبة.
  • MinCapacity ≥ 1 لنقطة إنتاج: النزول إلى صفر يعني بدءًا باردًا في المرّة التالية.

الاستدلال بلا خوادم (Serverless Inference)

الفكرة: لا تدفع إلّا حين يصل طلب. يوفّر SageMaker العتاد لحظة الاستدعاء ثمّ يحرّره:

from sagemaker.serverless import ServerlessInferenceConfig

serverless_config = ServerlessInferenceConfig(
memory_size_in_mb=2048, # بين 1024 و6144
max_concurrency=20, # الطلبات المتوازية القصوى
)

predictor = sk_estimator.deploy(
endpoint_name="churn-serverless-v1",
serverless_inference_config=serverless_config,
)

الفاتورة تُحسب على زمن الحساب فقط (بالميلي‌ثانية) وحجم الذاكرة. لخيطنا الأحمر بذاكرة 2 غيغابايت وطلب يُعالج في 50 ميلي‌ثانية، الطلب الواحد يكلّف نحو 0.000002 دولار. بألف طلب يوميًّا: 6 سنتات في الشهر. مقارنة بـ74 دولارًا لنقطة عاديّة، الفرق واضح.

البدء البارد (Cold Start): الثمن غير المُعلَن

ما لا يقال دائمًا: الطلب الأوّل بعد فترة خمول قد يستغرق 5 إلى 30 ثانية لأنّ SageMaker يحتاج إلى توفير حاوية، وسحب صورة الاستدلال، وتحميل النموذج. إذا كان نموذجك 2 غيغابايت والصورة 3 غيغابايت، الرقم يقترب من الثلاثين. لتطبيق ويب تفاعليّ، هذا كارثة.

قواعد اتّخاذ القرار:

السياقالاختيار المفضّل
حمولة مستمرّة > 10 طلبات/دقيقةنقطة نهاية عاديّة
حمولة متقطّعة (لوحة داخليّة)بلا خوادم
زمن استجابة صارم < 200 ميلي‌ثانية دائمًانقطة عاديّة، لا خيار
نموذج ثقيل جدًّا (> 5 غيغابايت)نقطة عاديّة (البدء البارد يصبح دقائق)
بيئة تطوير قليلة الاستعمالبلا خوادم

متغيّرات الإنتاج (Production Variants)

نقطة نهاية واحدة يمكن أن تخدم عدّة متغيّرات بأوزان مختلفة. هذا الأساس التقنيّ لاختبار A/B ونشر canary:

from sagemaker.model import Model

model_a = Model(model_data="s3://.../v1/model.tar.gz", image_uri=xgb_image, role=role)
model_b = Model(model_data="s3://.../v2/model.tar.gz", image_uri=xgb_image, role=role)

# Configuration avec 90% du trafic vers A, 10% vers B

يمرّر SDK هذا عبر production_variants عند إنشاء EndpointConfig. سلوك حسن: بدء المتغيّر الجديد بـ5٪ من الحمولة، مراقبة المقياس التجاريّ 24 ساعة، ثمّ الرفع إلى 100٪ لا دفعة واحدة بل تدريجيًّا.

الحذف: قاعدة تلقائيّة

الفخّ رقم 1 على فاتورة SageMaker: نقطة نهاية نُسيت مفتوحة. أضف الحذف نهاية كلّ سكربت تجريبيّ:

predictor.delete_endpoint()
predictor.delete_model()

للبيئات التنمويّة، اضبط قاعدة CloudWatch/EventBridge تحذف كلّ نقطة نهاية اسمها يبدأ بـdev- بعد 12 ساعة من الإنشاء. تلقائيًّا، بدون تدخّل. هذه القاعدة تدفع نفسها من فاتورة الشهر الأوّل.

اختبر بلا خوادم أوّلًا

حتّى لو كان الهدف نقطة نهاية عاديّة، ابدأ بنشر بلا خوادم للاختبار. الفاتورة قريبة من الصفر أثناء التطوير، ولا تدفع في الليل ولا في العطل. حين يقترب التطبيق من الإطلاق، انسخ التهيئة إلى نقطة عاديّة.

الخلاصة

  • Model / EndpointConfig / Endpoint ثلاثة كائنات مستقلّة تفصل «ما النموذج» عن «كيف يعمل».
  • نقطة النهاية العاديّة تُفوتر بالثانية دائمًا؛ الحذف بعد الاستعمال قاعدة إلزاميّة.
  • الاستدلال بلا خوادم يوفّر جوهريًّا للحمولات المتقطّعة، لكنّ البدء البارد يجعل الطلب الأوّل يستغرق 5-30 ثانية.
  • متغيّرات الإنتاج توزّع الحمولة بين نسختين لاختبار A/B أو نشر canary تدريجيّ.

الوحدة التالية: عندما لا يحتاج التطبيق زمن استجابة قصير، التحويل بالدفعات يخفض الفاتورة درجات.