2019年9月15日日曜日

Fedora 30でTensorflow 2.0.0rc1(CUDA10.1 cuDNN7.6)をビルドする

2019/9/16 CUDAのHost compilerに指定するGCCのバージョンが間違っていたため修正(@PINTO03091 さんからの指摘)。

目的


Tensorflowの2.0.0rc1をFedora 30でソースビルドする。
2.0.0の正式版リリースに向けての準備と備忘録。


環境


  • Fedora 30 x86_64
  • python 3.7.4(virtualenv)
  • CUDA 10.1 + cuDNN 7.6.3
  • CPU AMD Ryzen 7 1700
  • GPU GeForce GTX 1070


事前の準備


GCC5.5をソースビルドしておく。

理由

CUDAはFedora 30のGCC9.2.1をサポートしていない。
前回はGCC7.3をソースビルドしてCUDAのHostコンパイラーに指定していた。
しかし、2.0.0rc1のビルドではXLA関連でビルドエラーとなり、GCC5.5にしたところビルドできた(CUDAのHostコンパイラーとXLA関連のビルドエラーの詳細は未確認。ただ、前回も同様なこともあった)。



GCC5.5のビルド

実はFedora 30のGCC9.2.1ではGCC5.5をビルドできない(これはFedora 29のGCC8でもおなじ)。
このため、GCC7.3を用意して、GCC5.5をビルドする。

GCC5.5.0のソースをダウンロード。しかし、これをGCC6以上でビルドしようとするとエラーとなってしまうため、パッチを入手して適用してからビルドを行う。

(筆者はたしかFedora 28あたりにぶち当たった...それから環境を残してある...)


Bazelのビルド


Bazelをソースビルドする(リポジトリのバージョンだとTensorflowが期待するバージョンと一致しないことがあるため)。今回は0.25.3をソースビルドした。
ソースビルドの方法は以下を参照。


ビルドが終わったらoutputフォルダのパスをPATHに追加するか、/usr/local/bin配下にoutput/bazelをコピーする。


CUDA、cuDNNのインストール


CUDA: 10.1、cuDNN: 7.6.3をインストール。RPM Fusion Howto/ CUDA を参考にインストールを行う。[CUDA Toolkit]、[Machine Learning repository]でCUDAとcuDNNをインストールする。

$ dnf list cuda
インストール済みパッケージ
cuda.x86_64            10.1.243-1                  @cuda

$ dnf list libcudnn7
インストール済みパッケージ
libcudnn7.x86_64       7.6.3.30-1.cuda10.1         @nvidia-machine-learning


(cuDNNはダウンロードサイトからダウンロード&インストールしたのだが、なぜかビルドでエラーとなってしまった。理由はわからず...)


Tensorflowのビルド


公式の手順通りだけど、まずはvirtualenv(virtualenvwapper)でTensorflow用の仮想Python環境を作成し、必要なモジュールをインストール。

$ mkvirtualenv  --python=python3 tf2.0rc1
$ pip install pip six numpy wheel setuptools mock 'future>=0.17.1'
$ pip install keras_applications==1.0.6 --no-deps
$ pip install keras_preprocessing==1.0.5 --no-deps

Githubからv2.0.0-rc1 tagを指定して取得。

git clone -b v2.0.0-rc1 https://github.com/tensorflow/tensorflow.git

configure。
CUDAのサポートを有効とすることと、Host compilerにGCC7 GCC5のgccのパスを指定してあげること。

$ ./configure 
WARNING: Running Bazel server needs to be killed, because the startup options are different.
WARNING: --batch mode is deprecated. Please instead explicitly shut down your Bazel server using the command "bazel shutdown".
You have bazel 0.25.3- (@non-git) installed.
Please specify the location of python. [Default is /home/xxxx/.virtualenvs/tf2.0rc1/bin/python]: 




Traceback (most recent call last):
  File "", line 1, in 
AttributeError: module 'site' has no attribute 'getsitepackages'
Found possible Python library paths:
  /home/xxxx/.virtualenvs/tf2.0rc1/lib/python3.7/site-packages
