まえがき
R&Dの宮﨑です。最近プライベートではGoogle App Scriptを書いて遊んでいます。 今回はTensorRT 8.2.4の内容をメモしました。
気になった内容
- TensorRTはネットワークをノードのフュージョンを行うなどして最適化してくれますが、時にバグがあります。今回はそのあたりに多く修正が入ってくれたようです。
- チャンネルではない次元を軸とした
concatレイヤが水平マージに続いたときに機能的な問題がありました。本リリースでこの問題は修正されました。 - TensorRTはバッチの次元に沿ったバッチ化した
Matmulsの水平フュージョンを誤って実行していました。本リリースでこの問題は修正されました。 - TensorRTが
Pointwiseのtacticを見つけることに失敗するケースがありました。本リリースでこの問題は修正されました。 WeNetのtransformerエンコーダレイヤのおいてフュージョンされたリダクションカーネルが精度低下を引き起こす機能的な問題がありました。本リリースでこの問題は修正されました。- 2つのレイヤーの入力(または出力)が同じ
IQuantization/IDequantizationレイヤを共有したときに機能的な問題がありました。本リリースでこの問題は修正されました。 Convolution+QuantizationまたはPointwise+Quantizationのフュージョンで出力の型がINT8に制約されている場合、他のフュージョンが正しく行われるためにConvolutionとPointwise演算の精度を指定する必要がありました。ConvolutionとPointwiseの精度がまだ設定されていない場合、INT8の精度はDequantizationと明示的にフュージョンすることを要求するのでfloatにする必要がありました。本リリースでこの問題は修正されました。
- チャンネルではない次元を軸とした
意訳
これはTensorRT 8.2.4のリリースノートで、x86のLinuxとWindows向けです。Server Base System Architecture (SBSA) のためにARM®ベースのCPUコアを組み込んだLinuxのユーザー向けでもあります。 このリリースには、以前のTensorRTからのいくつかの修正と、以下の追加変更が含まれています。以前のTensorRTのドキュメントについては、NVIDIA TensorRT Archived Documentationを参照してください。
これらのリリースノートは、特に(Jetsonプラットフォームには適用されません)と付記されていない限り、ワークステーション、サーバー、およびNVIDIA JetPack™のユーザー向けに記載されています。
このリリースには、以前のTensorRT 8.x.xリリースからのいくつかの修正と、以下の追加変更が含まれています。以前リリースされたTensorRTのドキュメントについては、NVIDIA TensorRT Archived Documentationを参照してください。
非推奨APIのライフタイム
- TensorRT 8.0より前に非推奨となったAPIはTensorRT 9.0で削除されます。
- TensorRT 8.0で非推奨となったAPIは少なくとも2022年8月まで保持されます。
- TensorRT 8.2で非推奨となったAPIは少なくとも2022年11月まで保持されます。
非推奨となった機能の使用を削除するためにどのようにコードを更新するかはAPIドキュメント(C++、Python)をご参照ください。
互換性
- TensorRT 8.2.4 は以下でテストされています。
- このリリースでは以下のCUDAのバージョンをサポートしています。
- TensorRTはFeatures For Platforms And SoftwareセクションにあるcuDNNとcuBLASのバージョン含めテスト済みのソフトウェアスタックで使用することが推奨されています。他の意味的に互換性のあるcuDNNやcuBLASも使用できますが、性能が上下する可能性があります。またまれに機能的に後退するかもしれません。
修正された問題
UBSanの問題は、ドキュメントで議論されていませんでした。TensorRT Developer GuideにUndefined Behavior Sanitizerの問題を議論する新しいセクションを追加しました。- チャンネルではない次元を軸とした
concatレイヤが水平マージに続いたときに機能的な問題がありました。本リリースでこの問題は修正されました。 - 浮動小数点の出力を持つネットワークにおいて、エンジンでINT8を使用できる設定の場合、TensorRTは出力の過剰な量子化ノイズを回避するヒューリスティックを備えています。以前は、このヒューリスティックは必要に応じてプラグインが浮動小数点の出力に対応するか、エンジンのビルドに失敗することを想定していました。現在は、プラグインによるINT8出力からの量子化ノイズを回避しようとせずとも、エンジンはビルドされます。さらに、INT8型のネットワーク出力に接続されたINT8の出力を持つプラグインも現在は動作します。
- TensorRTはメモリ割り当ての計算を行う際に、テンソルのサイズを誤って計算していました。これは全てのネットワークI/Oテンソルのボリュームを累積するときに、ダイナミックシェイプが
max optの次元で整数オーバーフローを引き起こす場合に発生していました。
※訳注 「本リリースでこの問題は修正されました」といった旨の文がありませんが「修正された問題」セクションにあり、過去形で記述されていることから修正されたということでしょうか - TensorRTはバッチの次元に沿ったバッチ化した
Matmulsの水平フュージョンを誤って実行していました。本リリースでこの問題は修正されました。 - TensorRTが
Pointwiseのtacticを見つけることに失敗するケースがありました。本リリースでこの問題は修正されました。 WeNetのtransformerエンコーダレイヤのおいてフュージョンされたリダクションカーネルが精度低下を引き起こす機能的な問題がありました。本リリースでこの問題は修正されました。- 2つのレイヤーの入力(または出力)が同じ
IQuantization/IDequantizationレイヤを共有したときに機能的な問題がありました。本リリースでこの問題は修正されました。 Convolution+QuantizationまたはPointwise+Quantizationのフュージョンで出力の型がINT8に制約されている場合、他のフュージョンが正しく行われるためにConvolutionとPointwise演算の精度を指定する必要がありました。ConvolutionとPointwiseの精度がまだ設定されていない場合、INT8の精度はDequantizationと明示的にフュージョンすることを要求するのでfloatにする必要がありました。本リリースでこの問題は修正されました。- 特定の大型
GPT2-XLモデルバリエーションをビルドする際にクラッシュすることが知られていました。本リリースでこの問題は修正されました。
既知の問題
機能
- TensorRTはGPUのメモリアロケーションの失敗を補足し、メモリ不足エラーを引き起こすメモリ要求を持ったプロファイリングタクティクスを回避します。しかし、プラットフォームによってはGPUメモリアロケーションの失敗はCUDAによって体よく扱えず回復不能なアプリケーションステータスを引き起こします。もしこの問題が起こった場合は、ワークスペースのサイズが大きい場合は下げたり、大量のGPUメモリを要求するタクティクスを回避するために
IAlgorithmSelectorインターフェースを使用することをご検討ください。 - Azure VMのT4でTopKレイヤがあるネットワークを走らせるとTensorRTが不安定になることがあります。
- 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%のパフォーマンス低下が発生しました。- 活性化とバイアスの処理で
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.4のリリースノートの内容についてご紹介しました。 オプティムは常にリリースノートを追跡しプログラムの改善を行うエンジニアを募集しています。