Take’s diary

Macとマイコンに関すること--ワクワクの製作日記

Jetson TX1 でUSB3.0につないだSSDからUbuntuをBootしてみる。

 JETSON TX1の電源が壊れてから1.5ヶ月。

 交換品が戻ってきました。

f:id:TAKEsan:20161015142959j:plain

                  Jetson TX1本体はこんな感じ

f:id:TAKEsan:20161015143000j:plain

             分厚いアルミの放熱版でサンドイッチされてます。

 ちょうどJetpackが2.3にアップデートされていたので、最新版をインストールしてみました。最初の感想は、画面のもたつきや、起動時のHDMIディスプレイの認識不良がなくなり、市販ノートパソコン並みにとてもスムース。Bluetoothに接続した入力機器を起動時からストレスなく認識するようになりました。なぜかバージョンアップで、CPUスピードもintel Joule並みに早くなってます。下の方にZEDステレオカメラで画像測定を実行している動画を載せましたので、確認してみてください。

 待った甲斐がありました。やっぱハード発売からソフト安定まで1年以上かかるんですね。また、USBにつないだWebCAMERAをやっとVideo0で認識できるようになりました。ということは、OpenCVのカメラ系Exampleが修正なしで動くようになります。

 逆に弱点は、標準OpenCVやCaffeのインストールに特殊な前処理が必要になったことです。Torchに関して、現状インストールできないといった方が良さそうな感じです(時間の問題でしょうけど)。この辺りは後述します。

ここまで良くなると次はU-BOOTでOS選択。

※OSが3.1以降ではここに記述した方法ではSDカード、USB3.0共うまく起動できないようです。現在検証中なのでしばらくお待ち下さい。2018.3.20

 すなわち、本体内蔵のeMMCを使わずに、SDカードでUbuntuをブートさせることです。これが簡単にできると、応用の幅がグンと広がります。これが思いの外簡単に実現できました。いつものようにその後が地獄でしたけど。

f:id:TAKEsan:20161017200727j:plain

今回取り上げたSSD、Bluetooth入力機器、ZEDカメラを最小のマザーボードにTX1を取り付けてつないで、UbuntuはSSDから実行させてます。今回の操作は、すべてマザーボードにObrbitty Carrir for Jetson TX1を使ってます。

f:id:TAKEsan:20161017200728j:plain

              TX1の大きさはPiとほぼ同じ

SDカードでUBUNTUブートを実現させるには

ヒントは

https://devtalk.nvidia.com/default/topic/923800/boot-from-sd-card/

の中ほどに書いてありました。次のようにします。

まずNvideaのホームページから

Embedded Download Center | NVIDIA Developer

最新版のSample filesystemとDriver PackagesをTX1にダウンロードします。ダウンロードしたファイルは今回バージョンの場合以下の2種類です。

          Tegra210_Linux_R24.2.0_aarch64.tbz2

          Tegra_Linux_Sample-Root-Filesystem_R24.2.0_aarch64.tbz2

 バージョンアップしたTX1にはWebブラウザが全く付いていません。(実はコマンドラインからchromium-browser と打ち込むとchromiumブラウザが立ち上がるんですが)

  sudo apt install midori

で軽量なMidoriブラウザをインストールしました。ダウンロード用だけなら、TX1ではスピード的に全く問題ありません。

 ダウンロードにはNvideaへのログインが必要ありません。(現状の最新版は24.2です)当然最初は、本体のeMMCブートとなりますが、通常のバージョンアップをすると最終でも60%近くのeMMCディスク領域を使ってしまうので、ここからの操作は、ext4にフォーマットしたUSB接続SDカードなどで行うのが最良。本体のSDカードスロットは、OSインストール用に使います。

 まず、gpartedなどで、本体にセットしたSDカード(16G以上)をext4でフォーマットします。フォーマット領域は全領域で構いません。この時フォーマットした領域がemmcblk1p1であることを確認してから、TX1に上記2つのファイルをダウンロードしたディレクトリで次のコマンド群を実行。手っ取り早いのはdfコマンドで、ディスク接続内容を確認すればOK

f:id:TAKEsan:20161015103318p:plain

