Ultralytics YOLO27: انضم إلى قائمة الانتظار.
Get Started
درّب أول نموذج YOLO لديك·النشر·الدرس 10/10
الدرسمبتدئ

التصدير للنشر

صدّر best.pt إلى ONNX أو OpenVINO أو TensorRT أو CoreML أو LiteRT أو QNN، ثم أثبت تطابق التصدير مع نموذج PyTorch قبل نشره.

يحتاج best.pt إلى Python وPyTorch ليعمل؛ بينما لا تتوفر هذه الأدوات عادةً على الهواتف والمتصفحات وأجهزة Jetson وخوادم الإنتاج. يحوّل وضع التصدير النموذج، باستدعاء واحد، إلى ملف مستقل لهذه البيئات. لكن مجرد تحميل الملف لا يعني أن التصدير صحيح تلقائيًا، كما أن المقارنة غير المدروسة قد تجعل تصديرًا صحيحًا يبدو معطوبًا أو تخفي خللًا في تصدير معطوب.

في هذا الدرس، ستصدّر نموذج الحبوب إلى ONNX، وتشغّله عبر واجهة YOLO نفسها، وتثبت تطابقه مع PyTorch في الصناديق وmAP التحقق باستخدام إعدادات متطابقة، ثم تختار التنسيق الذي يتطلبه هدفك: ONNX أو OpenVINO أو TensorRT أو CoreML أو LiteRT أو QNN.

النتيجة

يمكنك تصدير نموذج مدرّب إلى التنسيق المناسب لهدف النشر، وإثبات تطابق التصدير مع best.pt من خلال فحص تكافؤ ومجموعة تحقق متطابقين في جميع الإعدادات.

المسار السريع
إذا كنت تعرف الأساسيات بالفعل، فإليك النسخة المختصرة.
  1. yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx — ابدأ من هنا.

  2. OpenVINO لوحدات Intel CPU؛ وTensorRT لوحدات NVIDIA GPU وأجهزة Jetson؛ وCoreML لأجهزة Apple؛ وLiteRT لنظام Android؛ وQNN لوحدات NPU من Snapdragon.

  3. قارن .pt بالتصدير على الصورة نفسها باستخدام rect=False على جانب .pt.

  4. تحقق من كليهما عند imgsz المستخدم في التدريب؛ ينبغي أن تتطابق mAP50-95.

عملي

مثال تطبيقي: التصدير إلى ONNX#

علامة تبويب التصدير لنموذج في منصة Ultralytics، تعرض تنسيقات النشر مثل ONNX وTensorRT وCoreML وOpenVINO

yolo export model=runs/detect/pills_v1/weights/best.pt format=onnx
PyTorch: starting from 'runs/detect/pills_v1/weights/best.pt' with input shape (1, 3, 320, 320) BCHW and output shape(s) (1, 5, 2100) (5.2 MB)
ONNX: export success ✅ 0.9s, saved as 'runs/detect/pills_v1/weights/best.onnx' (9.3 MB)
Predict:         yolo predict task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320
Validate:        yolo val task=detect model=runs/detect/pills_v1/weights/best.onnx imgsz=320 data=my_dataset/data.yaml

شرح الأسطر واحدًا تلو الآخر:

  • input shape (1, 3, 320, 320): صورة واحدة، و3 قنوات لونية، ومربع ثابت أبعاده 320×320 — قيمة imgsz المستخدمة في التدريب، والمدمجة في الملف.
  • output shape(s) (1, 5, 2100): 4 قيم للصندوق بالإضافة إلى درجة الفئة الواحدة لـ2,100 صندوق مرشح؛ ويُنفَّذ NMS خارج الرسم البياني افتراضيًا.
  • 9.3 MB: يخزّن ملف ONNX أوزان FP32، لذا حجمه أكبر من .pt بصيغة FP16.
  • Predict: / Validate:: أوامر جاهزة للملف المُصدَّر، معدّة مسبقًا وفق imgsz المناسب.

تغطي بضعة وسائط معظم الاحتياجات؛ ويسرد دليل تكامل ONNX بقية الوسائط.

الوسيطافتراضياستخدمه من أجل
imgszحجم التدريبالتصدير بحجم إدخال ثابت مختلف، مثل imgsz=640
dynamicFalseقبول أحجام إدخال متغيرة بدلًا من شكل ثابت واحد
quantizeلا شيء (FP32)16 لأوزان FP16 (yolo26n.onnx يقل حجمه من 9.5 MB إلى 4.8 MB)؛ و8 لـINT8 عند دعم التنسيق لذلك
nmsلا شيءيضمّن nms=True تقنية NMS في الرسم البياني، لذا تعيد بيئة التشغيل الصناديق النهائية

مثال تطبيقي: إثبات تطابق التصدير#

يحمّل الصنف YOLO الملفات المُصدَّرة أيضًا، لذا تعمل شيفرة التنبؤ السابقة دون تغيير. قارن الملفين على صورة التحقق نفسها:

from ultralytics import YOLO

