gem5-NVDLA は、NVDLA Verilog モデルで使用するように設計された gem5-RTL の特殊バージョンです。このプロジェクトのベースとなっている gem5+RTL フレームワークについては、元のリポジトリ gem5-RTL を参照してください。ここでは gem5+RTL の引用を示していますが、より初心者向けにインストール プロセスを書き直しました。
gem5 メモリ システムを NVDLA に特化して適応させることとは別に、このプロジェクトでは、NVDLA がサポートする任意の caffe NN モデルから NVDLA レジスタ トランザクション トレース (つまり、ここでは input.txn のようなもの) への変換も可能になります。この変換ユーティリティのコードと詳細な使用法はbsc-util/nvdla_utilities
にあります。
NVDLA (NVIDIA Deep Learning Accelerator) は、業界レベルのアクセラレータがどのように機能するかを示すフルスタック ユーティリティです。 2018 年にメンテナンスが停止されたため、コンパイルから実行時まで動作させるために一般ユーザーが自力で取り組んでいます。これまで、NVDLA を実行する唯一の方法は、NVDLA で提供されるコンパイラとランタイムを使用して、FPGA 上でインスタンスを作成し、物理的にボード上で NN を実行することでした。ただし、これにより、メモリ アーキテクトは、異なるメモリ構成の統計を取得するためにシミュレータが必要となるため、AI アクセラレータ システムのメモリ サブシステムを探索できなくなります。したがって、このリポジトリの目的は、このギャップを埋めることです。一方で、NVDLA コンパイラー、ランタイム、および仮想プラットフォームを実行するために必要な、文書化されていないすべてのバグと使用法に対するソリューションが統合されています。一方、シミュレータで NVDLA を実行するための新しい機能、つまり、スケジューリング アルゴリズム、SPM 割り当て、およびプリフェッチ メカニズムを適用するための新しい機能が提供され、NVDLA をさらに探索できるようになります。
ここでは、gem5 スケルトン以外のコードの構造をリストします。
ext/rtl/model_nvdla/
には、NVDLA と組み込み SPM のラッパー クラス ( wrapper_nvdla.cc
)、および gem5 パケットと NVDLA AXI リクエストの間の変換ロジック ( axiResponder.cc
) が含まれています。src/rtl/rtlNVDLA.cc
メモリリクエストの送受信など、NVDLA の動作を gem5 オブジェクトとして記述します。src/dev/dma_nvdla.cc
DMA エンジンの動作が記述されています。bsc-util/
シミュレーションで NVDLA を呼び出すためのすべてのスケジューラを配置します。bsc-util/nvdla_utilities/
には、単一 NVDLA および複数 NVDLA コンパイル スクリプトを含む、NVDLA のコンパイル関連のすべてのものが配置されます。bsc-util/nvdla_utilities/sweep/
には、パラメータ スイープとデータ収集用のスクリプトが含まれています。bsc-util/nvdla_utilities/example_usage/
には、caffe モデル、複数のテストケースのコンパイルされたレジスタ トレースとその他のログ ファイル、スイープ パラメーター設定のサンプル json ファイルが含まれています。依存関係をインストールする時間と労力を節約できるため、Docker 環境でシミュレーションを実行することを強くお勧めします。ただし、次の環境要件により、フロー全体 (つまり、Caffe NN の NVDLA レジスタ トレースへのコンパイル、シミュレーション ポイントの作成、およびシミュレーション) を 1 つの Docker イメージに統合することが困難になるため、コマンドを実行する必要があります。 2 つの異なる Docker 環境と sudo 権限を持つホスト マシン:
edwinlai99/advp
コンテナが必要です。edwinlai99/gem5_nvdla_env
コンテナ内) が必要です。幸いなことに、すべての依存関係がインストールされた Docker イメージと各フェーズのワンステップ スクリプト (およびbsc-util/nvdla_utilities/BUILD.md
でこれらの Docker イメージをビルドする手順) が提供されているため、手動の作業を最小限に抑えることができます。リポジトリ全体を通じて、実行環境を区別するために、各サンプル コマンドには(docker_image_name)#
または$
という接頭辞が付けられます。 #
記号のみの行はコメントです。
Gurobi をホスト マシンで使用し、 bsc-util/nvdla_utilities/match_reg_trace_addr/CVSRAMAlloc/Makefile
のパスを変更する必要があります。インストールされていない場合、アクティベーション固定および混合固定戦略は適切に実行できません。
gem5-nvdla/
とgem5_linux_images/
~/
ディレクトリの直下に配置することを強くお勧めします。これにより、以下のコマンドのパスと、事前に構築された Docker イメージのパス変数に追加の変更が必要なくなります。そうでない場合は、 gem5_nvdla_env
コンテナーのroot/.bashrc
ファイルを確認してください。
$ cd ~/
$ git clone https://github.com/suchandler96/gem5-NVDLA.git
$ mv gem5-NVDLA/ gem5-nvdla # simply a rename
$ mkdir nvdla # to put testcases in the steps afterwards
$ cd gem5-nvdla/
$ mkdir ext/rtl/model_nvdla/verilator_nvdla
$ mkdir mnt
$ git apply ban_git_hook_install_Ofast.patch # to prevent a git_hook bug in case of dubious ownership of the repo
$ docker pull edwinlai99/advp:v1
$ docker pull edwinlai99/gem5_nvdla_env:v3
このフレームワークは gem5 のフル システム モードで実行されるため、Linux カーネルとディスク イメージを準備する必要があります。 1 つの選択肢は、gem5 doc ARM fs バイナリで提供されているものを使用することです。ダウンロードしたファイルを以下の階層に整理します。
~/
|-- gem5_linux_images/
|-- ubuntu-18.04-arm64-docker.img
|-- aarch-system-20220707/
|-- binaries/
|-- disks/
......
gem5_linux_images
が~/
ディレクトリの直下に配置されていない場合:
configs/example/arm/fs_bigLITTLE_RTL.py
のグローバル変数default_kernel
とdefault_disk
それに応じて変更する必要があります。gem5_nvdla_env
Docker イメージの/root/.bashrc
にあるM5_PATH
変数を変更します。新しいコンテナがインスタンス化されるたびに、この変数を変更するか、同じコンテナを使用し続ける必要があります。nvdla_utilities/sweep/main.py
の Argparse 引数「disk_image」のデフォルト値を変更する必要があります。 NVDLA ワークロードは gem5 のフルシステム モードでシミュレートされるため、アクセラレータを呼び出す CPU バイナリが存在する必要があります。シミュレーションに使用されるアーキテクチャは ARM ベースであるため、クロスコンパイルが必要です。ソース コードがbsc-util/*.c
にあるバイナリは、 aarch64-linux-gnu-g++-9
でクロスコンパイルする必要があります。さらに、gem5 固有の操作を定義するアセンブリ ファイル ( util/m5/src/abi/arm64/m5op.S
) もクロスコンパイルする必要があります。したがって、それらを個別に *.o にコンパイルし、リンクすることもできます。コンパイル プロセスの例は次のようになります。
# The version of cross-compiling toolchain does not matter very much.
It depends on the user's OS version. Since we are tested on Ubuntu 18.04, gcc-7 is used. But gcc-9 may be more convenient on systems >= 20.04
$ sudo apt install gcc-9-aarch64-linux-gnu g++-9-aarch64-linux-gnu
$ cd gem5-nvdla/bsc-util/
$ aarch64-linux-gnu-g++-9 my_validation_nvdla_single_thread.cpp -c -o my_validation_nvdla_single_thread.o -I../include -fPIC -O3 --static -std=c++11
$ aarch64-linux-gnu-g++-9 ../util/m5/src/abi/arm64/m5op.S -c -o m5op.o -I../include -fPIC -O3 --static -std=c++11
$ aarch64-linux-gnu-g++-9 my_validation_nvdla_single_thread.o m5op.o -o my_validation_nvdla_single_thread -fPIC -O3 --static -std=c++11
$ python3 ../util/gem5img.py mount ~/gem5_linux_images/ubuntu-18.04-arm64-docker.img ../mnt
$ sudo mv my_validation_nvdla_single_thread ../mnt/home/
# ... (do the same thing to pipeline_execute scheduler)
# must move to ../mnt/home/ because bsc-util/nvdla_utilities/sweep/main.py will look for the binaries there
gem5_nvdla_env
Docker コンテナーで gem5 をビルドする $ docker run --net=host -v ~/:/home -it --rm edwinlai99/gem5_nvdla_env:v3
(gem5_nvdla_env)# cp /usr/local/nvdla/hw/outdir/nv_full/verilator/VNV_nvdla__ALL.a /home/gem5-nvdla/ext/rtl/model_nvdla/verilator_nvdla/
(gem5_nvdla_env)# cp /usr/local/nvdla/hw/outdir/nv_full/verilator/VNV_nvdla.h /home/gem5-nvdla/ext/rtl/model_nvdla/verilator_nvdla/
(gem5_nvdla_env)# cd /home/gem5-nvdla/ext/rtl/model_nvdla/verilator_nvdla/
(gem5_nvdla_env)# mv VNV_nvdla__ALL.a libVNV_nvdla__ALL.a # rename
(gem5_nvdla_env)# cd /home/gem5-nvdla/
# check Makefile to see the number of threads options before compilation
(gem5_nvdla_env)# make nvdla
(gem5_nvdla_env)# exit
以下のコマンドは、 gem5_linux_images/
のディスク イメージにファイルを書き込むことに注意してください。
$ mkdir -p ~/nvdla/traces # make a directory to store the simulation files
$ cd ~/gem5-nvdla/bsc-util/nvdla_utilities/sweep/
$ cp -r ../example_usage/traces/lenet ~/nvdla/traces/
$ cp -r ../example_usage/experiments/jsons_tiny/ ~/nvdla/traces/lenet/
$ python3 main.py --jsons-dir ~/nvdla/traces/lenet/jsons_tiny/ --out-dir ~/nvdla/traces/lenet/logs/ --vp-out-dir ~/nvdla/traces/lenet/ --sim-dir /home/lenet/ --model-name lenet --gen-points --num-threads 24 --scheduler my_validation_nvdla_single_thread --home /home
gem5_nvdla_env
Docker コンテナでシミュレーションを実行し、結果を収集する $ docker run --net=host -v ~/:/home -it --rm edwinlai99/gem5_nvdla_env:v3
(gem5_nvdla_env)# cd /home/gem5-nvdla/bsc-util/nvdla_utilities/sweep/
(gem5_nvdla_env)# python3 main.py --jsons-dir /home/nvdla/traces/lenet/jsons_tiny/ --out-dir /home/nvdla/traces/lenet/logs/ --vp-out-dir /home/nvdla/traces/lenet/ --sim-dir /home/lenet/ --model-name lenet --run-points --num-threads 24 --scheduler my_validation_nvdla_single_thread
# wait until the simulation ends... It may take roughly 30-60 seconds depending on the computer's performance
(gem5_nvdla_env)# exit
$ cd ~/gem5-nvdla/bsc-util/nvdla_utilities/sweep/
$ python3 get_sweep_stats.py -d ~/nvdla/traces/lenet/logs/ -j ~/nvdla/traces/lenet/jsons_tiny/ -p lenet_test --out-dir ~/
# Then a file named "lenet_test_summary.csv" would appear in ~/
以下の表に近い結果が必要です。
スイープID | dma を有効にする | アクセルプライベートキャッシュの追加 | 偽のメモリを使用する | pft を有効にする | nvdla_cycles[0] | メモリサイクル[0] |
---|---|---|---|---|---|---|
0 | 間違い | 間違い | 間違い | 真実 | 113221 | 76946 |
1 | 間違い | 間違い | 真実 | 真実 | 71137 | 0 |
2 | 間違い | 真実 | 間違い | 真実 | 89407 | 48231 |
3 | 真実 | 間違い | 間違い | 真実 | 73459 | 31553 |
例で提供されている他のワークロードの場合は、そのワークロードに対してステップ 5 ~ 6 を再度実行する必要があります。新しい NN をコンパイルする場合は、「単一 NN のコンパイル」および「パイプライン マルチバッチ NN のコンパイル」セクションも参照してください。ツールチェーンをカスタマイズしたいユーザーは、 bsc-util/nvdla_utilities/BUILD.md
を参照してください。
私たちのフレームワークは、gem5-rtl やオリジナルの NVDLA ベリレーター検証フローよりもはるかに優れたシミュレーション パフォーマンス (18 倍から 22 倍のシミュレーション速度) を提供し、その C モデルのパフォーマンスに近づいています。理想的なメモリ設定では、Resnet-50 は 2 時間以内にシミュレートできます。当社の最適化には次のものが含まれます。
ext/rtl/model_nvdla/verilator_nvdla/axiResponder.hh
) を使用して IO を削減します。.v
-> .cpp
コンパイルに-O3
適用します。-O3 -Ofast
.cpp
-> .a
コンパイルに適用します。.cpp
-> Clang を使用した.a
コンパイルに適用します (さらに 40% 改善)。gem5.fast
のコンパイルに-Ofast
適用します。このセクションではbsc-util/nvdla_utilities/example_usage/lenet/
にファイルを生成するプロセスについて説明します。
$ docker run -it --rm -v ~/:/home edwinlai99/advp:v1
(advp)# cd /home/gem5-nvdla/bsc-util/nvdla_utilities/
(advp)# python3.6 caffe2trace.py --model-name lenet --caffemodel example_usage/caffe_models/lenet/lenet_iter_10000.caffemodel --prototxt example_usage/caffe_models/lenet/Lenet.prototxt --out-dir /home/nvdla/traces/lenet/
その後、ログ ファイルと*.txn
レジスタ トレースが/home/nvdla/traces/lenet/
に表示されます。
私たちのリポジトリは、単一モデルの NN 推論タスクの複数のバッチを複数のシミュレートされた NVDLA にマッピングできるスケジューラーを提供します。したがって、このスクリプトpipeline_compile.py
、複数の prototxt ファイルを同時にコンパイルするのに役立ちます。このスクリプトは、ユーザーが Caffe NN を複数の*.prototxt
ファイル ( *.caffemodel
を変更する必要はありません) に手動で分割し、それぞれがパイプライン ステージに対応することを想定しています。これらの.prototxt
ファイルは、パイプライン ステージの順序でスクリプトに提供する必要があります。ユーザーは、パイプライン化されたワークロードのパラメーター スイープを実行するときに、 match_reg_trace_addr/remap.py
のPipelineRemapper
のサブクラスを使用することが期待されます。使用方法については以下を参照してください。
$ docker run -it --rm -v ~/:/home edwinlai99/advp:v1
(advp)# cd /home/gem5-nvdla/bsc-util/nvdla_utilities/
(advp)# python3.6 pipeline_compile.py --model-name lenet --caffemodel example_usage/caffe_models/lenet/lenet_iter_10000.caffemodel --prototxts /home/gem5-nvdla/bsc-util/nvdla_utilities/example_usage/traces/lenet_pipeline/stage_1/lenet_stage1.prototxt /home/gem5-nvdla/bsc-util/nvdla_utilities/example_usage/traces/lenet_pipeline/stage_2/lenet_stage2.prototxt --out-dir /home/nvdla/traces/lenet_pipeline/
CLion を IDE として使用している場合は、次のことができます。
configs/
を右クリック -> ディレクトリをマーク -> Python 名前空間パッケージ。~/gem5-nvdla/configs/
を追加~/gem5-nvdla/configs/
と~/gem5-nvdla/src/python/
PYTHONPATH に追加します。マサチューセッツ工科大学