検索
連載

低価格FPGAでニューラルネットワークの推論実行を並列化して高速化を図るFPGAにニューラルネットワークを実装する(5)(2/2 ページ)

FPGAにニューラルネットワークを実装するプロセスを学ぶ本連載。第5回では、低価格FPGAである「Tang Nano 9K」を用いた文字認識AIの推論実行について、並列化による高速化を試みたので、その結果を紹介する。

Share
Tweet
LINE
Hatena
前のページへ |       

推論を並列化するコードを書く

 リスト6は推論部分を並列化するために書き直したコードです。先に説明した通り、実行順序に依存したコードを全て排除したものになります。

 そのために前回は使いまわしていたsum変数(レジスタ)をneurosのドット数の25個分用意しました。そこにノンブロッキング代入で値を入れていきます。これを25回繰り返すことで推論結果である5×5の文字のドットを決定します。25ドットの1と0を決めるのは50行のコードです。コードとしてはちょっと冗長すぎますが執筆時はこの記述方法しか思い浮かびませんでした。読者の皆さんでもっとスマートな書き方をご存じの方がいらっしゃいましたら編集部までご一報ください。

23:         for (k=0;k<25;k=k+1) begin 
24:           sum[k]<=((neuros[0]==1)?links[25*k+0]:(-links[25*k+0]))+    
25:                   ((neuros[1]==1)?links[25*k+1]:(-links[25*k+1]))+
26:                   ((neuros[2]==1)?links[25*k+2]:(-links[25*k+2]))+
27:                   ((neuros[3]==1)?links[25*k+3]:(-links[25*k+3]))+
28:                   ((neuros[4]==1)?links[25*k+4]:(-links[25*k+4]))+
29:                   ((neuros[5]==1)?links[25*k+5]:(-links[25*k+5]))+
30:                   ((neuros[6]==1)?links[25*k+6]:(-links[25*k+6]))+
31:                   ((neuros[7]==1)?links[25*k+7]:(-links[25*k+7]))+
32:                   ((neuros[8]==1)?links[25*k+8]:(-links[25*k+8]))+
33:                   ((neuros[9]==1)?links[25*k+9]:(-links[25*k+9]))+
34:                   ((neuros[10]==1)?links[25*k+10]:(-links[25*k+10]))+
35:                   ((neuros[11]==1)?links[25*k+11]:(-links[25*k+11]))+
36:                   ((neuros[12]==1)?links[25*k+12]:(-links[25*k+12]))+
37:                   ((neuros[13]==1)?links[25*k+13]:(-links[25*k+13]))+
38:                   ((neuros[14]==1)?links[25*k+14]:(-links[25*k+14]))+
39:                   ((neuros[15]==1)?links[25*k+15]:(-links[25*k+15]))+
40:                   ((neuros[16]==1)?links[25*k+16]:(-links[25*k+16]))+
41:                   ((neuros[17]==1)?links[25*k+17]:(-links[25*k+17]))+
42:                   ((neuros[18]==1)?links[25*k+18]:(-links[25*k+18]))+
43:                   ((neuros[19]==1)?links[25*k+19]:(-links[25*k+19]))+
44:                   ((neuros[20]==1)?links[25*k+20]:(-links[25*k+20]))+
45:                   ((neuros[21]==1)?links[25*k+21]:(-links[25*k+21]))+
46:                   ((neuros[22]==1)?links[25*k+22]:(-links[25*k+22]))+
47:                   ((neuros[23]==1)?links[25*k+23]:(-links[25*k+23]))+
48:                   ((neuros[24]==1)?links[25*k+24]:(-links[25*k+24]));
49:           end
50:           for (k=0;k<25;k=k+1) neuros[k]<=(sum[k]>0)?1:0; 
リスト6 推論部分を並列化するために書き直したコード

両者の比較

 ここでは推論部分を並列化していない場合と並列化した場合について、FPGAのリソースの消費と実行速度を検証したいと思います。次に示すリスト7は、本連載で使用しているFPGA開発ボード「Tang Nano 9K」で利用できるGOWIN SemiconductorのIDE(統合開発環境)でシンセサイズした後に出力される“Resource Utilization Summary”からの抜粋です。

 リスト7の中身は、並列化していないコードのFPGAのリソース消費に関するレポートです。オリジナルのレポートに行番号などは付いていないのですが、説明の便宜上行番号をけました。1行目はFPGA内のロジック系、いわゆる組み合わせ回路の消費具合を示しています。このレポートの場合、ロジック系リソースはLUTsとALUsとなっていますが、LUT(Look Up Table)はルックアップテーブルといわれる回路ユニットです。そしてALU(Arithmetic and Logic Unit)は演算を担う回路ユニットです。

 このリスト7を見る限り、推論部分を並列していない場合、Tang Nano 9Kに搭載されているリソースのうちLUTとALUの合計が18%となります。あと4行目にあるレジスタ系のリソースを見ると、レジスタを使うとFF(Flip Flop)が消費されます。これらについては1%の消費にとどまっています。

Resource	Usage	Utilization
1: Logic	1537(247 LUTs, 1290 ALUs) / 8640	18%
2: Register	51 / 6693	1%
3:  --Register as Latch	0 / 6693	0%
4:  --Register as FF	51 / 6693	1%
5: BSRAM	0 / 26	0%
リスト7 並列化していないコードのFPGAのリソース消費に関するレポート

 リスト8は、このコードで実行できる最大周波数を示しています。“Actual Fmax”の欄にある通り、6.4(MHz)で実行可能ということを示しています。

Max Frequency Summary:
No.	Clock Name	Constraint	Actual Fmax	Logic Level	Entity
1	clk	50.0(MHz)	6.4(MHz)	139	TOP
リスト8 並列化していないコードの実行周波数

 次のリスト9は並列化したコードのFPGAのリソース消費に関するレポートです。レジスタ消費が多少増えているところでしょうか。それ以外はあまり遜色がないですね。

Resource	Usage	Utilization
Logic	1499(209 LUTs, 1290 ALUs) / 8640	17%
Register	202 / 6693	3%
  --Register as Latch	0 / 6693	0%
  --Register as FF	202 / 6693	3%
BSRAM	0 / 26	0%
リスト7 並列化したコードのFPGAのリソース消費に関するレポート

 リスト10は並列化したコードで実行可能な最大周波数を示しています。“Actual Fmax”が82.2(MHz)になっており、並列化する前の6.4(MHz)と比べて顕著に改善されていることが分かります。

Max Frequency Summary:
No.	Clock Name	Constraint	Actual Fmax	Logic Level	Entity
1	clk	50.0(MHz)	82.2(MHz)	11	TOP
リスト8 並列化したコードの実行周波数

おわりに

 本記事を執筆中にうれしいニュースが飛び込んできました。「ニューラルネットワークによる機械学習を可能にする基礎的発見と発明」の功績により、米プリンストン大学 名誉教授のジョン・ホップフィールド(John Hopfield)氏に2024年のノーベル物理学賞が授与されることが決まりました。本連載でも同氏のホップフィードネットワークを用いています。

⇒MONOist編集部へのご意見はこちらまで

前のページへ |       

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る