انشر نقطة نهاية واستدعها
أنشئ نقطة نهاية مخصصة في واحدة من 42 منطقة، واضبط حجمها وفقًا لحركة المرور لديك، واستدعها باستخدام عميل يتعامل مع بدء التشغيل البارد وأخطاء 429 والمفاتيح غير الصالحة.
قد يستغرق الرد على أول طلب ما يصل إلى دقيقة لنقطة نهاية مجانية تتوسع إلى الصفر، وقد يحوّل العميل الساذج ذلك إلى انتهاء مهلة يواجهه المستخدم. ويظل المفتاح المسرب صالحًا حتى بعد حذفه. ينشر هذا الدرس النموذج الفائز، ويحدد حجم نقطة النهاية عن قصد، ويكتب العميل الصغير الذي يحتاج إليه كل تكامل إنتاجي.
عملي
الاستدلال المشترك أم نقطة نهاية مخصصة#
يمكن بالفعل استدعاء كل نموذج من خلال واجهة API للاستدلال المشترك في Platform، وهي مناسبة للاختبار. أما حركة المرور الإنتاجية فمكانها نقطة نهاية مخصصة:
| الاستدلال المشترك | نقطة نهاية مخصصة | |
|---|---|---|
| الخدمة | مشتركة بين مستخدمي Platform | نموذج واحد لمستأجر واحد |
| المناطق | منطقة بياناتك (US أو EU أو AP) | أي منطقة من أصل 42 منطقة |
| حد المعدل | 20 طلبًا في الدقيقة لكل مفتاح | لا تفرض Platform حدًا على الاستدعاءات المباشرة |
| حجم الطلب | نحو 4.5 MB | 32 MB، وحتى ساعة واحدة لكل طلب (الفيديو مدعوم) |
| المصادقة | أي مفتاح API لمساحة العمل | المفتاح المرتبط بعملية النشر فقط |
إنشاء نقطة النهاية وتحديد حجمها#
افتح علامة التبويب Deploy الخاصة بالنموذج. يقيس متصفحك زمن الاستجابة إلى جميع المناطق الـ42 (14 في الأمريكتين، و13 في أوروبا، و12 في آسيا والمحيط الهادئ، و3 في الشرق الأوسط وأفريقيا)، ثم يرتب الجدول حسب زمن الاستجابة:

انقر على Deploy في الصف الأقرب إلى مواقع عملائك، وراجع وحدة المعالجة المركزية والذاكرة والسعر والاسم المُنشأ (مثل yolo26n-iowa)، ثم انقر على Create Deployment. يمكنك أيضًا البدء من New Deployment في علامة التبويب Deployments ضمن ملفك الشخصي:

حدّد الحجم وفق نمط حركة المرور:
| حركة المرور | الحجم | التكلفة |
|---|---|---|
| المهام الدفعية، والأدوات الداخلية، والعروض التوضيحية المتقطعة | الافتراضي: 1 vCPU و2 GiB؛ مع إمكانية التوسع إلى الصفر | مجانًا ضمن جميع الخطط |
| حركة مرور مستمرة وفورية لا تحتمل انتظار بدء التشغيل البارد | حجم مخصص (1–8 vCPU، و2–32 GiB) مع مثيل واحد جاهز | تُحتسب الفوترة بالساعة منذ الجاهزية وحتى الإيقاف، بما في ذلك أوقات الخمول: نحو $0.12/ساعة مقابل 1 vCPU و4 GiB في أيوا |
| مستخدمون في قارات متعددة | نقطة نهاية واحدة لكل منطقة خلف موجّه خاص بك | تُحتسب فوترة كل نقطة نهاية حسب حجمها |

تتيح الخطط 3 (Free) أو 10 (Pro) أو عددًا غير محدود (Enterprise) من عمليات النشر، وتُحتسب نقاط النهاية المتوقفة أيضًا. تقبل نقطة النهاية حركة المرور عندما تظهر شارتها Ready:
مثال عملي: عميل يصمد في بيئة الإنتاج#

