まえがき
R&Dの宮﨑です。FORTNITEの入力を弄るツールであるダブルムーブメント(合法)がRustで書かれているのを見て低レイヤはRustで書くのがセオリーになりつつあるのかと実感している次第です。
今回はTensorRT 8.2.2/8.2.3のリリースノートの内容をメモしました。
気になった内容
明示的な量子化関連の修正
MatMulのあるONNXモデルでQuantizeLinear/DequantizeLinearによりその重みを量子化し、重みをpre-transpose(i.e. 別のTransposeを使わない)した場合、量子化の処理中に起こるバグにより精度的なエラーを起こすことがありました。この問題は本リリースで修正されました。(8.2.2)- TensorRTはバッチ処理の行列乗算に対する明示的な量子化(i.e.
Q/DQ)をサポートしていません。今回の修正により行列Bが定数行列であり2次元行列へsqueezeできるときに量子化されたバッチ処理の行列乗算の特殊なケースへのサポートを導入しました。(8.2.3) - INT8のQATのネットワークで
Q/DQとConvolutionレイヤの前に配置されたPaddingレイヤがあるときに最大で20%のパフォーマンス低下がありました。この問題は本リリースで修正されました。(8.2.3)- 明示的な量子化は直接ネットワークを指定するので形成されるネットワークが予測できるのはもちろん、より細かく指定ができます。例えば「精度を維持したいからここは量子化したくない」といった調整ができます。またその際に用いるQ/DQ周辺では自動的にネットワーク最適化が行われますが、今回はそのあたりに強化と修正が入りよりチャレンジしやすくなりました。
PyTorch Multi-head Attention APIを使用してビルドした
transformerベースのネットワークの中には、グラフのパターンが異なることによって、他のAPIを使用してビルドした同等のネットワークに比べ最大45%の速度低下が起きうる問題がありました。この問題は本リリースで修正されました。(8.2.2)- 近年注目されている
Transformerにおいて処理の中心とも言えるMulti-head Attentionですが、TensorRTでは最大45%の速度低下を起こす大きな問題がありました。それがとうとうTensorRT 8.2.2で修正されました。
- 近年注目されている
既知の問題が多くあります。ワークアラウンドが記載されているものもあるので遭遇している問題がないかチェックしてみると良いかもしれません。
意訳
- TensorRT 8.2.2/8.2.3で重複している内容が多かったので合わせて記載します。
これはTensorRT 8.2.2/8.2.3のリリースノートで、x86のLinuxとWindows、ARM®ベースのCPUコアを組み込んだLinuxのユーザー向けです。 これらのリリースノートは、特に(Jetsonプラットフォームには適用されません)と付記されていない限り、ワークステーション、サーバー、およびNVIDIA JetPack™のユーザー向けに記載されています。
このリリースには、以前のTensorRT 8.x.xリリースからのいくつかの修正と、以下の追加変更が含まれています。以前のTensorRTのドキュメントについては、NVIDIA TensorRT Archived Documentationを参照してください。
互換性(TensorRT 8.2.2/8.2.3)
- TensorRT 8.2.2 / 8.2.3 は以下でテストされています。
- このリリースでは以下のCUDAのバージョンをサポートしています。
- TensorRTはFeatures For Platforms And SoftwareセクションにあるcuDNNとcuBLASのバージョン含めテスト済みのソフトウェアスタックで使用することが推奨されています。他の意味的に互換性のあるcuDNNやcuBLASも使用できますが、性能が上下する可能性があります。またまれに機能的に後退するかもしれません。
修正された問題(TensorRT 8.2.2)
- pip wheelファイルを使用してTensorRTをインストールするにはpipのバージョンが20未満である必要がありました。TensorRTが依存するCUDA 11.4 wheel metaパッケージの問題へのワークアラウンドにより古いバージョンのpipが必要でしたが、本リリースで修正されました。
samplesディレクトリの下にdeserializeTimerという空のディレクトリが誤って残っていた問題がありましたが、本リリースで修正されました。- PyTorch Multi-head Attention APIを使用してビルドした
transformerベースのネットワークの中には、グラフのパターンが異なることによって、他のAPIを使用してビルドした同等のネットワークに比べ最大45%の速度低下が起きうる問題がありました。この問題は本リリースで修正されました。 IShuffleLayerをIConstantLayerの出力とした際に、定数がkFLOAT型ではない場合不正に変換されビルドに失敗することがありました。この問題は本リリースで修正されました。MatMulのあるONNXモデルでQuantizeLinear/DequantizeLinearによりその重みを量子化し、重みをpre-transpose(i.e. 別のTransposeを使わない)した場合、量子化の処理中に起こるバグにより精度的なエラーを起こすことがありました。この問題は本リリースで修正されました。
修正された問題(TensorRT 8.2.3)
- TensorRT 8で導入されたカスタムアロケータとアロケーションリサイズが
p.second failureに関するアサートを引き起こす既知の問題がありました。これはアプリケーションがリアロケーションのルーチンでTensorRTへ全く同じポインタを渡すことが原因でした。このアサーションが有効なユースケースになるように修正しました。 PoolingレイヤーをConcatenateレイヤーの前後に配置したネットワークでは、最大で15%のパフォーマンス低下が発生します。この問題は本リリースで修正されました。- INT8のQATのネットワークで
Q/DQとConvolutionレイヤの前に配置されたPaddingレイヤがあるときに最大で20%のパフォーマンス低下がありました。この問題は本リリースで修正されました。 - TensorRTはバッチ処理の行列乗算に対する明示的な量子化(i.e.
Q/DQ)をサポートしていません。今回の修正により行列Bが定数行列であり2次元行列へsqueezeできるときに量子化されたバッチ処理の行列乗算の特殊なケースへのサポートを導入しました。具体的には、サポートされた構成では行列A(データ)はBSがバッチサイズのとき(BS, M, K)の形状を持つことができ、行列B(重み)は(1, K, N)の形状を持つことができます。重みがバッチの次元でブロードキャストされて演算されることにより出力は(BS, M, N)の形状を持ちます。量子化されたバッチ処理の行列乗算は入力データと重みを量子化する二組のQ/DQノードを持ちます。 - モデルのビルド時に2つの
transpose演算の不正な融合がアサーションを引き起こすことがありました。この問題は本リリースで修正されました。
既知の問題(TensorRT 8.2.2/8.2.3)
- 機能
- TensorRTはGPUのメモリアロケーションの失敗を補足し、メモリ不足エラーを引き起こすメモリ要求を持ったプロファイリング戦略を回避します。しかし、プラットフォームによってはGPUメモリアロケーションの失敗はCUDAによって体よく扱えず回復不能なアプリケーションステータスを引き起こします。もしこの問題が起こった場合は、ワークスペースのサイズが大きい場合は下げたり、大量のGPUメモリを要求する戦略を回避するために
IAlgorithmSelectorインターフェースを使用することをご検討ください。 - Azure VMのT4で
TopKレイヤがあるネットワークを走らせるとTensorRTが不安定になることがあります。この問題へのワークアラウンドは、CUBLAS_LT kernelsを--tacticSources=-CUBLAS_LT (setTacticSources)で無効化することです。- TensorRT 8.2.3ではワークアラウンドの記載が削除されています。8.2.3でもこのワークアラウンドを実施すること自体はできるので、効果なしなことが判明したのか単なる書き忘れか・・・
- WSL2の特定の条件下で、エンジンのビルド時に
Concatレイヤの前に水平に融合され得るConvolutionレイヤーのあるINetworkは、アプリケーションをクラッシュさせる内部エラー起きることがあります。ワークアラウンドはWSL2の代わりにLinuxでそのネットワークをビルドすることです。 - ダイナミックシェイプでONNXモデルを動作させる際、同じであることが予測される入力の次元名が異なる場合に精度の問題が起きる場合があります。例えば、もしモデルが2つの2次元入力を持ち、その次元セマンティクスが
batchとseqlenで、ONNXモデル上では2つの入力の次元名が異なったとき、ダイナミックシェイプで動作させると精度の問題が起きる場合があります。フレームワークからONNXモデルをエクスポートする際は次元セマンティクスが一致することをお確かめください。 - WSLプラットフォーム上で
ILoopレイヤのあるネットワークにおいて機能的な問題があります。コンパイル時にCUDAエラーを起こします。 - CUDA 10.xのSM 3.xを持つデバイスでは
cuBLASLtは選択できません。もし選択した場合はcuBLASにフォールバックされます。(Jetsonプラットフォームには適用されません) - 重みと活性化のデータが莫大なネットワークの中には、
DLAがsubgraphをコンパイルすることに失敗し、subgraphがGPUへフォールバックされることがあります。 - 条件によっては、TensorRT 8.0ではTensorRT 7.2よりも
RNNv2Layerが大きなワークスペースサイズを要求するかもしれません。これはサポートする全ての戦略を実行するためです。ワークスペースサイズを増やすことをご検討ください。 CUDA graph captureは11.xかつ11.1以上のドライバ(455以上)でビルドした時のみ、inputConsumedとプロファイライベントをキャプチャします。- 統合GPUにおいて、TensorRT 8.0の利用可能なメモリ量を人為的に制限するメモリトラッキングの問題は修正されました。その副作用としてTensorRTの
optimizerがより多くのメモリを使用するレイヤの実装を選べるようになりました。それによりこれまではOOM Killerを起こさなかったネットワークでOOM Killerを起こすようになってしまいました。この問題へのワークアラウンドとして、IAlgorithmSelectorインターフェースを使用して大量のメモリを要求するレイヤの実装を回避するか、layer precision APIを使用して大きなテンソルの精度を下げた上でSTRICT_TYPESを使用するか、バッチや他のより高い次元を減らすことによってbuilderへの入力テンソルのサイズを減らすことが考えられます。 - TensorRTはあるバージョンの
libnvptxcompiler_static.aをlibnvinfer_static.aの中にバンドルします。アプリケーションがTensorRTのビルド時に使用したバージョンと異なるバージョンのPTXJITでリンクするとシンボルの競合や望ましくない動作を起こす可能性があります。 cuda-compat-11-4をインストールすると、CUDAの拡張された互換性に干渉し、ドライバがr465でもTensorRTで失敗することがあります。ワークアラウンドとしては、cuda-compat-11-4パッケージを削除するか、ドライバをr470にアップグレードすることです。(Jetsonプラットフォームには適用されません)- TensorFlow 1.xはPython 3.9に対応していません。TensorFlow 1.xに依存するPythonサンプルは、Python 3.9で実行できません。
- TensorRTは
IConstantLayerとIShuffleLayerの融合を限定的にサポートしています。明示的な量子化モードではConvolutionsとFully-Connectedレイヤの重みは融合しなくてはいけません。従って、重みシャッフルがサポートされていない場合、レイヤーの量子化に失敗するかもしれません。 DLAのネットワークの中でconvolutionレイヤがNHWCなネットワークの入力を受け付ける場合、convolutionレイヤの演算精度は入力テンソルのデータ型と一致する必要があります。- 混合精度は
Poolingレイヤをサポートしていません。入力と出力のテンソルにおけるデータ型はレイヤの精度と一致させるべきです。 Jetson TX2でCPU版のPyTorchを使用し、engine_refit_mnist、network_api_pytorch_mnist、onnx_packnetのPythonサンプルを実行するとIllegal instruction (core dumped)に遭遇するかもしれません。ワークアラウンドはサンプルのREADMEに従いGPU対応版のPyTorchをインストールすることです。- WSL2上のINT8精度での
sample_mnistでは断続的な精度の問題が観測されています。 debianとRPMパッケージ(Pythonバインディング、UFF、GraphSurgeon、ONNX-GraphSurgeon)のwheelは自動的に依存解決しません。pipを使い手動でインストールするか、代わりにwheelをインストールするようにしてください。- ネットワークにあるレポジトリからTensorRTをインストールした際に以下のようなエラーを見るかもしれません。
Could not load library libcudnn_ops_infer.so.8. Error: libcublas.so.11: cannot open shared object file: No such file or directory
cuDNNはRPM依存のlibcublas.so.11()(64bit)に依存していますが、この依存インストールは最新版リリースのCUDAにあるcuBLASではなくCUDA 11.0にあるcuBLASをインストールします。このライブラリのサーチパスは正しく設定されずcuDNNはcuBLASライブラリを見つけられなくなります。ワークアラウンドは手動で最新版のlibcublas-11-xパッケージをインストールすることです。 - WindowsのPythonサンプル
uff_ssdでは、freezeしたTensorFlowグラフをUFFに変換する際に起こる既知の問題があります。ワークアラウンドとしては、Linuxやコンテナ上でUFFモデルを生成してコピーすることです。生成したUFFファイルを\path\to\samples\python\uff_ssd\models\ssd_inception_v2_coco_2017_11_17\frozen_inference_graph.uffにコピーしてください。
- TensorRTはGPUのメモリアロケーションの失敗を補足し、メモリ不足エラーを引き起こすメモリ要求を持ったプロファイリング戦略を回避します。しかし、プラットフォームによってはGPUメモリアロケーションの失敗はCUDAによって体よく扱えず回復不能なアプリケーションステータスを引き起こします。もしこの問題が起こった場合は、ワークスペースのサイズが大きい場合は下げたり、大量のGPUメモリを要求する戦略を回避するために
- パフォーマンス
NVIDIA Jetson AGX Xavier™でFP16モードにしたResNeXtネットワークではTensorRT 8.0.1.6と比較して、最大で7.5%のパフォーマンス低下が発生しました。PoolingレイヤーをConcatenateレイヤーの前後に配置したネットワークでは、最大で15%のパフォーマンス低下が発生します。- TensorRT 8.2.3でこの問題は修正されました
- 活性化とバイアスの処理で
FullyConnectedが支配的なネットワークの中には、TensorRT 7.1と比較してパフォーマンスの低下が見られる。- FP32モードで最大12%です。これは将来のリリースで修正される予定です。
NVIDIA Maxwell®/Pascal GPUsのFP16モードでは最大10%です。
- NVIDIA Jetson Nano™上でVGG16のような
FullyConnectedの処理が重いネットワークにはTensorRT 7.1と比較し最大8%のパフォーマンス低下が見られます。 - Xavierでは最大10-11%のパフォーマンス低下が見られます。
ResNet-152のバッチサイズ2、FP16でのTensorRT 7.2.3との比較ResNeXtネットワークの1か2の少ないバッチサイズ、FP32でのTensorRT 6との比較
- Xavier上では、大きなカーネルサイズの
deconvを使ったネットワークにおいて、このレイヤに対するエンジンビルドの時間が大きく増大することがあります。またJetson Nano/TX1でもまたthe launch timed out and was terminatedというエラーメッセージが表示されることがあります。 P100とV100上でCUDA 11.3を使用した時、TensorRT 7.2.3と比較し最大40%のパフォーマンス低下が見られます。CUDA 11.0では発生しません。(Jetsonプラットフォームには適用されません)ElementWise ADDレイヤの入力におけるdynamic rangesが異なるとき、NVIDIA DLA上のResNetライクなネットワークをJetPack 4.5で実行した際、TensorRT 7.2.3と比較し最大10%のパフォーマンス低下があります。これはDLAのバグであるElementWise ADDレイヤの2番目の入力に対するdynamic rangeを無視する問題を修正したことによるものです。何らかの精度の問題を引き起こします。- DLAでは精度を保つためにINT8の
LeakyReLUレイヤをFP16へ自動的に変換します。そのためReLUのような別の活性化関数を使った同等のネットワークに対してレイテンシが悪化することがあります。これを軽減するためにDLAではLeakyreLUレイヤを無効にできます。 - ビルダーはエンジンをビルドするために最大60%より多くのメモリを要求することがあります。
- 並行して
DLAのConvNetsを他のDLA、Xavierプラットフォーム上のiGPUと実行した場合、DLA単独で実行した場合と比較して最大126%のパフォーマンス低下が見られます。 NVIDIA Volta GPUs上のSSD-Inception2ネットワークではTensorRT 8.0と比較し最大21%のパフォーマンス低下が見られます。- FP16でスパース性を使ったネットワークでは最大5%のパフォーマンス低下があります。
InstanceNormプラグインを使ったネットワークでは最大25%のパフォーマンス低下があります。3d_unetのような3D convolutionを使ったネットワークではエンジンのビルド時間がTensorRT 8.0と比較し最大で500%長くなります。これは多くの高速カーネルが追加されためで、プロファイリング時間が増大しました。
最後に
今回はTensorRT 8.2.2/8.2.3のリリースノートの内容についてご紹介しました。 オプティムは常にリリースノートを追跡しプログラムの改善を行うエンジニアを募集しています。