Link to this sectionالاستدلال الآمن خيطياً باستخدام نماذج YOLO#
يتطلب تشغيل نماذج YOLO في بيئة متعددة الخيوط (multi-threaded) دراسة متأنية لضمان الأمان الخيطي. تتيح لك وحدة threading في Python تشغيل عدة خيوط في وقت واحد، ولكن عند استخدام نماذج YOLO عبر هذه الخيوط، هناك مشكلات أمان مهمة يجب أن تكون على دراية بها. سترشدك هذه الصفحة خلال عملية إنشاء استدلال آمن خيطياً باستخدام نموذج YOLO.
Watch: How to Perform Thread Safe Inference with Ultralytics YOLO Models in Python | Multi-Threading 🚀
Link to this sectionفهم خيوط المعالجة في Python#
خيوط المعالجة في Python هي شكل من أشكال التوازي الذي يسمح لبرنامجك بتنفيذ عمليات متعددة في وقت واحد. ومع ذلك، فإن قفل المفسر العام (GIL) في Python يعني أن خيطاً واحداً فقط يمكنه تنفيذ بايت كود Python في كل مرة.
على الرغم من أن هذا يبدو كقيد، إلا أن الخيوط لا تزال قادرة على توفير التزامن، خاصة للعمليات المرتبطة بـ I/O أو عند استخدام عمليات تقوم بتحرير GIL، مثل تلك التي تؤديها مكتبات C الأساسية في YOLO.
Link to this sectionخطر مثيلات النماذج المشتركة#
إن إنشاء مثيل لنموذج YOLO خارج خيوط المعالجة ومشاركة هذا المثيل عبر خيوط متعددة يمكن أن يؤدي إلى ظروف سباق (race conditions)، حيث يتم تعديل الحالة الداخلية للنموذج بشكل غير متسق بسبب الوصول المتزامن. يمثل هذا مشكلة خاصة عندما يحتفظ النموذج أو مكوناته بحالة لم يتم تصميمها لتكون آمنة خيطياً.
Link to this sectionمثال غير آمن خيطياً: مثيل نموذج واحد#
عند استخدام الخيوط في 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("yolo26n.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 يمكن تنفيذها في وقت واحد بواسطة خيوط متعددة.
Link to this sectionمثال غير آمن خيطياً: مثيلات نماذج متعددة#
وبالمثل، إليك نمط غير آمن مع مثيلات نماذج 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("yolo26n_1.pt")
shared_model_2 = YOLO("yolo26n_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 آمناً خيطياً، فقد لا يمنع استخدام مثيلات منفصلة ظروف السباق، خاصة إذا كانت هذه المثيلات تشترك في أي موارد أساسية أو حالات ليست محلية للخيط (thread-local).
Link to this sectionالاستدلال الآمن خيطياً#
لإجراء استدلال آمن خيطياً، يجب عليك إنشاء مثيل منفصل لنموذج YOLO داخل كل خيط. يضمن هذا أن كل خيط لديه مثيل نموذج خاص به ومعزول، مما يلغي خطر حدوث ظروف سباق.
Link to this sectionمثال آمن خيطياً#
إليك كيفية إنشاء مثيل لنموذج 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("yolo26n.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 الخاص به. هذا يمنع أي خيط من التدخل في حالة نموذج خيط آخر، مما يضمن أن كل خيط يؤدي الاستدلال بأمان ودون تفاعلات غير متوقعة مع الخيوط الأخرى.
Link to this sectionاستخدام المصمم ThreadingLocked#
يوفر Ultralytics مصمماً (decorator) يسمى ThreadingLocked يمكن استخدامه لضمان التنفيذ الآمن خيطياً للوظائف. يستخدم هذا المصمم قفلاً لضمان أن خيطاً واحداً فقط في كل مرة يمكنه تنفيذ الوظيفة المزينة.
from ultralytics import YOLO
from ultralytics.utils import ThreadingLocked
# Create a model instance
model = YOLO("yolo26n.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 مفيداً بشكل خاص عندما تحتاج إلى مشاركة مثيل نموذج عبر الخيوط ولكنك تريد التأكد من أن خيطاً واحداً فقط يمكنه الوصول إليه في كل مرة. يمكن أن يوفر هذا النهج في الذاكرة مقارنة بإنشاء مثيل نموذج جديد لكل خيط، ولكنه قد يقلل من التزامن حيث ستحتاج الخيوط إلى انتظار تحرير القفل.
Link to this sectionالخلاصة#
عند استخدام نماذج YOLO مع threading في Python، قم دائماً بإنشاء مثيلات النماذج الخاصة بك داخل الخيط الذي سيستخدمها لضمان الأمان الخيطي. تتجنب هذه الممارسة ظروف السباق وتضمن تشغيل مهام الاستدلال الخاصة بك بشكل موثوق.
للحصول على سيناريوهات أكثر تقدماً ولزيادة تحسين أداء الاستدلال متعدد الخيوط لديك، ضع في اعتبارك استخدام التوازي القائم على العمليات مع multiprocessing أو الاستفادة من طابور مهام مع عمليات عاملة مخصصة.
Link to this sectionالأسئلة الشائعة#
Link to this sectionكيف يمكنني تجنب ظروف السباق عند استخدام نماذج 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("yolo26n.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.
Link to this sectionما هي أفضل الممارسات لتشغيل استدلال نموذج YOLO متعدد الخيوط في Python؟#
لتشغيل استدلال نموذج YOLO متعدد الخيوط بأمان في Python، اتبع أفضل الممارسات التالية:
- قم بإنشاء نماذج YOLO داخل كل خيط بدلاً من مشاركة مثيل نموذج واحد عبر الخيوط.
- استخدم وحدة
multiprocessingفي Python للمعالجة المتوازية لتجنب المشكلات المتعلقة بقفل المفسر العام (GIL). - قم بتحرير GIL باستخدام عمليات تؤديها مكتبات C الأساسية في YOLO.
- فكر في استخدام المصمم
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("yolo26n.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()للحصول على سياق إضافي، راجع القسم الخاص بـ الاستدلال الآمن خيطياً.
Link to this sectionلماذا يجب أن يكون لكل خيط مثيل نموذج YOLO خاص به؟#
يجب أن يكون لكل خيط مثيل نموذج YOLO خاص به لمنع ظروف السباق. عندما تتم مشاركة مثيل نموذج واحد بين خيوط متعددة، يمكن أن تؤدي عمليات الوصول المتزامنة إلى سلوك غير متوقع وتعديلات على الحالة الداخلية للنموذج. باستخدام مثيلات منفصلة، تضمن عزل الخيوط، مما يجعل مهامك متعددة الخيوط موثوقة وآمنة.
للحصول على إرشادات مفصلة، تحقق من قسمي مثال غير آمن خيطياً: مثيل نموذج واحد ومثال آمن خيطياً.
Link to this sectionكيف يؤثر قفل المفسر العام (GIL) في Python على استدلال نموذج YOLO؟#
يسمح قفل المفسر العام (GIL) في Python لخيط واحد فقط بتنفيذ بايت كود Python في كل مرة، مما قد يحد من أداء مهام المعالجة المتعددة المرتبطة بـ CPU. ومع ذلك، بالنسبة للعمليات المرتبطة بـ I/O أو العمليات التي تستخدم مكتبات تقوم بتحرير GIL، مثل مكتبات C الأساسية في YOLO، لا يزال بإمكانك تحقيق التزامن. للحصول على أداء محسّن، فكر في استخدام التوازي القائم على العمليات مع وحدة multiprocessing في Python.
لمزيد من المعلومات حول الخيوط في Python، راجع قسم فهم خيوط المعالجة في Python.
Link to this sectionهل من الأكثر أماناً استخدام التوازي القائم على العمليات بدلاً من الخيوط لاستدلال نموذج YOLO؟#
نعم، استخدام وحدة multiprocessing في Python أكثر أماناً وغالباً ما يكون أكثر كفاءة لتشغيل استدلال نموذج YOLO بالتوازي. يخلق التوازي القائم على العمليات مساحات ذاكرة منفصلة، مما يتجنب قفل المفسر العام (GIL) ويقلل من خطر مشكلات التزامن. ستعمل كل عملية بشكل مستقل مع مثيل نموذج YOLO الخاص بها.
لمزيد من التفاصيل حول التوازي القائم على العمليات مع نماذج YOLO، راجع الصفحة الخاصة بـ الاستدلال الآمن خيطياً.