Ousia Engineering Blog

Studio Ousiaのエンジニアリングブログです。社内での技術的な取り組みを中心に紹介していきます。

PYNQ-Z1で始めるDeep Learning on FPGA入門(その1:購入からJupyter NotebookでLチカまで)

こんにちは。エンジニアの戸塚です。

自分へのクリスマスプレゼントとして PYNQ-Z1 を買ったので、25%ルール第一弾は「Deep Learning on FPGA入門」的なことをしてみたいと思います。

f:id:naoyaousia:20180110153259p:plain

【DISCLAIMER】スタート時点でFPGA素人です。Courseraでちょうど年末からFPGAコースを開講していたので併行して勉強中です。間違ったことを書いていたら必要に応じて訂正を入れていきます。有識者の皆様のご指摘を歓迎します。

1. 購入から起動まで

前日譚

25%ルール第一弾で何をやろうかあれこれ考えながらクリスマスの秋葉原をうろついていた時に、CQ出版社が出してるFPGAの入門用キット*1が気になりました。

↑こんなやつ

ちょうどNVIDIAが利用規約を変更し"データセンター"での深層学習用途でのGeForceの利用を禁止したというニュースが話題になっていて、GPU以外の選択肢としてのFPGAが少し気になり始めていたところでした。

とりあえず一旦帰って情報収集してからにしようと思い、その場では買わずに帰ってきました。

情報収集

FPGAのマーケットシェアの約9割は二大メーカーXilinxとIntel (Altera)*2が抑えているのですが、「FPGA 入門用」で検索して出てくるのはTerasicのDEシリーズ、先述のCQ出版社のスターターキットなど、AlteraのCycloneやMAXシリーズを載せたものが多いです。最大手のXilinxのFPGA(Spartanとか聞いたことあります)を利用した入門者に丁度よさそうなキットは無いのでしょうか?

XilinxのFPGAについて調べていたところ、XilinxがBNN-PYNQという、binarized neural network (BNN)を自社のFPGAを載せたPYNQというボードで動かすためのパッケージを出しているのを見つけました。

PYNQ

PYNQとは、Xilinxが自社のFPGAであるZynqをPythonでデザインできるようにするというオープンソースプロジェクトで、これに対応したボード PYNQ-Z1をDigilent社が出しています。 2016年に発売されたボードのようで、PYNQについて検索すると2016年末〜2017年初頭のブログ記事が色々出てきます。

PYNQ-Z1にはZynq XC7Z020*3の他にARMチップが載っていて、その上のLinuxで走るJupyter NotebookにアクセスしてPythonでFPGAを制御することができます*4

高位合成(HLS)

FPGAで回路を設計する方法は

  • Verilog-HDLやVHDLのようなハードウェア記述言語で記述する
  • 回路図で描いてこれらの言語に落とす開発環境*5を利用して設計
  • C/C++から直接FPGA用のコードを合成する高位合成(HLS)技術を用いる*6

のように進化していて、今ではPythonで書かれたコードからハードウェア記述言語を生成できるツールもあります。

PYNQでは、Vivado HLSで生成した回路デザイン(ビットストリーム)を読み込んでPythonコードから制御できる仕組みになっているそうです。*7

とても気になります。

  • 高位合成(C/C++やPythonでも書けるらしい)
  • ちゃんと動くBNNのライブラリがオープンソースで提供されている
  • PYNQ-Z1のピンク色のボードがなんか可愛い

そんなわけで、遅めの自分宛クリスマスプレゼントはPYNQ-Z1に決まりました。

注文

Digilent社のウェブサイトで注文しました。

PYNQ-Z1本体は229ドルします。Academic discountが適用できると65ドルで買えるらしいです。 その他、ボードを保護するアクリルボード、PYNQのシステムをmicro-SDカードに焼いたもの、128x32のモノクロOLEDディスプレイ、なども合わせて購入し、FedEx送料(38.83ドル)込みで307.80ドル(35,952円)のお買い物になりました*8

