التصدير للنشر
صدّر best.pt إلى ONNX أو OpenVINO أو TensorRT أو CoreML أو LiteRT أو QNN، ثم أثبت تطابق التصدير مع نموذج PyTorch قبل نشره.
يحتاج best.pt إلى Python وPyTorch ليعمل؛ بينما لا تتوفر هذه الأدوات عادةً على الهواتف والمتصفحات وأجهزة Jetson وخوادم الإنتاج. يحوّل وضع التصدير النموذج، باستدعاء واحد، إلى ملف مستقل لهذه البيئات. لكن مجرد تحميل الملف لا يعني أن التصدير صحيح تلقائيًا، كما أن المقارنة غير المدروسة قد تجعل تصديرًا صحيحًا يبدو معطوبًا أو تخفي خللًا في تصدير معطوب.
في هذا الدرس، ستصدّر نموذج الحبوب إلى ONNX، وتشغّله عبر واجهة YOLO نفسها، وتثبت تطابقه مع PyTorch في الصناديق وmAP التحقق باستخدام إعدادات متطابقة، ثم تختار التنسيق الذي يتطلبه هدفك: ONNX أو OpenVINO أو TensorRT أو CoreML أو LiteRT أو QNN.
عملي
مثال تطبيقي: التصدير إلى ONNX#

yolo export model=runs/detect/pills_v1/weights/best.pt format=onnxPyTorch: 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 |
dynamic | False | قبول أحجام إدخال متغيرة بدلًا من شكل ثابت واحد |
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 على الجهاز المستهدف لمعرفة سرعته الفعلية قبل النشر.
اختر تنسيقًا لهدفك#

| الهدف | التنسيق | ملاحظات |
|---|---|---|
| الخيار الافتراضي المحمول: الخوادم وأجهزة سطح المكتب التي تعمل بنظام Linux أو Windows أو Mac | onnx | ONNX Runtime على CPU أو GPU؛ أسرع تصدير للتحقق منه |
| وحدات معالجة الرسومات NVIDIA وJetson | engine (TensorRT) | الأسرع على NVIDIA؛ صدّر على الجهاز نفسه. راجع التحسين باستخدام TensorRT |
| وحدات المعالجة المركزية ووحدات معالجة الرسومات المدمجة من Intel | openvino | تحسينات حقيقية في سرعة وحدة المعالجة المركزية بفضل نوى Intel. راجع OpenVINO على وحدة المعالجة المركزية |
| تطبيقات iPhone وiPad وMac | coreml | أصلي؛ يستخدم Apple Neural Engine |
| Android وأجهزة محمولة أو مدمجة أخرى | litert | يوصى باستخدام INT8 للأجهزة المحمولة |
| وحدات NPU من Snapdragon | qnn | تسريع 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=640 إلى best.onnx، لكن السجل يظل يعرض 320x320. السبب: للتصدير ثابت الحجم مقاس إدخال واحد يُحدَّد وقت التصدير. الحل: صدّر بالحجم الذي ستشغّل به (imgsz=640)، أو صدّر باستخدام dynamic=True.
لن يعمل .engine المبني على A100 على Jetson Orin، وقد لا يصمد بعد ترقية TensorRT. أجرِ التصدير على الجهاز المستهدف وبإصدار TensorRT الذي سيُشغَّل عليه. إن ONNX قابل للنقل؛ أما المحركات فليست كذلك.
إذا لم تحدد data عند تصدير INT8، فسيصدر Ultralytics تحذيرًا ثم يجري المعايرة على عينة COCO8 الافتراضية — ثماني صور لا تشبه حبوبك إطلاقًا. مرّر عينتك الخاصة: model.export(format="litert", quantize=8, data="my_dataset/data.yaml").
لقد أطلقت المنتج#
لديك الآن best.pt مدرّب، وأدلة تحقق إلى جانب خط أساس، وملف مُصدّر لبيئة التشغيل لديك، وإثبات على تطابق التصدير مع الأصل. هذه هي الدورة الكاملة — البيانات، والتدريب، والتحقق، والتصدير، والنشر — وتنفذها فرق الإنتاج وفق جدول زمني. يتابع Ultralytics YOLO في الإنتاج انطلاقًا من التصدير الذي تحققت منه، ويتناول بيئات التشغيل المحسّنة، وخطوط أنابيب التتبع، وخدمة تدفقات متعددة، والمراقبة.
عرض الحل
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