12K Views
August 25, 22
スライド概要
CUDA高速化セミナーシリーズの第4回として、ディープラーニングモデルのTensorRT化について、一般的なワークフローの解説と、PyTorchモデルのTensorRT化事例におけるノウハウを紹介します。
深層学習に関連する研究および開発業務を行っており、推論処理の高速化に興味がある方に最適なセミナーです。
<講演内容>
・前提知識のおさらい
・TensorRT変換ワークフロー
・変換事例の紹介
<過去資料>
・vol.1 画像処理アルゴリズムの高速化: https://www.docswell.com/s/fixstars/K24MYM-20220527
・vol.2 CUDAアーキテクチャの進化: https://www.docswell.com/s/fixstars/5RXQJ2-20220623
・vol.3 ソフトウェア高速化と深層学習:
https://www.docswell.com/s/fixstars/5DEJQD-20220728
・vol.4 TensorRT化のワークフロー事例紹介: https://www.docswell.com/s/fixstars/524MGM-20220825
・vol.5 画像処理アルゴリズムの高速化2:https://www.docswell.com/s/fixstars/ZQ81QX-20220929
フィックスターズは、コンピュータの性能を最大限に引き出すソフトウェア開発のスペシャリストです。車載、産業機器、金融、医療など、幅広い分野での開発経験があります。また、ディープラーニングや機械学習などの最先端技術にも力を入れています。 並列化や最適化技術を駆使して、マルチコアCPU、GPU、FPGA、量子アニーリングマシンなど、さまざまなハードウェアでソフトウェアを高速化するサービスを提供しています。さらに、長年の経験から培ったハードウェアの知識と最適化ノウハウを活かし、高精度で高性能なアルゴリズムの開発も行っています。 ・開催セミナー一覧:https://www.fixstars.com/ja/seminar ・技術ブログ :https://proc-cpuinfo.fixstars.com/
CUDA高速化セミナー vol.4 TensorRT化のワークフロー事例紹介 Copyright © Fixstars Group
本日のAgenda ● はじめに ● フィックスターズのご紹介 ● TensorRT変換ワークフロー ● 変換事例の紹介 Copyright © Fixstars Group 2
はじめに Copyright © Fixstars Group
本講演の位置づけ ● CUDAに関連する様々な技術情報を、CUDA高速化セミナーとして発信しています vol.1 画像処理アルゴリズムの高速化 https://speakerdeck.com/fixstars/cudagao-suhua-seminavol-dot-1-hua-xiang-chu-liarugorizumufalsegao-su-hua vol.2 CUDAアーキテクチャの進化 https://speakerdeck.com/fixstars/cudagao-suhua-seminavol-dot-2-cudaakitekutiyafalsejinhua vol.3 ソフトウェア高速化と深層学習 https://speakerdeck.com/fixstars/cudagao-suhua-seminavol-dot-3-sohutoueagao-su-huatoshen-ceng-xue-xi ● 今回は、深層学習を題材とし、学習済みモデルをGPU向けに最適化するための 標準ツールになっている TensorRT について、ワークフローの事例を紹介します ● こんな方に向いています ○ これから TensorRT を使ってみようと考えている ○ 普段使用しているが最新の情報をキャッチアップしたい Copyright © Fixstars Group 4
発表者紹介 冨田 明彦 前川 利紀 ソリューションカンパニー 執行役員 ソリューション第3事業部 シニアエンジニア 2008年に入社。金融、医療業界において、ソ フトウェア高速化業務に携わる。その後、新規 事業企画、半導体業界の事業を担当し、現職。 2017年入社。元は組み込みエンジニアだが現在 はAI関連製品の開発に従事。仕事でも趣味でも ONNXモデルを使うことが多い。 Copyright © Fixstars Group 5
フィックスターズの ご紹介 Copyright © Fixstars Group
フィックスターズの強み コンピュータの性能を最大限に引き出す、ソフトウェア高速化のエキスパート集団 ハードウェアの知見 目的の製品に最適なハードウェアを見抜き、 その性能をフル活用するソフトウェアを開 発します。 アルゴリズム実装力 各産業・研究分野の知見 ハードウェアの特徴と製品要求仕様に合わ せて、アルゴリズムを改良して高速化を実 現します。 開発したい製品に使える技術を見抜き、実 際に動作する実装までトータルにサポート します。 Copyright © Fixstars Group 7
サービス概要 お客様専任のエンジニアが直接ヒアリングを行い、高速化を実現するために乗り越えるべき 課題や問題を明確にしていきます。 高速化のワークフロー コンサルティング 高速化 サポート 先行技術調査 アルゴリズムの改良・開発 レポートやコードへのQ&A 性能評価・ボトルネックの特定 ハードウェアへの最適化 実製品への組込み支援 レポート作成 Copyright © Fixstars Group 8
サービス提供分野 半導体 産業機器 金融 自動車 ● NAND型フラッシュメモリ向けフ ァームウェア開発 ● 次世代AIチップの開発環境基盤 生命科学 ● Smart Factory実現への支援 ● マシンビジョンシステムの高速化 ● 自動運転の高性能化、実用化 ● ゲノム解析の高速化 ● 次世代パーソナルモビリティの 研究開発 ● 医用画像処理の高速化 Copyright © Fixstars Group ● デリバティブシステムの高速化 ● HFT(アルゴリズムトレード)の高速化 ● AI画像診断システムの研究開発 9
サービス領域 様々な領域でソフトウェア開発サービスを提供しています。大量データの高速処理は、 お客様の製品競争力の源泉となっています。 AI・深層学習 組込み高速化 FPGAを活用した システム開発 自動車向け フラッシュメモリ向けフ ソフトウェア開発 ァームウェア開発 画像処理・アルゴリズム 開発 GPU向け高速化 Copyright © Fixstars Group 分散並列システム開発 量子コンピューティング 10
自動車向けソフトウェア開発 アルゴリズム開発から量産車ターゲット向けの高速化まで、 自動運転の実現に向けた統合的な技術開発を行っています。 ご支援内容 Copyright © Fixstars Group
画像処理アルゴリズム開発 高速な画像処理需要に対して、経験豊富なエンジニアが 責任を持って製品開発をご支援します。 お客様の課題 ご支援内容 高度な画像処理や深層学習等のアルゴリズム を開発できる人材が社内に限られている アルゴリズム調査・改変 課題に合ったアルゴリズム・実装手法を調査 製品実装に向けて適切な改変を実施 機能要件は満たせそうだが、ターゲット機器 上で性能要件までクリアできるか不安 深層学習ネットワーク精度の改善 様々な手法を駆使して深層学習ネットワークの精度を改善 製品化に結びつくような研究ができていない 論文調査・改善活動 論文調査から最先端の手法の探索 性能向上に向けた改善活動を継続 Copyright © Fixstars Group
GPU向け高速化 高性能なGPUの本来の性能を十分に引き出し、 ソフトウェアの高速化を実現します。 お客様の課題 ご支援内容 GPUで計算してみたが期待した性能が出ない GPU高速化に関するコンサルティング GPU/CPUを組み合わせた全体として最適な CPU・GPU混在環境でのシステム設計 設計がしたい アルゴリズムのGPU向け移植 原価を維持したまま機能を追加するため、も う少し処理を速くしたい GPUプログラム高速化 品質確保のため、精度を上げたく演算量は増 継続的な精度向上 えるが性能は維持したい Copyright © Fixstars Group
前提知識のおさらい Copyright © Fixstars Group
TensorRT ● TensorRT ○ DNNモデルをNVIDIAハードウェア向けに変換して推論処理を高速化してくれる ● やってくれること ○ 量子化(INT8化、fp16化) ○ 複数レイヤの結合 ○ チューニングパラメータの自動選択 ○ 実行ハードの自動選択 ■ CUDA Core/TensorCore ○ メモリ管理、最適な実行方法など ※画像引用元:https://developer.nvidia.com/tensorrt Copyright © Fixstars Group 15
推論プログラムのイメージ 初期化(CUDAメモリなど) 画像の取得 前処理 前処理 モデル TensorRT推論 変換 後処理 後処理 元のモデル 推論プログラム(新規作成) Copyright © Fixstars Group 16
ONNX ● DNNモデルをフレームワーク間で交換するためのフォーマット 入力 ModelProto ・モデル入力 ・グラフ構造 - オペレータ - 重みデータ ・モデル出力 GraphProto input[] output[] initializer[] node[] ・・・モデル入力定義 ・・・モデル出力定義 ・・・固定値、重み ・・・オペレータ 出力 DNNモデル ONNX Copyright © Fixstars Group 17
ONNX以外の対応状況 ● Caffe Parser and UFF ParserはTensorRT 7.0でdeprecated(※1) ○ TensorRT 9.0で削除されそう… > APIs deprecated before TensorRT 8.0 will be removed in TensorRT 9.0 ● tf2onnx, keras2onnx, TF-TRT への移行が推奨されている ● TF-TRT ○ TensorFlowの1機能として取り込まれている ■ ONNX変換せず直接モデルをTensorRT変換する ■ TensorFlowでそのまま推論を行える ○ PyTorchにもTorch-TensorRTというのがある ※1:https://docs.nvidia.com/deeplearning/tensorrt/release-notes/tensorrt-8.html#rel_8-0-1 Copyright © Fixstars Group 18
TensorRT変換 ワークフロー Copyright © Fixstars Group
TensorRT変換ワークフロー 必要に応じてDNNモデルを修正する ONNXモデルに変換する 固定値を定数化する TensorRTのエンジンファイルに変換する エラーの内容を見て適宜戻る 推論プログラムを作成する Copyright © Fixstars Group 20
固定値の定数化 ● TensorRTは重みなどの入力がinitializerのケースのみ対応している場合がある ● initializer ○ ONNXファイルで定数値を保持しているリスト(配列) ● ONNXモデル出力した際に固定値を計算によって算出するモデルが生成され るケースがある ○ 事前に計算を実行してinitializerに変換が可能(Constant folding) ● Constant foldingに対応しているツール ○ ONNX Simplifier (有志作成。カスタムオペレータはDLL開発が必要。※1) ○ ONNX GraphSurgeon (NVIDIA製。Python呼び出しコードが必要。※2) ○ Polygraphy (NVIDIA製。※3) ※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 Copyright © Fixstars Group 21
変換時のエラー ● オペレータがサポート対象外 ○ レイヤーごとの対応表(※1) ○ ONNXオペレータの対応表(※2) ● 特定のパラメータなどに対応していない ○ 基本的に変換時のエラーメッセージをよく読むしかない ■ 問題切り分けのため普段から--verboseで変換実行しておくと良い ○ パワーユーザであればソースコード(※3)で直接assertしている箇所を確認すれば詳細な条 件が分かる ● TensorRTのバグ ○ 「Internal Error」と表示されたらバグの可能性 ○ エラーメッセージに表示されている.cppファイル名がGitHubのソースコードから見つからなけ ればTensorRT本体(非公開)の可能性 ※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 Copyright © Fixstars Group 22
モデルの修正 ● 重みをもたないオペレータは別の等価なオペレータに置き換え可能 ○ 単純な四則演算など ● 重みをもつオペレータや等価なオペレータに置き換え不能な場合 ○ ○ 再学習が必要 推論精度が悪化するケースも ● 前処理、後処理でエラーになっている場合 ○ ○ ○ ONNXエクスポートの範囲外にする方法もある 推論プラグラム側に処理を移動させるイメージ 当然TensorRTの恩恵を受けられない Copyright © Fixstars Group 23
バグ報告 ● TensorRT本体の不具合が疑われる場合、思い切ってバグ報告・問い合わせしてみ た方が良い ○ ただし英語… ● 必要な準備 ○ ○ ○ 再現環境の情報を整理する 再現用の最小セットONNXモデルを作成する ■ Polygraphyを使う場合のサンプルがある(※1) trtexecコマンドで再現する手順を整理し、再現時のログを取得する ● バグ報告先 ○ ○ ONNXパーサー、TensorRTプラグインはGithub(※2) 上記以外はNVIDIAフォーラム(※3) ※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 Copyright © Fixstars Group 24
キャリブレーション ● INT8で推論する場合はキャリブレーションが必要 ○ モデルをエンジンファイルに変換する際に一緒にキャリブレーションを行う ○ 昔は変換プログラムを作成する必要があったが、今はPolygraphyにデータ読み込みPythonスク リプトを渡すだけで良くなった(※1) ● キャリブレーションに使用するデータ ○ 実際に推論を行う環境に近いデータ ○ ImageNetの画像分類タスクなら500画像(※2) ※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 Copyright © Fixstars Group 25
変換事例の紹介 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) ※1:Toan Dao Minh. 2019. A Pytorch Implementation of EfficientDet Object Detection https://github.com/toandaominh1997/EfficientDet.Pytorch Copyright © Fixstars Group 27
変換事例の概要(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の文字列化、画像への重畳、画像ファイルの保存 ※1:https://arxiv.org/abs/1911.09070 ※2:https://arxiv.org/abs/1905.11946 ※3:https://arxiv.org/abs/1708.02002 Copyright © Fixstars Group 28
問題解決事例 - 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) ※1: https://maminus.hatenadiary.org/entry/2022/01/12/200806 Copyright © Fixstars Group 29
問題解決事例 - Resizeオペレータ(2) PyTorchでのexport実験 # 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) Copyright © Fixstars Group 30
問題解決事例 - Resizeオペレータ(3) ● PyTorch 1.12での実験結果 scale_factor指定 size指定 Copyright © Fixstars Group 31
問題解決事例 - Non Maximum Suppression(1) ● Non Maximum Suppression ○ 1つの物体に対して複数候補が推論されるようなケースで1つの答えに統合する処理 ○ 推論結果のBoxの重なり具合が大きいものを1つに統合する Copyright © Fixstars Group 32
問題解決事例 - Non Maximum Suppression(2) ● TensorRTはNon Maximum Suppressionに直接対応していない ○ プラグインで対応している ○ ONNXのNonMaxSuppressionオペレータはプラグインに変換される ● I/Fが異なる ○ torchvision → ONNX → プラグインだとバッチサイズ1固定になってしまう ○ ONNX変換時に直接プラグイン向けオペレータ出力するのが一番自由度が高い score_threshold 戻り値 bboxをクラスごとに別 に扱うか バッチ次元 ONNX あり インデックス クラスごとに別々のbbox 対応 torchvision なし インデックス 全クラス共通のbbox 非対応 TensorRTプラグイン あり 値(Bboxそのもの) どちらにも設定できる 対応 Copyright © Fixstars Group 33
問題解決事例 - Non Maximum Suppression(3) ● ONNX変換時にONNXオペレータではなくTensorRTプラグイン向けオペレー タを出力する ○ カスタムオペレータで実現可能 ■ PyTorchのカスタムオペレータからONNXのカスタムオペレータを出力する ○ TensorRTプラグインの出力テンソル(Bbox数)はSliceオペレータに使えない ■ 後段の処理はONNX出力対象外に変更(推論プログラム側で後段処理を実行する) ● PyTorchのカスタムオペレータ ○ ONNX出力定義(Pythonコード) ○ カスタムオペレータ実装(C++コード) Copyright © Fixstars Group 34
問題解決事例 - Non Maximum Suppression(4) ● ONNXのカスタムオペレータとして出力 @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, ONNXのカスタムオペレータ出力 background_class_i=-1, score_activation_i=0, box_coding_i=0, ) return num_detections, detection_boxes, detection_scores, detection_classes PyTorchの推論(ONNXエクスポート)時 はカスタムオペレータのDLLを呼び出す 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) Copyright © Fixstars Group 35
問題解決事例 - Non Maximum Suppression(5)
● DLLのダミー実装
○
ONNXのエクスポート時には最低限テンソルのshapeは正しくないとダメ
○
データの個数や内容によって分岐するようなケースはそれらしい値を出力しないと意図する
ONNXモデルが生成できない
○
今回はNMS処理を行わずそのままBboxを返すだけの実装とした
#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);
}
Copyright © Fixstars Group
36
所感 ● 対象モデルやONNXのオペレータに詳しくないとトラブルシューティングが 難しい ○ エラーメッセージを読んでモデルのどの箇所なのか分からないと対処ができない ○ 対象モデルの構造やソースコードの構造はある程度把握しておいた方が良い ● すでにTensorRT化済みモデルがあるならそちらを使った方がよさそう ○ EfficientDetならTensorFlow版が公式でTensorRT化されている(※1) ● 慣れるまでONNX変換→trtexecコマンドでTensorRT変換した方が楽そう ※1: https://github.com/NVIDIA/TensorRT/tree/main/samples/python/efficientdet Copyright © Fixstars Group 37
Thank you! お問い合わせ窓口 : [email protected] Copyright © Fixstars Group