【2023年ライトニングトーク】FPGAを使ってみた
2023年4月4日に第1回ALT(Arp Lighting Talk) が開催されました。
ここではプログラム2-1のライトニングトーク「FPGAでオセロ対戦に殴込み」に関して紹介します。
※)「オセロ対戦」とは
株式会社アープが毎年11月に開催する全社員参加型のイベント「アープの日」に行われるプログラミングコンテストです。
その年に入社した新人が開発したオセロプログラム同士で競い合い、優勝者にはトロフィーが送られます。
概要
昨年末から今年初めにかけて、ACRi HLSチャレンジにおいて、手書き数字画像を認識するチャレンジが開催されました。 複数のチャレンジを通して、MNISTの手書き数字画像から数字を認識するCNN(Convolutional Neural Network)を実装します。 ここでは、全5回のチャレンジで実装したコードについて解説します。
ACRi HLSチャレンジ
(※)出典https://acri-vhls-challenge.web.app/
実装したCNNは以下のような構造になります。
畳み込み層 → 最大値プーリング層 → 畳み込み層 → 最大値プーリング層 → 全結合層
各パラメータは、以下のように量子化(Quantization)されています。
- input 1bit 二値化(Binary Quantization) 0,1
- weight 2bit 三値化(Trinary Quantization) -1,0,1
- activation 2bit 閾値(Threshold)で2ビット化 0,1,2,3
コード解説
1.mnist1-matmul0 MNIST向けCNNの全結合層
全結合層は、行列とベクトルの積で表されます。
要素の掛け算はそれぞれ独立しているので、unrollで一度に計算することができます。
また、掛け算結果の足し算は、隣同士一度に足し算を最後の1つまで繰り返す、ことで 計算時間をlognに抑えることができます。
2.mnist2-maxpool0 MNIST向けCNNのMax Pooling層
最大値プーリング層では、2×2の要素から最大値を返します。 水平方向の最大値を返す層と、垂直方向の最大値を返す層に分割することで 水平方向と垂直方向の最大値判別を、並列に実行することができます。
3.mnist3-conv0 MNIST向けCNNの初段の畳み込み層
畳み込み層では、入力に対して複数のフィルターを適用します。 各フィルターの計算はそれぞれ独立して計算することができます。
4.mnist4-conv1-mp1 MNIST向けCNNの畳み込み層とMax Pooling層
2層目の畳み込み層および最大値プーリング層を実装します。 最初の実装では、ここでリソース制限のLUT:50,000に引っ掛かり リソース超過でコンパイルできませんでした。 後述する積和演算のLUT置き換えでリソース削減するまでは 畳み込み層の最外ループのpipelineをoffにすることで リソース超過を回避していました。
5.mnist5-all CNN全体
最後にCNN全体をひとつのカーネル内に実装します。 入出力のinterfaceにはAXI Streamを使用し、配列へのアクセスを 画像の幅に合わせてcyclicに指定します。 前チャレンジで実装した各層の関数を、dataflowで並列実行します。
6.積和演算のLUT置き換え
1.で実装したように、積和演算の計算を並列化することで 計算時間を短くすることができましたが、演算回路が増えるため CNN全体を実装すると、リソース超過でコンパイルできませんでした。 量子化によりビット数を減らした計算では 積和演算の結果をテーブルに持つことができるので乗算回路が不要となり リソース制限内でCNN全体を実装することができました。
アーパボー