上の例では.dev/mmcblk0p1が内部eMMCの第1パーテーション、/dev/mmcblk1p1がSDカードスロットにセットしたSDカードの第1パーテーション。ちなみにsda2はUSBに接続したSSDの第2パーテーションです。

 今回の外部メモリへのOSインストール方法の良いところは、TX1上で全ての操作ができてしまうことです。操作は以下のようにコマンド入力します。朱書きで書いたディスク名称はくれぐれも間違えないように!!。この部分でOSの書き込み先を変更できます。

sudo tar xvpf Tegra210_Linux_R23.2.0_armhf.tbz2
sudo mount /dev/mmcblk1p1 Linux_for_Tegra/rootfs
cd Linux_for_Tegra/rootfs
 sudo tar xvpf ../../Tegra_Linux_Sample-Root-Filesystem_R24.2.0_aarch64.tbz2

 cd ..
 sudo ./apply_binaries.sh

これだけです。コマンド間でちょっと時間が必要ですが、あとはブートディスク選択部分を書き換えるだけ。書き換えるファイルは、本体のeMMC入っている extlinux.confです。

cd /boot/extlinux

sudo nano extlinux.conf

次の様に直します、

TIMEOUT 30
DEFAULT sdcard

MENU TITLE p2371-2180 eMMC boot options

LABEL primary
MENU LABEL primary kernel
LINUX /boot/Image
INITRD /boot/initrd
FDT /boot/tegra210-jetson-tx1-p2597-2180-a01-devkit.dtb
APPEND fbcon=map:0 console=tty0 console=ttyS0,115200n8 androidboot.modem=none androidboot.serialno=P2180A00P00940c003fd androidboot.security=non-secure tegraid=21.1.2.0.0 ddr_die=2048M@2048M ddr_die=2048M@4096M section=256M memtype=0 vpr_resize usb_port_owner_info=0 lane_owner_info=0 emc_max_dvfs=0 touch_id=0@63 video=tegrafb no_console_suspend=1 debug_uartport=lsport,0 earlyprintk=uart8250-32bit,0x70006000 maxcpus=4 usbcore.old_scheme_first=1 lp0_vec=${lp0_vec} nvdumper_reserved=${nvdumper_reserved} core_edp_mv=1125 core_edp_ma=4000 gpt android.kerneltype=normal androidboot.touch_vendor_id=0 androidboot.touch_panel_id=63 androidboot.touch_feature=0 androidboot.bootreason=pmc:software_reset,pmic:0x0 net.ifnames=0 root=/dev/mmcblk0p1 rw rootwait

LABEL sdcard
MENU LABEL sdcard kernel
LINUX /boot/Image
INITRD /boot/initrd
FDT /boot/tegra210-jetson-tx1-p2597-2180-a01-devkit.dtb
APPEND fbcon=map:0 console=tty0 console=ttyS0,115200n8 androidboot.modem=none androidboot.serialno=P2180A00P00940c003fd androidboot.security=non-secure tegraid=21.1.2.0.0 ddr_die=2048M@2048M ddr_die=2048M@4096M section=256M memtype=0 vpr_resize usb_port_owner_info=0 lane_owner_info=0 emc_max_dvfs=0 touch_id=0@63 video=tegrafb no_console_suspend=1 debug_uartport=lsport,0 earlyprintk=uart8250-32bit,0x70006000 maxcpus=4 usbcore.old_scheme_first=1 lp0_vec=${lp0_vec} nvdumper_reserved=${nvdumper_reserved} core_edp_mv=1125 core_edp_ma=4000 gpt android.kerneltype=normal androidboot.touch_vendor_id=0 androidboot.touch_panel_id=63 androidboot.touch_feature=0 androidboot.bootreason=pmc:software_reset,pmic:0x0 net.ifnames=0 root=/dev/emmcblk1p1 rw rootwait