12/26に注文したのが出荷されたのは28日の昼過ぎでした。(2日の停滞はクリスマス休暇の為らしいです) アメリカから届くのかと思ってFedExの荷物追跡を見てみたら発送元が台北でした。Digilentは世界各地に拠点を持っているようなので、アジア地区は台湾から発送なのでしょう。

台北(台湾)→桃園(台湾)→アンヘレス(フィリピン)→広州*9(中国)→成田→東京税関→自宅

という経路で、12/28の昼過ぎに出荷されたものが29日の朝には成田に着いていて、通関から後は西濃運輸さんが運んでくれました。着いたのは15時頃。
f:id:naoyaousia:20180120205504j:plain

早速開封の儀。
f:id:naoyaousia:20180120205534j:plain f:id:naoyaousia:20180110153554j:plain f:id:naoyaousia:20180120205621j:plain f:id:naoyaousia:20180120210006j:plain

起動の前に

GitHubリポジトリやオンラインの公式ドキュメントが充実しているので読みながら進めます。

PYNQ-Z1はシステムのイメージをmicroSDカードから読み込んでブートする仕組みになっています。起動に際し、

  • 給電用のmicroUSBケーブル(お手持ちのものでどうぞ)
  • PYNQのシステムイメージを焼いたmicroSDカード

が必要となりますのであらかじめ準備しておきます。microSDカードは準備済みのものをPYNQ-Z1ボードと一緒にDigilentから購入することもできます(実際そうしました)が、システムが最新のものではなかったりします*10

Pythonから利用できるpynqライブラリの仕様もところどころ変わっていますので、購入された方も(何かコードを書き始める前に)最新システムイメージでの上書きを推奨します。

PYNQシステムmicroSDカードの準備

  • 8GB以上のmicroSDカードを用意。
  • PYNQ公式サイトからPYNQ-Z1 image*11をダウンロード。1.6GB弱のZIPファイルで、これを解凍すると4GB前後のイメージファイル(拡張子.img)が得られる。
  • microSDカードをカードスロットなりアダプタなりに差し込んで認識したら初期化。
  • TerminalでmicroSDカードのpathを確認。(diskutil listで認識中のデバイスが列挙されるので、microSDのデバイスを探して下さい。以下 /dev/disk2 として進めますが適宜読み替えて下さい。上書きするので注意してください!)
  • このデバイスのマウントを解除。
    $ diskutil unmountDisk /dev/disk2
  • ddコマンドでmicroSDカードにイメージを書き込む。
    ZIPファイルを解凍したimgファイルを pynq_v2.0.img とすると
    $ sudo dd bs=1M if=pynq_v2.0.img of=/dev/rdisk2
    disk2 の代わりに rdisk2 とすることで読み書きが高速になるらしいです。

起動!

公式ドキュメントによると、起動の手順は以下の通りです。

  1. ジャンパーピン JP4(ブートジャンパ。USBプラグのそばにある)を SD にセット。
  2. JP5(パワージャンパ。電源スイッチの右隣りにある)を USB にセット。
  3. PYNQシステムのイメージが入ったmicroSDカードをSDカードスロットに挿入。
  4. microUSBケーブルをPROG-UART / J14ポート(※USB HOSTと書かれた普通のUSBが刺さるポートではない)に接続。
  5. LANケーブルを接続。
  6. 電源スイッチをON。

とりあえずmicroUSBをMacBookに繋いで電源スイッチを入れると、ボード上のARMプロセッサの上でLinuxが起動し、

  • 赤LED (LD13) がすぐに点灯
  • 2秒ぐらい待って近くの緑LED (LD12) が1つ点灯
  • 18秒ぐらい待つ
  • 青LED2つ (LD4, LD5) +緑LED4つ (LD0LD3) が8回点滅
  • 青LED消灯、緑LED点灯、で落ち着く

これでスタンバイ状態になります。*12

2. Jupyter Notebookにアクセスする

さて、PYNQの目玉でもあるJupyter Notebookにアクセスしてみるところから始めましょう。

a) LAN経由でアクセス

