تحويل نموذج ذكاء اصطناعي للرافعة العلوية: PyTorch إلى ONNX وTensorRT

حل النشر الطرفي لنموذج الذكاء الاصطناعي للرافعة العلوية

مسار النشر الكامل: PyTorch ResNet-18 (FP32, 45MB, استدلال GPU 5ms) ← تصدير ONNX (44MB, صيغة وسيطة متعددة المنصات, فقدان الدقة <0.1%) ← تكميم TensorRT INT8 (6MB, الحجم 87%, فقدان الدقة <0.5%) ← استدلال طرفي Jetson Orin NX (1.2ms/صورة, استهلاك 15W). مقارنة باستدلال خادم GPU (350W/5ms), يخفض Jetson استهلاك الطاقة بنسبة 96% ويزيد سرعة الاستدلال 4.2 مرة. تقدم هذه المقالة سكربتات التصدير الكاملة, وطرق معايرة INT8, وعملية التحقق من الدقة, وهندسة خط إنتاج متعدد النماذج.

مهما كان أداء نموذج الذكاء الاصطناعي للرافعة العلوية ممتازًا على GPU في المختبر, فإن عدم نشره في الموقع يعني صفرًا. الظروف البيئية في المواقع الصناعية (الاهتزاز, الحرارة المرتفعة, المساحات المحدودة, عدم توفر تكييف) لا تناسب نشر خوادم GPU عالية القدرة (350W+ تتطلب تكييفًا لغرفة الخوادم). النشر الطرفي (Edge Deployment) يحول نموذج PyTorch المدرب إلى صيغة ONNX الوسيطة, ثم يحسنه عبر تكميم TensorRT INT8 وينشره على أجهزة Jetson الطرفية منخفضة الاستهلاك. تتناول هذه المقالة نموذج ResNet-18 لكشف انكسار أسلاك الحبل السلكي للرافعة كمثال, وتقدم مسارًا هندسيًا كاملاً من التصدير إلى النشر, وكل الخطوات قابلة لإعادة الإنتاج. بيئة التجربة: تدريب NVIDIA A10(48GB) / طرفي Jetson Orin NX 16GB(15W) / PyTorch 2.1.0 / TensorRT 8.6 / JetPack 6.0.

تطبيق عملي لنشر نموذج الذكاء الاصطناعي للرافعة العلوية: من PyTorch إلى ONNX/TensorRT ثم الاستدلال الطرفي Jetson

الخطوة الأولى: تصدير PyTorch إلى ONNX

ONNX (Open Neural Network Exchange) هي "اللغة المشتركة" لنشر النماذج. تقوم الدالة torch.onnx.export() بتحويل الرسم البياني الديناميكي لـ PyTorch إلى رسم بياني ثابت لـ ONNX. إعدادات المعاملات الأساسية: input_names=["input"] و output_names=["output"] و dynamic_axes={"input":{0:"batch_size",2:"height",3:"width"}} (لدعم مدخلات بأحجام متغيرة). بعد التصدير, يُستخدم onnxruntime للتحقق من اتساق الدقة: فرق دقة استدلال FP32 عن PyTorch أقل من 0.1% (متوسط 20 صورة من مجموعة التحقق).

import torch, torch.onnx model = torch.load("resnet18_crane.pth") # FP32النموذج المُدرَّب مسبقًا نوع dummy = torch.randn(1, 3, 224, 224) torch.onnx.export(model, dummy, "resnet18_crane.onnx", input_names=["input"], output_names=["output"], dynamic_axes={"input": {0: "batch", 2: "h", 3: "w"}}, opset_version=17) # دقة التحقق والتصدير import onnxruntime as ort sess = ort.InferenceSession("resnet18_crane.onnx") out_ort = sess.run(None, {"input": dummy.numpy()})[0] out_pt = model(dummy).detach().numpy() print(f"Max diff: {abs(out_ort - out_pt).max():.6f}") # التطبيق<1e-5

الخطوة الثانية: تكميم TensorRT INT8