LABEL usbssd
MENU LABEL usbssd kernel
LINUX /boot/Image
INITRD /boot/initrd
FDT /boot/tegra210-jetson-tx1-p2597-2180-a01-devkit.dtb
APPEND fbcon=map:0 console=tty0 console=ttyS0,115200n8 androidboot.modem=none androidboot.serialno=P2180A00P00940c003fd androidboot.security=non-secure tegraid=21.1.2.0.0 ddr_die=2048M@2048M ddr_die=2048M@4096M section=256M memtype=0 vpr_resize usb_port_owner_info=0 lane_owner_info=0 emc_max_dvfs=0 touch_id=0@63 video=tegrafb no_console_suspend=1 debug_uartport=lsport,0 earlyprintk=uart8250-32bit,0x70006000 maxcpus=4 usbcore.old_scheme_first=1 lp0_vec=${lp0_vec} nvdumper_reserved=${nvdumper_reserved} core_edp_mv=1125 core_edp_ma=4000 gpt android.kerneltype=normal androidboot.touch_vendor_id=0 androidboot.touch_panel_id=63 androidboot.touch_feature=0 androidboot.bootreason=pmc:software_reset,pmic:0x0 net.ifnames=0 root=/dev/sda1 rw rootwait

 簡単に言えば元々記述してあるデータ extlinux.conf(黒部分)をコピーして、2回ペースト。各々青の部分を変更するだけです。ブート指定は緑の部分です。sda1とはUSB3.0に接続した外部記憶装置のこと、とりあえず追加しておくと後で便利。ここではsdcardでブートする設定です。内部eMMCブートの場合は緑の部分をsdcardからprimaryに変更するだけです。

 ブートは内部eMMC上の/boot/extlinux/extlinux.confで判断する様なので、SDカードからBOOTしてもファイルマネージャーで内部eMMCを変更できるのでどうにでもなります。

 くれぐれもextlinux.confの書き換えは注意してください。間違えるとTX1に直結したターミナルでないとBOOTできなくなります。完了したら、 

sudo reboot -f

ワクワクの時です。

一応SDカードからBOOTできたものの

 なんか反応が鈍すぎる。まるで一時代前のPiでXwindowを操作してるみたいな....。

考えてみたら当然ですよね。どんなに早いSDカードを入れても、USB2.0並みの読み書きスピードですから。そこで、USB3.0対応のSDカードリーダーにSDカードを差してUSB3.0へ接続。extlinux.confの「DEFAURT sdcard」をDEFAURT usbssd に変えてrebootしてみました。こうすると内部eMMC並みのスピードになります。ここでUSB接続のSSDに変えたらどうなるんでしょ。そこで

USB3.0に接続したSSDにUbuntuを書き込んだら

(SSDにUbuntuをインストールして、上記茶色のemmcblk1p1 を sda1に変更してリブート)

さらにサクサク快適!!。ノートパソコン並みになりました。でもここからが大変。

CUDA、cuDNN、OpenCV2.4.13、Caffeインストールがなかなか...。

 インストールしたUbuntuは、見た目がサクサクでも。サードパーティーのアプリケーションがインストールできない。という最悪の状況。

 ここからは失敗の挙句なんとか使える様にした結果です。Linuxに精通している方は笑っちゃって下さい。

まずCUDAインストール

 標準JetpackインストールでeMMCのhomeにインストールされたCuda-l4tをディレクトリごとBootしたhomeへコピー。

cd cuda-l4t 

./cuda-l4t.sh cuda-repo-l4t-8-0-local_8.0.34-1_arm64.deb 8.0 8-0

でcuda8.0がインストールできます。でもこれだけではcuDNNが使えません。

次にcuDNN5.1インストール。

 一般的なlinuxへのインストール方法では全くダメでした。TX1へのインストールは、Ubuntu母艦環境でTX1のインストール時にダウンロードされたcuDNN-v5.1.zipを母艦からTX1のhomeへコピーすることから始めます。コピー方法はSDカードを使うなりなんなり各自考えて下さい。

 とにかくコピーしたら解凍して、中にあるlibcudnn5-dev_5.1.5.-1+cuda8_arm64.debを使います。同じディレクトリから、

sudo dpkg -i libcudnn5-dev_5.1.5.-1+cuda8_arm64.deb

sudo apt update

を実行。

これを実行するとdevcudnn-xxxxxをインストールしろとかなんとかメッセージが出るのでこの通り sudo apt install XXXXXXXX でcuDNNをインストール。