PYNQ-Z1にはwi-fiは載ってないので有線でLANに繋ぎます。 PYNQ-Z1はデフォルトでIPアドレスは 192.168.2.99 なのですが、が、残念ながら部屋のLANは 192.168.2.0/24 ではないので、DHCPから貰ったIPアドレスを調べる必要がありました。ping broadcastで捕捉できなかったので一軒ずつ総当たりでpingを打って見つけました。IP Scanner等のユーティリティを使う手もあります。 (後述のUSB-serial接続でコンソールを掴めれば、ifconfigでeth0を見れば分かります)

以下、IPアドレスはデフォルトの 192.168.2.99 で記載しますが適宜読み替えて下さい。 あとPCとか言っていますがMacBook(macOS Sierra)から繋いでいます。

Webブラウザで http://192.168.2.99:9090/ にアクセスすると、Jupyter Notebook が開きます。

f:id:naoyaousia:20180117110737p:plain

パスワードを求めてきます。デフォルトのパスワードは xilinx ですが変更しておきましょう。

PYNQのJupyter Notebookのパスワード設定

パスワードの編集は /root/.jupyter/jupyter_notebook_config.py の c.NotebookApp.password にハッシュ化したパスワードを設定します。 Jupyter Notebook上で from notebook.auth import passwd; passwd() を実行すると、設定したいパスワードの入力を求められるので入力します。確認を求められるのでもう一度同じものを入力すると 'sha1:xxxxxxxxxxxxxxxxxxxxx' のような文字列を返されるので、/root/.jupyter/jupyter_notebook_config.py の中(217行目あたり)で c.NotebookApp.password にこれを代入します。

b) LANケーブルでPCと直接接続

この場合、PYNQ側にIPアドレスが振られる必要があるのですが LANケーブルを繋いでいるポートを経由するインターネット共有(うちの場合はWifiを共有する形です)をすれば行けるのを確認しています。*13

3. Jupyter NotebookからLチカさせてみる

Hello, world代わりに、ボードの端の緑色LED0を5回点滅するドリカム的なトイプログラムをJupyter Notebookで書いてみます。

PYNQ v2.0 では、BaseOverlay (pynq.overlays.base.BaseOverlay) 越しにボード上のインターフェイスを制御することができます。 (この時点ではまだFPGAのロジックは1mmもいじっていません)

import time
from pynq.overlays.base import BaseOverlay
base = BaseOverlay("base.bit")
led0 = base.leds[0]
for i in range(5):
led0.on()
time.sleep(0.5)
led0.off()
time.sleep(0.5)
view raw eltika.py hosted with ❤ by GitHub

コンソールが叩けるなら、Jupyter Notebookを使わなくても直接pythonコードとして実行できます。

$ sudo python3.6 eltika.py

デバイスの読み書きにはroot権限が必要なので sudo で実行する必要があります*14

4. コンソールを叩いてみる

PYNQ-Z1のボード上ではLinux*15が動いています。Jupyter Notebookからのアクセスが可能なほか、当然ログインしてコンソールを叩いて操作することもできます。Python以外で遊ぶこともできます。

a) Jupyter Notebook経由で

Jupyter Notebookの画面の右の方の New▼ から Terminal を選ぶと、ブラウザでf:id:naoyaousia:20180117110501p:plain Terminalが開きます。(勝手にrootで入ります) f:id:naoyaousia:20180117110441p:plain

b) ssh経由で

ユーザ名は xilinx です。(デフォルトのパスワードは xilinx です)

ssh xilinx@192.168.2.99
xilinx@192.168.2.99's password: ******
Welcome to Ubuntu 15.10 (GNU/Linux 4.6.0-xilinx armv7l)

 * Documentation:  https://help.ubuntu.com/
Last login: Tue Aug 15 23:10:22 2017
xilinx@pynq:~$ ls
jupyter_notebooks  pynq  REVISION
xilinx@pynq:~$

passwd コマンドでパスワードを変更しておきましょう。

xilinx@pynq:~$ passwd
Changing password for xilinx.
(current) UNIX password: 
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
xilinx@pynq:~$

c) USB-serial経由で

