ショートカット

よくある質問

ここでは、多くのユーザーが直面する一般的な問題とその解決策をリストアップしています。 頻繁に発生する問題を発見し、他の人がそれを解決するのを助ける方法があれば、自由にリストを充実させてください。 ここで内容が問題を網羅していない場合は、提供されているテンプレートを使用して issue を作成し、テンプレートに必要なすべての情報を入力してください。

PyTorch 2.0 のサポート

MMDetection のアルゴリズムの大部分は、PyTorch 2.0 とその torch.compile 関数をサポートするようになりました。ユーザーは MMDetection 3.0.0rc7 以降のバージョンをインストールするだけで、この機能を利用できます。 使用中にサポートされていないアルゴリズムが見つかった場合は、お気軽にご意見をお寄せください。 また、 torch.compile 関数を使用することで得られる速度向上をベンチマークするためのコミュニティからの貢献も歓迎します。

torch.compile 関数を有効にするには、train.py または test.py の後に --cfg-options compile=True を追加するだけです。 たとえば、RTMDet の torch.compile を有効にするには、次のコマンドを使用できます。

# Single GPU
python tools/train.py configs/rtmdet/rtmdet_s_8xb32-300e_coco.py  --cfg-options compile=True

# Single node multiple GPUs
./tools/dist_train.sh configs/rtmdet/rtmdet_s_8xb32-300e_coco.py 8 --cfg-options compile=True

# Single node multiple GPUs + AMP
./tools/dist_train.sh configs/rtmdet/rtmdet_s_8xb32-300e_coco.py 8 --cfg-options compile=True --amp

PyTorch 2.0 の動的形状のサポートはまだ完全には開発されていないことに注意することが重要です。 ほとんどのオブジェクト検出アルゴリズムでは、入力形状が動的であるだけでなく、損失計算と後処理の部分も動的です。 これにより、torch.compile 関数を使用すると、トレーニング速度が低下する可能性があります。 したがって、torch.compile 関数を有効にする場合は、次の原則に従う必要があります。

  1. ネットワークへの入力画像は固定形状であり、マルチスケールではありません。

  2. torch._dynamo.config.cache_size_limit パラメータを設定します。TorchDynamo は Python バイトコードを変換してキャッシュし、コンパイルされた関数はキャッシュに保存されます。 次のチェックで関数を再コンパイルする必要があることが判明した場合、関数は再コンパイルされてキャッシュされます。 ただし、再コンパイルの回数が設定された最大値 (64) を超えると、関数はキャッシュまたは再コンパイルされなくなります。 上記のように、オブジェクト検出アルゴリズムの損失計算と後処理の部分も動的に計算されるため、これらの関数は毎回再コンパイルする必要があります。 したがって、torch._dynamo.config.cache_size_limit パラメータを小さい値に設定すると、コンパイル時間を効果的に短縮できます。

MMDetection では、環境変数 DYNAMO_CACHE_SIZE_LIMIT を介して torch._dynamo.config.cache_size_limit パラメータを設定できます。 たとえば、コマンドは次のとおりです。

# Single GPU
export DYNAMO_CACHE_SIZE_LIMIT = 4
python tools/train.py configs/rtmdet/rtmdet_s_8xb32-300e_coco.py  --cfg-options compile=True

# Single node multiple GPUs
export DYNAMO_CACHE_SIZE_LIMIT = 4
./tools/dist_train.sh configs/rtmdet/rtmdet_s_8xb32-300e_coco.py 8 --cfg-options compile=True

PyTorch 2.0 のダイナモに関するよくある質問については、こちらを参照してください。

インストール

MMCV と MMDetection の互換性の問題。「ConvWS は conv レイヤーに既に登録されています」。「AssertionError: MMCV==xxx が使用されていますが、互換性がありません。 mmcv>=xxx, <=xxx をインストールしてください。」

互換性のある MMDetection、MMEngine、および MMCV のバージョンを以下に示します。 インストールの問題を回避するには、正しいバージョンの MMCV を選択してください。

