西川和久の不定期コラム

CUDAコア128基のGPUを搭載したAI/深層学習向け「Jetson Nano開発者キット」を試す

 NVIDIAが3月中旬に発表したNVIDIA「Jetson Nano」の開発者キットが、5月下旬から菱洋エレクトロが取り扱いを開始し、国内でも購入可能になった。今回、菱洋よりレビュワーズキットをお借りできたので、概要/セットアップ編と実践編、2回に分けて試用レポートをお届けしたい。

100×80mmの小型基板にCUDAコア128基のGPUやさまざまなI/Oを搭載

 AI/深層学習や仮想通貨のマイニングなど、CPUよりGPUの方が得意とする演算があるのはご存知のとおり。従来はPCにeGPUを取り付け、そのGPUを使って演算するケースがほとんどだった。この場合、(お金に糸目をつけなければ)かなりのレベルまで演算能力を上げることが可能となるが、小型化は難しく、消費電力も高い。

 そこで、おもに組み込み用として登場したのがNVIDIAのJetsonシリーズだ。同社のJetsonに関するサイトを見ると、512基のCUDAコア/6基のTensorコアを実装したNVIDIA Voltaアーキテクチャの「Jetson AGX Xavier」、256基のCUDAコアを実装したPascalアーキテクチャの「Jetson TX2」、そして今回ご紹介する128基のCUDAコアを実装したMaxwellアーキテクチャの「Jetson Nano」……と、現在3つのモジュールが用意されている。

 「Jetson Nano開発者キット」は、Jetson NanoモジュールにI/O基板をセットにした構成で文字どおり開発用だ。おもな仕様は以下のとおり。

NVIDIA「Jetson Nano開発者キット」の仕様
CPUARM Cortex-A57(4コア/1.43GHz)
GPUCUDAコア128基/Maxwellアーキテクチャ/472GFLOPS
メモリ4GB/64bit LPDDR4
インターフェイスGigabit Ethernet、USB 3.0×4、Micro USB(おもに電源用)、microSDカードスロット、HDMI、DisplayPort、CSI、GPIO、I2C、I2S、UART、M.2スロット
サイズ100×80×29mm
電源Micro USB 5V/2Aまたは電源入力5V/最大4A(2.1×5.5×9.5mmプラグ)
OSJetson Nano Developer Kit(Ubuntu 18.04 LTS)
税別価格12,800円

 CPUは4コアで最大1.43GHzのARM Cortex-A57。GPUはMaxwellアーキテクチャでCUDAコア128基。演算性能は472GFLOPS。メモリは64bit LPDDR4で4GB、microSDカードスロットを搭載。ここまでがJetson Nanoとなり、写真からもわかるようにDDR4/SO-DIMMメモリと同じ260ピンのコネクタでI/O基板に接続される。またCPUファンは標準では非搭載、ヒートシンクでの対応となる。

 I/O基板には、Gigabit Ethernet、USB 3.0×4、Micro USB(おもに電源用)、HDMI、DisplayPort。そしてCSI、GPIO、I2C、I2S、UART、M.2スロットを配置。

 CSI(Camera Serial Interface)/GPIOはRaspberry Piコンパチになっており、豊富な周辺デバイスが物理的には接続可能だ。後者はRPi.GPIOと同等のライブラリJetson.GPIOも用意されている。

 Raspberry Piと比較して性能はもちろん、Gigabit EthernetやUSB 3.0など今時のインターフェイスが使えるため、GPUを使わず純粋に小型サーバーなどにする手もあるだろう。なおWi-FiやBluetoothに関しては必要に応じてUSBやM.2(Wi-Fi/Bluetoothコンボカード)を使い増設することになる。

 電源はMicro USBでは5V/2A、電源入力では5V/最大4A。サイズは100×80×29mm(幅×奥行き×高さ)、重量は実測で139g。OSはUbuntu 18.04 LTSベースのJetson Nano Developer Kitを別途用意したmicroSDカード(16GB以上)へ書込み使用する。税別価格は12,800円。内容を考えるとかなり安い。

