FPGAにおけるAIを考察する

技術記事

FPGAの能力

ここでは私がよく使っている AMD の Kria KV260 ボードを例に取り上げて具体的な話をしてみようと思います。

リソース名個数容量演算
DSP1,248Multiply and Add
LUT117,12064 bit(LUT)6 input binary OP
FF234,2401 bit
Distributed RAM57,60064 bit
Block RAM14464k bit
Ultra RAM64288k bit
OCM1256k Byte
DDR4-SDRAM14G Byte

ここで例えば 1,248個 DSP ある DSP に目をやると、これはうまく詰め込むと INT8 を 2つぐらい同時に計算することができますし、頑張れば 500MHz 程度で動かすことができます。
早い話が 1.2T MACs 程度の INT8 演算性能があり、実際 DPU などはその水準程度の演算をこなしているわけです。
例えばこの辺りにパフォーマンスの記載がありますが、ResNet18 などいわゆるよく見るネットワークで60fpsを遥かに超える性能で動いており、まさにカタログスペック通りという感じですし、FPGAの低消費電力性や、リアルタイム性、IO回路との相互接続などメリットも多いでしょう。

一方で、これらは GPGPU や CPU の為に作られたネットワークを単にFPGA上にポーティングしただけであり、何らFPGAのメリットを生かしたネットワーク設計になっていません。

AI以前のFPGAの使われ方の例から眺めてみる

FPGAがCPU/GPUに比べて得意なのは画像処理などでよく表れるパイプライン処理です。

例えばビデオ信号の高画質化処理とかノイズ除去のような処理は非常に得意であり、ピクセルクロックで演算回路を動かせば、1ピクセル当たりDSPを1248個使った演算を施すことができます。この時DSPはほぼ100%稼働して演算器の利用効率も非常に高いことになります。

実際、FullHD(1080p)のピクセルクロックが150MHz、4k画像が 600MHz、当サイトのような VGA で1000fpsをやるような特殊センシングでも350MH程度が処理クロックになってきますので、非常に相性が良い分野になります。

ではこのFPGAがもともと得意としている分野にAIを持ち込もうとしたらどうなるかという事なのですが、従来の使い方だと、DSP 1248個 が100% 稼働する世界なので、これをINT8 のディープニューラルネットワークに置き換えたところで、高々、パラメータ数 1248×2 = 2,496個 しか扱えないわけです。

パラメータ数 2,496個(19,968bit) のネットワークなんて、極めてチープな事しかできないのは想像に難くないでしょう。
FPGA と同程度の演算能力のGPUなどが凄い認識が出来ているのは、例えば ResNet18 などが入力画像サイズを 224×224 に縮小してから扱っているためです。これはいかにもパソコンなどの汎用コンピュータの考え方で演算能力の都合に合わせて Input や Output をスケールさせているためです。

もちろんFPGAでも同じように縮小してから計算するようにし、大量のパラメータをDDR4-SDRAMなどに配置して計算することは可能です。
224×224@60fps でよければ、ピクセルクロックは3MHz 程度ですので、300MHzでFPGAを動かすだけで、DSP数の100倍のパラメータを外部メモリに置いておいて、パラメータをとっかえひっかえいろいろな計算ができるでしょう。
ただし、縮小回路や、パラメータの入れ替え回路、DMAや各種の回路も追加で必要になり、FPGAらしさが低下していきます。もしやりたいことがそれだけならCPU/GPUでもよいし、電力やコストが気になるなら適当なNPUを持ってくれば済む部分はあり、FPGAを使うメリットがこれだけではなくなってしまいます。

FPGA の良さを生かしたままAIを入れたい

当サイトの考え方はここにあります。私が着目したのは、64bit のLUTをもつ 117,120個の LUT です。BinaryBrainではLUTモデルそのものをネットワークモデルとしているので余計な回路を追加することなくLUTをほぼ100%ネットワーク演算に投入できます。
64bit が 117,120個 のパラメータ(7.5Mbit) というと、多くは無いですが先ほどの DSP の 2.5k個のパラメータと比べると桁違いに多いですし、少しはましなことが出来そうに思えるわけです。

また、パラメータの方が固定且つ数に上限があるためサンプリングレートを上げて、データの方を変調して精度を上げるような試みも行っております。

