tkato’s blog

ブログ名は暫定。

BNN-PYNQを理解する(1) FAQ

3月以降、仕事が激しくなり、余暇もほとんど仕事に関わる分野の勉強に当てていました。 以下の5/20のイベント出席に向けて、DeepLearning x FPGAの勉強を再開しました。

「PYNQ祭り」延長戦 : FPGAディープラーニング実践懇親会 - connpass

まずは、手近な勉強材料としてBNN-PYNQのソースを解析してみました。 勉強した内容は、ブログに何回かに分けて書きたいと思います。

尚、BNN-PYNQのソースコードは5/2時点で最新のものを使いました。

GitHub - Xilinx/BNN-PYNQ at a86e0863418ce4161ed61b69ba89ec1481014362

初回は、自分も含めて多くの人が気になりそうな話題について、ざっくりFAQ形式で書きたいと思います。

BNN-PYNQってなに?

ホビーFPGAボード"PYNQ(ピンク)“で動作するNeuralNetworkのシステム。 行列演算などをハードウェア化することで、DeepLearningアルゴリズムを、CPUより高速化(アクセラレーション)する試みが、至る所で行われています。これもその一種。

推論に関しては、Pythonのアプリケーション層、Cのドライバ、高位合成用の実装まで、全コード公開されているためDeepLearningのアルゴリズムFPGAで動かすことを学ぶには良い素材です。

アプリケーションは、例えば以下。

BNN-PYNQ/Cifar10.ipynb at master · Xilinx/BNN-PYNQ · GitHub

BNN-PYNQは同じNeuralNetworkをCPUとFPGAそれぞれで動かせるようになっていて、「CPUよりFPGA化したほうがこんなに速いよ」という内容が上記でも確認できます。

BNN-PYNQは、以下のような工夫をして高速化しています。 詳細は論文*1に記載があります。

  • 演算精度のバイナリ化(0,1)
    • メモリの使用量、転送量を削減
    • ビット演算器を活用した高速化
  • 演算の並列化

学習も推論もFPGAでやるの?

No。学習はPCで行い推論をFPGAで実行する仕組み。

PCのDeepLeraningフレームワークで学習したモデルを、BNN-PYNQ用のデータフォーマットに変換するスクリプトは付属しています。 現時点でTheanoで学習したパラメータの変換に対応しているようです。 サンプルは、Lasagne(Theanoをバックエンドにできる)で記述されています。

データフォーマットの変換だけなので、ちょいとスクリプトを書けば、TensorFlowやChainerなどとも連携できるはずです。(今度のイベント向けにやってみようかな)

認識精度は?

付属の学習済みモデルに関する認識率は、ここに記載があります。

BNN-PYNQ/bnn/src/training at master · Xilinx/BNN-PYNQ · GitHub

バイナリ化しない場合に比べて、GPUでの学習時間がすこし長い印象がありますが、どうなんでしょうか?

PCで動く任意のモデルをFPGA化できるの?

No。現状はLFCとCNVと呼ばれる2種類のモデルに対応してます。 例えばLSTMなど含むモデルは動かせません。

ただし、BNN-PYNQが対応しているレイヤーで構成されるモデルであれば、FPGAのリソースに乗る範囲でレイヤーを組み替えて任意のモデルは作れると思います。

BNN-PYNQでは、バイナリ化したConvolutionやFullyConnectedレイヤーのハードウェアを使います。 そのため、PC側もそれに合わせてバイナリ化したレイヤーを定義して学習しないと、学習した重みをFPGAに乗せられません。 通常のPC側のフレームワークだとfloat(32bit)で計算する部品がほとんどです。 そのため、BNN-PYNQでは、PCのフレームワーク用にもバイナリ化したレイヤーを定義して、それを用いてモデルを作り、学習しています*2

もし、ConvolutionやFullyConnected以外を使いたい場合は、ハード側にそのレイヤーを実装するか、そのレイヤーをソフト処理するかだと思います。 しかし、ソフト処理は現実的ではないと思います。BNN-PYNQは推論開始後、最期のレイヤが計算完了するまで制御がCPUに戻らない仕組みです。そのため、途中の一部のレイヤだけソフト処理にするのはBNN-PYNQのコアの修正が必要で、できたとしても速度が遅くなると思います。 そのため、追加したいレイヤーのCPUよりも高効率なハードウェアアルゴリズムを考えて、それを高位合成なりでハード化するのが面白いんじゃないでしょうか??

任意のデータで既存のモデル(LFCとCNV)を再学習できるの?

Yes

CNV, LFCは それぞれ学習データのフォーマットが決まっているので、それに従い作成したデータなら学習可能です。

任意のタスクにBNN-PYNQを応用する場合は、まずは既存のネットワーク(LFC,CNV)を使うところから考えるのが良さそうですね。

CPUとアクセラレータ間のデータ転送のタイミングは?

データのコピーが性能上のボトルネックになるので、どのタイミングでコピーしているかは重要です。 ソースを見ると、以下のタイミングでコピーが発生しているようです。

  1. モデル初期化時に、全レイヤーのパラメータをCPUからアクセラレータへコピー
  2. 推論開始時に、入力画像データを、CPUからアクセラレータへコピー
  3. 推論終了時に、推論結果をアクセラレータからCPUへコピー

推論中は、アクセラレータとメモリ内で閉じて演算しているようです。

最期に

今回は書けなかったのですが、ソフト側のソースはざっくり読みました。

以下のような流れでPythonからアクセラレータを叩いています。 モデル依存のC実装は薄くて、コアライブラリ(共通部)が厚いかんじ。

  1. Pythonのラッパーから、CFFIを使ってモデルのCライブラリを叩く
  2. モデルのCライブラリは、コアライブラリを叩いて、パラメータの設定や推論の実行を命令する
  3. コアライブラリは、アクセラレータのドライバを叩いて、アクセラレータ用のバッファ管理やレジスタ制御を行う

アプリからハードまで、ほんとに勉強になりますね…

次回はソフト側の記事を書きたいと思います。

*1:https://arxiv.org/abs/1612.07119

*2:元祖 Binarized Neural Networksの論文の実装をベースにしてるぽいですね