雑多な趣味の記録帳

tom01h.exblog.jp

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

tiny-dnn アクセラレータを逆方向傾き伝搬に対応する2

アドレス生成部分にいまいち納得のいかない記述が残っていますが、とりあえず FPGA 上でも動きました。
100秒切りを期待していたのですが、あとちょっとで届きませんでした。
f0054075_23561733.png
なんか微妙に認識精度が下がっていくのが気になりますねぇ。
0.1~2%程度の話なんですが…
まぁ、でもシミュレーション時(学習データが3008の時)とは同じみたいです。
ちなみに学習データが 3008 だと、傾きの逆伝搬アクセラレータ化で認識率は微増します。
学習データが 20000 だと、認識率が 97.17% から 97.01% に低下しました。
バグなのかどうかが分からないのが、ニューラルネットの難しいところです。

[PR]
by tom01h | 2018-11-14 23:59 | Trackback | Comments(0)

tiny-dnn アクセラレータを逆方向傾き伝搬に対応する1

これまでは、DMA 版 tiny-dnn アクセラレータは順方向伝搬にしか対応していませんでした。
まだまだ高速化の余地は残っていますが、細かい調整の前に逆方向も高速化したいと思います。
今まで乗っけてきたグラフでは、逆方向はオレンジ色で 1番たくさんの時間がかかっています。
でも実はこの部分は大きく 2つの処理に分割でき、多分ほぼ 2等分だと思っています(計っていませんが…)。
それぞれの処理は、特徴量の傾きの逆方向伝搬とウェイトの傾きの計算です。
結局のところ畳み込みの計算時間は、大雑把に順方向を含めて 3等分だと思っています(計っていませんが…)。

今回は特徴量の傾きの逆方向伝搬に対応したいと思います。
まずは C言語のレベルで計算順序の入れ替えをしました。
この段階で、ハードウェアの変更が少なくて済む方法を探ります。
もしも細かいことを知りたいと思う方がいるなら、 sim_lv1 ブランチのコミットを追いかけてみると理解できるかも…
結構派手に変更していますが、順番を変えただけです。多分…
ここでストライド 1以外が対応不能になりました。(まぁ、順方向も対応していなかったけど、この変更で決定的に難しくなりました。)

そして RTL を書き始めましたが、アドレス生成部分が想像以上に難しいですねぇ。
C 言語レベルでかなり改造しておいたはずなのに…

[PR]
by tom01h | 2018-11-12 23:22 | Trackback | Comments(0)

tiny-dnn アクセラレータを ACP につなぐ

tiny-dnn アクセラレータを高速化すべく、DMA バッファをキャッシャブルにして ACP 経由でアクセスしたいと思います。
まずは、DMA と tiny-dnn アクセラレータのレジスタアクセスを UIO 経由に変更します。
いつも参考にさせてもらっている ここ を真似しました。
次に、DMA バッファを open("/dev/mem", O_RDWR) で開くように変更します( | O_SYNC をはずす)。
この時点で、速くはなるけどちゃんと動かなくなります。
そして、PS のスレーブポートを HP0 から ACP に変更します。
何やら Critical Warinig 出ていますが…
あれ?動きませんよ。
調べてみると、こんな話 がありました。なんか最近よく見る人だ…
Constant IP を使って AxCACHE に 1111 を入れます。
して、11秒くらいだった畳み込み順方向が 8.4 秒まで縮まりました。
f0054075_22101589.png

[PR]
by tom01h | 2018-11-05 22:59 | Trackback | Comments(0)

tiny-dnn アクセラレータ 速報 動いた

これからいろいろとまとめますが、やっと DMA 版の tiny-dnn アクセラレータが動きました。
20000 サンプルの学習 1エポックで認識率 97.17% 出ているので、致命的なバグはないと思います。
畳み込みの順方向だけ対応した途中経過ですが、結構速くなりました。
f0054075_12125890.png
そして、この成果を確認してから Ultra96 を買おうと思っていたのですが…
f0054075_11591904.png

[PR]
by tom01h | 2018-11-03 12:13 | Trackback | Comments(0)

tiny-dnn アクセラレータ 動くこともある?

最後のあと1歩の所はちゃんとシミュレーションしていないので、そこでバグると実機デバッグになって大変です。
今回は wire 宣言をしていないバスが 1bit しか接続されないってやつを見つけました。
修正した結果、運が良ければ1サンプルの1層分は動いて、結果もシミュレーションと一致します。
でも、ハングアップする時もあって五分五分な感じです。
たぶん初期化不良なんだと思います。
明らかにダメなところとかいくつか見つけているし…

ちなみに今は全く工夫無く順番に処理していますが、ソフトの工夫だけで真ん中に、SrcBuf と DstBuf をダブルバッファにすると下のタイミングまで高速化できると思っています。
これだけ見ると、IOMMU なくてもよいように感じますねぇ。
[追記 この絵のように計算時間(紫)が転送時間(紫以外)よりも長いときには問題ないですが、転送時間が長くなるようならIOMMUが欲しくなります。つまり、Ultra96 が欲しいってことです。]
f0054075_22135569.png

[PR]
by tom01h | 2018-11-01 23:34 | Trackback | Comments(0)