前面。上/左からMicro USB、Gigabit Ethernet、USB 3.0×4、HDMI、DisplayPort、電源入力。左側にGPIO、その上にLED、横にファン用電源。右側中央辺りにCSI
背面とくにコネクタなどはないが、各コネクタ/PINの内容が書かれている
斜めから。ヒートシンクが結構嵩張っているのが分かる。ただこれでも負荷がかかるとかなり熱くなる
Jetson Nanoモジュールは、260ピンのソケットでI/O基板と接続されており、ネジ2本外すと簡単に分離可能。I/O基板ソケット上にM.2スロット、Jetson Nanoモジュール側にmicroSDカードスロットがある

 サイズは100×80×29mm(同)。Raspberry Pi 3 model Bが約86×57×17mm(同)なのでそれなりに大きいが、扉の写真からも分かるように手のひらサイズだ。重量は実測で139g。

 側面にMicro USB、Gigabit Ethernet、USB 3.0×4、HDMI、DisplayPort、電源入力と一般的なインターフェイスが並び、両サイドにGPIOやCISなどのコネクタなどを配置している。Jetson NanoとI/O基板との接続はご覧のようにDDR4/SO-DIMMメモリと同じ260ピンソケットが使われており、ネジ2本外せば簡単に分離できる。ソケットの上にM.2スロット、Jetson Nanoモジュールの裏にmicroSDカードスロットがある。

 電源は先に書いたとおりMicro USBでは5V/2A、電源入力では5V/最大4Aが必要となる。今回は作業場に転がっていた普通のUSB式ACアダプタ5V/2Aを使用した。

 振動やノイズは当然皆無。発熱は標準でヒートシンクによる放熱となるが、負荷をかけると触るのがつらいほどの熱を持つ。従って、本格的な運用時には冷却ファンを付けたいところ。ソケット左上に冷却ファン用の電源コネクタ、そしてヒートシンクには冷却ファン固定用のネジ穴が4つあり、増設は容易だ。

セットアップ

 ほかのJetsonモジュールはeMMCを搭載しており、そこへOSを流し込む必要があるためセットアップが少し面倒だが、Nanoに関してはmicroSDカードを使うので非常に簡単だ。

 まずJetson Download CenterでOSイメージをダウンロードする。ちょうど2019年6月7日に「Jetson Nano Developer Kit SD Card Image New JP 4.2」が出たばかりだ。zipのファイルサイズは約5GB、解凍すると約12GBのimgファイルとなる。

 このimgをmicroSDカードに焼けば準備完了。今回は以前Raspberry Piの記事を書くときに使った「Win32 Disk Imager」がそのまま残っていたので使用したが、同等の機能があれば何でも良い。

Jetson Download Center
microSDカードへOSイメージを書き込む(Win32 Disk Imager使用)

 書き込んだあと、microSDカードをJetson Nanoのスロットへ入れ、USB 3.0へキーボード/マウスなどHIDデバイス(USB版ThinkPadトラックポイント・キーボード日本語を使用)、HDMIへフルHDのディスプレイ、Ethernet、Micro USBへ5V/2AのUSB式ACアダプタを接続するとMicro USBとGPIOの間にあるLEDがグリーンに点灯、システムが起動する。

 以下、初期セットアップの画面キャプチャを掲載するが、LinuxのGUIを使ったインストーラそのものでとくに難しい部分はない。

 初回はご覧のように日本語環境にしたものの、余分なメモリを食うのと、フォルダ名が「ピクチャ」などになるため、後で英語環境に入れ直している。一とおりインストールが終わるとリブートしてデスクトップが起動する。

License Agreementsなど
言語設定/日本語
キーボード設定/日本語(OADG 109A)
地域設定/Tokyo
アカウント設定
設定中……

 長年Linuxのデスクトップは触っていないので、これが一般的かどうかは不明だが、ありがちなデスクトップ環境となっている。デフォルトで、左端にタスクバーとChromiun、NVIDIA JetPack SDKなどへのショートカットが配置されていた。

 Ubuntuのバージョンは18.04 LTS。EthernetはGigabit Ethernetで接続され、DHCPサーバーから自動的にIPアドレスなどが設定済みだ。試しにGoogle Octane 2.0を動かしたところ、スコアは7,878と意外と速い。ほかのアプリを動かしても予想外にキビキビ動く。ただストレージ周りが遅いのはmicroSDカードを使っているので仕方ないところ。

 初期起動直後からsshによる接続が可能になっており、PCやMacなどからsshクライアントを使って接続可能だ。rootはsudoを使う。この段階で377のパッケージがアップデート可能と出るので、sudo apt-get update、sudo apt-get upgradeを使ってパッケージの更新を行なった方が良いだろう。

 ストレージは、16GBのmicroSDカードを使ってすでに約72%が使用中だ。あれこれパッケージをインストールするのであれば、32GBあった方が無難そうだ。メモリは4GBで約600MBがフリーとなる。

 ここでJetson Nano固有のコマンドを2つ試した。一つはnvpmodel。パフォーマンスモードの確認(nvpmodel -q)/設定(nvpmodel -m 0|1)用だ。-mは0が最大、1が5Wモードとなる。もう1つのjetson_clocksはCPU/GPU/EMCの保存/設定ができる。