TensorRT هو محرك تحسين الاستدلال من NVIDIA, يحول نموذج ONNX إلى محرك TensorRT (.trt) عبر دمج الطبقات (Layer Fusion), ومعايرة الدقة (INT8 Calibration), وتحسين الذاكرة (Pool Allocation). عملية تكميم INT8: تعيين الأوزان وقيم التنشيط في نموذج FP32 من أرقام الفاصلة العائمة 32-بت إلى أعداد صحيحة 8-بت (دقة 256 مستوى). يتطلب التعيين 100~500 صورة معايرة (Calibration Dataset), باستخدام طريقة معايرة الانتروبيا (Entropy Calibration) لإيجاد عتبة التكميم ذات الحد الأدنى لتباعد KL.

الأمر المحدد: trtexec --onnx=resnet18_crane.onnx --saveEngine=resnet18_int8.trt --int8 --calib=calibration_data --fp16 --workspace=4096. شرح المعاملات الأساسية: --int8 لتفعيل تكميم INT8; --calib لتحديد دليل صور المعايرة (500 صورة); --fp16 لتفعيل الحسابات الوسيطة FP16 (دقة مختلطة مع أوزان INT8); --workspace=4096 يسمح بمساحة عمل 4GB (يمكن لـ Jetson Orin NX 16GB تخصيص 8GB). مدة التحويل حوالي 11 دقيقة (على GPU A10), حجم محرك INT8 هو 6.2MB (14% من حجم ONNX بنسخة FP32).

مؤشرPyTorch FP32(GPU)ONNX FP32(GPU)TensorRT INT8(Jetson)نطاق التحسين
حجم النموذج45MB44MB6.2MB86%
زمن الاستدلال5.0ms4.8ms1.2ms4.2x
استهلاك الطاقة350W350W12~15W96%
تكلفة العتاد¥80,000+¥80,000+¥3,50096%
Top-1دقة94.0%93.9%93.6%0.4%
F1النتيجة0.930.930.920.01

الخطوة الثالثة: التحقق من دقة النموذج

بعد عملية التكميم بنوع INT8، يجب التحقق من أن فقدان الدقة ضمن الحدود المقبولة. تتم عملية التحقق على النحو التالي: تشغيل نموذج PyTorch FP32 (كمرجع أساسي) ونموذج TensorRT INT8 (قيد الاختبار) على مجموعة اختبار مكونة من 1,000 صورة، ومقارنة دقة Top-1 ودرجة F1 ومصفوفة الارتباك لكل فئة. في هذه التجربة، كانت نتائج INT8 مقابل FP32 كالتالي: انخفضت دقة Top-1 من 94.0% إلى 93.6% (بفارق 0.4%)، وانخفضت درجة F1 من 0.93 إلى 0.92 (بفارق 0.01). تركز فقدان الدقة على مستوى الفئات في فئة "كسر الحبل السلكي" (ارتفع معدل عدم الاكتشاف من 2.3% إلى 3.1%، بزيادة 0.8%)، بينما كان فقدان الدقة في الفئات الأربع المتبقية أقل من 0.3%. إذا تجاوز فقدان الدقة لنموذج INT8 حد 1%، يُنصح بالتحول إلى التكميم بنوع FP16 (بحجم 12MB وفقدان دقة أقل من 0.1%) كحل وسط.


الخطوة الرابعة: النشر على Jetson وخط الإنتاج

يتم حرق ملف TensorRT Engine مباشرة على جهاز Jetson Orin NX (مع نظام JetPack 6.0 المثبت مسبقًا مع TensorRT 8.6). يستخدم كود الاستدلال واجهة برمجة تطبيقات TensorRT المرتبطة بلغة Python (أو واجهة C++ API لتحقيق زمن استجابة أقل). بالنسبة لخط الإنتاج متعدد النماذج (مثل كشف YOLO مع تصنيف ResNet): يتم استخدام CudaStream لتحقيق الاستدلال غير المتزامن، بحيث تتداخل معالجة وحدة المعالجة المركزية (NMS) مع استدلال وحدة معالجة الرسومات للنموذج التالي. يبلغ زمن الاستجابة الكلي لخط الإنتاج حوالي 60% من مجموع أزمنة استجابة النماذج الفردية (في هذه التجربة: YOLOv8s بزمن 3.8ms + ResNet18 بزمن 1.2ms ≈ 5ms للاستدلال الكامل).