tiny-dnn アクセラレータが Zynq の上で動かない

検証環境ではテストベンチから入れていた設定レジスタの値は、昨日は AXI GPIO で行こうかと思っていたけど、数が多いのでやはり自前の AXI-Lite スレーブを持つことにしました。
そして、Zynq に乗っけてみて devmem コマンドでレジスタを読み書きしてい見ると、ちゃんと出来ているようです。
つぎに、最初の 1サンプル・1層の計算が終わったところで結果を表示して終了するようなプログラムを作って流してみました。
結果は全部 0。とりあえずハングアップはしないけど、全然動いていません。
結果を転送するための DMA バッファは、きっちりサイズ分だけ 0 に変化するので、DMA の設定は出来ているように思います。

合成の結果がやたらと大きかったので調べてみましたが、AXI とか DMA ってすごく大きいんですね。
f0054075_22380069.png

[PR]
by tom01h | 2018-10-28 23:29 | Trackback | Comments(0)

tiny-dnn アクセラレータの AXI Stream 完了

tiny-dnn アクセラレータを高速化すべく、CPU の介在なしでウェイト・入力データ・出力データを転送できる構成への変更が完了しました。
ウェイトに加えて 1サンプル分の入出力データを置くためのバッファを内蔵し、AXI Stream 経由でデータを送受信します。
1サンプル分の計算はすべてアクセラレータ内で処理します。
AXI Stream データの生成は AXI DMA にお任せのつもりです。
f0054075_18350407.png
最初は DMA にミニバッチ 1層分の設定をして、Ready を使ってサンプルごとにデータを受け取ろうと思っていたのですが、どうやら C++ の std::vector はデータが連続配置されていないようなので、サンプルごとに DMA の設定をし直す必要がありそうです。

続いて、本物の FPU でのシミュレーションも完了しました。
ちゃんと考えていたはずなのに、real で計算していた時よりも 1サイクル長かったです…

これで、FPGA で動かす準備は完了のはずです。今度こそ速くなっていると良いな。

[PR]
by tom01h | 2018-10-27 23:35 | Trackback | Comments(0)

tiny-dnn アクセラレータのパラメータ書き込み

tiny-dnn アクセラレータのパラメータを AXI Stream 経由で書き込めるようにしました。
まだ、テストベンチからの制御がちょっとだけ残っています。
AXI Stream の Valid, Ready の扱いもちゃんとしないと駄目そうですが、完成が見えてきました。
シミュレーション波形です。
f0054075_23472837.png
ウェイト、バイアス、入力データを読み込んで、計算して、結果を書きだすまでが黄色の線です。
そのあと、2回目のデータの入力を始めます。
ダブルバッファにした方が良いですかね?まぁ、まずはとにかく動くことを目標に…

[PR]
by tom01h | 2018-10-25 23:54 | Trackback | Comments(0)

tiny-dnn アクセラレータに入出力バッファ追加

tiny-dnn アクセラレータに 1サンプル分の入出力データを置くためのバッファを追加しました。
sample controller で 1サンプル内の制御をして、batch controller でミニバッチ 1層の制御をします。

sample controller は以前も書いたように、batch controller からリクエストを受けて
1. カーネルごとに入力データのアドレスを生成してデータを取ってきつつ計算する
2. 1カーネル分の計算が終わると出力データのアドレスを生成してデータを吐き出す
3. 終わったらストライド分(1限定だけど)だけ移動して、1サンプルの計算が終わるまで繰り返す
1サンプルの計算が終わると batch controller に知らせます。

batch controller は CPU からリクエストを受けて
1. 入力側の AXI Stream の ready を上げて 1サンプル分のデータを受け取る
2. 入力側の AXI Stream の ready を下げて、sample controller にリクエストを投げる
3. sample controller から計算終了の通知を受けると 出力側の AXI Stream の valid を上げる
4. 1サンプル分のデータを出力したら valid をさげて、ミニバッチ分だけ繰り返す
ミニバッチが終わると CPU に制御を戻します。

まだ、ちゃんとAXI Stream になっていないし、テストベンチからの制御も残っているし、パラメータの書き込みに変なインタフェースが残っていますが、いったんバージョン切りました

だいたいこんな感じのを作っています。
f0054075_23021309.png

[PR]
by tom01h | 2018-10-24 23:30 | Trackback | Comments(0)

tiny-dnn アクセラレータのシーケンサ追加

tiny-dnn アクセラレータに 1サンプル分のシーケンサを追加しました。
カーネルごとに入力データのアドレスを生成してデータを取ってきつつ計算し、出力データのアドレスを生成してデータを吐き出します。
終わったらストライド分(1限定だけど)だけ移動して、1サンプルの計算が終わるまで繰り返します。
ここまでは自動で動くようになりました。

次は 1サンプル分のデータ用バッファを内蔵して、AXI-Stream っぽいインタフェースを追加したいと思います。

しかし、ごちゃごちゃしたシーケンサを作ってしまったため、逆伝搬への対応がすごく難しい事になりそうな予感です…

[PR]
by tom01h | 2018-10-22 23:57 | Trackback | Comments(0)