Saltar al contenido

Inferencia a prueba de hilos con modelos YOLO

Ejecutar los modelos YOLO en un entorno multihilo requiere una cuidadosa consideración para garantizar la seguridad de los hilos. Python's threading te permite ejecutar varios subprocesos simultáneamente, pero cuando se trata de utilizar modelos YOLO en estos subprocesos, hay que tener en cuenta importantes cuestiones de seguridad. Esta página te guiará en la creación de la inferencia de modelos YOLO a prueba de hilos.

Comprender el roscado Python

Python Los hilos son una forma de paralelismo que permite a tu programa ejecutar varias operaciones a la vez. Sin embargo, Python's Global Interpreter Lock (GIL) significa que sólo un hilo puede ejecutar Python bytecode a la vez.

Ejemplos de un solo hilo frente a varios hilos

Aunque esto parezca una limitación, los subprocesos pueden proporcionar concurrencia, especialmente para operaciones de E/S o cuando se utilizan operaciones que liberan el GIL, como las que realizan las bibliotecas C subyacentes de YOLO.

El peligro de las instancias modelo compartidas

Instanciar un modelo YOLO fuera de tus subprocesos y compartir esta instancia entre varios subprocesos puede provocar condiciones de carrera, en las que el estado interno del modelo se modifica de forma incoherente debido a accesos concurrentes. Esto es especialmente problemático cuando el modelo o sus componentes contienen un estado que no está diseñado para ser seguro para los subprocesos.

Ejemplo no seguro: Una sola instancia del modelo

Cuando utilices hilos en Python, es importante reconocer los patrones que pueden provocar problemas de concurrencia. Esto es lo que debes evitar: compartir una única instancia del modelo YOLO entre varios subprocesos.

# 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("yolov8n.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()

En el ejemplo anterior, el shared_model es utilizado por varios subprocesos, lo que puede dar lugar a resultados impredecibles porque predict podría ser ejecutado simultáneamente por varios hilos.

Ejemplo no seguro: Múltiples instancias del modelo

Del mismo modo, aquí tienes un patrón inseguro con varias instancias del modelo 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("yolov8n_1.pt")
shared_model_2 = YOLO("yolov8n_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()

Aunque haya dos instancias del modelo separadas, sigue existiendo el riesgo de problemas de concurrencia. Si la implementación interna de YOLO no es seguro para los subprocesos, el uso de instancias separadas podría no evitar las condiciones de carrera, especialmente si estas instancias comparten recursos o estados subyacentes que no son locales para los subprocesos.

Inferencia segura de hilos

Para realizar una inferencia a prueba de hilos, debes instanciar un modelo YOLO independiente dentro de cada hilo. Esto garantiza que cada subproceso tenga su propia instancia aislada del modelo, eliminando el riesgo de condiciones de carrera.

Ejemplo de hilo seguro

He aquí cómo instanciar un modelo YOLO dentro de cada hilo para una inferencia paralela segura:

# 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("yolov8n.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()

En este ejemplo, cada hilo crea su propio YOLO instancia. Esto impide que cualquier hilo interfiera con el estado del modelo de otro, garantizando así que cada hilo realice la inferencia de forma segura y sin interacciones inesperadas con los demás hilos.

Conclusión

Si utilizas los modelos YOLO con Python's threadinginstanciar siempre tus modelos dentro del subproceso que los utilizará para garantizar la seguridad del subproceso. Esta práctica evita las condiciones de carrera y garantiza que tus tareas de inferencia se ejecuten de forma fiable.

Para escenarios más avanzados y para optimizar aún más el rendimiento de tu inferencia multihilo, considera la posibilidad de utilizar el paralelismo basado en procesos con multiprocessing o aprovechando una cola de tareas con procesos de trabajadores dedicados.

PREGUNTAS FRECUENTES

¿Cómo puedo evitar las condiciones de carrera al utilizar modelos YOLO en un entorno multihilo Python ?

Para evitar condiciones de carrera al utilizar modelos Ultralytics YOLO en un entorno multihilo Python , instanciar un modelo YOLO separado dentro de cada hilo. Esto garantiza que cada hilo tenga su propia instancia aislada del modelo, evitando la modificación concurrente del estado del modelo.

Ejemplo:

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("yolov8n.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()

Para más información sobre cómo garantizar la seguridad de los hilos, visita Inferencia segura de hilos con modelos YOLO .

¿Cuáles son las mejores prácticas para ejecutar la inferencia del modelo YOLO multihilo en Python?

Para ejecutar la inferencia del modelo YOLO multihilo de forma segura en Python, sigue estas buenas prácticas:

  1. Instanciar modelos YOLO dentro de cada subproceso en lugar de compartir una única instancia de modelo entre subprocesos.
  2. Utiliza Python's multiprocessing para el procesamiento paralelo, a fin de evitar problemas relacionados con el Bloqueo Global del Intérprete (GIL).
  3. Libera el GIL utilizando operaciones realizadas por las bibliotecas C subyacentes de YOLO.

Ejemplo de instanciación del modelo a prueba de hilos:

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("yolov8n.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()

Para más contexto, consulta la sección sobre Inferencia segura de subprocesos.

¿Por qué debe tener cada hilo su propia instancia del modelo YOLO ?

Cada subproceso debe tener su propia instancia del modelo YOLO para evitar condiciones de carrera. Cuando se comparte una única instancia del modelo entre varios subprocesos, los accesos simultáneos pueden provocar un comportamiento impredecible y modificaciones del estado interno del modelo. Al utilizar instancias separadas, garantizas el aislamiento de los subprocesos, haciendo que tus tareas multihilo sean fiables y seguras.

Para obtener información detallada, consulta las secciones Ejemplo no seguro para subprocesos: Instancia de modelo único y Ejemplo de seguridad de subprocesos.

¿Cómo afecta el Bloqueo Global del Intérprete (GIL) de Python a la inferencia del modelo YOLO ?

PythonEl Bloqueo Global del Intérprete (GIL) sólo permite que un hilo ejecute el código de bytes de Python a la vez, lo que puede limitar el rendimiento de las tareas multihilo vinculadas a CPU. Sin embargo, para operaciones vinculadas a E/S o procesos que utilicen bibliotecas que liberen el GIL, como las bibliotecas C de YOLO, aún puedes conseguir concurrencia. Para mejorar el rendimiento, considera la posibilidad de utilizar el paralelismo basado en procesos con Python's multiprocessing módulo.

Para más información sobre el roscado en Python, consulta la sección Comprender el roscado en Python .

¿Es más seguro utilizar el paralelismo basado en procesos en lugar de hilos para la inferencia de modelos YOLO ?

Sí, utilizando Python's multiprocessing es más seguro y, a menudo, más eficaz para ejecutar en paralelo la inferencia del modelo YOLO . El paralelismo basado en procesos crea espacios de memoria separados, evitando el Bloqueo Global del Intérprete (GIL) y reduciendo el riesgo de problemas de concurrencia. Cada proceso funcionará independientemente con su propia instancia del modelo YOLO .

Para más detalles sobre el paralelismo basado en procesos con los modelos YOLO , consulta la página sobre Inferencia a prueba de hilos.



Creado 2023-11-12, Actualizado 2024-07-05
Autores: glenn-jocher (5)

Comentarios