image = "my_dataset/images/val/Frame_144.jpg"
pt = YOLO("runs/detect/pills_v1/weights/best.pt")(image, rect=False, verbose=False)[0]  # square input, like ONNX
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx")(image, verbose=False)[0]

print(f"pt:   {len(pt.boxes)} pills, mean conf {pt.boxes.conf.mean():.3f}")
print(f"onnx: {len(onnx.boxes)} pills, mean conf {onnx.boxes.conf.mean():.3f}")
print(f"max box difference: {(pt.boxes.xyxy - onnx.boxes.xyxy).abs().max():.4f} px")
pt:   25 pills, mean conf 0.870
onnx: 25 pills, mean conf 0.870
max box difference: 0.0002 px

العدد نفسه، والثقة نفسها، والصناديق متطابقة بفارق لا يتجاوز أجزاءً من البكسل. والآن، الاختبار الأقوى: التحقق على مجموعة البيانات الفرعية بأكملها:

from ultralytics import YOLO

pt = YOLO("runs/detect/pills_v1/weights/best.pt").val(data="my_dataset/data.yaml", rect=False, verbose=False)
onnx = YOLO("runs/detect/pills_v1/weights/best.onnx").val(data="my_dataset/data.yaml", verbose=False)
print(f".pt   mAP50-95 {pt.box.map:.4f}")
print(f".onnx mAP50-95 {onnx.box.map:.4f}")
.pt   mAP50-95 0.6570
.onnx mAP50-95 0.6570

متطابقان. (سجّل الملف .pt درجة 0.659 في التحقق المستطيل الافتراضي: فرق بسيط ناتج عن حشو الإدخال، لا عن التصدير.)

بعد التحقق من التطابق، قِس الزمن باستخدام yolo benchmark على الجهاز المستهدف لمعرفة سرعته الفعلية قبل النشر.

اختر تنسيقًا لهدفك#

دورة حياة منصة Ultralytics: وضع التعليقات التوضيحية باستخدام التعليقات التوضيحية الذكية في SAM، والتدريب على وحدات GPU سحابية، والنشر في مناطق عالمية، مع شعارات شركاء التكامل

الهدفالتنسيقملاحظات
الخيار الافتراضي المحمول: الخوادم وأجهزة سطح المكتب التي تعمل بنظام Linux أو Windows أو MaconnxONNX Runtime على CPU أو GPU؛ أسرع تصدير للتحقق منه
وحدات معالجة الرسومات NVIDIA وJetsonengine (TensorRT)الأسرع على NVIDIA؛ صدّر على الجهاز نفسه. راجع التحسين باستخدام TensorRT
وحدات المعالجة المركزية ووحدات معالجة الرسومات المدمجة من Intelopenvinoتحسينات حقيقية في سرعة وحدة المعالجة المركزية بفضل نوى Intel. راجع OpenVINO على وحدة المعالجة المركزية
تطبيقات iPhone وiPad وMaccoremlأصلي؛ يستخدم Apple Neural Engine
Android وأجهزة محمولة أو مدمجة أخرىlitertيوصى باستخدام INT8 للأجهزة المحمولة
وحدات NPU من Snapdragonqnnتسريع Hexagon HTP؛ أوزان INT8 مع عمليات تنشيط 16 بت افتراضيًا؛ اختر بنية HTP باستخدام name
متصفح الويبonnx مع ONNX Runtime Webالنماذج الأصغر عملية: n وs
from ultralytics import YOLO

model = YOLO("runs/detect/pills_v1/weights/best.pt")

model.export(format="onnx")  # ⁨متعدد المنصات: ONNX Runtime⁩
model.export(format="openvino")  # ⁨وحدة المعالجة المركزية / وحدة معالجة الرسومات المدمجة من Intel⁩
model.export(format="engine", quantize=16)  # ⁨NVIDIA TensorRT، FP16 (شغّله على وحدة معالجة الرسومات المستهدفة)⁩
model.export(format="coreml")  # Apple iOS / macOS
model.export(format="litert", quantize=8, data="my_dataset/data.yaml")  # ⁨Android / الطرفية، INT8⁩
model.export(format="qnn", name="73", data="my_dataset/data.yaml")  # ⁨وحدة NPU من Qualcomm Snapdragon (HTP v73)؛ أجرِ المعايرة باستخدام بياناتك الخاصة⁩

يكتب كل تصدير الملفات بجوار الأوزان: best.onnx وbest_openvino_model/ وbest.engine، وهكذا. ابدأ بـ ONNX حتى إن كنت ستستخدم تنسيقًا آخر في النهاية؛ فهو الأسرع للتحقق، كما أنه مدخل لعدد من سلاسل الأدوات الأخرى. يقارن دليل خيارات النشر بين جميع التنسيقات، ويرشدك اختيار هدف النشر خلال عملية اتخاذ القرار.

تُوازن كمّية النموذج بين الدقة والحجم والسرعة. يقلّص FP16 (quantize=16) حجم الملف إلى النصف مع بقاء الدقة شبه ثابتة. أما INT8 (quantize=8) فهو أصغر وأسرع، لكنه يحتاج إلى صور معايرة — أي إطارات تمثيلية يمرّرها التصدير لاختيار نطاقات القيم؛ وتوصي Ultralytics باستخدام 300 صورة على الأقل. تحقّق دائمًا من نموذج INT8 قبل شحنه: فقد يكون الفقد ضئيلًا أو كبيرًا بحسب النموذج ومجموعة المعايرة.