Please input the desired Python library path to use.  Default is [/home/xxxx/.virtualenvs/tf2.0rc1/lib/python3.7/site-packages]


Do you wish to build TensorFlow with XLA JIT support? [Y/n]: 
XLA JIT support will be enabled for TensorFlow.


Do you wish to build TensorFlow with OpenCL SYCL support? [y/N]: 
No OpenCL SYCL support will be enabled for TensorFlow.


Do you wish to build TensorFlow with ROCm support? [y/N]: 
No ROCm support will be enabled for TensorFlow.


Do you wish to build TensorFlow with CUDA support? [y/N]: Y
CUDA support will be enabled for TensorFlow.


Do you wish to build TensorFlow with TensorRT support? [y/N]: 
No TensorRT support will be enabled for TensorFlow.


Found CUDA 10.1 in:
    /usr/local/cuda/lib64
    /usr/local/cuda/include
Found cuDNN 7 in:
    /usr/local/cuda/lib64
    /usr/local/cuda/include




Please specify a list of comma-separated CUDA compute capabilities you want to build with.
You can find the compute capability of your device at: https://developer.nvidia.com/cuda-gpus.
Please note that each additional compute capability significantly increases your build time and binary size, and that TensorFlow only supports compute capabilities >= 3.5 [Default is: 6.1]: 6.1




Do you want to use clang as CUDA compiler? [y/N]: 
nvcc will be used as CUDA compiler.


Please specify which gcc should be used by nvcc as the host compiler. [Default is /usr/lib64/ccache/gcc]: /xxx/xxx/gcc/5.5/bin/gcc




Do you wish to build TensorFlow with MPI support? [y/N]: 
No MPI support will be enabled for TensorFlow.


Please specify optimization flags to use during compilation when bazel option "--config=opt" is specified [Default is -march=native -Wno-sign-compare]: 




Would you like to interactively configure ./WORKSPACE for Android builds? [y/N]: 
Not configuring the WORKSPACE for Android builds.


Preconfigured Bazel build configs. You can use any of the below by adding "--config=<>" to your build command. See .bazelrc for more details.
    --config=mkl             # Build with MKL support.
    --config=monolithic      # Config for mostly static monolithic build.
    --config=gdr             # Build with GDR support.
    --config=verbs           # Build with libverbs support.
    --config=ngraph          # Build with Intel nGraph support.
    --config=numa            # Build with NUMA support.
    --config=dynamic_kernels    # (Experimental) Build kernels into separate shared objects.
    --config=v2              # Build TensorFlow 2.x instead of 1.x.
Preconfigured Bazel build configs to DISABLE default on features:
    --config=noaws           # Disable AWS S3 filesystem support.
    --config=nogcp           # Disable GCP support.
    --config=nohdfs          # Disable HDFS support.
    --config=noignite        # Disable Apache Ignite support.
    --config=nokafka         # Disable Apache Kafka support.
    --config=nonccl          # Disable NVIDIA NCCL support.
Configuration finished

ビルド。
TensorFlow 2.0の場合、オプションに  --config=v2 をつける。
NVIDIA NCCLを無効とするため、--config=nonccl もつける(NCCLのライブラリをインストールしたがビルドエラーとなったので外す)。

$ bazel build --config=opt --config=v2 --cxxopt="-D_GLIBCXX_USE_CXX11_ABI=0" --config=cuda --config=nonccl  --verbose_failures //tensorflow/tools/pip_package:build_pip_package

...

INFO: Elapsed time: 9788.259s, Critical Path: 378.10s
INFO: 25250 processes: 25250 local.
INFO: Build completed successfully, 34867 total actions

ビルドが完了したら、pipパッケージを作成して、インストール!

$ ./bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
$ pip install /tmp/tensorflow_pkg/tensorflow-2.0.0rc1-cp37-cp37m-linux_x86_64.whl 

インストール後の確認

  • tf.__version__が2.0.0-rc1であること。
  • GPUデバイスを認識していること。

