YOLO モデルによるスレッドセーフ推論
マルチスレッド環境でYOLO モデルを実行するには、スレッドセーフを確保するための慎重な配慮が必要です。Python's threading
モジュールでは複数のスレッドを同時に実行することができますが、これらのスレッドにまたがってYOLO モデルを使用する場合、注意すべき重要な安全上の問題があります。このページでは、スレッドセーフなYOLO モデル推論を作成する方法を説明します。
Python スレッドを理解する
Python スレッドは並列処理の一形態で、プログラムが一度に複数の処理を実行できるようにする。しかし、Python'のグローバル・インタープリタ・ロック(GIL)は、Python バイトコードを一度に実行できるスレッドが1つだけであることを意味する。
これは制限のように聞こえるが、スレッドは、特にI/Oバウンド操作や、YOLO'の基礎となるCライブラリによって実行されるようなGILを解放する操作を使用する場合に、依然として並行性を提供することができる。
共有モデル・インスタンスの危険性
スレッド外でYOLO モデルをインスタンス化し、このインスタンスを複数のスレッドで共有すると、同時アクセスによってモデルの内部状態が矛盾して変更される競合状態が発生する可能性があります。これは、モデルやそのコンポーネントがスレッドセーフに設計されていない状態を保持している場合に特に問題となります。
スレッドセーフでない例:単一モデルインスタンス
Python でスレッドを使用する場合、同時実行の問題につながるパターンを認識することが重要です。ここで避けるべきことは、1つの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("yolo11n.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
は複数のスレッドによって同時に実行される可能性がある。
スレッドセーフでない例:複数のモデルインスタンス
同様に、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("yolo11n_1.pt")
shared_model_2 = YOLO("yolo11n_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()
2つの別々のモデル・インスタンスがあっても、並行性の問題のリスクはまだ存在する。もし YOLO
がスレッドセーフでない場合、特にこれらのインスタンスがスレッドローカルでない基礎的なリソースやステートを共有している場合、別々のインスタンスを使用しても競合状態を防げない可能性がある。
スレッドセーフ推論
スレッドセーフな推論を行うためには、各スレッド内で別々のYOLO ・モデルをインスタンス化する必要がある。こうすることで、各スレッドがそれぞれ独立したモデル・インスタンスを持つようになり、競合状態が発生するリスクがなくなります。
スレッドセーフの例
ここでは、安全な並列推論を行うために、各スレッド内で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("yolo11n.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
インスタンスを作成する。これにより、どのスレッドも他のスレッドのモデル状態に干渉することがなくなり、各スレッドが他のスレッドと予期せぬ相互作用をすることなく、安全に推論を実行できるようになる。
結論
Python のYOLO モデルを使用する場合。 threading
スレッドセーフを保証するために、常にモデルを使用するスレッド内でインスタンス化する。こうすることで、競合状態を回避し、推論タスクを確実に実行することができます。
より高度なシナリオや、マルチスレッド推論のパフォーマンスをさらに最適化するには、次のようなプロセスベースの並列処理を使用することを検討します。 multiprocessing
あるいは、専用のワーカープロセスでタスクキューを活用する。
よくあるご質問
マルチスレッドPython 環境でYOLO モデルを使用する場合、どのようにすれば競合状態を回避できますか?
マルチスレッドPython 環境でUltralytics YOLO モデルを使用する際に競合状態を防ぐには、各スレッド内で別々の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("yolo11n.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 モデルによるスレッドセーフ推論をご覧ください。
Python でYOLO モデルの推論をマルチスレッドで実行するためのベストプラクティスは?
Python でマルチスレッドYOLO モデル推論を安全に実行するには、以下のベストプラクティスに従ってください:
- スレッド間で単一のモデルインスタンスを共有するのではなく、各スレッド内でYOLO モデルをインスタンス化する。
- Python を使用する。
multiprocessing
モジュールを並列処理に使用することで、グローバル・インタープリタ・ロック(GIL)に関連する問題を回避できる。 - YOLO の基礎となるCライブラリによって実行される操作を使って、GILを解放する。
スレッドセーフなモデルのインスタンス化の例:
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("yolo11n.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()
その他の文脈については、スレッドセーフ推論のセクションを参照のこと。
なぜ各スレッドが独自のYOLO モデルインスタンスを持つ必要があるのか?
競合状態を防ぐために、各スレッドはそれぞれ独自のYOLO モデルインスタンスを持つべきです。一つのモデル・インスタンスを複数のスレッドで共有すると、同時アクセスによって予測不可能な動作やモデルの内部状態の変更が発生する可能性があります。別々のインスタンスを使用することで、スレッドの分離が保証され、マルチスレッドタスクの信頼性と安全性が高まります。
詳細なガイダンスについては、「スレッドセーフでない例」を参照してください:Single Model InstanceとThread-Safe Exampleのセクションを参照してください。
Python のグローバル・インタープリタ・ロック(GIL)は、YOLO モデル推論にどのような影響を与えるのか?
Pythonのグローバル・インタープリタ・ロック(GIL)は、Python バイトコードを一度に実行できるスレッドを1つしか許さないため、CPU-バウンド・マルチスレッディング・タスクのパフォーマンスが制限される可能性がある。しかし、I/Oバウンド操作や、YOLO のCライブラリのようにGILを解放しているライブラリを使用するプロセスでは、まだ同時実行が可能です。パフォーマンスを向上させるには、Python の multiprocessing
モジュールである。
Python のスレッディングの詳細については、 Python スレッディングを理解するのセクションを参照してください。
YOLO 、モデル推論にはスレッドではなくプロセスベースの並列処理を使う方が安全なのだろうか?
はい、Python multiprocessing
モジュールは、YOLO モデル推論を並列に実行する際に、より安全で、多くの場合より効率的です。プロセス・ベースの並列処理は、別々のメモリ空間を作成し、グローバル・インタープリタ・ロック(GIL)を回避し、並行性の問題のリスクを低減します。各プロセスは、独自のYOLO モデルインスタンスで独立して動作します。
YOLO モデルによるプロセスベースの並列処理の詳細については、スレッドセーフ推論のページを参照のこと。