人気ブログランキング |

雑多な趣味の記録帳

tom01h.exblog.jp

タグ:ニューラルネット ( 112 ) タグの人気記事

tiny-dnn-fpga アクセラレータの DW-Convolution ΔW の計算方法を考えてみる

ΔW を求める式の入力は、レイヤへの入力データと、出力データの傾きです。
どちらも大きなデータなのでフリップフロップで持つ訳にはいかないし、データの再利用は畳み込みの分しかありません。
今回は、各レイヤチャンネルごと、一度に9個のウェイトデータを計算したいと思います。

src_buf のデータを順になめながら、
1サイクル目は Core0 で 0番のウェイトデータを読み出して src_buf の 0番目と掛ける
2サイクル目は Core1 は Core0 から 0番目のウェイトデータを受け取って src_buf の 1番目と掛ける
同時に、Core0 で 1番のウェイトデータを読み出して src_buf の 1番目と掛ける
(略)
11サイクル目は Core0 の累積結果を Core4 にわたして、8番のウェイトデータを読み出して src_buf の 10番目と掛ける
同時に、core0 の 0番のウェイトデータを読み出して src_buf の 10番目と掛ける
(略)
なんかずれちゃうけどこんな感じ
f0054075_21584331.png
で、うまくいくかな?
とりあえず実装は大変そうだ。

by tom01h | 2019-07-29 22:51 | Trackback | Comments(0)

tiny-dnn-fpga アクセラレータを DW-Convolution 逆方向誤差伝搬に対応する

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みとプーリング順方向をプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。

今回は Depthwise Convolution レイヤの逆方向誤差伝搬です。
結構少ない修正で対応できました。
0.48s で終わってほしいところが 0.84s 位で終わりました。
f0054075_19521235.png
正直、結構飽きてきました。多分見てくれている方も飽きてますよね。
で、最後の ΔW の計算はひと工夫必要なのに、まだいい方法を思いついていないんです。
github 更新しました。

by tom01h | 2019-07-28 20:26 | Trackback | Comments(0)

tiny-dnn-fpga アクセラレータを DW-Convolution 順方向伝搬に対応する2

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みとプーリング順方向をプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。

昨日は Depthwise Convolution レイヤの順方向伝搬のシミュレーションを流せるようにしました。
今日は 、その成果を FPGA で確認してい見たいと思います。
0.38s で終わってほしいところが 0.9s 位で終わりました。
まぁ、その程度は仕方ないのでしょうかね。
f0054075_22041876.png
このままいくと、CPU では倍くらい時間のかかる単純な畳み込みよりも速くなるか微妙なところです。
github 更新しました。

by tom01h | 2019-07-27 22:24 | Trackback | Comments(0)

tiny-dnn-fpga アクセラレータを DW-Convolution 順方向伝搬に対応する1

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みとプーリング順方向をプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。

今回は Depthwise Convolution レイヤの順方向伝搬に対応します。
普通の Convolution と同じ(出力チャンネル数)だけ並列に演算するためには入力データもチャンネル分だけ並列に読み出す必要があります。
ただし DW-conv では必要なウェイトメモリが少ないので、
- ウェイト用に演算コア内に新たにフリップフロップ(LUT-ramかも)のメモリを準備
- コア内の従来からあるウェイト用メモリにはそのチャンネル用の入力データを格納
- 入力データバッファは使わない
で、フリップフロップと、従来のウェイト用メモリを並列アクセスすることで大量のデータを準備します。
シミュレーションでは、アクセラレータ回路の実行時間は 380ms 位になっています。

3x3 DW-Conv ならこれでも良いと思うけど、MixNet みたいに 11x11 とか使われるとどうかと思います…
github 更新しました。
by tom01h | 2019-07-26 23:55 | Trackback | Comments(0)

tiny-dnn-fpga アクセラレータを MaxPooling 順方向伝搬に対応する2

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みをプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。

昨日は MaxPooling レイヤの順方向伝搬のシミュレーションを流せるようにしました。
今日は 、その成果を FPGA で確認してい見たいと思います。
0.34s で終わってほしいところが 1.6s かかるとは…
[追記 FPU と CPU を行ったり来たりしているのかな?
ただのメモリコピーなのに、データ型を気にしなきゃいけないのが Verilog 脳にはつらい…]
でも、ソフトのチューニングは後回しにして github 更新しました。
逆方向伝搬はもともとあまり遅くないので、ソフトウェアのチューニングで対応することにしました。
f0054075_23041539.png
そして、Depthwise 対応する前から…
チャネルごとにカーネルサイズを変えるらしいです。
もはや人間には最適化不可能。あらゆる手を尽くして AutoML と GCP を使わせるつもりらしい…

by tom01h | 2019-07-24 23:47 | Trackback | Comments(0)

tiny-dnn-fpga アクセラレータを MaxPooling 順方向伝搬に対応する1

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みをプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。

今回は、MaxPooling レイヤの順方向伝搬に対応します。
Poolig の計算では入力データを 1度しか使用しないので、入力データバッファは使わない方法で考えています。
入力データを直接比較して、出力データバッファに結果を書き込みます。
CPU 側でデータを整列する必要があるので、そこがネックになったら考え直しますが…
シミュレーションでは、アクセラレータ回路の実行時間は 340ms 位になっています。