$ python
Python 3.7.4 (default, Jul  9 2019, 16:32:37) 
[GCC 9.1.1 20190503 (Red Hat 9.1.1-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import tensorflow as tf
>>> tf.__version__
'2.0.0-rc1'
>>> from tensorflow.python.client import device_lib
>>> device_lib.list_local_devices()
2019-09-15 22:22:42.479984: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2993965000 Hz
2019-09-15 22:22:42.480879: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x5604fd404b10 executing computations on platform Host. Devices:
2019-09-15 22:22:42.480911: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): Host, Default Version
2019-09-15 22:22:42.483667: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcuda.so.1
2019-09-15 22:22:42.637759: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-09-15 22:22:42.638947: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x5604fd4ae4b0 executing computations on platform CUDA. Devices:
2019-09-15 22:22:42.638973: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): GeForce GTX 1070, Compute Capability 6.1
2019-09-15 22:22:42.639193: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-09-15 22:22:42.639825: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1618] Found device 0 with properties: 
name: GeForce GTX 1070 major: 6 minor: 1 memoryClockRate(GHz): 1.7085
pciBusID: 0000:09:00.0
2019-09-15 22:22:42.644617: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.1
2019-09-15 22:22:42.697319: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcublas.so.10
2019-09-15 22:22:42.731915: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcufft.so.10
2019-09-15 22:22:42.741549: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcurand.so.10
2019-09-15 22:22:42.796043: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusolver.so.10
2019-09-15 22:22:42.803769: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcusparse.so.10
2019-09-15 22:22:42.896828: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudnn.so.7
2019-09-15 22:22:42.897112: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-09-15 22:22:42.898295: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-09-15 22:22:42.899517: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1746] Adding visible gpu devices: 0
2019-09-15 22:22:42.899595: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library libcudart.so.10.1
2019-09-15 22:22:42.901482: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1159] Device interconnect StreamExecutor with strength 1 edge matrix:
2019-09-15 22:22:42.901502: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1165]      0 
2019-09-15 22:22:42.901509: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1178] 0:   N 
2019-09-15 22:22:42.901613: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-09-15 22:22:42.902209: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:1006] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2019-09-15 22:22:42.902767: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1304] Created TensorFlow device (/device:GPU:0 with 7079 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1070, pci bus id: 0000:09:00.0, compute capability: 6.1)
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 5999673194408362367
, name: "/device:XLA_CPU:0"
device_type: "XLA_CPU"
memory_limit: 17179869184
locality {
}
incarnation: 3782286546875987284
physical_device_desc: "device: XLA_CPU device"
, name: "/device:XLA_GPU:0"
device_type: "XLA_GPU"
memory_limit: 17179869184
locality {
}
incarnation: 2769759803836561573
physical_device_desc: "device: XLA_GPU device"
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 7423911527
locality {
  bus_id: 1
  links {
  }
}
incarnation: 9925876743775063780
physical_device_desc: "device: 0, name: GeForce GTX 1070, pci bus id: 0000:09:00.0, compute capability: 6.1"
]



2019年9月8日日曜日

Jetson NanoでTF-TRTを試す(Image Classification)


