Meet YOLO26: next-gen vision AI.

Link to this sectionInferencia segura para subprocesos con modelos YOLO#

To run Ultralytics YOLO inference safely across Python threads, instantiate a separate YOLO model inside each thread instead of sharing one instance across them. Sharing a single model causes race conditions that corrupt its internal state and produce unpredictable results, because Python's threading module runs the threads concurrently against the same object. This guide explains why sharing fails, shows the safe per-thread pattern, and covers the ThreadingLocked decorator for cases where you must share an instance.

Ve a por qué falla compartir un modelo, al patrón de inferencia segura para hilos o al decorador ThreadingLocked.



Watch: How to Perform Thread Safe Inference with Ultralytics YOLO Models in Python | Multi-Threading 🚀

Link to this sectionComprender el uso de subprocesos en Python#

Los subprocesos en Python son una forma de paralelismo que permite que tu programa ejecute varias operaciones a la vez. Sin embargo, el Bloqueo Global del Intérprete (GIL, por sus siglas en inglés) de Python significa que solo un subproceso puede ejecutar código de bytes de Python a la vez.

Single-thread vs multi-thread inference

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

Link to this sectionEl peligro de las instancias de modelos compartidas#

Crear una instancia de un modelo YOLO fuera de tus subprocesos y compartir esta instancia entre múltiples subprocesos puede provocar condiciones de carrera, donde el estado interno del modelo se modifica de manera inconsistente debido a accesos concurrentes. Esto es particularmente problemático cuando el modelo o sus componentes mantienen un estado que no está diseñado para ser seguro para subprocesos.

Link to this sectionEjemplo no seguro para subprocesos: instancia de modelo único#

Al usar hilos en Python, es importante reconocer los patrones que pueden llevar a problemas de concurrencia. Esto es lo que debes evitar: compartir una única instancia del modelo YOLO26 entre varios hilos.

# 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()

En el ejemplo anterior, shared_model es utilizado por múltiples subprocesos, lo que puede llevar a resultados impredecibles porque predict podría ser ejecutado simultáneamente por múltiples subprocesos.

Link to this sectionEjemplo seguro: una instancia dedicada por hilo#

Varias instancias de modelo por separado funcionan bien siempre que cada hilo sea propietario de su instancia y nunca la comparta con otro hilo. No importa que las instancias siguientes se creen antes de que los hilos comiencen; el único patrón inseguro es compartir una instancia entre hilos:

# Safe: each thread uses its own dedicated model instance
from threading import Thread

from ultralytics import YOLO

