أتمتة دورة إعادة التدريب
حوّل عملية نشر واحدة إلى دورة قابلة للتكرار: دليل تشغيل، وبوابة ترقية مكتوبة بنص برمجي، وإصدار آلي مع إمكانية التراجع، ومراجعة أسبوعية.
النشر الأول مشروع؛ وكل عملية نشر بعده عملية تشغيلية. تعيد الفرق التي تبرمج الدورة التدريبية النموذج في فترة بعد الظهر كلما أطلق تنبيه مجموعة التحقق المحجوزة؛ أما الفرق التي لا تفعل ذلك فتعيد بناء الدورة من الذاكرة تحت الضغط، وتطلق إصدارات تتضمن تراجعات. ينفّذ هذا الدرس الدورة كاملة مرة واحدة على نموذج الأقراص، من الضبط الدقيق إلى اجتياز البوابة والإصدار، ويكتب دليل التشغيل الذي يجعل المرة التالية إجراءً روتينيًا.
عملي
الحلقة، مع مسؤول عن كل خطوة#
يصبح تتبّع النسب متاحًا تلقائيًا إذا اتبعت الدروس السابقة: تعرض بطاقة معلومات التشغيل الخاصة بالنموذج النموذجَ الأصل وإصدار مجموعة البيانات المثبّت، وتعرض علامة التبويب النماذج في مجموعة البيانات كل نموذج دُرّب على كل إصدار، كما تربط صفحة النشر بالنموذج الذي تقدّمه. عندما تنخفض الدقة، ابدأ من النشر وتتبع الخطوات عكسيًا.

تتولى الوكلاء أتمتة خطوة الجمع. يتنبأ جمع الاكتشافات غير المؤكدة عبر عملية النشر وينسخ الصور التي تتضمن اكتشافات ضمن نطاق ثقة إلى مجموعة بيانات للمراجعة؛ أما التقاط الصور وإرسال التنبيهات فيحفظ الصور المطابقة ويرسل منشورًا إلى Slack. لا تعمل مسارات العمل إلا عند النقر على تشغيل، لذا أدرج تشغيلًا ضمن المراجعة الأسبوعية.

