FC2カウンター FPGAの部屋 2020年06月03日
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

finn をやってみる8(tfc_end2end_example.ipynb その3)

finn をやってみる7(tfc_end2end_example.ipynb その2)”の続き。

前回は、end2end_example の tfc_end2end_example.ipynb の 2. Network preparation の FINN-style Dataflow Architectures, Tidy-up transformations, Streamlining をやってみた。今回は、end2end_example の tfc_end2end_example.ipynb の Conversion to HLS layers, Creating a Dataflow Partition, Folding and Datawidth Converter, FIFO and TLastMarker Insertion をやってみた。

今回も end2end_example の tfc_end2end_example.ipynb の図や文章の翻訳、コードを引用して勉強していく。

Conversion to HLS layers
finn-hls library の関数に対応する HLS レイヤーに変換する。今回の変換では、バイナリXnorPopcountMatMulレイヤーのペアをStreamingFCLayer_Batchレイヤーに変換する。直後のMultiThresholdレイヤーもMVTUに吸収される。
StreamingFCLayer_Batch、finn-hlslibライブラリからの関数呼び出しに対応するノードを含む新しい構造を作成する。
注:変換でto_hls.InferBinaryStreamingFCLayerは、引数として "decoupled" という文字列を取得する。これは、重みの mem_mode を示す。FINNには、重みの保存方法とアクセス方法を設定するためのさまざまなオプションがある。 FINN readthedocs website を参照のこと。
finn-hlslib ライブラリの StreamingFCLayer_Batch 関数はここにある。
finn_49_200602.png

tfc_w1_a1_hls_layers.onnx の全体を示す。
finn_50_200602.png

各StreamingFCLayer_Batchノードには、フォールディングの度合いを指定する2つの属性、PEとSIMDがある。すべてのノードで、これらの属性の値はデフォルトで1に設定される。これは、最大のフォールディング(時間多重化)に対応し、したがってパフォーマンスが最小になる。これらをどのように調整できるかについては後ほど説明するが、最初に、このネットワークでHLSレイヤーを非HLSレイヤーから分離したい。

Creating a Dataflow Partition
上のグラフでは、FINN HLSレイヤー(StreamingFCLayer_Batch)と通常のONNXレイヤー(Reshape、Mul、Add)が混在していることがわかります。ビットストリームを作成するには、FINNはHLSレイヤーのみのモデルを必要とします。これを実現するために、 CreateDataflowPartition 変換を使用してこのグラフに "dataflow partition" を作成し、HLSレイヤーを別のモデルに分離し、それらを StreamingDataflowPartition と呼ばれる 1 つの placeholder layer に置き換える。
finn_51_200602.png

StreamingDataflowPartition のプロパティを示す。
finn_52_200602.png

tfc_w1_a1_dataflow_parent.onnx 全体を示す。
finn_53_200602.png

StreamingFCLayerインスタンスがすべて、HLSデータフローのみのグラフとして抽出された属性モデルを持つ単一のStreamingDataflowPartitionに置き換えられていることが分かる。
finn_54_200602.png

df_model.onnx 全体を示す。
finn_55_200602.png

抽出されたすべてのStreamingFCLayerインスタンスが子(データフロー)モデルに移動されていることが分かる。子モデルを ModelWrapper で読み込んで作業を続ける。

Folding and Datawidth Converter, FIFO and TLastMarker Insertion
FINNの折りたたみ(Folding in FINN)は、実行リソースの観点からレイヤーが時間多重化される量を表す。元のFINN論文で説明されているように、PE(出力での並列化)およびSIMD(入力での並列化)パラメーターによって制御される、各レイヤーにはいくつかの折りたたみ係数がある。PE値とSIMD値の設定が高いほど、生成されたアクセラレータの実行が速くなり、消費するFPGAリソースが増える。
折りたたみパラメータはノード属性であるため、ModelWrapperのヘルパー関数を使用して簡単にアクセスおよび変更できる。最初に、StreamingFCLayer_Batch操作を実装するノードの1つを詳しく見ていく。これは、Netronの視覚化が役立つ。上の図では、最初の4つのノードがStreamingFCLayer_Batchであることが分かる。例として、最初のノードを抽出する。

このノードには、より高レベルのHLSCustomOpラッパーを使用できる。これらのラッパーは、folding factors (PEおよびSIMD)など、これらのノードの特定のプロパティへの簡単なアクセスを提供します。 CustomOp ラッパーで定義されているノード属性を見て、SIMD属性とPE属性を調整してみよう。
finn_56_200602.png

PEとSIMDがノード属性としてリストされており、連続するレイヤーの間に挿入されるFIFOの深さも表示されている。また、set_nodeattrを使用して、特定の制約に従ってすべてを調整できる。
このノートブックでは、folding factors とFIFOの深さを手動で設定しているが、将来のバージョンでは、FINN-Rペーパーの分析モデルに従って、FPGAリソースバジェットを考慮して folding factors を決定できるようにする予定だそうだ。
finn_57_200602.png

PEとSIMDを設定して、各レイヤーの合計フォールディングが16になるようにする。
PEとSIMDの他に、3つのノード属性が設定されている。 ram_style は重みの格納方法を指定する(BRAM, LUTRAM など) auto にすると Vivado が決定する。 inFIFODepth and outFIFODepth はノード間に適切な FIFO の深さを指定する。
ただし、FIFOを追加する前に、データ幅コンバーター(DWC)が必要かどうかを判断し、それらを正しく挿入する必要がある。フォールディングを設定すると、あるノードのフォールド出力形状が次のノードのフォールド入力形状と一致しない場合があるためだ。
以下では、最初にDWC、次にFIFOがFINNの対応する変換を使用して挿入される。
finn_58_200602.png

最後に、InsertTLastMarker変換を実行して、このグラフの出力でTLastMarkerノードを入れる。これは、DMAエンジンを正しく実行するために必要ということだ。 netronを使用すると、ノードにFIFOが挿入され、必要に応じてDWCが挿入されたセットフォールディングがノードに含まれていることが分かる。
finn_59_200602.png

tfc_w1_a1_set_folding_factors.onnx のグラフを示す。
finn_60_200602.png

これでネットワークの準備が完了し、ネットワークを次のブロックVivado HLSおよびIPIに渡すことができる。
  1. 2020年06月03日 04:12 |
  2. finn
  3. | トラックバック:0
  4. | コメント:0