MMDetection バージョン MMCV バージョン MMEngine バージョン
メイン mmcv>=2.0.0, <2.2.0 mmengine>=0.7.1, <1.0.0
3.3.0 mmcv>=2.0.0, <2.2.0 mmengine>=0.7.1, <1.0.0
3.2.0 mmcv>=2.0.0, <2.2.0 mmengine>=0.7.1, <1.0.0
3.1.0 mmcv>=2.0.0, <2.1.0 mmengine>=0.7.1, <1.0.0
3.0.0 mmcv>=2.0.0, <2.1.0 mmengine>=0.7.1, <1.0.0
3.0.0rc6 mmcv>=2.0.0rc4, <2.1.0 mmengine>=0.6.0, <1.0.0
3.0.0rc5 mmcv>=2.0.0rc1, <2.1.0 mmengine>=0.3.0, <1.0.0
3.0.0rc4 mmcv>=2.0.0rc1, <2.1.0 mmengine>=0.3.0, <1.0.0
3.0.0rc3 mmcv>=2.0.0rc1, <2.1.0 mmengine>=0.3.0, <1.0.0
3.0.0rc2 mmcv>=2.0.0rc1, <2.1.0 mmengine>=0.1.0, <1.0.0
3.0.0rc1 mmcv>=2.0.0rc1, <2.1.0 mmengine>=0.1.0, <1.0.0
3.0.0rc0 mmcv>=2.0.0rc1, <2.1.0 mmengine>=0.1.0, <1.0.0

注意

  1. mmdet-v2.x をインストールする場合、互換性のある MMDetection と MMCV のバージョンテーブルはこちらにあります。 インストールの問題を回避するには、正しいバージョンの MMCV を選択してください。

  2. MMCV-v2.x では、mmcv-fullmmcv に名前が変更されています。CUDA ops なしで mmcv をインストールする場合は、mmcv-lite をインストールできます。

  • 「 'mmcv.ops' というモジュールがありません」。 「 'mmcv._ext' というモジュールがありません」。

    1. pip uninstall mmcv-lite を使用して、環境に既存の mmcv-lite をアンインストールします。

    2. インストール手順に従って mmcv をインストールします。

  • Windows にインストール中に「Microsoft Visual C++ 14.0 以降が必要です」。

    このエラーは、pycocotools の 'pycocotools._mask' 拡張機能をビルドしていて、環境に対応する C++ コンパイル依存関係がない場合に発生します。 Microsoft 公式の visual-cpp-build-tools からダウンロードし、「C ++ デスクトップ開発を使用する」オプションを選択して最小限の依存関係をインストールしてから、pycocotools を再インストールする必要があります。

  • Albumentations の使用

    albumentations を使用したい場合は、pip install -r requirements/albu.txt または pip install -U albumentations --no-binary qudida,albumentations を使用することをお勧めします。 pip install albumentations>=0.3.2 を使用するだけでは、opencv-python を既にインストールしている場合でも、opencv-python-headless が同時にインストールされます。 詳細については、公式ドキュメントを参照してください。

  • 一部のアルゴリズムを使用すると ModuleNotFoundError が発生する

    Instaboost、Panoptic Segmentation、LVIS データセットなどには、追加の依存関係が必要です。 エラーメッセージに注意して、対応するパッケージをインストールしてください。例:

    # for instaboost
    pip install instaboostfast
    # for panoptic segmentation
    pip install git+https://github.com/cocodataset/panopticapi.git
    # for LVIS dataset
    pip install git+https://github.com/lvis-dataset/lvis-api.git
    