(すいませんファイル名忘れました)

 Cuda8.0とcuDNN5.1が連携して、TX1最強のGPU環境が構築されます。home にjetson_clocks.shがインストールされてるんで sudo ./jetson_clocks.sh を実行すると最速GPUクロックに変更されてFanが回り出します。卓上でTX1を使うには、これを実行するのが良いと思います。

 ここまで来ると、なぜかapt-getで自由にパッケージがインストールできる様になります。ここで、nanoやmidoriブラウザをインストールして、システムを最新にします

sudo apt update

sudo apt upgrade

かなり時間がかかりますが終了したらreboot。

ここからOpenCVとCaffeインストール

例によって依存アプリをいっぱいインストール

sudo add-apt-repository universe
sudo apt-get update

sudo apt-get -y install build-essential make cmake cmake-curses-gui g++
sudo apt-get -y install libavformat-dev libavutil-dev libswscale-dev
sudo apt-get -y install libv4l-dev
sudo apt-get -y install libeigen3-dev
sudo apt-get -y install libglew1.6-dev
sudo apt-get -y install libgtk2.0-dev
sudo apt-get install cmake git aptitude screen libboost-all-dev \
libgflags-dev libgoogle-glog-dev protobuf-compiler libprotobuf-dev \
bc libblas-dev libatlas-dev libhdf5-dev libleveldb-dev liblmdb-dev \
libsnappy-dev libatlas-base-dev python-numpy libgflags-dev \
libgoogle-glog-dev python-skimage python-protobuf python-pandas

sudo apt-get -y -qq install libgtk2.0-dev ocl-icd-opencl-dev qt5-default

 次にOpenCV2.4.13をインストール。(最初は何かと便利な2.4で状況を確認してから、必要に応じて3.0を再インストールすれば良い)

本家からOpenCV2.4.13をダウンロード。解凍したopencvディレクトリに入って

mkdir buikd 

cd build

今回はOpenGLソースもコンパイルできる環境を作りたかったのですが、OpenCVのmake中、どうしてもGL部分で引っかかるので、これを参考

Jetson TK1 compile from source fails with cuda and opengl interop · Issue #5205 · opencv/opencv · GitHub

にcudaヘッダーファイルを変更。

sudo nano /usr/local/cuda/include/cuda_gl_interop.h

開いたら、前の方に書いてある

#ifndef GL_VERSION

#error Please include the appropriate gl headers before including cuda_gl_interop.h

#endif

#else

を削除。それからいつものようにcmakeしてmake。(11/8 赤部分の数値が文字化けしてました)

cmake .. \

-DWITH_OPENGL:BOOL=ON \

-DWITH_QT:BOOL=ON \

-DWITH_CUDA:BOOL=ON \

-DCUDA_ARCH_BIN=5.3 \

-DCUDA_ARCH_PTX=5.3 \

-DENABLE_FAST_MATH=1 -DCUDA_FAST_MATH=1 -DWITH_CUBLAS=1 -D CUDA_USE_STATIC_CUDA_RUNTIME=OFF\

-DCMAKE_INSTALL_PREFIX=/usr/local \

-DBUILD_TESTS:BOOL=OFF \

-DBUILD_PERF_TESTS:BOOL=OFF \

-DWITH_FFMPEG:BOOL=OFF \

-DENABLE_NEON:BOOL=ON \

-DBUILD_EXAMPLES:BOOL=ON \

-DINSTALL_C_EXAMPLES:BOOL=OFF \

-DINSTALL_PYTHON_EXAMPLES:BOOL=ON \ ..

make -j4

驚くほどワーニングが出ますが、一応OKみたいです。

 すでにpython cv2ライブラリがインストールできています。cuda8.0になってNVCCコンパイル時間が早くなってることが確認できました。

次にcaffe

 Opecvがインストールできたら、Caffeは簡単。問題が多かったのですが、最終的に前の記事通りでOK。Pycaffeはインストール中エラーが出ますが、そのままコンパイルできるので一応対策は考えないことにしました。

Makefile.configの書き換えが必要。次の通り

## Refer to http://caffe.berkeleyvision.org/installation.html

# Contributions simplifying and improving our build system are welcome!

# cuDNN acceleration switch (uncomment to build with cuDNN).

 USE_CUDNN := 1

# CPU-only switch (uncomment to build without GPU support).

# CPU_ONLY := 1

# uncomment to disable IO dependencies and corresponding data layers

# USE_OPENCV := 0