LAN接続ができなくても、microUSBでPCから給電しているならその繋いでいるUSBを経由してシリアルポート通信でPYNQのコンソールが叩けます。Jupyter Notebookで操作できるPYNQ-Z1ですが、これは知っておくと何かと便利です。

/dev/ ディレクトリの下に tty.usbserial-* という最近出来たデバイスがあるはずです。 うちの場合

$ ls /dev/tty.usbserial*
/dev/tty.usbserial-003017A6E0D5A /dev/tty.usbserial-003017A6E0D5B

この2つがありました。(AとBがありますが、うちではBとだけ交信できました。)

$ screen /dev/tty.usbserial-003017A6E0D5B 115200

最初うんともすんとも言ってくれないのですが、returnキーを叩いたら反応がありました。

xilinx@pynq:~$ 

デフォルトユーザ (xilinx) で勝手にログインしています。

5. ファイル転送

a) sftpでファイル転送

ネットさえ繋がればssh同様、sftpでファイルのやりとりが可能です。

$ sftp xilinx@192.168.2.99
xilinx@192.168.2.99's password: 
Connected to 192.168.2.99.
sftp> ls
REVISION                                        jupyter_notebooks                                          pynq
sftp>

b) SMBでファイル共有

macOSの場合、Finder > 移動 > サーバへ接続… (⌘K) でサーバアドレス smb://xilinx@pynq/xilinx に接続し、パスワード(デフォルトはxilinx)を入力することでユーザ xilinx のホームディレクトリに接続できます。

SMBのパスワードは、ユーザ xilinx でコンソールにログインして smbpasswd コマンドで変更できます。

to be continued...

今年に入ってからGPUやFPGA回りで気になるニュースが続きます。

pc.watch.impress.co.jp techon.nikkeibp.co.jp

PFUが発表したDeep Learningアクセラレータカード(2018年11月に出荷開始予定)はChainerで学習したNNをFPGA*16に実装できるそうです。「AIというとGPUが話題に上ることが多いが、リアルタイム処理性能や低消費電力性、ボード寸法などを考慮した結果、FPGAを選んだ」とのことで、特に気になります。

というわけで、次回はPYNQのOverlayモジュール (pynq.overlays) を足がかりに早速FPGA部分に足を踏み入れていきたいと思います。

参考資料

*1:Intel®のMAX® 10 FPGA, 10M08SAE144C8GESを採用している

*2:2015年にIntelがAlteraを買収。

*3:Xilinx社のArtix-7シリーズ相当のFPGAを搭載

*4:もちろんssh等でコンソールを叩くこともできます。

*5:Altera(Intel) のQuartus Primeなど

*6:XilinxのVivado HLSなど

*7:PYNQ自体は、ベースとなるZYNQ向けにVivadoの上位ツールにあたるSDSoCで開発されています。

*8:PYNQ-Z1ボード : $229.00 PYNQシステムインストール済み8GB microSDカード(アダプタ付) : $12.99 透明樹脂製カバー : $7.00 GroveシステムAdd-onボード : $4.99 Pmod 128x32ピクセルモノクロOLEDディスプレイ : $14.99 /小計 : $268.97 FedEx送料 : $38.83 /合計 : $307.80 これとは別に後日、消費税と関税手数料で1800円の追加請求が来たので支払いました。

*9:FedExのアジア地区のハブ。

*10:マニュアルの記述はv2.0に準拠していますが、購入したmicroSDのシステムはそれより古いものでした。

*11:https://files.digilent.com/Products/PYNQ/pynq_z1_v2.0.img.zip

*12:30秒ぐらい待つけど大丈夫動いてるよという事が動画からお分かり頂けるかと思います。

*13:MacBook側からifconfigしてみたら bridge100 というインターフェイスで 192.168.2.0/24 のネットが出来ていて、PYNQは 192.168.2.2 にいました。

*14:デフォルトユーザ xilinx は sudo 権限を最初から与えられています。なおPYNQではJupyter Notebookをroot権限で実行しています。

*15:手元のPYNQでは Ubuntu 15.10 (GNU/Linux 3.17.0-xilinx armv7l)。

*16:FPGAにはIntelのArria10 GX1150を使用するそうです。