تجنّب هذه الأخطاء#

مقارنة مدخلات مختلفة

العَرَض: يكتشف نموذج .pt عدد 35 حبة على Frame_144.jpg، بينما يكتشف ملف ONNX عدد 25، فيبدو التصدير معطوبًا. السبب: يضيف استدلال PyTorch حشوًا لكل صورة حتى أصغر مستطيل يتوافق مع خطوة الشبكة (192×320 لإطارات 16:9 هذه)، بينما يأخذ نموذج ONNX ثابت الحجم مربعًا بأبعاد 320×320 دائمًا. يؤدي اختلاف المدخلات إلى اكتشافات مختلفة منخفضة الثقة. الحل: مرّر rect=False إلى نموذج .pt عند المقارنة، كما في parity.py.

التصدير ثابت الحجم يتجاهل imgsz الذي تحدده

العَرَض: تمرّر imgsz=640 إلى best.onnx، لكن السجل يظل يعرض 320x320. السبب: للتصدير ثابت الحجم مقاس إدخال واحد يُحدَّد وقت التصدير. الحل: صدّر بالحجم الذي ستشغّل به (imgsz=640)، أو صدّر باستخدام dynamic=True.

محركات TensorRT خاصة بالجهاز

لن يعمل .engine المبني على A100 على Jetson Orin، وقد لا يصمد بعد ترقية TensorRT. أجرِ التصدير على الجهاز المستهدف وبإصدار TensorRT الذي سيُشغَّل عليه. إن ONNX قابل للنقل؛ أما المحركات فليست كذلك.

يُجري INT8 المعايرة على COCO8 ما لم تحدد خلاف ذلك

إذا لم تحدد data عند تصدير INT8، فسيصدر Ultralytics تحذيرًا ثم يجري المعايرة على عينة COCO8 الافتراضية — ثماني صور لا تشبه حبوبك إطلاقًا. مرّر عينتك الخاصة: model.export(format="litert", quantize=8, data="my_dataset/data.yaml").

لقد أطلقت المنتج#

لديك الآن best.pt مدرّب، وأدلة تحقق إلى جانب خط أساس، وملف مُصدّر لبيئة التشغيل لديك، وإثبات على تطابق التصدير مع الأصل. هذه هي الدورة الكاملة — البيانات، والتدريب، والتحقق، والتصدير، والنشر — وتنفذها فرق الإنتاج وفق جدول زمني. يتابع Ultralytics YOLO في الإنتاج انطلاقًا من التصدير الذي تحققت منه، ويتناول بيئات التشغيل المحسّنة، وخطوط أنابيب التتبع، وخدمة تدفقات متعددة، والمراقبة.

جرّبه

صدّر pills_v1/weights/best.pt إلى ONNX، ثم شغّل parity.py وval_export.py. أعد تشغيل parity.py من دون rect=False وسجّل كيف يتغير عدد .pt. قدّم أربعة عناصر: عدد الكشوف المتطابقة، وأقصى اختلاف بين الصناديق، وقيمتا mAP50-95، وسطرًا واحدًا يذكر التنسيق الذي يحتاجه هدف النشر الفعلي لديك والسبب.

التزام
git add -A && git commit -m "feat(deploy): exported best.pt to onnx for production runtime"
متى يُعدّ مكتملًا
تكون قد أتممت الدرس عند تحقق جميع الشروط التالية.
  • يوجد runs/detect/pills_v1/weights/best.onnx ويُصدر تنبؤات عبر YOLO().

  • باستخدام rect=False، تتطابق أعداد الكشوف ويقل أقصى اختلاف بين الصناديق عن 1 px.

  • تتطابق قيم mAP50-95 للتحقق من ONNX و.pt عند استخدام الإعدادات نفسها، وقد حددت التنسيق المستهدف وسبب اختياره.

عرض الحل
from ultralytics import YOLO

# Train
model = YOLO("yolo26n.pt")
model.train(data="my_dataset/data.yaml", epochs=10, imgsz=320, name="pills_e2e")

# Validate
metrics = model.val()
print(f"mAP50-95 = {metrics.box.map:.3f}")  # 0.659

# Export
model.export(format="onnx")
parity.py:      pt 25 pills, onnx 25 pills, max box difference 0.0002 px
without rect:   pt 35 pills (192x320 input) vs onnx 25 (320x320): input mismatch, not an export bug
val_export.py:  .pt 0.6570, .onnx 0.6570
Target:         Intel laptop CPU -> openvino, for faster CPU inference than ONNX Runtime
ما الخطوة التالية

اكتملت الدورة — أجرِ الاختبار النهائي لتحصل على شهادة تدريب أول نموذج YOLO لك، ثم تابع مع Ultralytics YOLO في الإنتاج.

سجّل الدخول لحفظ التقدم