Markdownで表示

トラブルシューティング

表示されるメッセージ別にエラーをまとめています。最後の2項目では逆の問題を扱います。コードは動作し、もっともらしいものを返しますが、その結果は誤っています。

表示されるテキスト別にエラーをまとめています。該当するメッセージがない場合は、FAQで障害以外の疑問を確認できます。また、libreyolo models で現在のインストールが実際に読み込めるものを確認できます。

インポートしていないパッケージを示すModuleNotFoundError

一部のファミリーには任意の追加パッケージが必要です。メッセージには追加パッケージ名ではなく、不足しているパッケージ名が表示されるため、トレースバックから修正方法が分かるとは限りません。

libreyolo models を実行してください。依存関係が不足しているファミリーごとに、有効化するための正確なpipコマンドが表示されるため、パッケージから追加パッケージへの対応を自身で調べる必要はありません。libreyolo models --json では同じ内容をオブジェクトとして出力します。

インストールページには、すべての追加パッケージとその対象が記載されています。

ONNX推論にはonnxruntimeが必要

ImportError: ONNX inference requires onnxruntime. Install with: pip install onnxruntime

どのランタイムが必要かはハードウェアによって決まるため、基本パッケージはランタイムに依存しません。CPU用には onnxruntime、CUDA用には onnxruntime-gpu をインストールしてください。どちらも同じ onnxruntime モジュールを提供するため、両方ではなく片方だけをインストールします。

ONNXモデルが見つからない

FileNotFoundError: ONNX model not found: <path>

パスはスクリプトではなく、作業ディレクトリを基準に解決されます。エクスポート先が黙って別の場所になった場合にも、このエラーが表示されます。export() は書き込んだパスを返すため、名前を推測せずに戻り値を取得してください。

train()からのNotImplementedError

すべてのファミリーが学習できるわけではありません。一部は推論、検証、エクスポート専用に移植されており、実行したように見せかけずに train() から例外を送出します。

FAQの項目でその理由を説明しています。学習スクリプトを書く前に特定のファミリーを確認するには、そのモデルページで学習の可否を確認してください。

export()からのNotImplementedError

ファミリーがタスクに対応していても、エクスポートには対応していない場合があります。よく遭遇するのがEoMTです。export() はsemanticタスクを受け付けますが、segmentpanoptic では例外を送出します。これらに必要なquery-maskランタイム仕様が定義されていないためです。

NotImplementedError: LibreEoMT instance and panoptic export need query-mask runtime contracts.

各ファミリーのページには、検証済みのタスクと形式の組み合わせを示すエクスポートマトリックスがあります。

CUDAのメモリ不足

まず batch を減らし、次に imgsz を減らしてください。どちらもおおむねサイズに応じてメモリ量を変えますが、モデルが見る内容を変えずに減らせるのはバッチです。

学習ではなく検証時に失敗する場合、検証は独自のバッチサイズで実行されるため、そちらも減らしてください。

Windowsでは、ディスプレイ用GPUにメモリ不足とは別の障害モードがあります。応答がタイムアウト時間より長く止まったGPUをドライバーがリセットし、実行中の処理を終了させます。このとき、メモリ不足ではなくランダムなCUDAエラーに見えます。モニターを駆動するカード上で長時間動くカーネルは、この問題を引き起こす可能性があります。

重みをダウンロードできない

重みは初回使用時にHugging Faceから取得され、ローカルにキャッシュされます。FAQでは、キャッシュの保存場所と完全オフラインで実行する方法を説明しています。

ダウンロードで404が発生した場合は、渡したファイル名を確認してください。URLはタスク接尾辞を含むファイル名から生成されるため、公開済みチェックポイントと一致しない名前を使うと、存在しないURLが生成されます。各モデルページのチェックポイント表には、公開されている正確なファイル名が記載されています。

Windowsで学習が停止または再起動する

Windowsには fork がないため、dataloaderのworkerはスクリプトを再インポートして起動します。if __name__ == "__main__": ガードがないと、各workerが学習呼び出しを再実行し、デッドロックするか、プロセスを際限なく生成します。

python
def main():
    ...  # モデルを構築してtrain()を呼び出す

if __name__ == "__main__":
    main()

workers=0 を設定しても回避できますが、スループットが低下します。ガードを使う方が適切な修正です。

例外を送出しない2つの障害

このページのほかの部分ではエラーを扱っています。次の2つは、コードが実行されて正しそうなものが返るため、さらに深刻です。

1つの結果に対するインデックス指定

predict() は、画像が1枚なら1つの Results、複数ならリストを返します。1枚画像の戻り値にインデックスを指定すると、画像ではなく1件の検出結果が選択されます。

python
result = model.predict("image.jpg")   # 1つのResults
result.boxes                          # すべての検出結果、正しい
result[0].boxes                       # 1件だけの検出結果、通知なし

Results へのインデックス指定は部分集合を返す有効な操作なので、例外は送出されません。リスト形式を前提に書いたコードは、画像ごとに1つのボックスだけを黙って報告します。リストであると分かっているものだけにインデックスを指定してください。

指標を属性として読み取る

val() は属性アクセスを持つオブジェクトではなく、指標名をキーとする通常の辞書を返します。

python
metrics = model.val(data="coco8.yaml")
metrics["metrics/mAP50-95"]   # 正しい
metrics.box.map               # AttributeError

キーは metrics/speed/ で名前空間化されています。タスクによって項目が異なるため、辞書を一度出力し、そのタスクが生成した内容を確認してください。

学習前にデータセットを確認

学習失敗のほとんどはデータセットの問題です。libreyolo doctor data.yaml は検出データセット全体の健全性チェックを実行し、重大度別に所見を報告します。これは最初のエポックのトレースバックを読むより高速です。

python
from libreyolo import doctor

report = doctor.diagnose("data.yaml", imgsz=640)
if report.errors:
    ...

チェック項目の一覧についてはdoctorコマンドを参照してください。

LibreYOLO v1.5.0で検証済みです。