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

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

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

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.

DOMANDE FREQUENTI

Come posso evitare le condizioni di gara quando utilizzo i modelli di YOLO in un ambiente multi-thread di Python ?

Per evitare condizioni di gara quando si utilizzano i modelli Ultralytics YOLO in un ambiente Python multi-thread, istanzia un modello YOLO separato in ogni thread. Questo assicura che ogni thread abbia la propria istanza isolata del modello, evitando la modifica simultanea dello stato del modello.

Esempio:

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

Per ulteriori informazioni su come garantire la sicurezza delle filettature, visita il sito Thread-Safe Inference with YOLO Models.

Quali sono le migliori pratiche per eseguire l'inferenza del modello YOLO in multi-thread in Python?

Per eseguire l'inferenza del modello YOLO in multi-thread in modo sicuro in Python, segui queste best practice:

  1. Istanziare i modelli di YOLO all'interno di ogni thread piuttosto che condividere una singola istanza di modello tra i vari thread.
  2. Utilizza il sito Python multiprocessing per l'elaborazione parallela per evitare problemi legati al Global Interpreter Lock (GIL).
  3. Rilascia il GIL utilizzando le operazioni eseguite dalle librerie C di YOLO.

Esempio di istanziazione del modello thread-safe:

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

Per un ulteriore contesto, consulta la sezione sull'inferenza Thread-Safe.

Perché ogni thread dovrebbe avere la propria istanza del modello YOLO ?

Ogni thread dovrebbe avere la propria istanza del modello YOLO per evitare condizioni di gara. Quando una singola istanza del modello viene condivisa tra più thread, gli accessi simultanei possono portare a comportamenti imprevedibili e a modifiche dello stato interno del modello. Utilizzando istanze separate, si garantisce l'isolamento dei thread, rendendo le attività multi-thread affidabili e sicure.

Per una guida dettagliata, consulta le sezioni Esempio non thread-safe: Istanza di un singolo modello e Esempio Thread-Safe.

In che modo il Global Interpreter Lock (GIL) di Python influisce sull'inferenza del modello di YOLO ?

PythonIl Global Interpreter Lock (GIL) di CPU permette a un solo thread di eseguire il bytecode di Python alla volta, il che può limitare le prestazioni delle operazioni multi-threading legate a . Tuttavia, per le operazioni legate all'I/O o per i processi che utilizzano librerie che rilasciano il GIL, come le librerie C di YOLO, puoi ancora ottenere la concomitanza. Per migliorare le prestazioni, prendi in considerazione l'utilizzo del parallelismo basato sui processi con Python's multiprocessing modulo.

Per maggiori informazioni sul threading in Python, consulta la sezione Comprendere il threading in Python .

È più sicuro utilizzare il parallelismo basato sui processi invece del threading per l'inferenza del modello YOLO ?

Sì, utilizzando Python's multiprocessing è più sicuro e spesso più efficiente per eseguire l'inferenza del modello YOLO in parallelo. Il parallelismo basato sui processi crea spazi di memoria separati, evitando il Global Interpreter Lock (GIL) e riducendo il rischio di problemi di concorrenza. Ogni processo opererà in modo indipendente con la propria istanza del modello YOLO .

Per ulteriori dettagli sul parallelismo basato sui processi con i modelli di YOLO , consulta la pagina sull'inferenza Thread-Safe.



Creato 2023-11-12, Aggiornato 2024-07-05
Autori: glenn-jocher (5)

Commenti