(2019.10.16 MobileNet v1, v2のFP16の処理時間を最適化する記事を書いた

目的


TF-TRT(TensorFlow integration with TensorRT)を使ってFP16に最適化したモデルを生成し、NVIDIA GPU、Jetson Nanoでどの程度最適化の効果ががあるのかを確認する。
今回は、Image Classificationのモデルについて確認する。


動機


NVIDIA公式のGithubリポジトリにJetxon(TX, TX2向け)のTF-TRTモデルが公開されている。


TF-TRTはJetson Nanoでも有効であるはずなのだが、ベンチマークなどの情報がすくない。
また、TensorFlow1.14とTensorRT5.1.5では、TF-TRTモデルに変換する際のIFが変更になったことと、Jetson NanoのSDKのバージョンが上がったことから、新しいIFでモデルを作成し、ベンチマークすることにした。




まとめとか


  • TF-TRTをつかうことで、モデルの推論時間を短縮することができることが確認できた(今回はFP16による最適化)。
  • GTX1070, Jetson Nanoで効果が確認できた。
    Jetson NanoはMobileNet v1, v2がImage Classificationのモデルで使用できそう。
  • TF-TRTモデルを生成する側と推論を行う側でTensorRTのバージョンが一致していないとNG(回避方法あり)。


TF-TRTを使うメリット


TensorRTではなく、TF-TRTを使うメリットとしては以下と考えている。
  • TensorFlowで学習したモデル(Frozen Graph or Saved Model)が流用できる。
  • 学習・推論のコードはTensorFlowのコードがほぼそのまま流用できる。


参考ドキュメント


モデルの作成から推論まで


大きな流れとして、
  1. ホスト環境(PC: Ryzen1700+GTX1070)でNGCコンテナーの立ち上げ。
  2. ホスト環境でpretrained modelを読み込み->TF-TRTモデルに変換。
  3. ホスト環境、JetsonNanoで推論を行う。
作成するモデルはTensorFlow/models/slimで用意されているpretrained modelを使用する。

NGCコンテナーの立ち上げ


TF-TRTを使うにはTensorRTが必要である。TensorRTがなくてもモデル生成や実行ができるが、最適化されていないため注意が必要。
ホスト環境にNGCコンテナーを立ち上げる。まずは、DockerをインストールしてGPUを使えるようにセットアップする(前回の記事を参照)。
NVIDIA/TensorFlowから19.08-py3(2019/9/8時点の最新)をPullし、起動する。

sudo docker pull nvcr.io/nvidia/tensorflow:19.08-py
sudo docker run -it --gpus all -p 8888:8888 nvcr.io/nvidia/tensorflow:19.08-py3


TF-TRTリポジトリの取得

TF-TRTモデルを作成するためのリポジトリは本家からForkしている。



モデルの変換はnotebookで用意している。


TF-TRTでFP16のモデルを生成


TF-TRTでpretrained modelを変換し、FP16で最適化する流れを説明する。


pretrained modelの読み込み


pretrained modelのcheckpointファイルからモデルをロード・リストアする。
実際のコードはここ。一般的な方法であるので説明は省略する。
ただし、Relu6についてはTensorRTで最適化するためにrelu(x) - relu(x - 6)に置き換えている(TensorFlow Container 18.11-19.01 (TensorFlow 1.12)でRelu6がサポートされているので置き換えの必要がないかもしれないが今回は未検証)。


TF-TRTモデルの変換


TrtGraphConverterを使ってモデルを変換する(古いAPIはcreate_inference_graph)。
convertメソッドによって最適化されたモデルを得ることができる。
converter = trt.TrtGraphConverter(
    input_graph_def=frozen_graph,
    nodes_blacklist=output_names, #output nodes
    max_batch_size=1,
    is_dynamic_op=True,
    max_workspace_size_bytes=trt.DEFAULT_TRT_MAX_WORKSPACE_SIZE_BYTES,
    precision_mode=trt.TrtPrecisionMode.FP16,
    minimum_segment_size=50)
trt_graph = converter.convert()

TrtGraphConverterの引数には
  • input_graph_def:  ロードしたGraphDefを指定。
  • nodes_blacklist:  最適化しないnode。
    Output nodeを指定(create_inference_graphではoutputs)。
  • is_dynamic_op:  推論の実行時にTensorRTの最適化を行う。
    最適化の際は入力のサイズが予め決まっている必要がある。入力サイズが決まっていないモデルの場合は、TrtGraphConverterによって最適化できない。
    Trueにすることによって、推論時に最適化を行うことができる。
    しかし、初回の推論時に最適化が行われるため処理時間が増加する。
    また、ホストとJetson NanoのTensorRTのバージョンが不一致の場合は、最適化により動作することができる。
  • max_workspace_size_bytes:  TensorRTエンジンが実行できる最大のGPUメモリサイズ。
    DEFAULT_TRT_MAX_WORKSPACE_SIZE_BYTES は新しく追加された定義。
  • precision_mode:  量子化のモード。
    FP16とINT8が選択できる。今回はFP16を選択。
  • minimum_segment_size:  subgraphをTRTEngineOpで置き換える最小のノード数。

最適化が行われると、いくつかのSubGraphがTensorRTEngineOpで置き変わる。
どの程度、置き換わったかは以下のコードで確認できる。
trt_engine_opts = len([1 for n in trt_graph.node if str(n.op) == 'TRTEngineOp'])
print("trt_engine_opts = {}".format(trt_engine_opts))


TF-TRTモデルの保存


モデルの保存は、SerializeToStringを使用する。
base_name = os.path.splitext(os.path.basename(checkpoint_path))[0]
save_model_file_name = base_name + '_frozen_fp16.pb'
with open(os.path.join(MODEL_DIR, save_model_file_name), 'wb') as f:
    f.write(trt_graph.SerializeToString())


ベンチマーク


GTX1070とJetson Nanoでベンチマークを行う。
推論時間のベンチマークに使用したスクリプトはここ
TF-TRTのモデルを扱うためには、以下のインポートが必要。

from tensorflow.python.compiler.tensorrt import trt

推論(session.run)前後の処理時間を100回計測した平均とする。
ただし、初回はモデルの構築を行うため省く。

ファイルサイズ


変換前後でのファイルサイズを比較する。
驚いたことに、TF-TRTモデルのほうがオリジナルの倍になっていた。
ファイルサイズが大きくなるのは組込デバイスには少し負担になる気がするのだが...

ModelOriginal

TF-TRT
(FP16)
MobileNet_v1_1.0_22417M33M
MobileNet_v2_1.0_22414M28M
VGG 16528M1.1G
VGG 19549M1.1G
Inception v126M51M
Inception v243M86M
Inception v392M183M
Inception v4164M327M
ResNet v1 5098M196M
ResNet v1 101171M342M
ResNet v1 152231M461M
ResNet v2 5098M196M
ResNet v2 101171M342M
ResNet v2 152231M462M
Inception Resnet v2214M428M


GTX1070の初回の推論時間


モデル構築を行うため、初回の推論は処理時間が多くかかる。
is_dynamic_opによる違いがあるかを確認した。
  • is_dynamic_opにTrueを指定した場合
    TF-TRTモデルの場合、初回の推論に多く時間がかかっている(約20〜30倍)。
    これは、モデルの最適化が行われるためと思われる。
  • is_dynamic_opにFalseを指定した場合
    TF-TRTモデルのほうがオリジナルより推論時間が短くなっており、最適化の効果が確認できる。


初回の推論時間(is_dynamic_opにTrueを指定)


Model
Inference time [ms]
Original

TF-TRT
(FP16)
MobileNet_v1_1.0_224142322194
MobileNet_v2_1.0_224170532443
VGG 16373745574
VGG 19411752471
Inception v1132124132
Inception v2139227833
Inception v3207830763
Inception v4301946492
ResNet v1 50157029993
ResNet v1 101213854414
ResNet v1 152285977768
ResNet v2 50190130391
ResNet v2 101236054616
ResNet v2 152273877686
Inception Resnet v2339271582

GTX1070 初回の推論時間を比較(is_dynamic_opにTrueを指定)


初回の推論時間(is_dynamic_opにFalseを指定)


Model
Inference time [ms]
Original

TF-TRT
(FP16)
MobileNet_v1_1.0_22414231066
MobileNet_v2_1.0_2241705968
VGG 1637372889
VGG 1941172916
Inception v113211067
Inception v213921043
Inception v320781062
Inception v430191367
ResNet v1 5015701214
ResNet v1 10121381448
ResNet v1 15228591657
ResNet v2 5019011242
ResNet v2 10123601401
ResNet v2 15227381615
Inception Resnet v233921632

GTX1070 初回の推論時間を比較(is_dynamic_opにFalseを指定)


GTX1070の2回目以降の推論時間


TF-TRTモデルのほうが処理時間が短縮している。
FP16の最適化の効果が出ている。is_dynamic_opの違いはなかった。これは、TF-TRTモデルの生成時に最適化が行われているためと思われる。

Model
Inference time [ms]
Original

TF-TRT
(FP16)
MobileNet_v1_1.0_22462
MobileNet_v2_1.0_22473
VGG 16758
VGG 19829
Inception v172
Inception v283
Inception v3188
Inception v43114
ResNet v1 50104
ResNet v1 101177
ResNet v1 1522410
ResNet v2 50136
ResNet v2 1012111
ResNet v2 1522915
Inception Resnet v23814

GTX1070の推論時間(2回目以降、100回の平均)


Jetson Nanoの初回の推論時間


is_dynamic_opにTrueを指定した場合
傾向はGTX1070と同じである。Jetson Nanoではモデルサイズが大きいものは起動できなかった。

is_dynamic_opにFalseを指定した場合、「Segmentation fault (コアダンプ)」が発生し起動できなかった。
ログから、Host側とJetsonNano側のTensorRTのバージョンが一致しておらず、TF-TRTモデルが読み込めなかったと思われる。

2019-09-08 16:24:10.910053: E tensorflow/compiler/tf2tensorrt/utils/trt_logger.cc:41] DefaultLogger The engine plan file is not compatible with this version of TensorRT, expecting library version 5.1.6 got 5.1.5, please rebuild.
Segmentation fault (コアダンプ)