# USE_LEVELDB := 0

# USE_LMDB := 0

# uncomment to allow MDB_NOLOCK when reading LMDB files (only if necessary)

# You should not set this flag if you will be reading LMDBs with any

# possibility of simultaneous read and write

# ALLOW_LMDB_NOLOCK := 1

# Uncomment if you're using OpenCV 3

# OPENCV_VERSION := 3

# To customize your choice of compiler, uncomment and set the following.

# N.B. the default for Linux is g++ and the default for OSX is clang++

# CUSTOM_CXX := g++

# CUDA directory contains bin/ and lib/ directories that we need.

CUDA_DIR := /usr/local/cuda

# On Ubuntu 14.04, if cuda tools are installed via

# "sudo apt-get install nvidia-cuda-toolkit" then use this instead:

# CUDA_DIR := /usr

# CUDA architecture setting: going with all of them.

# For CUDA < 6.0, comment the *_50 lines for compatibility.

CUDA_ARCH := -gencode arch=compute_30,code=sm_30 \

              -gencode arch=compute_35,code=sm_35 \

              -gencode arch=compute_50,code=sm_50 \

               -gencode arch=compute_53,code=sm_53 \

               -gencode arch=compute_53,code=compute_53

 

# BLAS choice:

# atlas for ATLAS (default)

# mkl for MKL

# open for OpenBlas

BLAS := atlas

# Custom (MKL/ATLAS/OpenBLAS) include and lib directories.

# Leave commented to accept the defaults for your choice of BLAS

# (which should work)!

# BLAS_INCLUDE := /path/to/your/blas

# BLAS_LIB := /path/to/your/blas

# Homebrew puts openblas in a directory that is not on the standard search path

# BLAS_INCLUDE := $(shell brew --prefix openblas)/include

# BLAS_LIB := $(shell brew --prefix openblas)/lib

# This is required only if you will compile the matlab interface.

# MATLAB directory should contain the mex binary in /bin.

# MATLAB_DIR := /usr/local

# MATLAB_DIR := /Applications/MATLAB_R2012b.app

# NOTE: this is required only if you will compile the python interface.

# We need to be able to find Python.h and numpy/arrayobject.h.

PYTHON_INCLUDE := /usr/include/python2.7 \

/usr/lib/python2.7/dist-packages/numpy/core/include

# Anaconda Python distribution is quite popular. Include path:

# Verify anaconda location, sometimes it's in root.

# ANACONDA_HOME := $(HOME)/anaconda

# PYTHON_INCLUDE := $(ANACONDA_HOME)/include \

# $(ANACONDA_HOME)/include/python2.7 \

# $(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include \

# Uncomment to use Python 3 (default is Python 2)

# PYTHON_LIBRARIES := boost_python3 python3.5m

# PYTHON_INCLUDE := /usr/include/python3.5m \

#                 /usr/lib/python3.5/dist-packages/numpy/core/include

# We need to be able to find libpythonX.X.so or .dylib.

PYTHON_LIB := /usr/lib

# PYTHON_LIB := $(ANACONDA_HOME)/lib

# Homebrew installs numpy in a non standard path (keg only)

# PYTHON_INCLUDE += $(dir $(shell python -c 'import numpy.core; print(numpy.core.__file__)'))/include

# PYTHON_LIB += $(shell brew --prefix numpy)/lib

# Uncomment to support layers written in Python (will link against Python libs)

 WITH_PYTHON_LAYER := 1

# Whatever else you find you need goes here.

INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/include/hdf5/serial 

LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib/aarch64-linux-gnu/hdf5/serial

# If Homebrew is installed at a non standard location (for example your home directory) and you use it for general dependencies

# INCLUDE_DIRS += $(shell brew --prefix)/include

# LIBRARY_DIRS += $(shell brew --prefix)/lib

# Uncomment to use `pkg-config` to specify OpenCV library paths.

# (Usually not necessary -- OpenCV libraries are normally installed in one of the above $LIBRARY_DIRS.)

# USE_PKG_CONFIG := 1

# N.B. both build and distribute dirs are cleared on `make clean`

BUILD_DIR := build

DISTRIBUTE_DIR := distribute

# Uncomment for debugging. Does not work on OSX due to https://github.com/BVLC/caffe/issues/171

