FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

NVDLAの勉強 (NVDLA Primerを読んでまとめる: ハードウェア編)

関連記事


前回せっかくNVDLAを実行できるようになったので、NVDLAについて理解を深めていこう。

今のところ資料として良さそうなのは、NVIDIAの公開している公式の資料だ。 これを読んでいけば、NVDLAの仕組みについて理解することができそうだ。

  • NVDLA Primer

NVDLA Primer — NVDLA Documentation

今回は、NVDLA Primerを読んで、分かったことを纏めていく。 まずは前半。ハードウェアの構成のところから。後半のソフトウェア編は後日。


NVDLAは推論をハードウェアで実行するためのコンポーネントであるということ。 主な特徴としては、ハードウェアモジュールを分割することで自分のアプリケーションに応じて自由に組み立てることができるということ。 現代のディープラーニングアルゴリズムに応じて自由にスケーリングさせることができるということも特徴の一つである。

NVDLAのすべての資料はGitHubに公開されている。 公開されているものは、ハードウェア・ドキュメントなども含めてすべて公開されており、これに対して改造を行ったり、フィードバックを行うことができる。 フィードバックを行う際には、ほかのユーザが自由にこの機能を使うことができる、ということに合意したとみなされる。

NVDLAを使ってディープラーニングの推論を高速化する

NVDLAは構成をシンプルにし、実装しやすさと携帯性を向上させるために、モジュール化されたアーキテクチャを採用している。 これにより、ディープラーニングのコアの部分である推論処理に使用させるブロックを組み立てることが出来るようになる。 NVDLAハードウェアは以下のコンポーネントから構成されている。

  • 畳み込みコア - 最適化された高性能畳み込みエンジン
  • シングルデータプロセッサ - 発火関数のための、単一ポイントルックアップエンジン
  • Planarデータプロセッサ - プーリングのためのPlanar平均化エンジン
  • チャネルデータプロセッサ - 高度な正規化関数のためのマルチチャネルの平均化エンジン。
  • 専用メモリとデータ変形エンジン - テンソルの変形とコピー操作のためのメモリからメモリへの転送を高速化するアクセラレーションエンジン

例えば、プーリングが必要ないシステムであれば、Planar平均化エンジン全体を除去することが出来るし、畳み込みの性能を向上させるためには、アクセラレータ内のそれ以外のユニットを変更することなく畳み込みユニットを追加することが出来る。

タスクスケジューリングのためのホストプロセッサの構成について

各ユニットのスケジューリング操作は、コプロセッサもしくはCPUに委任されている; これは各ユニットの操作を独立して非常に際粒度に操作を行う。 これには、NVDLAのサブシステムの一部として、特別な管理コプロセッサに加えて緊密に連携されたスケジューリングが必要になる ("ヘッド付き"の実装)。 もしくはマインシステムプロセッサにより、より高レベルのドライバを使って制御する("ヘッドなし"実装)。 これにより、NVDLAハードウェアアーキテクチャはさまざまなサイズの実装を構成することが出来る。

NVDLAのメモリインタフェース

NVDLAは大きく分けて2つのメモリインタフェースを持っている。

  1. メインメモリインタフェース。データの読み込みなどを行うインタフェースで、CPUやI/O周辺デバイスなども共有する。
  2. 専用メモリインタフェース。NVDLAにダイレクトに接続する専用メモリなどを接続するためのインタフェース。

NVDLAの動作フロー

NVDLAの管理プロセッサ(マイクロコントローラを用いた「ヘッド付き」の実装と、メインCPUを用いた「ヘッドなし」のどちらでも)を用いた、典型的な推論動作のフローは、まず"activate"コマンドを用いて1つのハードウェアレイヤの構成を転送する。 もしデータ依存を含んでいなければ、複数のハードウェアレイヤを複数の異なるエンジンに転送し、同時にアクティベートさせることができる(例えば、もし入力が前のレイヤの出力に依存しないレイヤが存在するような場合)。 全てのエンジンはコンフィグレーションレジスタにダブルバッファが備わっており、一つのアクティブレイヤが処理を始めると、即時にコンフィグレーションレジスタに次のコンフィグレーションをロードし、処理が完了するとすぐに次の処理を開始することが出来る。