لكل نقطة نهاية عنوان URL مثل https://predict-<id>-<hash>-<region>.a.run.app، وتخدم /predict (POST) و/health وصفحة تفاعلية /docs. ولا تقبل إلا مفتاح API المرتبط بها عند الإنشاء؛ ويرى مالكو مساحة العمل هذا المفتاح مُعبأ مسبقًا في علامة التبويب Predict ضمن Docs في عملية النشر، إلى جانب أمثلة Python وJavaScript وcURL. تنفّذ الأمثلة طلبًا واحدًا؛ أما تعليمات الإنتاج، فيجب أن تصمد أيضًا أمام بدء التشغيل البارد والمثيل المشغول:
import os
import time
from collections import Counter
import httpx
URL = "https://YOUR_DEPLOYMENT_URL.run.app/predict"
HEADERS = {"Authorization": f"Bearer {os.environ['ULTRALYTICS_API_KEY']}"} # the deployment's bound key, server-side only
def predict(client, path, conf=0.25, attempts=4):
"""POST one image; retry timeouts, 429, and 5xx with backoff; fail fast on other errors."""
for attempt in range(attempts):
try:
with open(path, "rb") as f:
r = client.post(URL, headers=HEADERS, data={"conf": conf}, files={"file": f}, timeout=90)
if r.status_code < 400:
return r.json()
if r.status_code != 429 and r.status_code < 500:
r.raise_for_status() # 401 wrong key, 413 too large: retrying won't help
wait, reason = float(r.headers.get("Retry-After", 2**attempt)), r.status_code
except httpx.TimeoutException: # a scaled-to-zero endpoint can take up to a minute to wake
wait, reason = 2**attempt, "timeout"
print(f"attempt {attempt + 1}: {reason}, retrying in {wait:.0f} s")
time.sleep(wait)
raise RuntimeError(f"endpoint still unavailable after {attempts} attempts")
with httpx.Client() as client:
response = predict(client, "bus.jpg")
for image in response["images"]:
counts = Counter(d["name"] for d in image["results"])
print(f"{sum(counts.values())} objects {dict(counts)} in {image['speed']['inference']:.1f} ms")اختبرنا ذلك باستخدام بديل محلي يجيب عن 429 مرة واحدة، ثم يعيد نتيجة حقيقية لـYOLO26n تخص bus.jpg بتنسيق استجابة نقطة النهاية:
attempt 1: 429, retrying in 2 s
5 objects {'bus': 1, 'person': 4} in 34.9 msفيما يلي القرارات المهمة، سطرًا بسطر:
timeout=90يغطي بدء تشغيل بارد قد يستغرق نحو دقيقة؛ فالمهل الزمنية الافتراضية لمعظم عملاء HTTP أقصر بكثير.- تُعاد المحاولة عند أخطاء 429 و5xx مع مراعاة
Retry-Afterعندما ترسله نقطة النهاية. تخدم كل نقطة نهاية الطلبات من مثيل واحد، وتخفّض الحمل باستخدام429عندما تكون مشغولة. - تؤدي أخطاء 4xx الأخرى إلى الفشل فورًا: يعني
401أن المفتاح غير صحيح، ويعني413أن حجم المحتوى يتجاوز 32 MB؛ ولا يُصلح أي منهما نفسه تلقائيًا. - تتضمن الاستجابة عنصرًا واحدًا لكل صورة (أو لكل إطار فيديو) في
images، ويحتوي كل عنصر علىresults(classوnameوconfidenceوboxمعx1وy1وx2وy2) وspeedبالمللي ثانية.
حقول النموذج الاختيارية هي conf (القيمة الافتراضية 0.25)، وiou (0.7)، وimgsz (حجم تدريب النموذج)، وvid_stride للفيديو، وnormalize=true للإحداثيات ضمن النطاق 0–1. ويُكتب أمر cURL المكافئ كسطر لكل حقل:
curl -X POST "https://YOUR_DEPLOYMENT_URL.run.app/predict" \
-H "Authorization: Bearer $ULTRALYTICS_API_KEY" \
-F "file=@bus.jpg" -F "conf=0.25" -F "iou=0.7" -F "imgsz=640"إصدار نسخ جديدة دون تغيير عنوان URL#
يستبدل Replace model في صفحة النشر النموذج بنموذج آخر مكتمل من مساحة العمل نفسها. ويواصل النموذج القديم تقديم الخدمة إلى أن يصبح النموذج الجديد جاهزًا؛ كما يظل عنوان URL والمنطقة والمفتاح كما هي، وإذا فشل الطرح، يظل النموذج السابق قيد التشغيل. وللتراجع، نفّذ الإجراء نفسه مع تحديد النموذج السابق، لذا أبقه في المشروع. يغيّر Update configuration الحجم في موضعه، بينما يوقف Stop الفوترة مع الإبقاء على عنوان URL.
تتطلب بعض التغييرات نقطة نهاية جديدة: فالمناطق ثابتة (ويستلزم الانتقال حذف نقطة النهاية وإعادة إنشائها، ما ينتج عنه عنوان URL جديد)، كما أن النطاقات المخصصة غير مدعومة، لذا ضع بوابتك الخاصة أمام نقطة النهاية إذا احتاج المستدعون إلى اسم مضيف ثابت يحمل علامتك التجارية. للتشغيل خارج Platform، صدّر النموذج (التصدير للنشر) أو استضفه بنفسك خلف Triton Inference Server.
مواطن الخلل#
العَرَض: يتلقى الطرف النهائي لديك حركة مرور لا تستطيع تفسيرها. الحل: لا تضع المفتاح مطلقًا في تطبيق ويب أو تطبيق جوّال؛ استدعِ الطرف النهائي من خادمك الخلفي. لا يؤدي حذف المفتاح المرتبط أو إلغاء تنشيطه إلى قفل الطرف النهائي، لأنه يظل يقبل سلسلة المفتاح تلك. لإبطال الوصول، أوقف النشر أو احذفه، وأنشئ نشرًا جديدًا مرتبطًا بمفتاح جديد.
العَرَض: يفشل أول طلب صباحي، وينجح الطلب عند إعادة المحاولة. الحل: تتقلص الأطراف النهائية ذات الحجم الافتراضي إلى الصفر. استخدم مهلة لا تقل عن 90 ثانية، أو أرسِل طلب /health إلى الطرف النهائي لتدفئته قبل حركة المرور المتوقعة، أو انتقل إلى حجم مخصص إذا كان يجب أن تكون كل الطلبات سريعة.
العَرَض: تفشل عمليات الرفع مع 413. الحل: تقبل الأطراف النهائية المخصصة أجسام الطلبات حتى 32 MB. قسّم مقاطع الفيديو الطويلة إلى مقاطع أقصر أو أرسل إطارات مأخوذة على فترات، ومرّر vid_stride لتجاوز الإطارات على جانب الخادم.
عرض الحل
مثال للإجابة عن كاميرا خط إنتاج الحبوب: انشر v2-finetune في europe-west1 (سان غيسلان، المنطقة الأقل زمنًا للاستجابة من المصنع الألماني) بالحجم الافتراضي. زمن الطلب البارد بعد ساعة من الخمول: 38 s، وهو ضمن مهلة الـ90 ثانية؛ وزمن الطلب الدافئ: 0.3 s. القرار: يرسل متحكم PLC الخاص بالخط إطارًا كل 30 ثانية أثناء نوبات العمل، لذا تظل نقطة النهاية دافئة طوال النوبة، ولا يتحمل الإطار الأول سوى بدء التشغيل البارد. ويؤدي استدعاء /health من متحكم الخط قبل كل نوبة بدقيقتين إلى إلغاء ذلك أيضًا، لذا نُبقي على الحجم الافتراضي المجاني، موفرين نحو $90 شهريًا مقارنة بمثيل مخصص بقدرة 1 vCPU وذاكرة 4 GiB. يعيد استبدال النموذج مجددًا بـv1-baseline نتائج v1 من عنوان URL نفسه؛ ثم استبدله مجددًا بـv2 للإكمال.