مثال عملي: دورة كاملة على نموذج الحبوب#
1. الضبط الدقيق انطلاقًا من النموذج المنشور. في Platform، اختر النموذج المنشور ضمن نماذجي، وفعّل حفظ إصدار مجموعة البيانات، وحدد المحسّن صراحةً. محليًا، تكون الخطوة نفسها كما يلي:
from ultralytics import YOLO
model = YOLO("pills-v1.pt") # ملف best.pt الخاص بالنموذج المنشور
model.train(data="medical-pills.yaml", epochs=5, imgsz=320, optimizer="SGD", lr0=0.001, name="v2-finetune")هذا هو الضبط الدقيق المذكور في التدريب وقراءة عمليات التشغيل وضبطها الدقيق: ارتفع mAP50-95 من 0.659 إلى 0.687.
2. اختباره مقابل النموذج المنشور. أعد استخدام gate.py من الدرس 6 مع مجموعة التحقق والنسختين المحفوظتين:
DATA = "medical-pills.yaml" # ملف YAML لمجموعة بيانات التحقق أو عنوان URI من نوع ul://
BASELINE, CANDIDATE = "pills-v1.pt", "pills-v2.pt" # النموذج المنشور مقابل النموذج المرشح المعاد تدريبهPASS mAP50-95 0.659 -> 0.687 beats noise
PASS every class keeps 90% of its AP (weak: none)
PASS inference 4.0 ms within 100 ms
verdict: ship the candidateتنتهي بوابة الاختبار بالرمز 0، لذا يمكن لـ CI المتابعة إلى خطوة الإصدار. (في هذا العرض التوضيحي، تحل مجموعة التحقق من الحبوب الطبية محل مجموعة التحقق المستقلة؛ أما في بيئة الإنتاج، فاستخدم إصدارًا من مجموعة تحقق لم يسبق للنموذج رؤيته.)
3. إصداره. حمّل النموذج المرشح أو درّبه في مساحة العمل نفسها، ثم دع CI يستدعي استبدال النموذج عبر SDK ultralytics-platform وتحقق مما يجري تقديمه:
import time
from ultralytics_platform import Platform
OWNER, DEPLOYMENT = "your-username", "pill-detector-st-ghislain"
PROJECT, NEW_MODEL = "pill-inspection", "v2-finetune"
with Platform() as client: # reads ULTRALYTICS_API_KEY
body = {"action": "replace", "project": PROJECT, "model": NEW_MODEL}
reply = client.deployments.update(OWNER, DEPLOYMENT, body=body)
print(reply["status"], "-", reply["message"]) # "deploying" while the new model starts
while (deployment := client.deployments.retrieve(OWNER, DEPLOYMENT)["deployment"])["status"] == "deploying":
time.sleep(15)
print(f"status={deployment['status']} model={deployment.get('model')}")
if deployment.get("model") != NEW_MODEL: # a failed rollout leaves the previous model serving
raise SystemExit("Replacement failed; the previous model is still live")مع واجهة API بديلة تُرجع deploying مرة واحدة ثم ready، يطبع:
deploying - Replacement model is deploying
status=ready model=v2-finetuneيرسل deployments.update الرمز PATCH /api/deployments/{owner}/{deployment} مع action: "replace"؛ ويواصل النموذج القديم تقديم الخدمة إلى أن يصبح النموذج الجديد جاهزًا. تستطلع الحلقة retrieve حتى تغادر الحالة deploying، ثم تتحقق من النموذج الذي يقدّم الخدمة، لأن عملية النشر الفاشلة تنتهي أيضًا بالحالة ready، لكن مع بقاء النموذج القديم. يتم التراجع باستخدام البرنامج النصي نفسه مع ضبط NEW_MODEL على الإصدار السابق. وتغلّف أداة سطر الأوامر ul cloud المرفقة مع ultralytics واجهة API نفسها، كما يوثّق مرجع API كل استدعاء.
4. إعادة ضبط خط الأساس. شغّل holdout_check.py من الدرس 8 باستخدام نقطة التحقق الجديدة وملف سجلّ جديد.
اكتب دليل التشغيل#
# Retraining runbook: pill-detector
## Trigger
- Holdout mAP50-95 more than 1 point below baseline for 2 consecutive weeks, OR
- Batch Annotation edit rate above 25% on a new batch.
## Steps
1. Collect: Save to dataset from Monitoring, plus the "Collect Uncertain Detections" agent into pill-review.
2. Label: Batch Annotation with the deployed model at the swept threshold; review every image; record the edit rate.
3. Merge into the training dataset; rerun the duplicate check, class audit, and Clustering.
4. Create dataset version v(n+1) with a description of what changed.
5. Fine-tune from the deployed model with Save Dataset Version on; optimizer SGD, lr0 0.001.
6. Run gate.py against the deployed model on the holdout. Stop here on any FAIL.
7. ML lead approves; CI runs release.py.
8. Watch endpoint_check.py for 24 hours; start a new holdout baseline.
## Rollback
- Run release.py with NEW_MODEL set to the previous version. Never delete that model while it's the rollback target.
## Owner
- ML lead approves step 7. On-call runs steps 1-6 and 8.خصص 15 دقيقة للمراجعة الأسبوعية في التقويم، واطرح سؤالين: هل هناك أي مؤشرات حمراء (فحص نقطة النهاية، مجموعة التحقق، معدل التعديل)؟ وهل طرأ أي تغيير على النشر، وما سببه؟ غالبًا ما تكون الإجابة عن السؤالين «لا»، وينتهي الاجتماع خلال خمس دقائق. إليك شكل ربع سنة نموذجي:
Week 1 : Holdout alert. Collect, label, retrain, gate, release v(n+1).
Week 2-3 : Quiet. Checks green.
Week 4 : New defect class requested. Label, new version, retrain v(n+2).
Week 5-7 : Quiet.
Week 8 : Second plant in Poland. Check regions; add an endpoint in europe-central2.
Week 9-11: Quiet.
Week 12 : Quarterly holdout refresh and review.مواطن الخلل#
العَرَض: يفشل إصدار جديد، ويكون النموذج السابق قد اختفى. الحل: احتفظ في المشروع بنموذجَي الإنتاج الأخيرين على الأقل. يؤدي حذف نموذج إلى نقله إلى سلة المهملات، كما أن حذف النموذج نهائيًا يزيل أي نشر لا يزال يخدمه.
العَرَض: خططت لتوزيع تدريجي بنسبة 10%/50%/100%، لكن خيار Replace model يحوّل كل حركة المرور دفعة واحدة. الحل: تخدم الأطراف النهائية نموذجًا واحدًا. لإجراء طرح تجريبي، انشر النموذج المرشح على طرف نهائي ثانٍ ووزّع حركة المرور عبر الموجّه الخاص بك، ثم استبدل النموذج واحذف الطرف النهائي الثاني.
العَرَض: يجتاز كل نموذج مرشح بوابة التقييم، ومع ذلك يتراجع الأداء في الإنتاج. الحل: لا تكون بوابة التقييم موثوقة إلا على إصدار لمجموعة تحقق مستبعدة لم تستخدمه أي عملية تشغيل في التدريب. احتفظ بمجموعة التحقق المستبعدة في مجموعة بيانات خاصة بها، ولا تدمجها مطلقًا مع بيانات التدريب.
عرض الحل
دورة عملية لخط إنتاج الحبوب. المحفّز: انخفضت نتيجة فحص مجموعة التحقق الخاصة بالوردية الليلية بمقدار 0.05. الجمع: حُفظت 180 عينة من المراقبة في الوردية المسائية ضمن pill-review، بالإضافة إلى 120 عينة من وكيل جمع الاكتشافات غير المؤكدة؛ ثم أُجريت عملية التعليق التوضيحي الدفعي عند 0.35 باستخدام v2-finetune المنشور، وكان معدل التعديل 18%؛ وبعد المراجعة والدمج، اجتازت عمليات التدقيق دون ملاحظات؛ وأصبح الإصدار v6: +300 night-shift frames. الضبط الدقيق لـ v3-night انطلاقًا من v2-finetune، باستخدام SGD، وlr0 بقيمة 0.001، و20 حقبة. الاختبار على مجموعة تحقق من 300 صورة، تشمل 100 صورة ليلية: ارتفع mAP50-95 من 0.66 إلى 0.71، ولم تظهر فئات ضعيفة، واستغرق الأمر 4 ms: اجتاز الاختبار. أبلغ release.py مع NEW_MODEL = "v3-night" عن status=ready model=v3-night؛ وكتب holdout_check.py خط أساس جديدًا بقيمة 0.71. بقي v2-finetune في المشروع بوصفه هدف التراجع، والتزمنا بدليل التشغيل وبوابة الاختبار والبرنامج النصي للإصدار معًا.