Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TensorRT化のワークフロー事例紹介 / CUDA Acceleration Seminar 4 20220825

TensorRT化のワークフロー事例紹介 / CUDA Acceleration Seminar 4 20220825

2022年8月25日に開催した「CUDA高速化セミナーvol.4 / TensorRT化のワークフロー事例紹介」の当日資料です。

More Decks by 株式会社フィックスターズ

Other Decks in Programming

Transcript

  1. Copyright © Fixstars Group • CUDAに関連する様々な技術情報を、CUDA高速化セミナーとして発信しています • 今回は、深層学習を題材とし、学習済みモデルをGPU向けに最適化するための 標準ツールになっている TensorRT

    について、ワークフローの事例を紹介します • こんな方に向いています ◦ これから TensorRT を使ってみようと考えている ◦ 普段使用しているが最新の情報をキャッチアップしたい 本講演の位置づけ 4 https://speakerdeck.com/fixstars/cudagao-su- hua-seminavol-dot-1-hua-xiang-chu-li- arugorizumufalsegao-su-hua https://speakerdeck.com/fixstars/cudagao-su- hua-seminavol-dot-2-cudaakitekutiyafalsejin- hua https://speakerdeck.com/fixstars/cudagao-su- hua-seminavol-dot-3-sohutoueagao-su-hua- toshen-ceng-xue-xi vol.1 画像処理アルゴリズムの高速化 vol.2 CUDAアーキテクチャの進化 vol.3 ソフトウェア高速化と深層学習
  2. Copyright © Fixstars Group 発表者紹介 冨田 明彦 ソリューションカンパニー 執行役員 2008年に入社。金融、医療業界において、ソ

    フトウェア高速化業務に携わる。その後、新規 事業企画、半導体業界の事業を担当し、現職。 5 前川 利紀 ソリューション第3事業部 シニアエンジニア 2017年入社。元は組み込みエンジニアだが現在 はAI関連製品の開発に従事。仕事でも趣味でも ONNXモデルを使うことが多い。
  3. Copyright © Fixstars Group フィックスターズの強み コンピュータの性能を最大限に引き出す、ソフトウェア高速化のエキスパート集団 ハードウェアの知見 アルゴリズム実装力 各産業・研究分野の知見 7

    目的の製品に最適なハードウェアを見抜き、 その性能をフル活用するソフトウェアを開 発します。 ハードウェアの特徴と製品要求仕様に合わ せて、アルゴリズムを改良して高速化を実 現します。 開発したい製品に使える技術を見抜き、実 際に動作する実装までトータルにサポート します。
  4. Copyright © Fixstars Group サービス概要 お客様専任のエンジニアが直接ヒアリングを行い、高速化を実現するために乗り越えるべき 課題や問題を明確にしていきます。 高速化のワークフロー コンサルティング 先行技術調査

    性能評価・ボトルネックの特定 高速化 アルゴリズムの改良・開発 ハードウェアへの最適化 レポート作成 サポート レポートやコードへのQ&A 実製品への組込み支援 8
  5. Copyright © Fixstars Group サービス提供分野 9 半導体 自動車 産業機器 生命科学

    金融 •NAND型フラッシュメモリ向けフ ァームウェア開発 •次世代AIチップの開発環境基盤 •自動運転の高性能化、実用化 •次世代パーソナルモビリティの 研究開発 •Smart Factory実現への支援 •マシンビジョンシステムの高速化 •ゲノム解析の高速化 •医用画像処理の高速化 •AI画像診断システムの研究開発 •デリバティブシステムの高速化 •HFT(アルゴリズムトレード)の高速化
  6. Copyright © Fixstars Group サービス領域 様々な領域でソフトウェア開発サービスを提供しています。大量データの高速処理は、 お客様の製品競争力の源泉となっています。 10 組込み高速化 画像処理・アルゴリズム

    開発 分散並列システム開発 GPU向け高速化 FPGAを活用した システム開発 量子コンピューティング AI・深層学習 自動車向け ソフトウェア開発 フラッシュメモリ向けフ ァームウェア開発
  7. Copyright © Fixstars Group 画像処理アルゴリズム開発 高速な画像処理需要に対して、経験豊富なエンジニアが 責任を持って製品開発をご支援します。 お客様の課題 高度な画像処理や深層学習等のアルゴリズム を開発できる人材が社内に限られている

    機能要件は満たせそうだが、ターゲット機器 上で性能要件までクリアできるか不安 製品化に結びつくような研究ができていない ご支援内容 深層学習ネットワーク精度の改善 様々な手法を駆使して深層学習ネットワークの精度を改善 論文調査・改善活動 論文調査から最先端の手法の探索 性能向上に向けた改善活動を継続 アルゴリズム調査・改変 課題に合ったアルゴリズム・実装手法を調査 製品実装に向けて適切な改変を実施
  8. Copyright © Fixstars Group GPU向け高速化 高性能なGPUの本来の性能を十分に引き出し、 ソフトウェアの高速化を実現します。 お客様の課題 GPUで計算してみたが期待した性能が出ない GPU/CPUを組み合わせた全体として最適な

    設計がしたい ご支援内容 GPU高速化に関するコンサルティング CPU・GPU混在環境でのシステム設計 アルゴリズムのGPU向け移植 GPUプログラム高速化 継続的な精度向上 原価を維持したまま機能を追加するため、も う少し処理を速くしたい 品質確保のため、精度を上げたく演算量は増 えるが性能は維持したい
  9. Copyright © Fixstars Group TensorRT 15 ※画像引用元:https://developer.nvidia.com/tensorrt • TensorRT ◦

    DNNモデルをNVIDIAハードウェア向けに変換して推論処理を高速化してくれる • やってくれること ◦ 量子化(INT8化、fp16化) ◦ 複数レイヤの結合 ◦ チューニングパラメータの自動選択 ◦ 実行ハードの自動選択 ▪ CUDA Core/TensorCore ◦ メモリ管理、最適な実行方法など
  10. Copyright © Fixstars Group 推論プログラムのイメージ 16 前処理 モデル 後処理 初期化(CUDAメモリなど)

    画像の取得 前処理 TensorRT推論 後処理 元のモデル 推論プログラム(新規作成) 変換
  11. Copyright © Fixstars Group ONNX • DNNモデルをフレームワーク間で交換するためのフォーマット 17 入力 出力

    ・モデル入力 ・グラフ構造 - オペレータ - 重みデータ ・モデル出力 input[] ・・・モデル入力定義 output[] ・・・モデル出力定義 initializer[] ・・・固定値、重み node[] ・・・オペレータ ModelProto GraphProto DNNモデル ONNX
  12. Copyright © Fixstars Group ONNX以外の対応状況 • Caffe Parser and UFF

    ParserはTensorRT 7.0でdeprecated(※1) ◦ TensorRT 9.0で削除されそう… • tf2onnx, keras2onnx, TF-TRT への移行が推奨されている • TF-TRT ◦ TensorFlowの1機能として取り込まれている ▪ ONNX変換せず直接モデルをTensorRT変換する ▪ TensorFlowでそのまま推論を行える ◦ PyTorchにもTorch-TensorRTというのがある 18 ※1:https://docs.nvidia.com/deeplearning/tensorrt/release-notes/tensorrt-8.html#rel_8-0-1 > APIs deprecated before TensorRT 8.0 will be removed in TensorRT 9.0
  13. Copyright © Fixstars Group 固定値の定数化 • TensorRTは重みなどの入力がinitializerのケースのみ対応している場合がある • initializer ◦

    ONNXファイルで定数値を保持しているリスト(配列) • ONNXモデル出力した際に固定値を計算によって算出するモデルが生成され るケースがある ◦ 事前に計算を実行してinitializerに変換が可能(Constant folding) • Constant foldingに対応しているツール ◦ ONNX Simplifier (有志作成。カスタムオペレータはDLL開発が必要。※1) ◦ ONNX GraphSurgeon (NVIDIA製。Python呼び出しコードが必要。※2) ◦ Polygraphy (NVIDIA製。※3) 21 ※1:https://github.com/daquexian/onnx-simplifier ※2:https://github.com/NVIDIA/TensorRT/tree/main/tools/onnx-graphsurgeon ※3:https://github.com/NVIDIA/TensorRT/tree/main/tools/Polygraphy
  14. Copyright © Fixstars Group 変換時のエラー • オペレータがサポート対象外 ◦ レイヤーごとの対応表(※1) ◦

    ONNXオペレータの対応表(※2) • 特定のパラメータなどに対応していない ◦ 基本的に変換時のエラーメッセージをよく読むしかない ▪ 問題切り分けのため普段から--verboseで変換実行しておくと良い ◦ パワーユーザであればソースコード(※3)で直接assertしている箇所を確認すれば詳細な条 件が分かる • TensorRTのバグ ◦ 「Internal Error」と表示されたらバグの可能性 ◦ エラーメッセージに表示されている.cppファイル名がGitHubのソースコードから見つからなけ ればTensorRT本体(非公開)の可能性 22 ※1:https://docs.nvidia.com/deeplearning/tensorrt/support-matrix/index.html#layers-precision-matrix ※2:https://github.com/onnx/onnx-tensorrt/blob/main/docs/operators.md ※3:https://github.com/onnx/onnx-tensorrt/blob/main/builtin_op_importers.cpp
  15. Copyright © Fixstars Group モデルの修正 • 重みをもたないオペレータは別の等価なオペレータに置き換え可能 ◦ 単純な四則演算など •

    重みをもつオペレータや等価なオペレータに置き換え不能な場合 ◦ 再学習が必要 ◦ 推論精度が悪化するケースも • 前処理、後処理でエラーになっている場合 ◦ ONNXエクスポートの範囲外にする方法もある ◦ 推論プラグラム側に処理を移動させるイメージ ◦ 当然TensorRTの恩恵を受けられない 23
  16. Copyright © Fixstars Group バグ報告 • TensorRT本体の不具合が疑われる場合、思い切ってバグ報告・問い合わせしてみ た方が良い ◦ ただし英語…

    • 必要な準備 ◦ 再現環境の情報を整理する ◦ 再現用の最小セットONNXモデルを作成する ▪ Polygraphyを使う場合のサンプルがある(※1) ◦ trtexecコマンドで再現する手順を整理し、再現時のログを取得する • バグ報告先 ◦ ONNXパーサー、TensorRTプラグインはGithub(※2) ◦ 上記以外はNVIDIAフォーラム(※3) 24 ※1:https://github.com/NVIDIA/TensorRT/tree/main/tools/Polygraphy/examples/cli/debug/02_reducing_failing_onnx_models ※2:https://github.com/NVIDIA/TensorRT/issues ※3:https://forums.developer.nvidia.com/c/ai-data-science/deep-learning/tensorrt/92
  17. Copyright © Fixstars Group キャリブレーション • INT8で推論する場合はキャリブレーションが必要 ◦ モデルをエンジンファイルに変換する際に一緒にキャリブレーションを行う ◦

    昔は変換プログラムを作成する必要があったが、今はPolygraphyにデータ読み込みPythonスク リプトを渡すだけで良くなった(※1) • キャリブレーションに使用するデータ ◦ 実際に推論を行う環境に近いデータ ◦ ImageNetの画像分類タスクなら500画像(※2) 25 ※1: https://github.com/NVIDIA/TensorRT/tree/main/tools/Polygraphy/examples/cli/convert/01_int8_calibr ation_in_tensorrt#running-the-example ※2:https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#enable_int8_c
  18. Copyright © Fixstars Group 変換事例の概要(1) • やったこと ◦ PyTorch版EfficientDet実装(※1)をTensorRT化 •

    環境 ◦ PC(ONNXモデル出力) ▪ Ubuntu 18.04 ▪ PyTorch v1.7.0 ▪ torchvision v0.8.0 ◦ Jetson AGX Xavier開発者キット(TensorRT変換、推論実行) ▪ 初回:JetPack 4.6 (TensorRT 8.0.1) ▪ 追試:JetPack 5.0 Developer Preview(TensorRT 8.4.0 Early Access) 27 ※1:Toan Dao Minh. 2019. A Pytorch Implementation of EfficientDet Object Detection https://github.com/toandaominh1997/EfficientDet.Pytorch
  19. Copyright © Fixstars Group 変換事例の概要(2) • 前処理 ◦ Float化、[0, 255]→[0.0,

    1.0]化、正規化、512x512リサイズ • モデル(EfficientDet-D0 ※1) ◦ バックボーンネットワーク:EfficientNet-B0(※2) ◦ neck層:BiFPN ◦ head層:RetinaHead(RetinaNetのhead層※3) ◦ 入力:[batch_size, 3, 512, 512] ◦ 出力:[batch_size, 49104, num_classes], [batch_size, 49104, 4] ▪ 49104 = [64x64(1/8), 32x32(1/16), 16x16(1/32), 8x8(1/64), 4x4(1/128)] × num_anchors(9) • 後処理 ◦ (ONNX化対象)閾値以下のBboxを破棄、 Bboxのデコード、 Non Maximum Suppression ◦ (ONNX化対象外)Bboxのスケーリング、ClassIDの文字列化、画像への重畳、画像ファイルの保存 28 ※1:https://arxiv.org/abs/1911.09070 ※2:https://arxiv.org/abs/1905.11946 ※3:https://arxiv.org/abs/1708.02002
  20. Copyright © Fixstars Group 問題解決事例 - Resizeオペレータ(1) • Resizeオペレータ ◦

    output_feature = Resize(input_feature, roi, scales, sizes) ◦ Featureを2倍に拡大する箇所で使用されていた(「画像の拡大」のイメージ) • エラーの内容 ◦ [graph.cpp::computeInputExecutionUses::519] Error Code 9: Internal Error (node_of_floor_0: IUnaryLayer cannot be used to compute a shape tensor) • 原因 ◦ ONNXエクスポート時に拡大サイズ指定がfloat型で計算するように出力されていた ▪ 今回のケースは2倍なので整数型でも計算可能 ▪ ONNXモデルにはCastで整数型にするオペレータも出力されていたがダメだった ◦ TensorRTはfloat型での指定にv8.4まで未対応だった • NVIDIAフォーラムに報告済み ◦ より詳細な内容はブログの報告記事を参照(※1) 29 ※1: https://maminus.hatenadiary.org/entry/2022/01/12/200806
  21. Copyright © Fixstars Group 問題解決事例 - Resizeオペレータ(2) PyTorchでのexport実験 30 #

    F.interpolate() -> Resize の影響チェック import torch class Resize_x2(torch.nn.Module): def __init__(self, use_scale=False): super().__init__() self.use_scale = use_scale def forward(self, input): if self.use_scale: kwargs = dict(scale_factor=2) else: scaled_hw = list(input.shape[2:]) scaled_hw[0] *= 2 scaled_hw[1] *= 2 kwargs = dict(size=scaled_hw) y = torch.nn.functional.interpolate(input, **kwargs) return y dummy_input = torch.ones([16, 3, 224, 224], dtype=torch.float32) model = Resize_x2(use_scale=True) torch.onnx.export(model, dummy_input, 'resize_use_scale.onnx', verbose=True, input_names=['in'], output_names=['out'], opset_version=11)
  22. Copyright © Fixstars Group 問題解決事例 - Non Maximum Suppression(1) •

    Non Maximum Suppression ◦ 1つの物体に対して複数候補が推論されるようなケースで1つの答えに統合する処理 ◦ 推論結果のBoxの重なり具合が大きいものを1つに統合する 32
  23. Copyright © Fixstars Group 問題解決事例 - Non Maximum Suppression(2) •

    TensorRTはNon Maximum Suppressionに直接対応していない ◦ プラグインで対応している ◦ ONNXのNonMaxSuppressionオペレータはプラグインに変換される • I/Fが異なる ◦ torchvision → ONNX → プラグインだとバッチサイズ1固定になってしまう ◦ ONNX変換時に直接プラグイン向けオペレータ出力するのが一番自由度が高い 33 score_threshold 戻り値 bboxをクラスごとに別 に扱うか バッチ次元 ONNX あり インデックス クラスごとに別々のbbox 対応 torchvision なし インデックス 全クラス共通のbbox 非対応 TensorRTプラグイン あり 値(Bboxそのもの) どちらにも設定できる 対応
  24. Copyright © Fixstars Group 問題解決事例 - Non Maximum Suppression(3) •

    ONNX変換時にONNXオペレータではなくTensorRTプラグイン向けオペレー タを出力する ◦ カスタムオペレータで実現可能 ▪ PyTorchのカスタムオペレータからONNXのカスタムオペレータを出力する ◦ TensorRTプラグインの出力テンソル(Bbox数)はSliceオペレータに使えない ▪ 後段の処理はONNX出力対象外に変更(推論プログラム側で後段処理を実行する) • PyTorchのカスタムオペレータ ◦ ONNX出力定義(Pythonコード) ◦ カスタムオペレータ実装(C++コード) 34
  25. Copyright © Fixstars Group 問題解決事例 - Non Maximum Suppression(4) •

    ONNXのカスタムオペレータとして出力 35 @parse_args('v', 'v', 'i', 'f', 'f') def symbolic_efficient_nms_standard(g, boxes, scores, num_boxes, score_threshold, iou_threshold): num_detections, detection_boxes, detection_scores, detection_classes = g.op('tensorrt::EfficientNMS_TRT', boxes, scores, outputs=4, score_threshold_f=score_threshold, iou_threshold_f=iou_threshold, max_output_boxes_i=num_boxes, background_class_i=-1, score_activation_i=0, box_coding_i=0, ) return num_detections, detection_boxes, detection_scores, detection_classes def forward(self, input): … torch.ops.load_library('custom_ops.so') return torch.ops.custom_ops.efficient_nms_standard(transformed_anchors, confs, num_boxes, self.threshold, self.iou_threshold) register_custom_op_symbolic('custom_ops::efficient_nms_standard‘, symbolic_efficient_nms_standard, 11) 「ドメイン名::プラグイン名」で ONNXのカスタムオペレータ出力 PyTorchの推論(ONNXエクスポート)時 はカスタムオペレータのDLLを呼び出す
  26. Copyright © Fixstars Group 問題解決事例 - Non Maximum Suppression(5) •

    DLLのダミー実装 ◦ ONNXのエクスポート時には最低限テンソルのshapeは正しくないとダメ ◦ データの個数や内容によって分岐するようなケースはそれらしい値を出力しないと意図する ONNXモデルが生成できない ◦ 今回はNMS処理を行わずそのままBboxを返すだけの実装とした 36 #include <cstdint> #include <torch/script.h> std::tuple<torch::Tensor, torch::Tensor, torch::Tensor, torch::Tensor> efficient_nms_standard(torch::Tensor boxes, torch::Tensor scores, std::int64_t num_boxes, double score_threshold, double iou_threshold) { auto nmsed_scores = scores.index({"...", 0}); return {torch::tensor({boxes.sizes()[1]}, torch::dtype(torch::kInt64)).reshape({-1, 1}), boxes, nmsed_scores, torch::zeros(nmsed_scores.sizes(), torch::dtype(torch::kInt64))}; } TORCH_LIBRARY(custom_ops, torch_lib) { torch_lib.def("efficient_nms_standard", &efficient_nms_standard); }
  27. Copyright © Fixstars Group 所感 • 対象モデルやONNXのオペレータに詳しくないとトラブルシューティングが 難しい ◦ エラーメッセージを読んでモデルのどの箇所なのか分からないと対処ができない

    ◦ 対象モデルの構造やソースコードの構造はある程度把握しておいた方が良い • すでにTensorRT化済みモデルがあるならそちらを使った方がよさそう ◦ EfficientDetならTensorFlow版が公式でTensorRT化されている(※1) • 慣れるまでONNX変換→trtexecコマンドでTensorRT変換した方が楽そう 37 ※1: https://github.com/NVIDIA/TensorRT/tree/main/samples/python/efficientdet