gem5-NVDLA 是 gem5-RTL 的專門版本,旨在與 NVDLA verilog 模型一起使用。對於此專案基於的gem5+RTL框架,請參閱其原始repo gem5-RTL。這裡我們展示了gem5+RTL的引用,但是我們重寫了安裝過程以使其對新手更加友好。
除了針對 NVDLA 專門採用 gem5 記憶體系統之外,該專案還支援從任何 NVDLA 支援的 caffe NN 模型到 NVDLA 暫存器事務追蹤(即此處的 input.txn 之類的內容)的轉換。這個轉換實用程式的代碼和詳細用法可以在bsc-util/nvdla_utilities
中找到。
NVDLA(NVIDIA 深度學習加速器)是一個全端實用程序,展示了業界級加速器的工作原理。隨著 2018 年停止維護,公眾必須自行使其從編譯到運行時都能正常運作。以前,運行 NVDLA 的唯一方法是在 FPGA 上實例化,並使用 NVDLA 提供的編譯器和運行時在板上物理運行 NN。然而,這使得記憶體架構師無法探索人工智慧加速器系統中的記憶體子系統,因為他們需要模擬器來獲取不同記憶體配置的統計資料。因此,本回購協議的目的就是要彌補這一差距。一方面,它整合了運行 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 寄存器追蹤、模擬點建立和模擬)整合到一個 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核心和磁碟映像。一種選擇是使用 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。如果要編譯新的神經網絡,請另參閱「編譯單一神經網路」和「編譯管線多批次神經網路」部分。對於想要自訂我們工具鏈的用戶,請參考bsc-util/nvdla_utilities/BUILD.md
。
我們的框架提供了比 gem5-rtl 和原始 NVDLA verilator 驗證流程更好的模擬效能(18x-22x 模擬速度),接近其 C 模型的效能。在理想的記憶體設定下,Resnet-50可以在2小時內模擬出來。我們的優化包括:
ext/rtl/model_nvdla/verilator_nvdla/axiResponder.hh
);-O3
應用於.v
-> .cpp
編譯;-O3 -Ofast
應用於.cpp
-> .a
編譯;.cpp
-> .a
編譯(額外提高 40%);-Ofast
應用於gem5.fast
的編譯;本節提供在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
不需要修改),每個檔案對應一個 pipeline stage。這些.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/src/python/
到 PYTHONPATH。麻省理工學院