import tensorrt as trt, pycuda.driver as cuda # التحميلINT8 engine with open("resnet18_int8.trt", "rb") as f, trt.Runtime(trt.Logger()) as r: engine = r.deserialize_cuda_engine(f.read()) ctx = engine.create_execution_context() # التخصيصGPUالذاكرة d_input = cuda.mem_alloc(1*3*224*224*4) # FP32الإدخال(الاستخدام الفعليINT8المعالجة الأولية) d_output = cuda.mem_alloc(1*6*4) stream = cuda.Stream() # حلقة الاستدلال for img in camera_stream(): cuda.memcpy_htod_async(d_input, preprocess(img), stream) ctx.execute_async_v2([int(d_input), int(d_output)], stream.handle) cuda.memcpy_dtoh_async(output, d_output, stream) stream.synchronize() result = postprocess(output) # الفئة+درجة الثقة push_to_hmi(result) # الإرسال إلى الرافعة العلويةHMIالعرض

حالة نشر واقعية في مصنع صلب

في مشروع الكشف البصري الذكي بالذكاء الاصطناعي لحبال الرفع في 17 رافعة علوية بأحد مصانع الصلب (رقم المشروع KL-EDGE-2024-003)، تم تثبيت جهاز Jetson Orin NX على كل رافعة علوية (بتكلفة 1,900 درهم إماراتي للجهاز الواحد). تم تركيب كاميرتين صناعيتين على كل رافعة علوية (طراز Basler acA2440-75um، لالتقاط صور لكامل أطوال الحبل السلكي)، ويعمل على Jetson خط إنتاج YOLOv8s+ResNet18 (لكشف مواضع كسر الأسلاك وتصنيف درجة الخطورة). يبلغ زمن استجابة الاستدلال الكامل 5.0ms (خط إنتاج مزدوج النماذج)، ويتم معالجة حوالي 14,400 صورة يوميًا (كاميرتان × صورة كل 5 ثوانٍ × 10 ساعات). على مدى 14 شهرًا من التشغيل المتواصل (من يناير 2025 إلى فبراير 2026): اكتشف النظام 328 حالة كسر في الأسلاك، وأكد المراجعون البشريون 307 حالات منها (دقة 93.6%)، مع 8 حالات لم يتم اكتشافها (معدل استدعاء 97.5%). وبالمقارنة مع الفحص اليومي اليدوي (فحص بصري واحد يوميًا لكل رافعة علوية، بمعدل اكتشاف لكسر الأسلاك يبلغ حوالي 40%)، فإن معدل اكتشاف الفحص التلقائي بالذكاء الاصطناعي أعلى بمقدار 2.3 مرة.


مقارنة حلول النشر: خادم GPU مقابل الاستدلال الطرفي

يعتمد اختيار حل النشر على قيود الظروف الميدانية — فيما يلي مقارنة لمزايا وعيوب أربعة حلول:

عنصر المقارنة الحلA:GPUخادم الحلB:ONNX Runtime CPU الحلC:TensorRT FP16 الحلD:TensorRT INT8
منصة العتادNVIDIA A10/RTX 4090صناعيPC (i7-12700)Jetson Orin NX 16GBJetson Orin NX 16GB
حجم النموذج45MB (FP32)44MB (ONNX FP32)12MB (FP16)6.2MB (INT8)
زمن الاستدلال~5ms(صورة واحدة224×224)~25ms~2.5ms~1.2ms
استهلاك الطاقة350W65W12~15W12~15W
Top-1دقة94.0%93.9%93.8%93.6%
تكلفة العتاد¥80,000+¥8,000~15,000¥3,500¥3,500
موقع النشرغرفة الخوادم(يتطلب تكييف هواء)غرفة التحكم/غرفة التوزيع الكهربائيلوحة كهربائية للرافعة العلويةداخليلوحة كهربائية للرافعة العلويةداخلي
تعقيد التشغيل والصيانةمرتفع(توافق المشغلات/إدارة البيئة)متوسط(نظام التشغيلالصيانة)منخفض(جاهز للاستخدام بعد التثبيت)منخفض(جاهز للاستخدام بعد التثبيت)
سيناريو موصى بهتدريب النموذج/استدلال دفعي دون اتصالموجودحاسوب صناعيوغير حساس لزمن الاستجابةدقةنشر طرفي ذو أولويةالخيار الأمثل من حيث القيمة مقابل السعر