is_dynamic_opにTrueを指定した場合は、初回の推論時にモデルの最適化が行われるため、事象が発生しなかったと思われる。

Jetson NanoのTensorRTのバージョンは5.1.6、Host側のNGCコンテナーは5.1.5なので、確かにバージョンは不一致。でも、TensorRTのリリースノートにはバージョン5.1.5まで、NGCコンテナーにもない... これはどういうことだろうか?
5.1.6がリリースされたら、is_dynamic_opにFalseを指定した場合も検証することとする。


初回の推論時間(is_dynamic_opにTrueを指定)


Model
Inference time [ms]
Original

TF-TRT
(FP16)
MobileNet_v1_1.0_22427551129589
MobileNet_v2_1.0_22421224172359
VGG 16強制終了起動せず
VGG 19強制終了起動せず
Inception v1994418599
Inception v21735827673
Inception v3強制終了48400
Inception v4強制終了強制終了
ResNet v1 5016651OOM
ResNet v1 101強制終了
ResNet v1 152
ResNet v2 5032912起動せず
ResNet v2 101強制終了
ResNet v2 152
Inception Resnet v2

※強制終了: "強制終了"を表示してスクリプトが終了した。
※OOM: "OutOfMemory"を表示してスクリプトが終了した。
※起動せず: 5分以上経過しても初回の推論が終わらないので諦めた。
※ー: 計測していない。

