يُعد نشر نماذج رؤية الكمبيوتر على الأجهزة الطرفية تحدياً فريداً. بينما حدد YOLOv8 (You Only Look Once version 8) معياراً جديداً للدقة والسرعة في كشف الكائنات، فإن تشغيل نموذج بدقة كاملة على أجهزة محدودة الموارد مثل NVIDIA Jetson أو Raspberry Pi أو الأجهزة المحمولة غالباً ما يؤدي إلى تأخير غير مقبول. في التطبيقات التي تتراوح بين الروبوتات المستقلة وتحليل الفيديو في الوقت الفعلي، كل جزء من الألف من الثانية يهم. يستكشف هذا المنشور الاستراتيجيات المعمارية وتقنيات التحسين العملية المطلوبة لتحويل نموذج YOLOv8 القياسي إلى نشر عالي الأداء على الحافة.
تحدي النشر على الحافة
تعمل الأجهزة الطرفية عادةً تحت قيود صارمة فيما يتعلق باستهلاك الطاقة، والحدود الحرارية، والموارد الحسابية (FLOPs). بينما يُعد نموذج YOLOv8 القياسي مبنيًا على PyTorch ممتازًا للتدريب والاستدلال على وحدات معالجة الرسومات (GPUs)، إلا أنه غالبًا ما يكون ثقيلًا جدًا للنشر المباشر على الحافة. تشمل الاختناقات الرئيسية ما يلي:
- عرض النطاق الترددي للذاكرة: نقل موترات كبيرة بين الذاكرة العشوائية (RAM) ووحدة معالجة الرسومات/وحدة المعالجة المركزية مكلف.
- قيود الحساب: غالبًا ما تفتقر وحدات معالجة Tensor الطرفية (TPUs) ووحدات معالجة التسريع (NPUs) إلى الإنتاجية اللازمة لإجراء عمليات النقطة العائمة بدقة كاملة.
- حساسية التأخير: تتطلب خطوط الأنابيب في الوقت الفعلي معالجة متسقة للإطارات، وليس فقط معدل إطارات متوسط عالٍ.
لمعالجة هذه القضايا، يجب علينا التخطي إلى ما وراء التصدير البسيط للنموذج والانخراط في خط أنابيب تحسين شامل يتضمن تحويل التنسيق، والتكميم، وتسريع مخصص للأجهزة.
الخطوة 1: التصدير إلى ONNX لحيادية الأجهزة
الخطوة الأولى في التحسين هي تحويل النموذج من إطار العمل الأصلي (PyTorch) إلى تمثيل وسيطي مثل ONNX (Open Neural Network Exchange). يعمل ONNX كتنسيق عالمي يسمح لنا بالاستفادة من محركات الاستدلال وأدوات التحسين المختلفة دون إعادة كتابة بنية النموذج.
باستخدام واجهة سطر الأوامر (CLI) الخاصة بـ Ultralytics، يكون التصدير إلى ONNX أمرًا بسيطًا:
yolo export model=yolov8n.pt format=onnx opset=11 simplify=true
تفعّل العلامة simplify=true أداة ONNX Simplifier، والتي تقوم بتحسينات على الرسم البياني مثل طي الثوابت ودمج المشغلين، مما يقلل من حجم الرسم البياني الحسابي قبل المعالجة الإضافية.
الخطوة 2: التكميم للدقة المخفضة
يُعد التكميم التقنية الأكثر تأثيرًا في تحسين الحافة. فهو يقلل من الدقة الرقمية لمعاملات النموذج وتنشيطاته. بينما يتم تدريب YOLOv8 بـ FP32 (نقطة عائمة 32 بت)، تتفوق الأجهزة الطرفية في استدلال INT8 (عدد صحيح 8 بت). يمكن أن يؤدي هذا إلى تقليل حجم النموذج بنسبة تصل إلى 75٪ وتسريع سرعات الاستدلال بشكل كبير.
هناك نهجان رئيسيان:
- التكميم بعد التدريب (PTQ): يحول أوزان النموذج إلى INT8 دون إعادة التدريب. هذه الطريقة سريعة ولكنها قد تقلل الدقة قليلاً.
- التدريب الواعي بالتكميم (QAT): يحاكي التكميم أثناء التدريب للسماح للأوزان بالتكيف، مما يحافظ على الدقة بشكل أفضل من PTQ.
بالنسبة لمعظم حالات الاستخدام على الحافة، يكون PTQ كافيًا. عند استخدام TensorRT، يتم التعامل مع ذلك تلقائيًا أثناء مرحلة بناء المحرك، ولكن يجب عليك توفير مجموعة بيانات معايرة لضمان أن النطاق الديمني للقيم INT8 يتطابق مع توزيع بياناتك.
الخطوة 3: التسريع المخصص للأجهزة باستخدام TensorRT
إذا كانت جهاز الحافة الخاص بك يستخدم وحدة معالجة رسومات من NVIDIA، فإن TensorRT هو المعيار الذهبي لتسريع الاستدلال. يقوم بدمج الطبقات، والضبط التلقائي للنواة، ومعايرة الدقة لإنشاء محرك استدلال محسن.
إليك كيفية بناء محرك TensorRT من نموذج ONNX الخاص بك:
# Using trtexec command line tool
trtexec --onnx=yolov8n.onnx \
--saveEngine=yolov8n.engine \
--fp16 \
--int8 \
--calib=input_tensor_batch.bin \
--workspace=1024
يحول هذا الأمر نموذج ONNX إلى FP16 (نقطة عائمة نصفية) ثم يقوم بمعايرته لـ INT8. ملف .engine الناتج محسن خصيصًا لهندسة وحدة معالجة الرسومات الخاصة بك، مما يوفر أقل تأخير ممكن.
التطبيق العملي: حلقة الاستدلال
تحسين النموذج هو نصف المعركة؛ يجب أن يكون خط أنابيب الاستدلال نفسه فعالاً. استخدم المعالجة غير المتزامنة للمجموعات وتجميع الذاكرة لتقليل الحمل الزائد.
import tensorrt as trt
import pycuda.driver as cuda
import numpy as np
# Initialize TensorRT engine
engine = trt.Runtime(logger).deserialize_engine(open("yolov8n.engine", "rb").read())
context = engine.create_execution_context()
# Pre-allocate host and device memory
input_buffer = cuda.mem_alloc(1 * 3 * 640 * 640 * 4) # FP32 example
output_buffer = cuda.mem_alloc(1 * 300 * 6 * 4)
def infer(frame):
# Preprocess frame (resize, normalize, transpose)
data = preprocess(frame)
# Asynchronous memory copy
cuda.memcpy_htod_async(input_buffer, data, stream)
# Execute inference
context.execute_async_v3 bindings=[int(input_buffer), int(output_buffer)], stream_handle=stream.handle
# Retrieve results
results = np.empty(300 * 6, dtype=np.float32)
cuda.memcpy_dtoh_async(results, output_buffer, stream)
stream.synchronize()
return postprocess(results)
الخاتمة
لا يعد تحسين YOLOv8 للنشر على الحافة خطوة واحدة، بل هو عملية متعددة المراحل تتضمن التصدير، والتكميم، والضبط المخصص للأجهزة. من خلال الاستفادة من ONNX للتشغيل البيني، والتكميم للكفاءة، وTensorRT للتسريع، يمكن للمطورين تحقيق أداء في الوقت الفعلي حتى على الأجهزة المقيدة. مع استمرار تطور الذكاء الاصطناعي على الحافة، سيكون إتقان هذه تقنيات التحسين أمرًا أساسيًا لبناء تطبيقات رؤية كمبيوتر مسؤولة وقابلة للتوسع وفعالة. ابدأ بـ PTQ لتحقيق مكاسب سريعة، وتدرج إلى QAT والنوى المخصصة كلما دعت متطلبات الأداء إلى ذلك.