Jetson TX1の代わりにSHIELD Android TVでTegra X1開発環境を構築する

2016年08月12日

概要

  • NVIDIA SHIELD Android TVにUbuntu 14.04を入れた
  • Chainerを動かしてみた
  • 2万円でJetson TX1とほぼ同等な開発環境を構築した

はじめに

半精度(fp16)で1TFLOPSの演算性能があるモバイル向けGPUのNVIDIA Tegra X1が昨年リリースされ、その開発環境としてJetson TX1が日本でも今年3月にようやく発売されました。

Jetson TX1はUbuntuをOSとして利用しており、インターフェースも多く自由度の高い開発が行えるのですが、米国価格$599が例によって日本円で10万円前後という簡単には手の出せない値段になっています。

(さらに米Amazonでは購入不可)

しかしTegra X1自体は他のNVIDIA製品にも組み込まれており、その中でもSHIELD Android TVは$199(米Amazonで23,000円で購入可能)と安価であり、USB3.0x2、micro USBx1、HDMIx1、Wifi、Bluetooth、Gigabit Ethernet、microSDカードスロット、とインターフェースもそれなりに多いハードなので、海外ではこれにUbuntuを入れてJetson TX1の代わりに使う方法が公開されています。

(ちなみにSHIELDは技適に通っており日本語に対応しています。なぜ日本で販売しないのかは不明です。)

SHILEDの分解

見た目の5倍くらいの重量があり分解してみるとフレームが金属製でかなり頑丈な作りになっていました。

私は16GBモデルを購入したのでHDDのスペースが空いています。

SHIELD

HDDをSSDに換装したい方はPro版を購入しましょう。

16GB版ではSATA→FFCケーブルやFFCコネクタが存在しません。

始める前に

現在日本語の情報は以下のPDFしかありませんので、おおまかな流れを確認しておきましょう。

Shield Android TVはJetson TX1の代わりに使えるか?

またSHIELDに入れたUbuntuでは仮想コンソールがモニターに映りません。

Ubuntuが壊れて起動しなくなった場合などに対処できないので注意しましょう。

(もしかしたら私が知らない別の方法があるのかもしれませんが)

SHIELDのWifiのMACアドレスを調べる

Android TVを起動しWifiに接続するとMACアドレスが見れるようになります。

後で使うため控えておきます。

ホストPCにfastbootとadbを入れる。

ホストPCはUbuntuを使います。

fastbootやadbだけならMacも使えます。

Android Studioをインストールすると自動的にfastbootとadbがインストールされます。

SHIELDをfastbootモードで起動する

SHILEDを起動し、Android TVのホーム画面からSettings→Device→Aboutへ移動し、Buildを選択したらコントローラのAボタンを8回連打すると開発者モードになります。

Settings→Preferences→Developer options→Debugging→USB debuggingをonにします。

ホスト側で

adb devices

を実行するとSHILEDに確認のダイアログが表示されるのでOKします。

ホスト側から

adb reboot bootloader

を実行するとSHIELDが再起動してfastboot menuが表示されます。

またfastboot menuはSHIELDの電源ボタンを操作して表示させることもできます。

  • SHIELDの電源が切れた状態で電源ボタンに触れて指を離します。
  • その後すぐに電源ボタンに触れ、今度はfastboot menuが出るまで触れ続けます。

Linux for Tegra (L4T)のインストール

先ほどのPDFはL4T R23.1をインストールしていますが、現在L4T R24.1がリリースれています。

そこでこの記事ではR24.1のインストール方法を紹介します。

