تخطي إلى المحتوى

استدلال آمن للخيوط مع نماذج YOLO

يتطلب تشغيل نماذج YOLO في بيئة متعددة الخيوط دراسة متأنية لضمان سلامة الخيوط. Python threading تتيح لك الوحدة تشغيل عدة سلاسل عمليات في وقت واحد، ولكن عندما يتعلق الأمر باستخدام نماذج YOLO عبر سلاسل العمليات هذه، هناك مشكلات أمان مهمة يجب الانتباه إليها. سترشدك هذه الصفحة خلال إنشاء استدلال نموذج YOLO آمن لسلاسل العمليات.



شاهد: كيفية إجراء استدلال آمن للخيوط باستخدام نماذج Ultralytics YOLO في python | تعدد الخيوط 🚀

فهم عملية تفرّع python

تعتبر سلاسل Python شكلاً من أشكال التوازي التي تسمح لبرنامجك بتشغيل عمليات متعددة في وقت واحد. ومع ذلك، فإن قفل المفسر العام (GIL) الخاص بـ Python يعني أنه لا يمكن إلا لسلسلة واحدة تنفيذ رمز Python byte في كل مرة.

أمثلة لخيط واحد مقابل خيوط متعددة

في حين أن هذا يبدو وكأنه قيد، إلا أن سلاسل العمليات لا تزال قادرة على توفير التزامن، خاصة بالنسبة للعمليات المرتبطة بالإدخال/الإخراج أو عند استخدام العمليات التي تحرر GIL، مثل تلك التي تنفذها مكتبات C الأساسية في YOLO.

خطر مثيلات النموذج المشتركة

يمكن أن يؤدي إنشاء نموذج YOLO خارج الخيوط الخاصة بك ومشاركة هذا المثيل عبر خيوط متعددة إلى حالات سباق، حيث يتم تعديل الحالة الداخلية للنموذج بشكل غير متناسق بسبب الوصول المتزامن. هذا يمثل إشكالية خاصة عندما يحتفظ النموذج أو مكوناته بحالة غير مصممة لتكون آمنة للخيوط.

مثال غير آمن للخيوط: مثيل نموذج واحد

عند استخدام سلاسل الرسائل في Python، من المهم التعرف على الأنماط التي يمكن أن تؤدي إلى مشكلات التزامن. إليك ما يجب عليك تجنبه: مشاركة مثيل نموذج YOLO واحد عبر سلاسل رسائل متعددة.

# Unsafe: Sharing a single model instance across threads
from threading import Thread

from ultralytics import YOLO

# Instantiate the model outside the thread
shared_model = YOLO("yolo11n.pt")


def predict(image_path):
    """Predicts objects in an image using a preloaded YOLO model, take path string to image as argument."""
    results = shared_model.predict(image_path)
    # Process results


# Starting threads that share the same model instance
Thread(target=predict, args=("image1.jpg",)).start()
Thread(target=predict, args=("image2.jpg",)).start()

في المثال أعلاه، shared_model يتم استخدامه بواسطة عدة سلاسل عمليات، مما قد يؤدي إلى نتائج غير متوقعة بسبب predict يمكن تنفيذه في وقت واحد بواسطة مؤشرات ترابط متعددة.

مثال غير آمن للخيوط: مثيلات نماذج متعددة

وبالمثل، إليك نمط غير آمن مع مثيلات متعددة لنموذج YOLO:

# Unsafe: Sharing multiple model instances across threads can still lead to issues
from threading import Thread

from ultralytics import YOLO

# Instantiate multiple models outside the thread
shared_model_1 = YOLO("yolo11n_1.pt")
shared_model_2 = YOLO("yolo11n_2.pt")


def predict(model, image_path):
    """Runs prediction on an image using a specified YOLO model, returning the results."""
    results = model.predict(image_path)
    # Process results


# Starting threads with individual model instances
Thread(target=predict, args=(shared_model_1, "image1.jpg")).start()
Thread(target=predict, args=(shared_model_2, "image2.jpg")).start()

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

الاستدلال الآمن لسير العمليات