コーディング

  • コードを修正した後、mmdet を再インストールする必要がありますか?

    ベストプラクティスに従って pip install -e . で mmdet をインストールした場合、コードに加えられたローカルな変更は再インストールせずに有効になります。

  • 複数の MMDetection バージョンで開発する方法

    mmdet-3.0、mmdet-3.1 などの複数のフォルダーを持つことができます。 train または test スクリプトを実行すると、現在のフォルダーにある mmdet パッケージが採用されます。

    作業中の MMDetection ではなく、環境にインストールされているデフォルトの MMDetection を使用するには、これらのスクリプトで次の行を削除します。

    PYTHONPATH="$(dirname $0)/..":$PYTHONPATH
    

PyTorch/CUDA 環境

  • 「MMCV または MMDet のビルド時に RTX 30 シリーズカードが失敗する」

    1. 一時的な回避策:MMCV_WITH_OPS=1 MMCV_CUDA_ARGS='-gencode=arch=compute_80,code=sm_80' pip install -e .を実行してください。一般的な問題はnvcc fatal : Unsupported gpu architecture 'compute_86'です。これは、コンパイラがsm_86、つまりNvidia 30シリーズカード用に最適化する必要があることを意味しますが、CUDAツールキット11.0ではそのような最適化がサポートされていません。この回避策は、MMCV_CUDA_ARGS='-gencode=arch=compute_80,code=sm_80'を追加することでコンパイルフラグを変更します。これは、nvccに**sm_80**、つまりNvidia A100用に最適化するように指示します。A100は30シリーズカードとは異なりますが、どちらも同様のAmpereアーキテクチャを使用しています。パフォーマンスに影響する可能性がありますが、動作します。

    2. PyTorch開発者は、デフォルトのコンパイラフラグがpytorch/pytorch#47585によって修正されるべきだと更新しました。そのため、PyTorch-nightlyを使用することで問題を解決できる可能性がありますが、まだテストしていません。

  • 「無効なデバイス関数」または「実行可能なカーネルイメージがありません」。

    1. cudaランタイムバージョン(/usr/local/以下)、nvcc --version、およびconda list cudatoolkitのバージョンが一致していることを確認してください。

    2. python mmdet/utils/collect_env.pyを実行して、PyTorch、torchvision、およびMMCVが正しいGPUアーキテクチャ用にビルドされているかどうかを確認してください。MMCVを再インストールするためにTORCH_CUDA_ARCH_LISTを設定する必要がある場合があります。GPUアーキテクチャテーブルはこちらにあります。たとえば、TORCH_CUDA_ARCH_LIST=7.0 pip install mmcvを実行して、Volta GPU用にMMCVをビルドします。互換性の問題は、古いGPU、たとえばcolabでTesla K80(3.7)を使用している場合に発生する可能性があります。

    3. 実行環境がmmcv/mmdetをコンパイルしたときと同じであることを確認してください。たとえば、CUDA 10.0を使用してmmcvをコンパイルし、CUDA 9.0環境で実行する場合などです。

  • 「未定義のシンボル」または「xxx.soを開けません」。

    1. これらのシンボルがCUDA/C++シンボル(例:libcudart.soまたはGLIBCXX)の場合、CUDA/GCCランタイムがmmcvのコンパイルに使用されたものと同じであることを確認してください。つまり、python mmdet/utils/collect_env.pyを実行して、"MMCV Compiler"/"MMCV CUDA Compiler""GCC"/"CUDA_HOME"と同じであるかどうかを確認してください。

    2. これらのシンボルがPyTorchシンボル(例:caffe、aten、THを含むシンボル)の場合、PyTorchのバージョンがmmcvのコンパイルに使用されたものと同じであることを確認してください。

    3. python mmdet/utils/collect_env.pyを実行して、PyTorch、torchvision、およびMMCVが同じ環境でビルドされ、実行されているかどうかを確認してください。

  • setuptools.sandbox.UnpickleableException: DistutilsSetupError(「'ext_modules'オプションの各要素はExtensionインスタンスまたは2タプルである必要があります」)

    1. anacondaではなくminicondaを使用している場合は、#3379に示されているように、Cythonがインストールされているかどうかを確認してください。最初にCythonを手動でインストールしてから、コマンドpip install -r requirements.txtを実行する必要があります。

    2. また、環境内のsetuptoolsCython、およびPyTorch間の互換性も確認する必要がある場合があります。

  • 「セグメンテーション違反」。

    1. GCCバージョンを確認し、GCC 5.4を使用してください。これは通常、PyTorchと環境(例:PyTorchのGCC < 4.9)との非互換性によって発生します。また、GCC 5.5は「セグメンテーション違反」を引き起こすというフィードバックが多く、GCC 5.4に変更するだけで問題が解決するという報告があるため、GCC 5.5の使用は避けることをお勧めします。

    2. PyTorchが正しくインストールされていて、CUDA opを使用できるかどうかを確認してください。たとえば、ターミナルで次のコマンドを入力します。

      python -c 'import torch; print(torch.cuda.is_available())'
      

      そして、それらが正しく結果を出力できるかどうかを確認します。

    3. Pytorchが正しくインストールされている場合は、MMCVが正しくインストールされているかどうかを確認してください。

      python -c 'import mmcv; import mmcv.ops'
      

      MMCVが正しくインストールされていれば、上記の2つのコマンドに問題はありません。

    4. MMCVとPytorchが正しくインストールされている場合は、ipdbpdbを使用してブレークポイントを設定するか、mmdetectionコードに直接「print」を追加して、どの部分がセグメンテーション違反を引き起こしているかを確認できます。