(現行スレッド:Build kernel from source and boot to Ubuntu using L4T (Linux for Tegra) rootfs

手順

ここからの操作は全てホスト側のUbuntuで行います。SHIELDはまだ使いません。

まずLinux For Tegra R24.1からJetson TX1 64-bit Driver Package64-bit Sample Root Filesystemをダウンロードします。

microSDカードをext4でフォーマットします。

sudo mkfs.ext4 /dev/mmcblk0p1

Driver Packageを展開します。

この時Linux_for_Tegraというディレクトリができ、その中にrootfsというディレクトリがあります。

microSDカードをこのrootfsにマウントします。

sudo mount /dev/mmcblk0p1 Linux_for_Tegra/rootfs

rootfsの中にSample Root Filesystemを展開します。

cd Linux_for_Tegra/rootfs/
sudo tar xpf ../../Tegra_Linux_Sample-Root-Filesystem_R24.1.0_aarch64.tbz2

NVIDIAのドライバなどを書き込むスクリプトを実行します。

cd ../
sudo ./apply_binaries.sh

microSDカードをアンマウントします

sudo umount rootfs

このmicroSDカードをSHIELDにセットします。

boot.imgの書き込み

R24.1のboot.imgをダウンロードします。

展開するとsatvL4t24というディレクトリができます。

まずSHIELDをfastbootモードで起動し、fastboot menuを表示させます。

ホストPCとSHIELDをUSBケーブルで繋ぎます。(コントローラ用のケーブルを使います)

boot loaderをアンロックします。

fastboot oem unlock

この時SHIELDの画面が切り替わり赤字で警告が出ます。(出ない場合unlockをやり直します。)

Confirmを選択します。(この時SHIELDが初期化されます。)

アンロックできたら、先ほどダウンロードしたboot.imgをSHIELDに書き込みます。

cd satvL4t24
sudo fastboot flash boot boot.img
./flash-dtb.sh

ちなみにdtbを書き換えないと起動できませんので、sudo fastboot boot boot.imgをする際は注意が必要です。

書き込みが完了したらfastboot menuを操作して一度SHIELDの電源を落とし再起動します。

boot領域にboot.imgを書き込んだので、SHIELDを起動すると自動的にUbuntuが立ち上がります。

初期ユーザー名はubuntu、パスワードはubuntuです。

Ubuntuが起動したら

sudo apt-mark hold xserver-xorg-core

を実行しNVIDIAのドライバが上書きされるのを防ぎます。

初期設定

Wifi

/lib/firmware/brcm内のfw_bcmdhd.binnvram.txtを、先ほどダウンロードしたsatvL4t24の中に入っているものと置き換えます。

その後nvram.txtを開きSHIELDのWifiのMACアドレスを正しいものに変更し、Ubuntuを再起動するとWifiに繋がります。

ターミナル

右クリックからターミナルを開けるようにします。

sudo apt-get install nautilus-open-terminal
nautilus -q

キーボードレイアウト

setxkbmap -layout jp

Jetpack for L4TでCUDAをインストール

Jetpackを使うと簡単にCUDAやCUDA SamplesをSHIELDにインストールできます。

この時注意点としては(常識かもしれませんが)Jetpackはホスト側のUbuntuに入れ、SHIELDに直接入れるわけではありません。

JetpackはLANを通じてホスト側からSHIELDに必要なコンポーネントを転送しインストール操作を行うようになっています。

Jetpack for L4Tのダウンロード

ダンロード後、

sudo ./JetPack-L4T-2.2.1-linux-x64.run

で起動するとまず対象のJetsonを選択しますが、私は64bit版のL4Tを入れているのでJetson TX1(64-bit)を選びました。

jetpack

次にインストールしたいコンポーネントを選択します。

Linux for Tegraはすでに入っているのでno actionにしておきます。

jetpack

転送先のSHIELDのIPアドレスとユーザー名(Ubuntu)、パスワード(Ubuntu)を入れます。

jetpack

転送が始まります。

jetpack

私はL4TをSDカードに入れているため非常に時間がかかりました。

この時sudoのパスワードを聞かれるので席を離れていると先に進めないことがあります。

CUDA Samplesを動かす

いつもどおりにビルドすると

libGL.so :`drmMap` に対する定義されていない参照です
.
.
.

というエラーが出てうまくいきません。

これは/usr/lib/aarch64-linux-gnu/libGL.soのリンク先がmesa/libGL.soになっているせいなので、

cd /usr/lib/aarch64-linux-gnu
sudo rm libGL.so
sudo ln -s tegra/libGL.so libGL.so

でシンボリックリンクを作り直します。

nbody

nbody

particles

particles

smoke

smoke

Chainerを入れる

まずpipを入れます

sudo apt-get install python-pip
sudo pip install -U pip

apt-getでpipを入れると古いバージョンのものが入るためアップデートしておきます。

L4Tに標準で入っているPythonは2.7.6なので、このままsudo pip install chainerをしてもInsecurePlatformWarningが出ます。

ですのでpyenvを入れてPython 2.7.12をインストールします。

参考:pyenvとvirtualenvで環境構築

またエラーが大量に出るので以下を実行して再度Python 2.7.12を入れます。

sudo apt-get install libssl-dev libbz2-dev libreadline-dev libsqlite3-dev
pyenv install 2.7.12
pyenv global 2.7.12
sudo apt-get install libhdf5-dev
pip install chainer

pyenvが有効の時はsudo pipではなくpipで良いようです。

ChainerがインストールできたのでAdversarial AutoEncoderを学習させてみました。

  Tegra X1 Geforce GTX 970M
CUDAコア 256 1280
浮動小数点演算 512.0 GFLOPS 2,657.3 GFLOPS
1 epochの学習時間 3分 1分

画像処理系の小さいモデルならデスクトップ版GPUとあまり差がない速度が出ました。

RNNなどの巨大なモデルではおそらくまともに学習できないんじゃないかと思います。

(そもそもメモリが3GBしかない)

CPUの比較

VPYLMで可変長文字n-gramモデルを学習させました。

SHIELDとMacbook Proの比較です。

  Tegra X1 Intel Core i5 2.6GHz
コア数 4 2
学習時間 780文/秒 1720文/秒

Boostのビルドも10分ほどで終わりました。

CPUもそこそこ速いです。

CUDA Samplesの比較

nbody