まえがき
相変わらずゲーム好きなR&Dの宮﨑です。VALORANTの世界大会で日本チームの「ZETA DIVISION」が快進撃を続けて盛り上がりましたね! 今回はTensorRT 8.4.0のリリースノートの内容をメモしました。
気になった内容
- TensorRT 8.2.1から既知の問題として挙げられていた以下の問題がとうとう修正されました。
- ダイナミックシェイプでONNXモデルを動作させる際、同じであることが予測される入力の次元名が異なる場合に精度の問題が起きる場合があります。例えば、もしモデルが2つの2次元入力を持ち、その次元セマンティクスがbatchとseqlenで、ONNXモデル上では2つの入力の次元名が異なったとき、ダイナミックシェイプで動作させると精度の問題が起きる場合がありました。この問題は今回のリリースで修正されました。
Orin
へのサポート。NVIDIA JetPack 5.0
ユーザへのサポートを追加しました。NVIDIA Xavier
とNVIDIA Orin™
ベースのデバイスがサポートされます。
- DLAがネットワークでロードできるメモリプールの制御ができるようになりました。ちなみにOrinはSRAM周りの仕様が少しXavierから変わっています。
意訳
これはTensorRT 8.4.0 Early Access(EA)のリリースノートで、x86のLinuxとWindows、Server Base System Architecture (SBSA) のためにARM®ベースのCPUコアを組み込んだLinuxのユーザー向けです。 これらのリリースノートは、特に(Jetsonプラットフォームには適用されません)と付記されていない限り、ワークステーション、サーバー、およびNVIDIA JetPack™のユーザー向けに記載されています。
このEAリリースは早期テストとフィールドバックのためにあります。TensorRTのプロダクション利用ではTensorRT 8.2.3やそれ以降のTensorRT 8.2.xパッチを引き続きご利用ください。
※訳注: 執筆時点ではTensorRT 8.2.4が最新版です。
注釈: TensorRT 8.4 EAはCUDAネットワークリポジトリの更新を含みません。代わりにローカルリポジトリのインストーラーパッケージを使うべきです。
このリリースには、以前のTensorRT 8.x.xリリースからのいくつかの修正と、以下の追加変更が含まれています。以前のTensorRTのドキュメントについては、NVIDIA TensorRT Archived Documentationを参照してください。
主要な機能と改善
このTensorRTのリリースは以下の主要な機能と改善を含んでいます。
- 大きな空間次元の
convolution
やdeconvolution
レイヤのある一部のネットワークにおいてエンジンファイルサイズとランタイムメモリの使用量を削減しました。 - 以下のC++ API関数とenumが追加されました:
- setMemoryPoolLimit (IBuilderConfig::setMemoryPoolLimit)
- getMemoryPoolLimit (IBuilderConfig::getMemoryPoolLimit)
- MemoryPoolType
setMaxThreads
(IBuilder::setMaxThreads, IRefitter::setMaxThreads, IRuntime::setMaxThreads)getMaxThreads
(IBuilder::getMaxThreads, IRefitter::getMaxThreads, IRuntime::getMaxThreads)- getBuilderPluginRegistry
- 以下のPython API関数とenumが追加されました:
- set_memory_pool_limit
- get_memory_pool_limit
- MemoryPoolType
max_threads property
(Builder.max_threads, Refitter.max_threads, Runtime.max_threads)- get_builder_plugin_registry
※訳注
Refitter.max_threads
に関しては本家がリンクミスをしていたので修正しています
TensorFlow
で学習し、tf2onnx
ツールを使ってエクスポートしたり、TF-TRT
で実行された一部のconvolutional
ニューラルネットワークにおけるパフォーマンスを改善しました。trtexec
ツールに--layerPrecisions
と--layerOutputTypes
フラグを追加し、レイヤ単位の精度制約とレイヤ単位の出力型制約を指定できるようになりました。trtexec
ツールに--memPoolSize
フラグを追加し、unified interface
を通してDLAメモリプール
と同様にワークスペースのサイズも指定できるようになりました。- 3つのDLAメモリプール:マネージドSRAM、ローカルDRAM、グローバルDRAMのサイズをカスタマイズ、クエリーする新しいインターフェースを追加しました。過去のふるまいとの一貫性のため、プールサイズはサブグラフ単位で(i.e. ローダブル単位で)適用されます。ローダブルのコンパイルに成功した場合、
builder
は各ローダブルのプールごとに実際に使われたメモリの量をレポートするので、微調整ができます; メモリ不足で失敗した場合、メッセージが表示されます。DLAのスコープ外でもまた変更があります。ワークスペースサイズ(setMaxWorkspaceSize
,getMaxWorkspaceSize
)を指定、クエリーする既存のAPIは非推奨となり新しいAPIに統合されています。また、デフォルトのワークスペースサイズはデバイスグローバルメモリーサイズへ更新され、TensorRTのサンプルでは新しいデフォルト値を優先して特定のワークスペースサイズが削除されています。詳細についてはNVIDIA TensorRT Developer Guide
にあるCustomizing DLA Memory Poolsセクションをご参照ください。 - ARMの
Server Base System Architecture (SBSA)
パッケージ使用時のA100X
とA30X
バリアントの両方にNVIDIA BlueField®-2data processing units (DPUs)
へのサポートを追加しました。 NVIDIA JetPack 5.0
ユーザへのサポートを追加しました。NVIDIA Xavier
とNVIDIA Orin™
ベースのデバイスがサポートされます。IEinsumLayer
で同じ添え字でラベル付けされた次元をブロードキャストできるようにした。- カーネルサイズの累積が32以下の場合、
sm70+
のGPUの3Dまたは拡張されたdeconvolution
レイヤーに向けたasymmetric padding
のサポートを追加しました。
非推奨APIのライフタイム
- TensorRT 8.0より前に非推奨となったAPIはTensorRT 9.0で削除されます。
- TensorRT 8.0で非推奨となったAPIは少なくとも2022年8月まで保持されます。
- TensorRT 8.2で非推奨となったAPIは少なくとも2022年11月まで保持されます。
- TensorRT 8.4で非推奨となったAPIは少なくとも2023年2月まで保持されます。
非推奨となった機能の使用を削除するためにどのようにコードを更新するかはAPIドキュメント(C++、Python)をご参照ください。
互換性
- TensorRT 8.4.0 は以下でテストされています。
- このリリースでは以下のCUDAのバージョンをサポートしています。
- TensorRTはFeatures For Platforms And SoftwareセクションにあるcuDNNとcuBLASのバージョン含めテスト済みのソフトウェアスタックで使用することが推奨されています。他の意味的に互換性のあるcuDNNやcuBLASも使用できますが、性能が上下する可能性があります。またまれに機能的に後退するかもしれません。
制約事項
- cuDNN、cuBLAS、cuBLASLtライブラリと静的にリンクする場合、TensorRTはCUDA>=11.3を必要とします。
- TensorRTはGPUのメモリアロケーションの失敗を補足し、メモリ不足エラーを引き起こすメモリ要求を持ったプロファイリングタクティクスを回避します。しかし、プラットフォームによってはGPUメモリアロケーションの失敗はCUDAによって体よく扱えず回復不能なアプリケーションステータスを引き起こします。もしこの問題が起こった場合は、ワークスペースのサイズが大きい場合は下げたり、大量のGPUメモリを要求するタクティクスを回避するために
IAlgorithmSelector
インターフェースを使用することをご検討ください。 - 3D非対称パディングはNVIDIA Volta GPU architecture (compute capability 7.0)より古いGPUではサポートされていません。
非推奨/削除された機能
以下の機能はTensorRT 8.4.0 EAでは非推奨となっています:
- 以下のC++ API関数とクラスが非推奨となりました:
IFullyConnectedLayer
getMaxWorkspaceSize
setMaxWorkspaceSize
- 以下のPython API関数とクラスが非推奨となりました:
IFullyConnectedLayer
get_max_workspace_size
set_max_workspace_size
- trtexexの
--workspace
フラグは非推奨となりました。TensorRT 8.2のtrtexecではデフォルトで16MBのワークスペースサイズの制限がありましたが、--workspace
/--memPoolSize
フラグが加えられなかったとき、TensorRTは現在デフォルトで利用できるGPUメモリと同量のワークスペースを割り当てます。ワークスペースのサイズを制限するには--memPoolSize=workspace:<size>
フラグを代わりにお使いください。 IFullyConnectedLayer
演算は非推奨です。一般的には、IMatrixMultiplyLayer
で置き換えるべきでしょう。MatrixMultiply
レイヤは現在FullyConnected
レイヤがサポートしている全てのデータレイアウトをサポートしていません。従ってMatrixMultiply
レイヤの入力がネットワーク I/O テンソルだった場合、BuilderFlag::kDIRECT_IO
を使う時、追加の作業が必要かもしれません:MatrixMultiply
レイヤが以下の組み合わせによりINT8精度を強制された場合:ILayer::setPrecision(DataType::kINT8)
IBuilderConfig::setFlag(BuilderFlag::kOBEY_PRECISION_CONSTRAINTS)
エンジンはビルドに失敗します。
MatrixMultiply
レイヤがDLA上で実行されることが望ましく、GPUへのフォールバックが以下の組み合わせで許可されている場合:IBuilderConfig->setDeviceType(matrixMultiplyLayer, DeviceType::kDLA)
IBuilderConfig->setFlag(BuilderFlag::kGPU_FALLBACK)
レイヤはGPUへフォールバックされて実行されます。
MatrixMultiply
レイヤがDLA上で実行されることを要求され、GPUへのフォールバックが以下の方法で許可されていない場合:IBuilderConfig->setDeviceType(matrixMultiplyLayer, DeviceType::kDLA)
エンジンはビルドに失敗します。
これらの問題を解決するには、制約の一つを緩和するか、IConvolutionLayer
を使用してIFullyConnectedLayer
に代わるConvolution 1x1レイヤを作成するとよいでしょう。
IFullyConnectedLayer
からIMatrixMultiplyLayer
への移行例としてはMNIST APIサンプル(C++, Python)をご参照ください。
修正された問題
EngineInspector
の詳細レイヤ情報ではエンジンが暗黙のバッチ次元でビルドされた際、常にbatch size = 1
と表示されていました。この問題は今回のリリースで修正されました。IElementWiseLayer
レイヤとIUnaryLayer
レイヤは使用される操作によって異なる入力のデータ型を受け付けることができます。どのデータ型がサポートされているか明示するようにドキュメントが更新されました。詳細はTensorRT Developer Guide
のIElementWiseLayerとIUnaryLayerのセクションをご参照ください。- ダイナミックシェイプでONNXモデルを動作させる際、同じであることが予測される入力の次元名が異なる場合に精度の問題が起きる場合があります。例えば、もしモデルが2つの2次元入力を持ち、その次元セマンティクスがbatchとseqlenで、ONNXモデル上では2つの入力の次元名が異なったとき、ダイナミックシェイプで動作させると精度の問題が起きる場合がありました。この問題は今回のリリースで修正されました。
Pooling
レイヤーをConcatenate
レイヤーの前後に配置したネットワークでは、最大で15%のパフォーマンス低下が発生していましたが、今回のリリースで修正されました。- 訳注: TensorRT 8.2.3にも同様の記述がありましたので、誤って記載した可能性があります。
3d_unet
のような3D convolution
を使ったネットワークではエンジンのビルド時間がTensorRT 8.0と比較し最大で500%長くなります。これは多くの高速カーネルが追加されためで、プロファイリング時間が増大しました。- 訳注: この記述が修正された問題のセクションにあるのはおかしいですね。既知の問題のセクションに書くべきところを間違えたのか、「今回のリリースで修正されました。」という文をつけ忘れたのかもしれません。
既知の問題
機能
- L4Tで
3D deconvolution
レイヤのあるネットワークを実行する際に既知の機能的な問題があります。 - K80で
convolution
レイヤのあるネットワークを実行する際に既知の機能的な問題があります。 - まれに特定のパターンを持つLSTMグラフによる推論結果のうちごく一部が非決定的になります。
- ネットワークが
indices
とinput
の両方が動的なGather
レイヤを持ち、最適化プロファイルが大きく動的な範囲(max
とmin
の差)を持つ場合、TensorRTは非常に大きなワークスペースを要求する可能性があります。 HuggingFace
のデモでは、T5-3B
モデルはA100
でのみ検証されており、A10
やT4
その他において動かすことは想定していません。ConvTranspose
の後にBN
が続く量子化(QAT)ネットワークでは、ConvTranspose
が最初に量子化され、次にBN
がConvTranspose
へ融合されます。この融合は不正であり、誤った出力を引き起こします。- LSTMグラフのごく一部で、複数の
MatMul
レイヤがopA/opB==kTRANSPOSE
で同じ入力テンソルを消費するとき、エンジンのビルドに失敗することがあります。 - グラフ最適化の際、新しいノードを追加されてもノード名の重複を防ぐ仕組みはありません。
- FP16モードのTensorRTで、出力の型のみ設定し、レイヤの精度を設定しない場合、キャスト演算が正しく実行されません。
- TensorRTはFP16モードでONNXモデルからインポートされる演算の精度を保持しません。
- TensorRTのプラグインライブラリはデータ競合を引き起こす可能性のあるスレッドセーフではないロガーを使用します。
Einsum
オペレータのあるモデルの実行時にメモリリークの可能性があります。ProfilingVerbosity
にkDETAILED
がセットされたとき、ProfilingVerbosity=kNONE
またはkLAYER_NAMES_ONLY
がセットされたときと比較して、enqueueV2()
の呼び出しに最大2msかかる既知の問題があります。- Azure VMのT4でTopKレイヤがあるネットワークを走らせるとTensorRTが不安定になることがあります。
- WSL2の特定の条件下で、エンジンのビルド時に
Concat
レイヤの前に水平に融合され得るConvolution
レイヤーのあるINetwork
は、アプリケーションをクラッシュさせる内部エラー起きることがあります。ワークアラウンドはWSL2の代わりにLinuxでそのネットワークをビルドすることです。 - 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
レイヤの演算精度は入力テンソルのデータ型と一致する必要があります。debian
とRPM
パッケージ(Pythonバインディング、UFF、GraphSurgeon、ONNX-GraphSurgeon)のwheelは自動的に依存解決しません。pipを使い手動でインストールするか、代わりにwheelをインストールするようにしてください。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
では断続的な精度の問題が観測されています。 - ネットワークにあるレポジトリから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
にコピーしてください。 - DLA上ではネットワークによっては、32以上のバッチサイズを使用すると精度低下が起こる場合があります。
- シングルチャンネルの入力を使用するモデルに対するDLA最適化の際に特定の空間次元がクラッシュを起こす場合があります。
convolutions
またはdeconvolutions
が先行せず、空間次元上のスライシングが続く特定のpointwise
演算を使ったネットワークではoptimizer
でクラッシュする場合があります。builder
がエンジンをビルドするために最大60%より多くのメモリを要求する場合があります。- TensorRTのPythonバインディングがGPUなしで使用された場合、例えば
NVIDIA Container Toolkit
がインストールされていない場合やDockerを実行する前に有効にしたような場合に、アプリケーションを終了させるためにプロセスを終了させなければならない無限ループを起こす可能性があります。
- L4Tで
パフォーマンス
Xavier GPU
向けにビルドされた特定のネットワークではデシリアライズされたエンジンが必要以上にGPUメモリを割り当てる場合があります。- 一部のネットワークではデシリアライズの時間が少し増加する場合があります。
Orin
とXavier
のDLAハードウェア仕様の違いにより、Orinでconvolution
(deconvolution
、fully-connected
とconcat
を含む)を含むDLA
のFP16演算を実行したとき、Xavierで実行したときと比較してレイテンシーの増加が予想されます。同じDLAクロックとメモリバンド幅のとき、OrinでのINT8のconvolution
演算はXavierよりも約4倍速く、OrinでのFP16演算のconvolution
演算はXavierよりも約40%遅くなると予想されます。- DLAクロックには既知の問題があり、
nvpmodel
のパワーモードを変更した後にシステムの再起動をユーザに求めることや性能の低下が発生することがあります。詳細はL4T board support package release notes
をご参照ください。 BERT
やGPT
などのtransformer
ベースのネットワークでは、TensorRTがコンパイルにモデルサイズの最大10倍のCPUメモリを消費する場合があります。Turing
世代のGPUでBS=1
としたとき、DeepASR
のネットワークでは最大17%の性能低下があります。pointwise
演算が2つの入力を持つ場合、フュージョンできなことがあり、パフォーマンス低下に繋がります。例えばMatMul
とSigmoid
は通常フュージョンしてConvActFusion
できますがこのシナリオではできません。Turing
世代のGPUでINT8精度のMaskRCNN-ResNet-101
では最大15%の性能低下があります。Volta
/Turing
世代のGPUでFP32精度のJasper
ネットワークでは最大23%の性能低下があります。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%です。
- Xavierでは最大10-11%のパフォーマンス低下が見られます。
ResNet-152
のバッチサイズ2、FP16でのTensorRT 7.2.3との比較ResNeXt
ネットワークの1か2の少ないバッチサイズ、FP32でのTensorRT 6との比較
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
レイヤを無効にできます。 - 並行して
DLA
のConvNets
を他のDLA
、Xavier
プラットフォーム上のiGPU
と実行した場合、DLA
単独で実行した場合と比較して最大126%のパフォーマンス低下が見られます。 NVIDIA Volta GPUs
上のSSD-Inception2
ネットワークではTensorRT 8.0と比較し最大21%のパフォーマンス低下が見られます。- FP16でスパース性を使ったネットワークでは最大5%のパフォーマンス低下があります。
最後に
今回はTensorRT 8.4.0のリリースノートの内容についてご紹介しました。 オプティムは常にリリースノートを追跡しプログラムの改善を行うエンジニアを募集しています。