トレーニング

  • 「損失がNaNになる」

    1. データセットのアノテーションが有効かどうかを確認してください。サイズがゼロの境界ボックスは、ボックス回帰によく使用される変換により、回帰損失がNaNになります。サイズが小さい(幅または高さが1より小さい)ボックスも、データ拡張(例:instaboost)後にこの問題を引き起こします。そのため、データを確認し、問題が発生した場合は、サイズがゼロのボックスを除外し、サイズが小さいボックスのリスクの高い拡張をスキップしてみてください。

    2. 学習率を下げる:バッチサイズの変更など、何らかの理由で学習率が高すぎる可能性があります。モデルを安定してトレーニングできる値に再スケールできます。

    3. ウォームアップの反復回数を増やす:一部のモデルは、トレーニング開始時の学習率に敏感です。ウォームアップの反復回数を増やすことができます。たとえば、warmup_itersを500から1000または2000に変更します。

    4. 勾配クリッピングを追加する:一部のモデルでは、トレーニングプロセスを安定させるために勾配クリッピングが必要です。grad_clipのデフォルトはNoneです。大きすぎる勾配を避けるために勾配クリッピングを追加できます。つまり、設定ファイルでoptim_wrapper=dict(clip_grad=dict(max_norm=35, norm_type=2))を設定します。

  • 「GPUメモリ不足」

    1. グラウンドトゥルースボックスが大量にある場合、ターゲット割り当て中にOOMが発生する可能性があります。設定ファイルのアサイナーでgpu_assign_thr=Nを設定することで、GTボックスがN個を超える場合、アサイナーはCPUを介してボックスのオーバーラップを計算します。

    2. バックボーンでwith_cp=Trueを設定します。これは、PyTorchの劣線形戦略を使用して、バックボーンのGPUメモリコストを削減します。

    3. config/fp16の例に従って、混合精度トレーニングを試してください。loss_scaleは、モデルによってさらに調整が必要になる場合があります。

    4. AvoidCUDAOOMを使用してGPUメモリ不足を回避してみてください。torch.cuda.empty_cache()を呼び出した後、最初に再試行します。それでも失敗する場合は、入力のタイプをFP16形式に変換して再試行します。それでも失敗する場合は、入力をGPUからCPUにコピーして計算を続行しようとします。コードでAvoidOOMを試して、GPUメモリが不足した場合でもコードが引き続き実行されるようにします

      from mmdet.utils import AvoidCUDAOOM
      
      output = AvoidCUDAOOM.retry_if_cuda_oom(some_function)(input1, input2)
      

      デコレータとしてAvoidCUDAOOMを使用して、GPUメモリが不足した場合でもコードが引き続き実行されるようにすることもできます

      from mmdet.utils import AvoidCUDAOOM
      
      @AvoidCUDAOOM.retry_if_cuda_oom
      def function(*args, **kwargs):
          ...
          return xxx
      
  • 「RuntimeError:新しい反復を開始する前に、前の反復で縮小が完了している必要があります」

    1. このエラーは、モジュールに損失の生成に使用されなかったパラメータがあることを示しています。この現象は、コードの異なるブランチをDDPモードで実行することによって発生する可能性があります。

    2. 設定でfind_unused_parameters = Trueを設定することで上記の問題を解決できますが、トレーニング速度が低下します。

    3. 設定でdetect_anomalous_params = Trueを設定するか、model_wrapper_cfg = dict(type='MMDistributedDataParallel', detect_anomalous_params=True)を設定することで(詳細はMMEngineを参照)、使用されていないパラメータの名前を取得できます。detect_anomalous_params = Trueはトレーニング速度を低下させるため、デバッグのみに推奨されます。

  • 最適なモデルを保存する

    default_hooks = dict(checkpoint=dict(type='CheckpointHook', interval=1, save_best='auto'),を設定することで有効にできます。autoパラメータの場合、返された評価結果の最初のキーが最適なモデルを選択するための基準として使用されます。たとえば、save_best='coco/bbox_mAP'のように、評価結果のキーを直接設定して手動で設定することもできます。

評価

  • COCOデータセット、APまたはAR = -1

    1. COCOデータセットの定義によれば、画像の小さい領域と中程度の領域はそれぞれ1024(32 * 32)、9216(96 * 96)未満です。

    2. 対応する領域にオブジェクトがない場合、APとARの結果は-1に設定されます。

モデル

  • ResNetのstyle

    ResNetのstyleパラメータは、pytorchまたはcaffeスタイルを指定できます。これは、Bottleneckモジュールの違いを示しています。Bottleneckは、1x1-3x3-1x1畳み込み層のスタッキング構造です。caffeモードの場合、stride=2の畳み込み層は最初の1x1畳み込みですが、pytorchモードでは、2番目の3x3畳み込みがstride=2を持ちます。サンプルコードは以下のとおりです。

    if self.style == 'pytorch':
          self.conv1_stride = 1
          self.conv2_stride = stride
    else:
          self.conv1_stride = stride
          self.conv2_stride = 1
    
  • ResNeXtパラメータの説明

    ResNeXtは、論文Aggregated Residual Transformations for Deep Neural Networksに由来します。これはグループを導入し、「カーディナリティ」を使用してグループ数を制御することで、精度と複雑さのバランスを実現します。内部のBottleneckモジュールの基本的な幅とグループ化パラメータを、2つのハイパーパラメータbaseWidthcardinalityで制御します。MMDetectionの構成名の例は、mask_rcnn_x101_64x4d_fpn_mstrain-poly_3x_coco.pyです。ここで、mask_rcnnはMask R-CNNを使用するアルゴリズム、x101はResNeXt-101を使用するバックボーンネットワーク、64x4dはボトルネックブロックが64グループで各グループの基本幅が4であることを表します。

  • バックボーンにおけるnorm_eval

    検出モデルは通常大きく、入力画像の解像度が高いため、検出モデルのバッチサイズが小さくなります。これにより、トレーニングプロセス中にBatchNormによって計算される統計量の分散が非常に大きくなり、バックボーンネットワークの事前トレーニング中に得られた統計量ほど安定しません。そのため、トレーニングでは一般的にnorm_eval=Trueモードが使用され、事前トレーニングされたバックボーンネットワークのBatchNorm統計量が直接使用されます。大きなバッチを使用する少数のアルゴリズムは、NASFPNなど、norm_eval=Falseモードです。ImageNetの事前トレーニングがないバックボーンネットワークでバッチが比較的小さい場合は、SyncBNの使用を検討できます。