# Instantiate one model per thread
model_1 = YOLO("yolo26n.pt")
model_2 = YOLO("yolo26n.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

# Each thread uses a separate, dedicated model instance
Thread(target=predict, args=(model_1, "image1.jpg")).start()
Thread(target=predict, args=(model_2, "image2.jpg")).start()

Debido a que cada hilo trabaja con su propia instancia dedicada, no hay estado de modelo compartido que los hilos puedan corromper. Instanciar el modelo dentro de cada hilo, como se muestra a continuación, es simplemente la forma más fácil de garantizar que una instancia nunca se comparta accidentalmente.

Link to this sectionInferencia segura para subprocesos#

Para realizar una inferencia segura para subprocesos, debes crear una instancia de un modelo YOLO independiente dentro de cada subproceso. Esto garantiza que cada subproceso tenga su propia instancia de modelo aislada, eliminando el riesgo de condiciones de carrera.

Link to this sectionEjemplo seguro para subprocesos#

Aquí tienes cómo crear una instancia de un modelo YOLO dentro de cada subproceso 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("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()

En este ejemplo, cada subproceso crea su propia instancia de YOLO. Esto evita que cualquier subproceso interfiera con el estado del modelo de otro, asegurando así que cada subproceso realice la inferencia de forma segura y sin interacciones inesperadas con los demás subprocesos.

Link to this sectionUso del decorador ThreadingLocked#

Ultralytics proporciona un decorador ThreadingLocked que puede utilizarse para garantizar la ejecución segura para hilos de las funciones. Este decorador utiliza un bloqueo para asegurar que solo un hilo a la vez pueda ejecutar la función decorada.

from ultralytics import YOLO
from ultralytics.utils import ThreadingLocked

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

# Decorate the prediction function 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

El decorador ThreadingLocked es especialmente útil cuando necesitas compartir una instancia de modelo entre hilos pero quieres asegurarte de que solo un hilo pueda acceder a ella a la vez.

Compromiso entre memoria y concurrencia

Compartir una instancia de modelo bloqueada ahorra memoria en comparación con cargar un modelo en cada hilo, pero reduce la concurrencia porque los hilos se serializan en el bloqueo y esperan su turno. Prefiere el patrón por hilo cuando tengas memoria de sobra y desees el máximo paralelismo, y recurre a ThreadingLocked cuando la memoria del modelo sea el cuello de botella.

Link to this sectionConclusión#

Al usar modelos YOLO con el threading de Python, proporciona a cada hilo su propia instancia de modelo dedicada y nunca compartas una instancia entre hilos. Instanciar el modelo dentro del hilo que lo utiliza es la forma más sencilla de garantizar esto, evitando condiciones de carrera y manteniendo tus tareas de inferencia fiables.

Para escenarios más avanzados y para optimizar aún más el rendimiento de tu inferencia con múltiples subprocesos, considera usar paralelismo basado en procesos con multiprocessing o aprovecha una cola de tareas con procesos de trabajo dedicados.

Link to this sectionFAQ#

Link to this section¿Cómo puedo evitar las condiciones de carrera al usar modelos YOLO en un entorno Python con múltiples subprocesos?#

Para evitar condiciones de carrera al usar modelos YOLO de Ultralytics en un entorno Python con múltiples subprocesos, crea una instancia de un modelo YOLO independiente dentro de cada subproceso. Esto asegura que cada subproceso tenga su propia instancia de modelo aislada, 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("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()

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

Link to this section¿Cuáles son las mejores prácticas para ejecutar inferencias de modelos YOLO con múltiples subprocesos en Python?#

Para ejecutar la inferencia de modelos YOLO con múltiples subprocesos de forma segura en Python, sigue estas mejores prácticas:

  1. Crea instancias de los modelos YOLO dentro de cada subproceso en lugar de compartir una única instancia de modelo entre ellos.
  2. Usa el módulo multiprocessing de Python para el procesamiento paralelo y evitar problemas relacionados con el Bloqueo Global del Intérprete (GIL).
  3. Recuerda que las bibliotecas C subyacentes de YOLO (PyTorch, OpenCV) liberan automáticamente el GIL durante cálculos pesados, por lo que los hilos aún pueden ejecutar inferencia de forma concurrente.
  4. Considera usar el decorador ThreadingLocked para instancias de modelos compartidas cuando la memoria sea una preocupación.

Ejemplo para la creación segura de instancias de modelo:

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."""
    local_model = YOLO("yolo26n.pt")
    results = local_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 obtener más contexto, consulta la sección sobre Inferencia segura para subprocesos.

Link to this section¿Por qué cada subproceso debería tener su propia instancia de modelo YOLO?#

Cada subproceso debe tener su propia instancia de modelo YOLO para evitar condiciones de carrera. Cuando se comparte una única instancia de modelo entre varios subprocesos, los accesos concurrentes 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 con múltiples subprocesos sean fiables y seguras.

Para obtener una guía detallada, consulta las secciones Ejemplo no seguro para subprocesos: instancia de modelo único y Ejemplo seguro para subprocesos.

Link to this section¿Cómo afecta el Bloqueo Global del Intérprete (GIL) de Python a la inferencia de modelos YOLO?#

El Bloqueo Global del Intérprete (GIL) de Python permite que solo un subproceso ejecute código de bytes de Python a la vez, lo que puede limitar el rendimiento de las tareas con múltiples subprocesos limitadas por la CPU. Sin embargo, para operaciones vinculadas a E/S o procesos que utilizan bibliotecas que liberan el GIL, como las bibliotecas C subyacentes de YOLO, puedes lograr concurrencia. Para mejorar el rendimiento, considera usar paralelismo basado en procesos con el módulo multiprocessing de Python.

Para obtener más información sobre el uso de subprocesos en Python, consulta la sección Comprender el uso de subprocesos en Python.

Link to this section¿Es más seguro usar paralelismo basado en procesos en lugar de subprocesos para la inferencia de modelos YOLO?#

Sí, el uso del módulo multiprocessing de Python es más seguro y a menudo más eficiente para ejecutar inferencias de modelos YOLO en paralelo. 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 operará de forma independiente con su propia instancia de modelo YOLO.

Para más detalles sobre el paralelismo basado en procesos con modelos YOLO, consulta la página sobre Inferencia segura para subprocesos.

Comentarios