初期起動時のDesktop
Ubuntuのバージョンは18.04 LTS
ネットワークはGigabit Ethernet、DHCPサーバーからIPアドレスなど自動取得
DesktopにはChromiunやNVIDIA JetPack SDKなどへのショートカット
Softwareセンター
Google Octane 2.0は7,878
Windowsからsshでログイン。rootはsudo
16GBのmicroSDカードだと既に約72%使用中
メモリ4GBで約600MBフリー
nvpmodelやjetson_clocksなど固有のコマンドを実行/確認

深層学習用のフレームワークをインストール&軽く確認

 ここから先は深層学習用の環境を整えるのだが、筆者にとっては未経験ゾーン。調べながら実行し、それを元に書いているものの、内容や表記などを間違っていることもあるかと思われる。予めご了承、そしてお許しいただきたい。

 使用言語はPython。2系と3系とがあり、コマンドで何も表記が無いのは2系、後ろに3が付くのが3系となる。今回は主に3系Python 3.6.7を使用している。またところどころ出てくるpip3は、Python3のパッケージマネージャだ(pipは2系)。

 さて深層学習用のフレームワークは数種類あるのだが、ここでは「TensorFlow」と「PyTorch」を使ってみたい。前者はGoogleが開発しオープンソースで公開している機械学習フレームワーク、後者はFacebookが開発しオープンソースで公開している機械学習フレームワークとなる。

 どちらもOS初期起動時には入っていないため、別途イントールが必要だ。まずTensorFlowから。ソースは同社のフォーラム「Official TensorFlow for Jetson Nano !!!」から。

TensorFlowのインストール

$ sudo apt-get install python3-pip libhdf5-serial-dev hdf5-tools
$ pip3 install --extra-index-url https://developer.download.nvidia.com/compute/redist/jp/v42 tensorflow-gpu==1.13.1+nv19.5 --user

確認(Get Started with TensorFlow https://www.tensorflow.org/tutorials より)


・コード
import tensorflow as tf
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
  tf.keras.layers.Flatten(input_shape=(28, 28)),
  tf.keras.layers.Dense(512, activation=tf.nn.relu),
  tf.keras.layers.Dropout(0.2),
  tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)

・実行結果
>>> model.fit(x_train, y_train, epochs=5)
Epoch 1/5
2019-06-09 23:22:55.678307: I tensorflow/stream_executor/dso_loader.cc:153] successfully opened CUDA library libcublas.so.10.0 locally
60000/60000 [==============================] - 40s 664us/sample - loss: 0.2241 - acc: 0.9350
Epoch 2/5
60000/60000 [==============================] - 39s 643us/sample - loss: 0.0983 - acc: 0.9697
Epoch 3/5
60000/60000 [==============================] - 38s 638us/sample - loss: 0.0704 - acc: 0.9774
Epoch 4/5
60000/60000 [==============================] - 38s 630us/sample - loss: 0.0542 - acc: 0.9825
Epoch 5/5
60000/60000 [==============================] - 38s 641us/sample - loss: 0.0436 - acc: 0.9856
>>> model.evaluate(x_test, y_test)
10000/10000 [==============================] - 2s 223us/sample - loss: 0.0661 - acc: 0.9806
[0.06610246316349949, 0.9806]

 次はPyTorch。これもソースは同社のフォーラム「PyTorch for Jetson Nano」から。Pythonはインタープリタなのでコンソールからコードを入力しつつ確認できる。以下、>>> 以降が入力した部分だ。

PyTorchのインストール

$ wget https://nvidia.box.com/shared/static/j2dn48btaxosqp0zremqqm8pjelriyvs.whl -O torch-1.1.0-cp36-cp36m-linux_aarch64.whl
$ pip3 install numpy torch-1.1.0-cp36-cp36m-linux_aarch64.whl