ハードウェアエンジンが現在のタスクを完了させると、管理プロセッサに割り込みを発生させて処理の完了を通知する。

管理プロセッサは次の処理を開始させる。 「コマンド」→「実行」→「割り込み」のフローを、全体のネットワークの処理が完了するまで続ける。

ノート

NVDLAの最初のリリースでは、「ヘッドなし」のソフトウェアソリューションのみ提供されており、「ヘッド付き」モードのドライバは今後リリースされる予定である。

図1のSmall-NVDLAのシステムモデルでは、ヘッドなしのNVDLAの実装を示しており、一方で大規模システムのモデルではヘッド付きの実装を示している。 Small-NVDLAのモデルは、コストに敏感なデバイス上で実装されることが前提である。 Large-NVDLAシステムモデルは、専用の制御コプロセッサと広帯域のSRAMを備え、NVDLAのサブシステムをサポートする。 Large-NVDLAシステムモデルは複数のタスクを同時に実行できる高性能なIoTデバイスに適合される。

Small-NVDLA モデル

Small-NVDLAは主にIoTデバイスなどの、コスト、面積、電力などが重視されるデバイス向けのモデル。 ニューラルネットワークは事前にコンパイルされる。 まずは性能優先でコンパイルし、それをブレークダウンしていく方法で面積を適合させていく。

Small-NVDLAモデルは、一般的にオプションのセカンダリメモリインタフェースを利用しない。

Large NVDLAモデル

Large-NVDLAモデルは、性能重視のニューラルネットワークにおいて使用される。 多くの推論動作を必要とし、複数のネットワークを動作させる必要性から柔軟性を求められる。 また、ホストとなるプロセッサに大きな負荷をかけることができない要因から、Large-NVDLAではセカンダリのメモリインタフェースを用いて広帯域のSRAMを接続することができる。

セカンダリのSRAMはNVDLAのキャッシュとして使用される。 オプションとして、高性能コンピュータビジョンシステムにおいてSRAMをシェアすることもできる。

NVDLAのコプロセッサに必要な要件は典型的なもので、 RISC-VベースのPicoRV32プロセッサ、Cortex-M、Cortex-Rプロセッサなどが良い。 コプロセッサの役割は、NVDLAのスケジュールの管理や、同期などの処理である。

NVDLAのハードウェアの細粒度プログラミングやスケジューリングの責任をコプロセッサが負うようになっても、ホストプロセッサは粗粒度のスケジューリングと、NVDLAのメモリアクセスのためのIOMMUのマッピングなどの責任は残されている。

ハードウェアアーキテクチャ

NVDLAは2つの動作モードを持っている。

  • 独立モード: 独立モードで動作しているときは、各機能ブロックは与えられたタスクを独立に実行する。 独立モードは、割り当てられたブロックがメモリからメモリへの操作を行うことで実行される。

  • Fusedモード: Fusedモードは独立モードと似ているが、それぞれのブロックがパイプライン化される。 これによりデータのやり取りにメモリを介す必要がなく処理を高速化できる。 各ブロックのやり取りには小さなFIFOを通じて行われる。

バス接続

NVDLAは外部のシステムと接続するために、以下のインタフェースを持っている。

  • Configuration Space Bus(CSB)インタフェース: 低帯域で32bitの制御バスであり、CPUがNVDLAをコンフィグレーションするために利用する。 CSBは非常に簡単なインタフェースであるため、AMBAやOCPに簡単に変換することができる。
  • 割り込みインタフェース: NVDLAハードウェアは1ビットのレベル駆動の割り込みを持っている。
  • DataBackbone (DBB) インタフェース: DBBインタフェースはNVDLAの明認たフェースで、同期かつ広帯域のインタフェースである。 DBBインタフェースはシンプルなインタフェースで、AXIに似ている。

なお、セカンダリのメモリインタフェースもDBBインタフェースである。

コンポーネント

NVDLAはディープラーニングフレームワークのためのコンポーネントを持っており、TensorFlowの操作などもこのNVDLAのコンポーネントに当てはめることができる。

畳み込み

