Vai al contenuto

Inferenza sicura con i modelli di YOLO

L'esecuzione dei modelli di YOLO in un ambiente multi-thread richiede un'attenta considerazione per garantire la sicurezza dei thread. Python's threading ti permette di eseguire più thread in contemporanea, ma quando si tratta di utilizzare i modelli di YOLO tra questi thread, ci sono importanti questioni di sicurezza da tenere presenti. Questa pagina ti guiderà nella creazione di un'inferenza del modello YOLO sicura per i thread.

Capire la filettatura di Python

Python I thread sono una forma di parallelismo che permette al tuo programma di eseguire più operazioni contemporaneamente. Tuttavia, il Global Interpreter Lock (GIL) di Python significa che solo un thread può eseguire il bytecode di Python alla volta.

Esempi di thread singolo o multiplo

Sebbene questo sembri un limite, i thread possono comunque garantire la concomitanza, soprattutto per le operazioni legate all'I/O o quando si utilizzano operazioni che rilasciano il GIL, come quelle eseguite dalle librerie C sottostanti a YOLO.

Il pericolo delle istanze di modello condivise

L'istanziazione di un modello YOLO al di fuori dei tuoi thread e la condivisione di questa istanza tra più thread può portare a condizioni di gara, in cui lo stato interno del modello viene modificato in modo incoerente a causa di accessi contemporanei. Questo è particolarmente problematico quando il modello o i suoi componenti contengono uno stato che non è stato progettato per essere thread-safe.

Esempio non thread-safe: Istanza di un singolo modello

Quando si utilizzano i thread in Python, è importante riconoscere gli schemi che possono portare a problemi di concorrenza. Ecco cosa dovresti evitare: condividere una singola istanza del modello YOLO tra più thread.

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

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

Nell'esempio precedente, l'opzione shared_model è utilizzato da più thread, il che può portare a risultati imprevedibili perché predict potrebbe essere eseguito simultaneamente da più thread.

Esempio non thread-safe: Istanze multiple del modello

Allo stesso modo, ecco un modello non sicuro con più istanze del modello YOLO :

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

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

Anche se ci sono due istanze di modello separate, il rischio di problemi di concorrenza esiste ancora. Se l'implementazione interna di YOLO non è thread-safe, l'utilizzo di istanze separate potrebbe non prevenire le condizioni di gara, soprattutto se queste istanze condividono risorse o stati sottostanti che non sono thread-local.

Inferenza thread-safe

Per eseguire un'inferenza thread-safe, devi istanziare un modello YOLO separato all'interno di ogni thread. Questo assicura che ogni thread abbia la propria istanza di modello isolata, eliminando il rischio di condizioni di gara.

Esempio sicuro per i thread

Ecco come istanziare un modello YOLO all'interno di ogni thread per un'inferenza parallela sicura:

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


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

In questo esempio, ogni thread crea il proprio YOLO istanza. Questo impedisce a qualsiasi thread di interferire con lo stato del modello di un altro, garantendo così che ogni thread esegua l'inferenza in modo sicuro e senza interazioni inaspettate con gli altri thread.

Conclusione

Quando si utilizzano i modelli YOLO con Python's threadingPer garantire la sicurezza dei thread, istanzia sempre i tuoi modelli all'interno del thread che li utilizzerà. Questa pratica evita le condizioni di gara e garantisce un'esecuzione affidabile delle attività di inferenza.

Per scenari più avanzati e per ottimizzare ulteriormente le prestazioni dell'inferenza multi-thread, prendi in considerazione l'utilizzo del parallelismo basato sui processi con multiprocessing o sfruttando una coda di attività con processi worker dedicati.



Creato 2023-11-12, Aggiornato 2024-05-03
Autori: glenn-jocher (2)

Commenti