作動確認(同スレッドVerificationより)

$ python3
Python 3.6.7 (default, Oct 22 2018, 11:32:17)
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import torch
>>> print(torch.__version__)
1.1.0
>>> print('CUDA available: ' + str(torch.cuda.is_available()))
CUDA available: True
>>> a = torch.cuda.FloatTensor(2).zero_()
>>> print('Tensor a = ' + str(a))
Tensor a = tensor([0., 0.], device='cuda:0')
>>> b = torch.randn(2).cuda()
>>> print('Tensor b = ' + str(b))
Tensor b = tensor([-1.7809, -0.9044], device='cuda:0')
>>> c = a + b
>>> print('Tensor c = ' + str(c))
Tensor c = tensor([-1.7809, -0.9044], device='cuda:0')
>>>

 どちらも問題なく作動した。CUDAも作動している。次はCUDA ON/OFF(CPU)、加えて手持ちのCore i7-7700(CPU)とのベンチマークテストを行ないたい。

 が、先に書いたとおり、筆者はそもそも初心者なので、3つの環境で比較的簡単に作動……と思ったところでかなりハードルが高い(笑)。いろいろ試行錯誤した結果、CUDA ON/OFF(CPU)とWSL(Ubuntu 18.04.2 LTS)で動くサンプルを見つけたのでそれを使うことにした。

 使用したコードはPytorchがGitHubで公開しているサンプルの一つMNIST。--no-cudaのオプションがあり、簡単にCUDA ON/OFFの比較もできる。セットアップやコード/内容の話は後編で行なうことにして結果だけ。

PytorchによるMNISTの実行結果(--epochs=1のオプションを使用)

Python 3.6.7/CUDA ON@Jetson Nano 約49秒
Python 3.6.7/CUDA OFF@Jetson Nano 約342秒
WSL/Ubuntu 18.04.2 LTS/Python 3.6.7/CUDA None@Core i7-7700 約26秒

 ざっくりCUDA ONを1とした場合、CUDA OFFだと約7倍の時間がかかり、Core i7-7700のCPUのみの演算だと約半分の時間で終了すると言う結果となった。

 Jetson Nano/CUDA ONが、Core i7-7700のCPUでの演算より倍の時間がかかってしまっているため、絶対性能としては及ばないが、サイズ/消費電力を考慮すると、かなり健闘しているように思える。

そのほか

 以降、ちょっとしたノウハウとなる。まず、デスクトップへGPUモニタを表示する方法だ。matplotlibが必要となるため先にインストール、次にgit cloneでGPUモニタのコードを得てそれを実行する。

matplotlibのインストール

$ sudo apt-get install python3-matplotlib

GPUモニタのインストールと実行

$ git clone https://github.com/JetsonHacksNano/gpuGraph
$ cd gpuGraph
$ python3 gpuGraph.py
GPUモニタを実行したところ

 もう1つはJetson Nano側にあるコードの編集環境の話だ。デスクトップ上で編集したり、sshで接続しvim、SMBで接続し他のマシンからファイルを開いて編集……などいろいろなパターンが考えられるが、ここは普段どおり、Visual Studio Codeを使いたい。

 ssh接続したPCやMac側のVisual Studio Codeで、Jetson Nano側のコードを編集できる拡張機能はいくつかあるのだが、サーバー(Jetson Nano)側の設定が必要だったり面倒なケースもあり、サクッと動く「SSH FS」をお勧めする。SSH FSをインストールして、sshと同じ接続情報を設定すれば、ご覧のようにフォルダのツリー構造も含め、使い慣れたマシンから快適に作業できる。

拡張機能「SSH FS」を使ってJetson Nano側にあるコードをWindows上のVisual Studio Codeで編集

 今回は前編としてNVIDIA「Jetson Nano開発者キット」の概要、セットアップ、簡単な作動確認、そしてベンチマークテストなどをご紹介した。ここまででもいろいろな意味で興味を持たれた方は多いのではないだろうか。

 後編は実践編としてチラ見せした(笑)PytorchによるMNISTの実行方法や内容などの説明と、できれば(できるのか!?)もう1つ何か別の例を掲載したいと思っている。お楽しみに!

(後編へ続く)