TensorRT-RTX 1.2 がリリース!
ずっと待ってたTensorRT-RTX 1.2 ですが、やっとリリースされました!
リリース1.2の主なトピックは次のようなものになります。
- CUDA 13に対応。CUDA 12.9と13で別のバイナリに。
- ダイナミックシェイプに自動的に対応可能なRTX CUDA Graphを実装。1行のコードを追加するだけで適用可能で、特に入力が動的に変わる場合、Windowsを利用している場合に効果が大きい。
CUDA 13対応は予告されていたもので驚きはありませんでしたが、ダイナミックシェイプ対応のCUDA Graph実装は予想外!わたしのお気持ちissue(しかも自分が間違ってた)の投稿に対して、技術力で全力で回答してくれた?
これは試さざるを得ない!
CUDA Graphってなんぞ?
CUDA Graphは、聞いたことはありましたが一体何者なのか?たぶん速くなる技術?
これまで特に意識せずともそこそこの速度が出ていたので気にしたことはありませんでした。
早速CUDA Graphについて調べてみます。
まずはNVIDIA公式技術blogから。
なるほど、わからん。(長くて)
たくさんの処理を順次進めていく中で、それぞれに小さな待機時間などが発生するので、積み重なって全体として大きなオーバーヘッドになるよ、ということでしょうか。
Windows Copilotに聞いてみます。
CUDA Graphの概要
CUDA Graphは、NVIDIAのCUDAプラットフォームで導入された機能で、複数のGPU操作(カーネル起動、メモリ転送など)をグラフ構造として定義し、それを一括で実行することで、従来の逐次的なAPI呼び出しによるオーバーヘッドを削減します。利点
- オーバーヘッドの削減:カーネル起動やメモリ転送のAPI呼び出しをまとめて実行
- パフォーマンス向上:特に小さなバッチサイズや短時間の処理で効果的
- 再利用性:一度構築したグラフは何度でも再利用可能
- 柔軟な制御:条件付きノードや動的パラメータにも対応
なるほど。オーバーヘッドを削減してパフォーマンスを向上させる技術のようです。(ふんわり)
TensorRT-RTX 1.2で実装されたRTX CUDA Graphって?
NVIDIA CUDA Toolkit には、GPU 操作の起動ワークフローを最適化する実行グラフのキャプチャまたは構築を可能にするCUDA グラフのサポートが含まれています。CUDA グラフは、CPU から GPU へのカーネル起動オーバーヘッドを最小限に抑え、GPU グリッドの初期化コストを削減することで、実行時のオーバーヘッドを削減するのに役立ちます。
現在、TensorRT推論ワークフローでは、推論中にストリームをキャプチャすることでCUDAグラフを実装できます。しかし、動的シェイプを使用するTensorRT for RTXでは、TensorRTはフォールバックカーネルとシェイプ特化カーネルという2種類の動的シェイプカーネルをコンパイルして実行します。その結果、CUDAグラフのキャプチャの開始と終了の最適なポイントを決定することが困難になる場合があります。
この問題に対処するため、TensorRT-RTX は、動的な形状に対応したインテリジェントな CUDA Graph キャプチャを、わずか 1 行のコード変更で実現するネイティブ API を提供します。この API により、実行時に形状が変化する場合でも、より正確かつ効果的なグラフ管理が可能になります。
この API によるパフォーマンスの向上が最も期待できるのは、次のシナリオです。
・動的な入力形状による推論
・ハードウェア アクセラレーションによる GPU スケジューリング機能を備えた Windows オペレーティング システム
なるほど、TensorRT-RTXでの動的シェイプに対してもCUDA Graphが簡単に扱えるようにAPIを作ってくれたということですね。控えめに行って神アップデートでは?
tensorrt_rtx.exeで試してみる
自作アプリに適用する前に、tensorrt_rtx.exeで試してみます。
現在アプリは、
- TensorRT-RTX 1.1
- CUDA Graphを利用していない
ので、TensorRT-RTX 1.2+RTX CUDA Graphを有効にするとどのようになるか比較してみます。
tensorrt_rtx.exeでRTX CUDA Graphを利用するには、--rtxCudaGraphStrategy=wholeGraphというオプションを設定するとよいようです。
利用するONNXモデルは、yolov8-mです。
[I] === Performance summary ===
[I] Throughput: 34.2773 qps
[I] Latency: min = 28.7866 ms, max = 30.1851 ms, mean = 29.0588 ms, median = 28.9851 ms, percentile(90%) = 29.3088 ms, percentile(95%) = 29.905 ms, percentile(99%) = 30.1851 ms
[I] Enqueue Time: min = 1.51196 ms, max = 2.68823 ms, mean = 1.72414 ms, median = 1.6521 ms, percentile(90%) = 1.90454 ms, percentile(95%) = 2.0415 ms, percentile(99%) = 2.68823 ms
[I] H2D Latency: min = 3.58496 ms, max = 3.78784 ms, mean = 3.63597 ms, median = 3.62524 ms, percentile(90%) = 3.68433 ms, percentile(95%) = 3.71411 ms, percentile(99%) = 3.78784 ms
[I] GPU Compute Time: min = 25.043 ms, max = 26.3413 ms, mean = 25.2986 ms, median = 25.2039 ms, percentile(90%) = 25.5479 ms, percentile(95%) = 26.1611 ms, percentile(99%) = 26.3413 ms
[I] D2H Latency: min = 0.120117 ms, max = 0.136963 ms, mean = 0.124198 ms, median = 0.120361 ms, percentile(90%) = 0.13208 ms, percentile(95%) = 0.134766 ms, percentile(99%) = 0.136963 ms
[I] Total Host Walltime: 1.02108 s
[I] Total GPU Compute Time: 0.885451 s
[I] Explanations of the performance metrics are printed in the verbose logs.
[I]
&&&& PASSED TensorRT-RTX.tensorrt_rtx [TensorRT v10101] [b26] # tensorrt_rtx --onnx=D:\source\repos\WoLNamesBlackedOutWin\.github\App12\App12\my_yolov8m_s_dy.onnx --minShapes=images:1x3x1280x736 --maxShapes=images:16x3x1280x736 --optShapes=images:8x3x1280x736
[I] === Performance summary ===
[I] Throughput: 34.4868 qps
[I] Latency: min = 28.4358 ms, max = 29.2969 ms, mean = 28.7514 ms, median = 28.7155 ms, percentile(90%) = 28.9849 ms, percentile(95%) = 29.0593 ms, percentile(99%) = 29.2969 ms
[I] Enqueue Time: min = 0.0556641 ms, max = 0.168457 ms, mean = 0.0884766 ms, median = 0.0848389 ms, percentile(90%) = 0.116699 ms, percentile(95%) = 0.140137 ms, percentile(99%) = 0.168457 ms
[I] H2D Latency: min = 3.59888 ms, max = 3.76611 ms, mean = 3.64595 ms, median = 3.63184 ms, percentile(90%) = 3.71094 ms, percentile(95%) = 3.74121 ms, percentile(99%) = 3.76611 ms
[I] GPU Compute Time: min = 24.7039 ms, max = 25.4045 ms, mean = 24.9713 ms, median = 24.913 ms, percentile(90%) = 25.2209 ms, percentile(95%) = 25.2356 ms, percentile(99%) = 25.4045 ms
[I] D2H Latency: min = 0.119873 ms, max = 0.152588 ms, mean = 0.134241 ms, median = 0.134644 ms, percentile(90%) = 0.147217 ms, percentile(95%) = 0.151367 ms, percentile(99%) = 0.152588 ms
[I] Total Host Walltime: 1.15987 s
[I] Total GPU Compute Time: 0.99885 s
[I] Explanations of the performance metrics are printed in the verbose logs.
[I]
&&&& PASSED TensorRT-RTX.tensorrt_rtx [TensorRT v10200] [b44] # tensorrt_rtx --onnx=D:\source\repos\WoLNamesBlackedOutWin\.github\App12\App12\my_yolov8m_s_dy.onnx --minShapes=images:1x3x1280x736 --maxShapes=images:16x3x1280x736 --optShapes=images:8x3x1280x736 --rtxCudaGraphStrategy=wholeGraph
スループットはあんまり変わらなそうですが、Enqueueの値が数桁違います!
enqueueは処理をキューに追加することらしいので、RTX CUDA Graphを利用することで処理への投入が速くなったということですね。
レイテンシーも改善しているように見えます。
自作アプリにRTX CUDA Graphを適用してみた!
RTX CUDA GraphをTensorRT-RTXに適用するには次の1行を書き足すだけでした。(簡単!)
runtimeConfig->setCudaGraphStrategy(nvinfer1::CudaGraphStrategy::kWHOLE_GRAPH_CAPTURE);
自作アプリは動画の処理を行うものなのですが、適用すると挙動はどのようになったかというと、
| FPS | |
|---|---|
| TensorRT-RTX 1.1 | 69fps |
| TensorRT-RTX 1.2 | 71fps |
という感じで、GPUの使用率があがってFPSも改善されました!
自作アプリ的には、推論の前後処理が遅くネックになっているので、そこをちょこちょこと改善していきたいと思っています。
まとめ
- TensorRT-RTX 1.2 ではRTX CUDA Graphがリリースされ、動的シェイプ、Windows環境で改善が期待できます。
- RTX CUDA Graphを適用したところ、Enqueue、Latencyで改善が認められました。
- 物体検出アプリに適用したところ処理FPSが改善しました。