畳み込みブロックは、学習済みの「重み」と入力「データ」を読み込み、畳み込みを行う。 NVDLAの畳み込みコンポーネントはメモリの帯域を節約するために、空間重み情報を圧縮する機能を持っている。 バッチ処理もサポートしており、これにより重み情報を再利用して複数の推論処理を並列にどうさせることができるようになる。

畳み込みユニットをTensorFlowのオペレーションにマップさせるためには、tf.nn.conv2d`などを使用する。

単一データポイントプロセッサ

単一データポイントプロセッサ(Single Data Point Processr: SDP)は線形もしくは非線形の関数を使って、あるデータを発火させる。 CNNのシステムでよく利用されており、ルックアップテーブルを使用して非線形の関数を実現し、バイアスとスケーリングを利用して線形の関数を実現する。ReLU, PReLUなどの関数を実現することができる。

TensorFlowのオペレーションにマップさせるためには、tf.nn.batch_normalization, tf.nn.bias_add, tf.nn.elu, tf.nn.relu, tf.sigmoid, tf.tanh などを利用する。

平面データプロセッサ

平面データプロセッサ(Planar Data Processor) は、空間的な処理をサポートしている。 主にプーリング関数の実現のために利用される。 Maxプーリング、Minプーリング、平均プーリングを実行することができる。

TensorFlowのオペレーションにマップさせるためには、tf.nn.avg_pool, tf.nn.max_pool, and tf.nn.pool などを利用する。

クロスチャネルデータプロセッサ

クロスチャネルデータプロセッサ(CDP)はローカルレスポンス正規化(Local Response Normalization: LRN)関数を実現するためのモジュールである。

CDPはTensorFlowにおいてはtf.nn.local_response_normalizationにマップされる。

データ変形エンジン

データ変形エンジンは、データのsplit, slice, merge, contraction, reshape-transposeなどに使用される。 「スライス」の操作は空間の情報を異なる特徴に分解する機能であり、「Reshape-Transpose」は入力データセットよりも高い次元に出力データセットを変形する。

TensorFlowにおいて、データ変形エンジンはtf.nn.conv2d_transpose, tf.concat, tf.slice, tf.transposeマッピングされる。

ブリッジDMA

ブリッジDMA(BDMA)はデータコピーエンジンで、システムDRAMと専用広帯域メモリインタフェースの間でデータを転送する。

コンフィグレーション可能なもの

NVDLAは以下の内容について構成を変更することができる。

  • データタイプ: デフォルトでイカをサポートしているが、綿製削減のために種類を削減することができる。int4, int8, int16, int32, fp16, fp32, f64
  • 入力画像メモリフォーマット: 平面画像、準平面画像、パックドメモリフォーマットをサポートしている。
  • 重み情報の圧縮: 畳み込み演算の重みを圧縮する機能をサポートしている。この機能は面積削減のために無効にすることができる。
  • Winograd Convolution: Winogradアルゴリズムは、特定の次元の畳み込みにおいて最適化されたアルゴリズムである。NVDLAはこのアルゴリズムをサポートすることができる。
  • バッチ付き畳み込み: メモリ帯域を節約するためにバッチ処理を行うことができる。面積を節約するためにこの機能を無効にすることができる。
  • 畳み込みのバッファサイズ: 畳み込みのバッファは、いくつかのバンクで構成される。
  • MACアレイサイズ: MAC演算は2次元で構成される。幅は8~64まで、深さは4~64まで変更可能である。
  • セカンドメモリインタフェース: 高速アクセスのためのセカンドメモリインタフェースをサポートしている。
  • 非線形活性化関数: NVDLAはルックアップテーブルを用いて非線形な悪手ベーション関数をサポートしている。これは無効にすることもできる。
  • 活性化エンジンサイズ: 1サイクルに生成できる活性化出力の量を調整することができる。
  • ブリッジDMAエンジン: 無効化することができる。
  • データ変形エンジン: 無効化することができる。
  • Local Response Normalizationエンジン: 無効化することができる。
  • メモリインタフェースのビット幅: メモリインタフェースのビット幅は、外部メモリインタフェースのサイズに応じて変更することができる。
  • メモリ読み込みレイテンシ: メモリレイテンシの大きさは、内部のレイテンシバッファのサイズにより調整することができる。