لتنفيذ استدلال آمن لسير العمليات، يجب عليك إنشاء نموذج YOLO منفصل داخل كل سير عمل. يضمن ذلك أن يكون لكل سير عمل نسخة نموذج معزولة خاصة به، مما يمنع خطر ظروف السباق.

مثال آمن للخيوط

إليك كيفية إنشاء نموذج YOLO داخل كل سلسلة رسائل للاستدلال المتوازي الآمن:

# Safe: Instantiating a single model inside each thread
from threading import Thread

from ultralytics import YOLO


def thread_safe_predict(image_path):
    """Predict on an image using a new YOLO model instance in a thread-safe manner; takes image path as input."""
    local_model = YOLO("yolo11n.pt")
    results = local_model.predict(image_path)
    # Process results


# Starting threads that each have their own model instance
Thread(target=thread_safe_predict, args=("image1.jpg",)).start()
Thread(target=thread_safe_predict, args=("image2.jpg",)).start()

في هذا المثال، تقوم كل سلسلة رسائل بإنشاء YOLO مثيل. يمنع هذا أي مؤشر ترابط من التدخل في حالة نموذج آخر، وبالتالي يضمن أن كل مؤشر ترابط يقوم بالاستدلال بأمان ودون تفاعلات غير متوقعة مع مؤشرات الترابط الأخرى.

استخدام ThreadingLocked Decorator

توفر Ultralytics ThreadingLocked أداة تزيين يمكن استخدامها لضمان تنفيذ الوظائف بشكل آمن لسلاسل العمليات. تستخدم أداة التزيين هذه قفلًا لضمان إمكانية تنفيذ سلسلة عمليات واحدة فقط للوظيفة المزخرفة في كل مرة.

from ultralytics import YOLO
from ultralytics.utils import ThreadingLocked

# Create a model instance
model = YOLO("yolo11n.pt")


# Decorate the predict method to make it thread-safe
@ThreadingLocked()
def thread_safe_predict(image_path):
    """Thread-safe prediction using a shared model instance."""
    results = model.predict(image_path)
    return results


# Now you can safely call this function from multiple threads

في ThreadingLocked تُعد أداة التزيين مفيدة بشكل خاص عندما تحتاج إلى مشاركة نموذج عبر سلاسل العمليات ولكنك تريد التأكد من أن سلسلة عمليات واحدة فقط يمكنها الوصول إليه في كل مرة. يمكن لهذا الأسلوب توفير الذاكرة مقارنة بإنشاء نموذج جديد لكل سلسلة عمليات، ولكنه قد يقلل من التزامن حيث ستحتاج سلاسل العمليات إلى انتظار تحرير القفل.

الخلاصة

عند استخدام نماذج YOLO مع threading، قم دائمًا بإنشاء نماذجك داخل سلسلة العمليات (thread) التي ستستخدمها لضمان سلامة سلسلة العمليات (thread safety). تتجنب هذه الممارسة حالات السباق وتضمن تشغيل مهام الاستدلال الخاصة بك بشكل موثوق.

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

الأسئلة الشائعة

كيف يمكنني تجنب حالات التعارض عند استخدام نماذج YOLO في بيئة python متعددة الخيوط؟

لمنع ظروف السباق عند استخدام نماذج Ultralytics YOLO في بيئة python متعددة الخيوط، قم بإنشاء نموذج YOLO منفصل داخل كل خيط. يضمن ذلك أن يكون لكل خيط نسخة نموذج معزولة خاصة به، مما يتجنب التعديل المتزامن لحالة النموذج.

مثال:

from threading import Thread

from ultralytics import YOLO


def thread_safe_predict(image_path):
    """Predict on an image in a thread-safe manner."""
    local_model = YOLO("yolo11n.pt")
    results = local_model.predict(image_path)
    # Process results


Thread(target=thread_safe_predict, args=("image1.jpg",)).start()
Thread(target=thread_safe_predict, args=("image2.jpg",)).start()

لمزيد من المعلومات حول ضمان سلامة مؤشرات الترابط، تفضل بزيارة الاستدلال الآمن لمؤشرات الترابط مع نماذج YOLO.

ما هي أفضل الممارسات لتشغيل استدلال نموذج YOLO متعدد الخيوط في Python؟

