Link to this sectionفهم الكشف الشامل (End-to-End) في Ultralytics YOLO26#
Link to this sectionمقدمة#
إذا كنت تقوم بالترقية إلى YOLO26 من نموذج أقدم مثل YOLOv8 أو YOLO11، فإن أحد أكبر التغييرات التي ستلاحظها هو إزالة كبت غير الأعظم (NMS). تنتج نماذج YOLO التقليدية آلاف التوقعات المتداخلة التي تتطلب خطوة معالجة لاحقة منفصلة بواسطة NMS للتصفية وصولاً إلى الاكتشافات النهائية. هذا يضيف زمن انتقال، ويعقد رسوم بيانية للتصدير، ويمكن أن يعمل بشكل غير متسق عبر منصات الأجهزة المختلفة.
تتبع YOLO26 نهجاً مختلفاً. فهي تُخرج الاكتشافات النهائية مباشرة من النموذج - دون الحاجة إلى تصفية خارجية. يُعرف هذا باسم اكتشاف الكائنات الشامل، وهو مفعل افتراضياً في جميع نماذج YOLO26. النتيجة هي خط أنابيب نشر أبسط، وزمن انتقال أقل، وسرعة استدلال تصل إلى 43% أسرع على وحدات المعالجة المركزية (CPUs).
يوضح لك هذا الدليل ما تغير، وما إذا كنت بحاجة إلى تحديث الكود الخاص بك، وتنسيقات التصدير التي تدعم الاستدلال الشامل، وكيفية الانتقال بسلاسة من نماذج YOLO القديمة.
لإلقاء نظرة أعمق على الدافع وراء هذا التحول المعماري، راجع منشور مدونة Ultralytics حول سبب إزالة YOLO26 لـ NMS وكيف يغير ذلك النشر.
- هل تستخدم Ultralytics API أو CLI؟ لا حاجة لإجراء تغييرات — فقط استبدل اسم النموذج بـ
yolo26n.pt. - هل تستخدم كود استدلال مخصص (ONNX Runtime، TensorRT، إلخ)؟ حدّث المعالجة اللاحقة لديك — مخرجات الكشف الآن هي
(N, 300, 6)بتنسيقxyxy، ولا حاجة إلى NMS. المهام الأخرى تضيف بيانات إضافية (معاملات القناع، أو النقاط الرئيسية، أو الزاوية). - هل تقوم بالتصدير؟ تدعم معظم التنسيقات مخرجات شاملة أصلاً. ومع ذلك، تعود بعض التنسيقات (NCNN، وRKNN، وPaddlePaddle، وExecuTorch، وIMX، وEdge TPU، وQNN) تلقائياً إلى المخرجات التقليدية بسبب قيود المشغل غير المدعومة (مثل
torch.topk). تتجمع سير عمل Hailo HEF من ONNX باستخدام نصوص برمجية خاصة بـ Hailo، لذا تحقق من رأس الكشف وتكوين NMS لنموذجك.
Link to this sectionكيف يعمل الكشف الشامل#
تستخدم YOLO26 معمارية ثنائية الرأس أثناء التدريب. يتشارك كلا الرأسين نفس العمود الفقري (Backbone) والرقبة (Neck)، لكنهما ينتجان المخرجات بطرق مختلفة:
| الرأس | الغرض | مخرجات الكشف | المعالجة اللاحقة |
|---|---|---|---|
| واحد لواحد (افتراضي) | استدلال شامل | (N, 300, 6) | عتبة الثقة فقط |
| واحد لكثير | مخرجات YOLO التقليدية | (N, nc + 4, 8400) | يتطلب NMS |
الأشكال أعلاه مخصصة لـ الكشف. المهام الأخرى توسع مخرجات الواحد لواحد ببيانات إضافية لكل كشف:
| المهمة | مخرجات شاملة | بيانات إضافية |
|---|---|---|
| الكشف | (N, 300, 6) | — |
| تجزئة المثيلات | (N, 300, 6 + nm) + proto (N, nm, H, W) | nm معاملات القناع (افتراضي 32) |
| الوضعية | (N, 300, 57) | 17 نقطة رئيسية × 3 (x, y, الرؤية) |
| OBB | (N, 300, 7) | زاوية الدوران |
أثناء التدريب، يعمل كلا الرأسين في وقت واحد — يوفر رأس الواحد لكثير إشارة تعليم أغنى، بينما يتعلم رأس الواحد لواحد إنتاج تنبؤات نظيفة وغير متداخلة. أثناء الاستدلال والتصدير، يكون رأس الواحد لواحد فقط هو النشط افتراضياً، مما ينتج ما يصل إلى 300 كشف لكل صورة بالتنسيق [x1, y1, x2, y2, confidence, class_id].
عندما تقوم باستدعاء model.fuse()، فإنه يقوم بطي طبقات Conv + BatchNorm لاستدلال أسرع، وفي النماذج الشاملة، يزيل أيضاً رأس الواحد لكثير — مما يقلل من حجم النموذج وعدد العمليات الحسابية (FLOPs). لمزيد من التفاصيل حول المعمارية ثنائية الرأس، راجع صفحة نموذج YOLO26.
Link to this sectionهل أحتاج إلى تغيير الكود الخاص بي؟#
Link to this sectionباستخدام Ultralytics Python API أو CLI#
لا حاجة لتغييرات. إذا كنت تستخدم Ultralytics Python API القياسي أو CLI، فكل شيء يعمل تلقائياً — التنبؤ، والتحقق، والتصدير تتعامل جميعها مع النماذج الشاملة بشكل مباشر.
from ultralytics import YOLO
# Load a YOLO26 model
model = YOLO("yolo26n.pt")
# Predict — no NMS step, no code changes
results = model.predict("image.jpg")Link to this sectionباستخدام كود استدلال مخصص#
نعم، تنسيق المخرجات مختلف. إذا كتبت منطق معالجة لاحقة مخصص لـ YOLOv8 أو YOLO11 (على سبيل المثال، عند تشغيل الاستدلال باستخدام ONNX Runtime أو TensorRT)، فستحتاج إلى تحديثه للتعامل مع شكل المخرجات الجديد:
| YOLOv8 / YOLO11 | YOLO26 (شامل) | |
|---|---|---|
| مخرجات الكشف | (N, nc + 4, 8400) | (N, 300, 6) |
| تنسيق الصندوق | xywh (مركز x، مركز y، العرض، الارتفاع) | xyxy (أعلى يسار x، أعلى يسار y، أسفل يمين x، أسفل يمين y) |
| التخطيط | إحداثيات الصندوق + درجات الفئة لكل مرساة (Anchor) | [x1, y1, x2, y2, conf, class_id] |
| NMS مطلوب | نعم | لا |
| المعالجة اللاحقة | NMS + تصفية الثقة | تصفية الثقة فقط |
بالنسبة لمهام التجزئة، والوضعية، وOBB، تضيف YOLO26 بيانات خاصة بالمهمة إلى كل كشف — انظر جدول أشكال المخرجات أعلاه.
حيث N هو حجم الدفعة وnc هو عدد الفئات (على سبيل المثال، 80 لـ COCO).
مع النماذج الشاملة، تصبح المعالجة اللاحقة أبسط بكثير — على سبيل المثال، عند استخدام ONNX Runtime:
import onnxruntime as ort
# Load and run the exported end-to-end model
session = ort.InferenceSession("yolo26n.onnx")
output = session.run(None, {session.get_inputs()[0].name: input_tensor})
# End-to-end output: (batch, 300, 6) → [x1, y1, x2, y2, confidence, class_id]
detections = output[0][0] # first image in batch
detections = detections[detections[:, 4] > conf_threshold] # confidence filter — that's it!Link to this sectionالتبديل إلى رأس الواحد لكثير#
إذا كنت بحاجة إلى تنسيق مخرجات YOLO التقليدي (على سبيل المثال، لإعادة استخدام كود المعالجة اللاحقة الحالي القائم على NMS)، يمكنك التبديل إلى رأس الواحد لكثير في أي وقت عن طريق ضبط end2end=False:
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
# Prediction with NMS (traditional behavior)
results = model.predict("image.jpg", end2end=False)
# Validation with NMS
metrics = model.val(data="coco.yaml", end2end=False)
# Export without end-to-end
model.export(format="onnx", end2end=False)Link to this sectionتوافق تنسيق التصدير#
تدعم معظم تنسيقات التصدير الاستدلال الشامل بشكل مباشر، بما في ذلك ONNX، وTensorRT، وCoreML، وOpenVINO، وTFLite، وTF.js، وMNN.
التنسيقات التالية لا تدعم الاستدلال الشامل وتعود تلقائياً إلى رأس الواحد لكثير: NCNN، وRKNN، وPaddlePaddle، وExecuTorch، وIMX، وEdge TPU، وQualcomm QNN.
بالنسبة لـ Hailo HEF، تحدث خطوة التجميع خارج model.export(format=...) بعد تصدير ONNX. استخدم سجلات Hailo DFC، والنص البرمجي للنموذج .alls، وJSON الخاص بـ NMS الذي يطابق نموذج الكشف الخاص بك بدقة؛ إذا لم يكن رسم YOLO26 البياني الشامل مدعوماً بواسطة سلسلة أدوات Hailo الخاصة بك، فقم بتصدير نموذج ONNX مع end2end=False وقم بتجميع رأس الكشف التقليدي.
يدعم TensorRT الاستدلال الشامل، ولكنه معطل تلقائياً عند التصدير باستخدام int8=True على TensorRT 10.3.0 على JetPack 6.
Link to this sectionمقايضات الدقة والسرعة#
يوفر الكشف الشامل فوائد نشر كبيرة مع تأثير ضئيل على الدقة:
| المقياس | شامل (افتراضي) | واحد لكثير + NMS (end2end=False) |
|---|---|---|
| سرعة استدلال CPU | أسرع بنسبة تصل إلى 43% | خط الأساس |
| تأثير mAP | ~0.5 mAP أقل | تطابق أو تتجاوز YOLO11 |
| المعالجة اللاحقة | تصفية الثقة فقط | خط أنابيب NMS كامل |
| تعقيد النشر | حد أدنى | يتطلب تنفيذ NMS |
بالنسبة لمعظم تطبيقات العالم الحقيقي، الفرق في mAP البالغ ~0.5 لا يكاد يذكر، خاصة عند النظر في مكاسب السرعة والبساطة. إذا كانت الدقة القصوى هي أولويتك القصوى، يمكنك دائماً العودة إلى رأس الواحد لكثير باستخدام end2end=False.
راجع مقاييس أداء YOLO26 للحصول على معايير مفصلة عبر جميع أحجام النماذج (n, s, m, l, x).
Link to this sectionالهجرة من YOLOv8 أو YOLO11#
إذا كنت تقوم بترقية مشروع موجود إلى YOLO26، فإليك قائمة تحقق سريعة لضمان انتقال سلس:
- مستخدمو Ultralytics API / CLI: لا حاجة لإجراء تغييرات — فقط قم بتحديث اسم النموذج إلى
yolo26n.pt(أوyolo26n-seg.pt، أوyolo26n-pose.pt، أوyolo26n-obb.pt) - كود معالجة لاحقة مخصص: قم بالتحديث للتعامل مع أشكال المخرجات الجديدة —
(N, 300, 6)للكشف، بالإضافة إلى بيانات خاصة بالمهمة لـ التجزئة، والوضعية، وOBB. لاحظ أيضاً تغيير تنسيق الصندوق منxywhإلىxyxy - خطوط أنابيب التصدير: تحقق من قسم توافق التنسيق أعلاه للتنسيق المستهدف
- TensorRT + INT8: على JetPack 6، يقوم TensorRT 10.3.0 بتعطيل الاستدلال الشامل تلقائياً مع
int8=True— استخدم إصدار TensorRT مختلف للحفاظ على الاستدلال الشامل - تصديرات FP16: إذا كنت بحاجة إلى جميع المخرجات بتنسيق FP16، فقم بالتصدير مع
end2end=False— انظر لماذا تظل output0 بتنسيق FP32 - iOS / CoreML: الاستدلال الشامل مدعوم بالكامل. إذا كنت بحاجة إلى دعم معاينة Xcode، فاستخدم
end2end=Falseمعnms=True - أجهزة الحافة (NCNN, RKNN): تعود هذه التنسيقات تلقائياً إلى الواحد لكثير، لذا قم بتضمين NMS في خط أنابيب الجهاز الخاص بك
Link to this sectionالأسئلة الشائعة#
Link to this sectionهل يمكنني استخدام end2end=True و nms=True معاً؟#
لا. هذه الخيارات متبادلة حصرياً. إذا قمت بضبط nms=True على نموذج شامل أثناء التصدير، فسيتم إجباره تلقائياً على nms=False مع تحذير. يتعامل رأس الاستدلال الشامل بالفعل مع تصفية التكرارات داخلياً، لذا فإن NMS الخارجي غير ضروري.
ومع ذلك، فإن end2end=False مقترناً بـ nms=True هو تكوين صالح — فهو يدمج NMS التقليدي في رسم التصدير البياني. يمكن أن يكون هذا مفيداً لتصديرات CoreML لأنه يتيح لك استخدام وظيفة المعاينة في Xcode مع نموذج الكشف مباشرة.
Link to this sectionما الذي يتحكم فيه المعامل max_det في النماذج من الطرف إلى الطرف؟#
يحدد المعامل max_det (القيمة الافتراضية: 300) الحد الأقصى لعدد الاكتشافات التي يمكن للرأس أحادي إلى أحادي (one-to-one head) إخراجها لكل صورة. يمكنك ضبطه أثناء الاستدلال أو عند التصدير:
model.predict("image.jpg", max_det=100) # fewer detections, slightly faster
model.export(format="onnx", max_det=500) # more detections for dense scenesلاحظ أن نقاط فحص YOLO26 الافتراضية قد تم تدريبها باستخدام max_det=300. على الرغم من إمكانية زيادة هذه القيمة، إلا أن الرأس أحادي إلى أحادي تم تحسينه أثناء التدريب لإنتاج ما يصل إلى 300 اكتشاف دقيق، لذا قد تكون الاكتشافات التي تتجاوز هذا الحد أقل جودة. إذا كنت بحاجة إلى أكثر من 300 اكتشاف لكل صورة، ففكر في إعادة التدريب باستخدام قيمة max_det أعلى.
Link to this sectionنموذج ONNX الذي قمت بتصديره يخرج (1, 300, 6) — هل هذا صحيح؟#
نعم، هذا هو تنسيق المخرج المتوقع من الطرف إلى الطرف (end-to-end) للاكتشاف: batch size يساوي 1، مع ما يصل إلى 300 اكتشاف، يحتوي كل منها على 6 قيم [x1, y1, x2, y2, confidence, class_id]. ببساطة قم بالتصفية حسب عتبة الثقة (confidence threshold) وستنتهي — لا حاجة إلى NMS.
بالنسبة للمهام الأخرى، يختلف شكل المخرجات:
| المهمة | شكل المخرجات | الوصف |
|---|---|---|
| اكتشاف | (1, 300, 6) | [x1, y1, x2, y2, conf, class_id] |
| التقسيم (Segmentation) | (1, 300, 38) + (1, 32, 160, 160) | 6 قيم للصندوق + 32 معامل قناع، بالإضافة إلى موتر قناع أولي |
| وضعية | (1, 300, 57) | 6 قيم للصندوق + 17 نقطة رئيسية × 3 (x, y, الرؤية) |
| OBB | (1, 300, 7) | 6 قيم للصندوق + 1 زاوية دوران |
Link to this sectionكيف أتحقق مما إذا كان النموذج الذي قمت بتصديره يعمل من الطرف إلى الطرف؟#
يمكنك التحقق باستخدام Ultralytics Python API أو عن طريق فحص بيانات تعريف نموذج ONNX الذي تم تصديره مباشرة:
from ultralytics import YOLO
model = YOLO("yolo26n.onnx")
model.predict(verbose=False) # run predict to setup predictor first
print(model.predictor.model.end2end) # True if end-to-end is enabledبدلاً من ذلك، تحقق من شكل المخرج — نماذج الاكتشاف من الطرف إلى الطرف تخرج (1, 300, 6)، بينما النماذج التقليدية تخرج (1, nc + 4, 8400). لأشكال المهام الأخرى، راجع الأسئلة الشائعة حول أشكال المخرجات.
Link to this sectionهل يتم دعم ميزة من الطرف إلى الطرف لمهام تقسيم المثيلات، وتحديد الوضع، و OBB؟#
نعم. تدعم متغيرات مهام YOLO26 بأسلوب الاكتشاف — الاكتشاف، وتقسيم المثيلات، وتقدير الوضع، واكتشاف الكائنات الموجهة (OBB) — الاستدلال من الطرف إلى الطرف بشكل افتراضي. خيار الرجوع end2end=False متاح عبر هذه المهام أيضاً.
توسع كل مهمة مخرجات الاكتشاف الأساسية ببيانات خاصة بالمهمة:
| المهمة | النموذج | مخرجات شاملة |
|---|---|---|
| اكتشاف | yolo26n.pt | (N, 300, 6) |
| تقسيم المثيلات | yolo26n-seg.pt | (N, 300, 38) + proto (N, 32, 160, 160) |
| وضعية | yolo26n-pose.pt | (N, 300, 57) |
| OBB | yolo26n-obb.pt | (N, 300, 7) |