gem5-NVDLA ist eine spezielle Version von gem5-RTL, die für die Verwendung mit dem NVDLA-Verilog-Modell konzipiert ist. Informationen zum gem5+RTL-Framework, auf dem dieses Projekt basiert, finden Sie im Original-Repo gem5-RTL. Hier zeigen wir Zitate für gem5+RTL, aber wir haben den Installationsprozess umgeschrieben, um ihn für Einsteiger benutzerfreundlicher zu machen.
Neben der speziellen Anpassung des gem5-Speichersystems für NVDLA ermöglicht dieses Projekt auch die Konvertierung von jedem NVDLA-unterstützten Caffe-NN-Modell in NVDLA-Register-Transaktionsspuren (d. h. hier etwa input.txn). Der Code und die detaillierte Verwendung dieses Konvertierungsdienstprogramms finden Sie in bsc-util/nvdla_utilities
.
Der NVDLA (NVIDIA Deep Learning Accelerator) ist ein Full-Stack-Dienstprogramm, das die Funktionsweise eines Beschleunigers auf Branchenebene demonstriert. Da die Wartung im Jahr 2018 eingestellt wurde, liegt es nun an der Öffentlichkeit, dafür zu sorgen, dass es von der Kompilierung bis zur Laufzeit funktioniert. Bisher bestand die einzige Möglichkeit, NVDLA auszuführen, darin, auf einem FPGA zu instanziieren und NNs physisch an Bord auszuführen, wobei der Compiler und die Laufzeit verwendet wurden, die mit NVDLA bereitgestellt werden. Dies führt jedoch dazu, dass Speicherarchitekten das Speichersubsystem in KI-Beschleunigersystemen nicht untersuchen können, da sie einen Simulator benötigen, um Statistiken mit unterschiedlicher Speicherkonfiguration zu erhalten. Ziel dieses Repos ist es daher, diese Lücke zu schließen. Einerseits integriert es Lösungen für alle undokumentierten Fehler und Verwendungen, die zum Ausführen des NVDLA-Compilers, der Laufzeit und der virtuellen Plattform erforderlich sind. Andererseits bietet es neue Möglichkeiten, NVDLA in einem Simulator auszuführen, d. h. die Anwendung von Planungsalgorithmen, SPM-Zuweisung und Prefetching-Mechanismen, was eine weitere Erkundung von NVDLA ermöglicht.
Hier listen wir die Struktur von Codes abseits des Gem5-Gerüsts auf:
ext/rtl/model_nvdla/
enthält die Wrapper-Klasse von NVDLA und eingebettetem SPM ( wrapper_nvdla.cc
) sowie die Logik der Konvertierung zwischen gem5-Paketen und NVDLA-AXI-Anfragen ( axiResponder.cc
);src/rtl/rtlNVDLA.cc
stellt das Verhalten von NVDLA als gem5-Objekt dar, z. B. Senden und Empfangen von Speicheranforderungen;src/dev/dma_nvdla.cc
beschreibt das Verhalten der DMA-Engine;bsc-util/
versetzt alle Scheduler zum Aufrufen von NVDLA in die Simulation;bsc-util/nvdla_utilities/
stellt alle kompilierungsbezogenen Dinge für NVDLA bereit, einschließlich Single-NVDLA- und Multi-NVDLA-Kompilierungsskripts.bsc-util/nvdla_utilities/sweep/
enthält Skripte für Parameter-Sweeps und Datenerfassung.bsc-util/nvdla_utilities/example_usage/
enthält Caffe-Modelle, kompilierte Registerspuren und andere Protokolldateien für mehrere Testfälle sowie JSON-Beispieldateien für die Sweeping-Parameterkonfiguration.Es wird dringend empfohlen, die Simulation in einer Docker-Umgebung auszuführen, da dies Zeit und Aufwand bei der Installation von Abhängigkeiten spart. Aufgrund der folgenden Umgebungsanforderungen stehen wir jedoch vor Schwierigkeiten, den gesamten Ablauf (d. h. das Kompilieren von Caffe-NNs in den NVDLA-Register-Trace, die Erstellung von Simulationspunkten und die Simulation) in ein Docker-Image zu integrieren, sodass Befehle von dort ausgeführt werden müssen 2 verschiedene Docker-Umgebungen sowie eine Hostmaschine mit Sudo-Berechtigung:
edwinlai99/advp
Container erforderlich.edwinlai99/gem5_nvdla_env
Container). Glücklicherweise stellen wir Docker-Images mit allen installierten Abhängigkeiten und einstufige Skripte für jede Phase bereit (und auch Schritte zum Erstellen dieser Docker-Images in bsc-util/nvdla_utilities/BUILD.md
), sodass der manuelle Aufwand minimiert werden kann. Im gesamten Repo wird jedem Beispielbefehl (docker_image_name)#
oder $
vorangestellt, um die laufende Umgebung zu unterscheiden. Zeilen mit nur einem #
-Symbol sind Kommentare.
Gurobi muss auf dem Host-Computer verwendet werden und dann die Pfade in bsc-util/nvdla_utilities/match_reg_trace_addr/CVSRAMAlloc/Makefile
ändern. Wenn sie nicht installiert sind, können die Aktivierungs-Pinning- und Mixed-Pinning-Strategien nicht ordnungsgemäß ausgeführt werden.
Wir empfehlen dringend, gem5-nvdla/
und gem5_linux_images/
direkt im Verzeichnis ~/
abzulegen, damit die Pfade in den folgenden Befehlen und Pfadvariablen in unseren vorgefertigten Docker-Images keiner zusätzlichen Änderung bedürfen. Wenn nicht, überprüfen Sie bitte die Datei root/.bashrc
in einem gem5_nvdla_env
-Container.
$ 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
Da dieses Framework im Vollsystemmodus von gem5 läuft, muss man einen Linux-Kernel und ein Disk-Image vorbereiten. Eine Möglichkeit besteht darin, die in gem5 doc ARM fs-Binärdateien bereitgestellten Dateien zu verwenden. Organisieren Sie die heruntergeladenen Dateien in der folgenden Hierarchie:
~/
|-- gem5_linux_images/
|-- ubuntu-18.04-arm64-docker.img
|-- aarch-system-20220707/
|-- binaries/
|-- disks/
......
Wenn gem5_linux_images
nicht direkt im Verzeichnis ~/
abgelegt ist:
default_kernel
und default_disk
in configs/example/arm/fs_bigLITTLE_RTL.py
müssen sich ebenfalls entsprechend ändern.M5_PATH
in /root/.bashrc
im Docker-Image gem5_nvdla_env
. Jedes Mal, wenn ein neuer Container instanziiert wird, sollte diese Variable geändert werden oder weiterhin derselbe Container verwendet werden.nvdla_utilities/sweep/main.py
sollten geändert werden. NVDLA-Workloads werden im Vollsystemmodus von gem5 simuliert, daher sollte es eine CPU-Binärdatei geben, die die Beschleuniger aufruft. Die für die Simulation verwendete Architektur ist ARM-basiert, daher ist eine Cross-Kompilierung erforderlich. Die Binärdateien, deren Quellcodes in bsc-util/*.c
liegen, sollten mit aarch64-linux-gnu-g++-9
kreuzkompiliert werden. Darüber hinaus sollte auch eine Assembly-Datei ( util/m5/src/abi/arm64/m5op.S
), die die gem5-spezifischen Vorgänge definiert, kreuzkompiliert werden. Man kann sie also separat in *.o's kompilieren und miteinander verknüpfen. Ein Beispiel für einen Kompilierungsprozess wäre:
# 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-Container $ 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
Beachten Sie, dass die folgenden Befehle Dateien in das Disk-Image in gem5_linux_images/
schreiben.
$ 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-Container aus und sammeln Sie Ergebnisse $ 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 ~/
Einige Ergebnisse in der Nähe der folgenden Tabelle sind erwünscht:
Sweep_id | DMA-aktiviert | add-accel-private-cache | use-fake-mem | pft-aktiviert | nvdla_cycles[0] | Speicherzyklen[0] |
---|---|---|---|---|---|---|
0 | FALSCH | FALSCH | FALSCH | WAHR | 113221 | 76946 |
1 | FALSCH | FALSCH | WAHR | WAHR | 71137 | 0 |
2 | FALSCH | WAHR | FALSCH | WAHR | 89407 | 48231 |
3 | WAHR | FALSCH | FALSCH | WAHR | 73459 | 31553 |
Für andere in unseren Beispielen bereitgestellte Workloads sollten die Schritte 5–6 für diesen Workload erneut durchgeführt werden. Wenn ein neues NN kompiliert werden soll, lesen Sie bitte auch die Abschnitte „Kompilieren eines einzelnen NN“ und „Kompilieren eines Pipeline-Multibatch-NN“. Für Benutzer, die unsere Toolchain anpassen möchten, lesen Sie bitte bsc-util/nvdla_utilities/BUILD.md
.
Unser Framework bietet eine weitaus bessere Simulationsleistung (18x-22x Simulationsgeschwindigkeit) als gem5-rtl und der ursprüngliche NVDLA-Verilator-Verifizierungsablauf und nähert sich der Leistung seines C-Modells. Bei idealer Speichereinstellung kann Resnet-50 innerhalb von 2 Stunden simuliert werden. Zu unseren Optimierungen gehören:
ext/rtl/model_nvdla/verilator_nvdla/axiResponder.hh
);-O3
auf .v
-> .cpp
-Kompilierung mit Verilator an;-O3 -Ofast
auf .cpp
-> .a
-Kompilierung mit clang an;.cpp
-> .a
-Kompilierung mit Clang an (zusätzliche 40 % Verbesserung);-Ofast
auf die Kompilierung von gem5.fast
an. Dieser Abschnitt beschreibt den Prozess zum Generieren der Dateien in 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/
Dann werden die Protokolldateien und *.txn
-Register-Trace in /home/nvdla/traces/lenet/
angezeigt.
Unser Repo bietet einen Scheduler, der mehrere Stapel von NN-Inferenzaufgaben eines einzelnen Modells auf mehrere simulierte NVDLAs abbilden kann. Dieses Skript, pipeline_compile.py
, hilft somit dabei, mehrere Prototxt-Dateien gleichzeitig zu kompilieren. Dieses Skript erwartet vom Benutzer, dass er ein Caffe NN manuell in mehrere *.prototxt
Dateien aufteilt (das *.caffemodel
muss nicht geändert werden), von denen jede einer Pipeline-Stufe entspricht. Diese .prototxt
Dateien sollten dem Skript in der Reihenfolge der Pipeline-Stufen bereitgestellt werden. Von Benutzern wird erwartet, dass sie eine Unterklasse von PipelineRemapper
in match_reg_trace_addr/remap.py
verwenden, wenn sie Parameter-Sweeps für Pipeline-Arbeitslasten durchführen. Siehe unten für die Verwendung:
$ 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/
Wenn Sie CLion als Ihre IDE verwenden, können Sie:
configs/
-> Verzeichnis markieren als -> Python-Namespace-Paket.~/gem5-nvdla/configs/
hinzufügen ~/gem5-nvdla/configs/
und ~/gem5-nvdla/src/python/
zu PYTHONPATH.MIT