# DEBUG := 1

# The ID of the GPU that 'make runtest' will use to run unit tests.

TEST_GPUID := 0

# enable pretty build (comment to see full commands)

Q ?= @

 朱書き部が修正したところです。ここまで来るには、cuDNNのインストールやMakefile.configの修正に手間取って無駄な時間を過ごしてしまいました。

今度は、ipython notebookが正常に動かない

 CaffeのExampleに入っているnotebookファイルが全く動きません。使ってみると分かるんですが、これ最高のライブラリなんです。原因はソフトが変更されたからみたいです jupyterに!!。本当にもう。

 sudo pip install jupyter でインストールできます。試しにcaffe/examples から jupyter notebook と打ち込むと、midoriからnotebookが立ち上がります。動作を確認するため00-classification.ipybを選択。初めての人は私のように驚いてしまうでしょう。 

f:id:TAKEsan:20161015115743p:plain

macにインストールしたCaffe examples からnotebookを立ち上げた例。Pythonで書かれた例題が画像を確認しながら実行できる。

全部終わったと思ったら

ubuntu software(前のUbuntuソフトセンター) 設定の中の「ソフトウエア&アップデート」と言語サポートが正常に動かない。これは、どっかのターミナルでsudo aptd実行したままにすれば。とりあえず動作。まーapt-get またはaptでパッケージが普通にインストールできるので良しとしました。

最後に

 caffeのexampleは全て完璧に動きます。しかも確実に前より早く。Mnistのスクリプトを実行してみると、

./data/mnist/get_mnist.sh

./examples/mnist/create_mnist.sh

./examples/mnist/train_lenet.sh

学習スタートから終了まで以前の最速環境で3分21秒に対して、2分36秒で終了。1分近く早くなってました。

 Torchはインストールできませんでした。ここ10日前後でインストールできた方がいるようですが、その通りスクリプトを実行してもビルドが止まってしまいます。解決は時間の問題だと思いますので、もう少し待ったほうが良いようです。

 Nividiaが説明していますが、DIGITSはTX1にインストールできません。TX1が早いと言っても i7 6700クラスでデープラーニングを実行した場合 i7より早いというだけです。(これだけでもすごいことですけど)本格的な学習を簡単に実行できるのがDIGITの売りですから、10倍以上早いGPU環境でないと全く実用的ではありません。最小の大きさで、学習済みデータを最速に実行できるのがTX1の特徴です。しかもGPIO制御もできる。もー夢がいっぱい広がります。DIGITSに執着しないで他のことを目一杯楽しみましょう。

 ZEDも試してみましたが、これもすごかったですよ。先のjetson_clock.shを実行させてからZEDのtoolsを試しに実行させてみるとこんな感じでした。(最近Cuda8.0用にバージョンアップされた)

         

 ステレオカメラで入力したデータを分析して、右側で取り込んだ画像の深度=距離を確認できます。画像の鮮度やスピードに関しては言うことありません。(TX1では1080X720 30fpsが限度みたいです)現状TX1では、OpenCV側のバグでZED SDKがコンパイルできません。これも時間の問題。

 母艦1080GPU環境では、1080x720で60fpsがステレオ2画面で実現できます。今までのWebCamera 30fsと比較するとリアルさがぐっと増します。まるで空気まで表現できる様な感じでした。

 WindowsではZED fuというサンプルが実行できます。これって何かというと、ZEDで写した画像をタイムリーに3D画像に変換できて、ZEDを移動させると3Dデータが自動連結されるサンプルなんです。

         

        基本設定画面。ここからカメラを持って周囲のデータをを記録させる

         

       記録されたデータを3Dデータに変換。メッシュで確認もできてしまう!!

 去年あたり長崎大学が、ドローンを使って軍艦島の3Dデータを作っていたことが話題になりましたが、これを手元で実現できることになります。衝撃以外の表現が見つかりません。

 ちょっと金銭的に無理をすれば、最小の大きさで、画像深度も、ディープラーニングも、それに関連付けた外部センサーなんかも実用レベルで、しかも個人レベルで実現できるんです。なんて幸せな時代なんでしょうか。

f:id:TAKEsan:20161017200729j:plain

 

                                   では、また。