شروط الاختبار: ResNet-18، الإدخال 224×224، batch=1. خادم GPU: NVIDIA A10 (48GB)، CUDA 12.1، PyTorch 2.1.0. ONNX Runtime CPU: i7-12700، ONNX Runtime 1.16. Jetson: Orin NX 16GB، JetPack 6.0، TensorRT 8.6. زمن الاستجابة هو متوسط 1000 عملية استدلال.

الأسئلة الشائعة حول نشر نماذج الرؤية الحاسوبية

س: هل فقدان الدقة بسبب تكميم TensorRT INT8 مقبول؟

ج: في هذه التجربة، انخفضت دقة Top-1 لـ INT8 مقارنة بـ FP32 من 94.0% إلى 93.6% (خسارة 0.4%)، وانخفض F1 من 0.93 إلى 0.92 (خسارة 0.01). في السيناريوهات الصناعية، فإن خسارة دقة 0.4% مقابل ضغط الحجم بمقدار 7.5 مرات وتسريع الاستدلال بمقدار 4.2 مرات أمر يستحق العناء تمامًا. إذا تجاوز فقدان الدقة لفئة عيب معينة 1% (مثل انخفاض كسر الحبل السلكي من 92% إلى 90%)، يُنصح باستخدام استدلال FP16 لهذه الفئة بشكل منفصل أو زيادة نسبة عينات هذه الفئة في مجموعة بيانات معايرة INT8.

س: كيف يمكن تنفيذ خط أنابيب متعدد النماذج (كشف YOLO + تصنيف ResNet) على Jetson؟

ج: استخدم CudaStream و CUDA Graph من TensorRT لتنفيذ خط أنابيب متعدد النماذج. الخطوات: ① إنشاء دفقين CudaStream (stream1=YOLO، stream2=ResNet)؛ ② يعمل YOLO على stream1، وتنفيذ NMS على وحدة المعالجة المركزية (يستغرق حوالي 0.5ms)، وقص منطقة الكشف، وإرسال النتيجة المقصوصة إلى تصنيف ResNet على stream2؛ ③ مزامنة الدفقين عبر CUDA Event. زمن الاستجابة من البداية إلى النهاية حوالي 60% من مجموع زمن استجابة كل نموذج (تداخل استدلال GPU ومعالجة CPU اللاحقة).

س: ما هي الأخطاء الشائعة عند تصدير ONNX؟

ج: ثلاثة مشاكل شائعة: ① الأبعاد الديناميكية — ONNX يثبّت أبعاد الإدخال افتراضيًا، يجب تعيين معامل dynamic_axes لدعم تغيير الأبعاد (مثل التبديل بين 224×224 و416×416)؛ ② تدفق التحكم — حلقات if/for في PyTorch يجب استبدالها بـ torch.where/torch.arange (ONNX لا يدعم تدفق التحكم في Python)؛ ③ العوامل المخصصة — يجب تسجيل torch.autograd.Function المخصص في ONNX symbolic. يُنصح باستخدام الواجهة الخلفية الجديدة torch.onnx.export(…, dynamo=True) للتصدير (PyTorch 2.1+).

س: هل يمكن لأجهزة Jetson العمل بثبات على المدى الطويل داخل خزانة تحكم الرافعة؟

ج: نعم. تدعم نسخة Jetson Orin NX الصناعية (JetPack 6.0) نطاق درجة حرارة واسع من -25°C إلى 80°C، ورطوبة 5~95% بدون تكاثف، ومقاومة اهتزاز 50G. في النشر الفعلي، تم استخدام تبريد سلبي (مبرد من سبائك الألومنيوم بأبعاد 145×80×35mm) + غطاء وقائي IP54 مثبت على الجدار الداخلي للخزانة الكهربائية. تم نشرها على 17 رافعة علوية (مشروع KL-EDGE-2024-003)، مع أطول تشغيل مستمر 14 شهرًا بدون أعطال (حتى فبراير 2026). درجة حرارة وحدة المعالجة المركزية مستقرة عند 65~72°C (داخل خزانة كهربائية بدرجة حرارة محيطة 35°C).

مقالات ذات صلة

contact

contact us

phone:
+86 13903802779

mail:3915269@qq.com

Working hours: Monday to Friday

Wechat
Wechat
SHARE
TOP