逆方向伝搬はもともとあまり遅くないので、ソフトウェアのチューニングで対応することにしました。
それでも Intel で試した限りではだいぶ速くなりました。

by tom01h | 2019-07-23 22:02 | Trackback | Comments(0)

tiny-dnn-fpga アクセラレータを Z-turn で動かす その3

Z-turn ボードで tiny-dnn-fpga を動かしてみました。
現状はサンプル DW-conv ネットでは、(1x1も含む)普通の畳み込み層だけ PL を使っています。

今日は実行時間の妥当性を確認すべく、シミュレーションサイクル数から計算した実行時間と比較してみました。
delta param はソフトの改善の余地がありそうですね。
まぁ、考えるまでもなく、パラメタメモリへ書き込むデータの準備に時間がかかっているのでしょう。
そんなわけで修正してみました。
まだ改善の余地はありそうですが、とりあえずはこんなところにして github を更新しました。
f0054075_21351394.png
ちなみに、逆伝搬の異様な速さは DW-conv レイヤも速くなるだろう期待を持たせてくれます。
これだけ速くなる可能性があるなら、pooling レイヤも対応したほうがよさそうですね。

by tom01h | 2019-07-16 22:00 | Trackback | Comments(0)

tiny-dnn-fpga アクセラレータ 新装開店

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みをプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。

今までは単純な畳み込みニューラルネットを使っていましたが、やはり、Depthwise Separable Convolution レイヤに対応できないダメだよなぁってずーっと思っていました。
でも、元にしている tiny-dnn 自体が DW-conv に対応していなかったり、アクセラレータ化の効果を得るのが難しそうだったりで腰が重かったのです。

でもまぁ、できることが尽きてきた感もあるし、重たい腰を持ち上げました。
まずは、ブランチとかファイル構成とかを見直して、tiny-dnn 本体の DW-conv 対応まで。
一応動いているみたいだけど、正しく動いているかは分かりません。

そして、やっぱり DW-conv の実行時間はとっても短く、アクセラレータ化でかえって遅くなる不安が…
f0054075_21093680.png
とりあえず ここ に置いてあります。

by tom01h | 2019-07-08 21:53 | Trackback | Comments(0)

tiny-dnn アクセラレータの演算並列数を増やす 構想

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みをプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。

今回は演算並列数を増やす方法を考えてみました。
考えただけで、実装には手を付けていませんが…
[追記 なんかいまいちな気がするので、もうちょっと良い案が出るまで考えてみようと思います]

入力データバッファから複数の入力データを読み出すことで、積和演算の並列数を増やしたいと思います。
入力データバッファは、外部とのデータ転送速度を向上した際に 4ワード (=64/16bit) の同時アクセスが可能になっています。
せっかく広い帯域を持っているので、演算にも生かしたいと思います。
ただし、今回はお試しってことで入力データバッファからの読出しは 2並列まで、使えるレイヤーも限定して、全体の最大演算並列数 16は据え置こうかと思います

従来は図の左の通り、出力チャンネル方向にだけ並列演算をしていました。
この図の例では2並列演算になります。
出力チャンネル数が少ないと、せっかくたくさん持っている演算器を使いきれません。
これに対して今回の変更では図の右のように、入力チャンネルも最大で2分割できるようにしたいと思います。
この図の例では4並列演算になります。
f0054075_21315712.png
今回は出力データバッファに 2入力の加算器があるのでそれを使おうと思いますが、どちらかというと Grouped Convolution というか Depthwise Convolution で使いたい方法だと思っています。
そのためには出力バッファへの書き込み方法を考えないといけないし、4並列ぐらいじゃ焼石に水ですが…
今のモデルには、単純な Convolution しかないのでこんな方法で試してみようと思います。

by tom01h | 2019-06-23 22:28 | Trackback | Comments(0)

tiny-dnn アクセラレータの転送データを削減する その3

Zynq (Arm CPU 内蔵の FPGA) 上でオープンソースの tiny-dnn を使った MNIST の学習をしています。
tiny-dnn を改変し、計算に時間のかかる畳み込みをプログラマブルロジック(PL)に作ったアクセラレータで並列に計算し、その他は PS 中の CPU で tiny-dnn をそのまま計算します。
今回は転送データの削減のために、パラメタ更新量(ΔW)の足し込みをアクセラレータ内で計算したいと思います。

だいぶ前からシミュレーションでは動いていたのですが、FPGA では全然ダメな状態が続いていました。
最初はハングアップしちゃう状態から、計算結果が全然だめって状態を経て、今日、やっと動くようになりました。
その間、いろいろな外乱を想定してみたり、簡単な制御に変更してみたり、現実逃避してみたりで、結構時間がかかりました。
最後に直した、結構時間のかかったバグは、DMA のリセット忘れっていうしょうもないバグなんですけどね…

予想の通り、畳み込み層は速くならず…
今までは other の部分にあった足し込み演算を PL に移したので、other だけがほんのちょっと速くなりました。
f0054075_23130266.png
github は可及的速やかに更新します。[追記 急いだらタイポしました]

by tom01h | 2019-06-16 23:25 | Trackback | Comments(0)