そしてこの動画のようにピクセルクロックで流れてくるリアルなカメラの速度で全部のピクセルで認識をやるというようなデモを作ったわけです。

そうはいっても最後はハイブリッド?

当方では今のところ LUT-Network の原理実験が出来ているにすぎません。
従ってまだ部分的な事しかできていないわけですが、最終的にはFPGAの良さを生かしたうえで従来ネットとのハイブリッドも重要だろうと考えております。DSPや外部メモリは活用しつつLUTも使えると面白いと思っています。

FPGAの良さとして

  • 外部のI/Oと同期したリアルタイム演算ができる
  • INT8からバイナリまでいろんな精度の演算器がヘテロ構造をもって共存できる
  • FF/LUT-RAM/BRAM/OCM/DDR4-SDRAMなど階層メモリの用途を自由に設計できる

FPGAをターゲットとしてこれらのことを考慮して設計されているネットワークがどれだけあるでしょうか? きっと殆どないんじゃないかと思っています。 だからこそまだまだ新しい開拓余地が沢山ある分野だと思っています。

推論性能を上げようとすると、学習性能が下がる問題

FPGAなど特殊構造のAIを学習させようとする場合の課題がこれだと思っています。
推論と異なり学習は、多くのメモリや高い精度が必要となる事が多いため、やはりGPGPUを使うことになりますが、GPGPUと異なるアーキテクチャに向けた学習ほどに学習が非効率になっていきます。
また、PyTorch や Tensorflow などのメジャーな学習プラットフォームがやはりGPGPUなどを基本としているため、特殊構造のネットワークを学習させる仕組みをそもそも持っていなかったりします(なので BinaryBrain を自作する羽目になったのですが)。

特に私が課題と思っているのが、ニューロンモデルがもともと1個のシナプスに何千もの接続という非常に大きな fanin/fanout を持っていて、これがそのまま行列サイズとなっているため、とにかくGEMMが得意な計算機を持ってくることが基本となってしまっている点です。
GEMM演算は階層メモリと大量の積和演算器があれば効率よくは解けるわけですが、あくまで計算機視点での効率であって、様々なデバイスとのI/Oを持つFPGAのようにリアルな世界と親和性がいいわけではありません。

FPGAの 6入力LUTとかもそうなのですが、そもそもシリコン半導体というのを考えたときに、デジタル回路に適合しやすいfanin/fanout を持っているネットワークモデルの方がもっといろいろ考えられそうな気はするのですが、その場合、モデルが疎行列になったり、非対称な小さな行列が沢山出来てしまったりと、GPGPUが苦手な演算だらけになってしまい、一向に学習が進まないという事にもなってしまい、なかなか歯がゆい問題となる気はしています。

どうアプローチするべきか

結局のところ何がしたいかという問題設定が一番大事ではあるのですが、次に考えるべきこととして

  • いつどのユニットに何を演算させるか
  • パラメータをどこにどう置くか

という極めて基本的なことを計算機リソースと整合するようにネットワーク設計することが重要に思います。

「先にネットワークがあって、これをFPGAで高速化したい」というアプローチは、あまりFPGAを使うメリットが出てこないです。
逆にFPGAでしかできないような信号処理が先にあって、「何とかしてこれにAI的な要素を足して賢くしたい」という出発点からアーキテクチャを考えていくとうまくいくような気はします。

折角FPGAという難しいプログラミングを覚えて使うわけですから、FPGAじゃなくてもできてしまう事をやるのはもったいないと思ってしまうわけで、是非、CPUやGPUじゃできないことに挑戦していければと思う次第です。

余談

BinaryBrain で扱っている LUT-Network に関しては、6入力のいくつかに今のステージのFFを繋いでRNN的な構造にできないかというのは前々から言っていたりしますが、これもまた現実的な学習方法が思いつけずに放置しているアイデアの一つだったりします。

GPGPUなどと違い、**身近にある自分の今の状態**に簡単にアクセスできるのはFPGAのいいところだと思っています。
一方でネットワークの中に状態を持ってしまうと、時系列変化の中で起こることを学習させねばならず、学習難易度が一気に跳ね上がります。
毎回綺麗さっぱり前のことを忘れてしまうワンショットの認識ですら、小規模FPGAの学習で難儀している次第ですので、まだまだ先の話になりそうです。

コメント

タイトルとURLをコピーしました