Jetson Nano 初回の推論時間を比較(is_dynamic_opにTrueを指定)


Jetson Nanoの2回目以降の推論時間


MobileNet v1, v2に限定すると、TF-TRTによる最適化の効果が出ている。
Inception v1, v2は差がない。おそらくGPUのメモリサイズが不足していると思われる。
ここから、TF-TRTで使用できるモデルはMobileNet v1, v2になる。


Model
Inference time [ms]
Original

TF-TRT
(FP16)
MobileNet_v1_1.0_2243425
MobileNet_v2_1.0_2243729
VGG 16強制終了起動せず
VGG 19強制終了起動せず
Inception v14949
Inception v27176
Inception v3強制終了191
Inception v4強制終了強制終了
ResNet v1 50161OOM
ResNet v1 101強制終了
ResNet v1 152
ResNet v2 50212起動せず
ResNet v2 101強制終了
ResNet v2 152
Inception Resnet v2

※青色セル: メモリ不足と思われる警告が出力
(The caller indicates that this is not a failure, but may mean that there could be performance gains if more memory were available.)

Jetson nanoの推論時間(2回目以降、100回の平均)


その他


  • 次はObject Detection モデルについて確認してみる。
    NGCコンテナーのTensorRTのバージョンがアップデートされてからか?
  • tf.kerasで作成したモデルもTF-TRTモデルに変換して実行することができる。
    notebookはここ。
    ただし、推論の際はtf.kerasではなく、session.runの方式になってしまう。
    変わってしまうのであれば、TensorRTで実行したほうがよいかもしれない。
    (TF2.0でTF-TRTがtf.kerasで推論できるようになればかなり強力)
  • Jetson NanoでTF-TRTモデルの作成を行ったが、ベンチマークした結果、最適化されなかった。
    おそらく、GPUの世代やメモリサイズが影響していると思われる。