لتشغيل استدلال نموذج YOLO متعدد الخيوط بأمان في Python، اتبع أفضل الممارسات التالية:

  1. قم بإنشاء نماذج YOLO داخل كل مؤشر ترابط بدلاً من مشاركة مثيل نموذج واحد عبر مؤشرات الترابط.
  2. استخدم وظيفة Python multiprocessing الوحدة للمعالجة المتوازية لتجنب المشكلات المتعلقة بقفل المترجم العام (GIL).
  3. إطلاق سراح GIL باستخدام العمليات التي تنفذها مكتبات C الأساسية لـ YOLO.
  4. ضع في اعتبارك استخدام ThreadingLocked ديكور لمثيلات النموذج المشتركة عندما تكون الذاكرة مصدر قلق.

مثال لإنشاء نموذج آمن لسير العمل:

from threading import Thread

from ultralytics import YOLO


def thread_safe_predict(image_path):
    """Runs inference in a thread-safe manner with a new YOLO model instance."""
    model = YOLO("yolo11n.pt")
    results = model.predict(image_path)
    # Process results


# Initiate multiple threads
Thread(target=thread_safe_predict, args=("image1.jpg",)).start()
Thread(target=thread_safe_predict, args=("image2.jpg",)).start()

لسياق إضافي، ارجع إلى القسم الخاص بـ الاستدلال الآمن بالخيوط.

لماذا يجب أن يكون لكل سلسلة رسائل مثيل نموذج YOLO خاص بها؟

يجب أن يكون لكل سلسلة عمليات مثيل نموذج YOLO خاص بها لمنع حالات السباق. عندما تتم مشاركة مثيل نموذج واحد بين سلاسل عمليات متعددة، يمكن أن تؤدي الوصولات المتزامنة إلى سلوك غير متوقع وتعديلات في الحالة الداخلية للنموذج. باستخدام مثيلات منفصلة، فإنك تضمن عزل السلاسل، مما يجعل مهامك متعددة السلاسل موثوقة وآمنة.

للحصول على إرشادات مفصلة، تحقق من قسم مثال غير آمن للمؤشرات: مثيل نموذج واحد وقسم مثال آمن للمؤشرات.

كيف يؤثر قفل المفسر العام (GIL) الخاص بـ Python على استدلال نموذج YOLO؟

يسمح قفل المفسر العام (GIL) الخاص ببايثون بتنفيذ سلسلة رسائل واحدة فقط لتعليمات بايثون البرمجية في كل مرة، مما قد يحد من أداء مهام تعدد مؤشرات الترابط المرتبطة بوحدة المعالجة المركزية. ومع ذلك، بالنسبة للعمليات المرتبطة بالإدخال/الإخراج أو العمليات التي تستخدم المكتبات التي تحرر GIL، مثل مكتبات C الأساسية لـ YOLO، لا يزال بإمكانك تحقيق التزامن. ولتحسين الأداء، ضع في اعتبارك استخدام التوازي القائم على العمليات مع وحدة المعالجة المتعددة الخاصة ببايثون. multiprocessing الوحدة.

لمعرفة المزيد حول استخدام الخيوط في Python، راجع قسم فهم استخدام الخيوط في Python.

هل من الأسلم استخدام التوازي القائم على العمليات بدلاً من استخدام سلاسل العمليات للاستدلال على نموذج YOLO؟

نعم، باستخدام multiprocessing تعتبر الوحدة أكثر أمانًا وغالبًا ما تكون أكثر كفاءة لتشغيل استدلال نموذج YOLO بالتوازي. تخلق الموازاة القائمة على العمليات مساحات ذاكرة منفصلة، وتتجنب قفل المترجم العام (GIL) وتقلل من خطر مشكلات التزامن. ستعمل كل عملية بشكل مستقل مع مثيل نموذج YOLO الخاص بها.

لمزيد من التفاصيل حول التوازي القائم على العمليات مع نماذج YOLO، راجع الصفحة الخاصة بـ الاستدلال الآمن بالخيوط.



📅 تم الإنشاء منذ سنة واحدة ✏️ تم التحديث منذ شهرين

تعليقات