gem5-NVDLA est une version spécialisée de gem5-RTL conçue pour être utilisée avec le modèle Verilog NVDLA. Pour le framework gem5+RTL sur lequel ce projet est basé, consultez son dépôt original gem5-RTL. Ici, nous montrons une citation pour gem5+RTL, mais nous avons réécrit le processus d'installation pour le rendre plus convivial pour les nouveaux arrivants.
Outre l'adaptation spécialisée du système de mémoire gem5 pour NVDLA, ce projet permet également la conversion de n'importe quel modèle caffe NN pris en charge par NVDLA en traces de transaction de registre NVDLA (c'est-à-dire quelque chose comme input.txn ici). Le code et l'utilisation détaillée de cet utilitaire de conversion peuvent être trouvés dans bsc-util/nvdla_utilities
.
Le NVDLA (NVIDIA Deep Learning Accelerator) est un utilitaire complet démontrant le fonctionnement d'un accélérateur de niveau industriel. Sa maintenance ayant été arrêtée en 2018, le public se retrouve seul pour le faire fonctionner de la compilation à l'exécution. Auparavant, la seule façon d'exécuter NVDLA était d'instancier sur un FPGA et d'exécuter des NN physiquement à bord, à l'aide du compilateur et du moteur d'exécution fournis avec NVDLA. Cependant, cela empêche les architectes de mémoire d'explorer le sous-système de mémoire dans les systèmes d'accélération d'IA, car ils ont besoin d'un simulateur pour obtenir des statistiques avec une configuration de mémoire différente. L’objectif de ce repo est donc de combler cette lacune. D'une part, il intègre des solutions à tous les bogues et utilisations non documentés requis pour exécuter le compilateur NVDLA, le runtime et la plate-forme virtuelle. D'autre part, il offre de nouvelles capacités pour exécuter NVDLA dans un simulateur, c'est-à-dire pour appliquer des algorithmes de planification, des mécanismes d'allocation SPM et de prélecture, ce qui permet une exploration plus approfondie avec NVDLA.
Nous listons ici la structure des codes en dehors du squelette gem5 :
ext/rtl/model_nvdla/
inclut la classe wrapper de NVDLA et le SPM intégré ( wrapper_nvdla.cc
) et la logique de conversion entre les paquets gem5 et les requêtes NVDLA AXI ( axiResponder.cc
) ;src/rtl/rtlNVDLA.cc
met le comportement de NVDLA en tant qu'objet gem5, par exemple, l'envoi et la réception de demandes de mémoire ;src/dev/dma_nvdla.cc
décrit le comportement du moteur DMA ;bsc-util/
met tous les planificateurs pour invoquer NVDLA en simulation ;bsc-util/nvdla_utilities/
met tous les éléments liés à la compilation pour NVDLA, y compris les scripts de compilation mono-NVDLA et multi-NVDLA.bsc-util/nvdla_utilities/sweep/
inclut des scripts pour le balayage des paramètres et la collecte de données.bsc-util/nvdla_utilities/example_usage/
inclut des modèles caffe, des traces de registre compilées et d'autres fichiers journaux pour plusieurs cas de test, ainsi que des exemples de fichiers JSON de configuration de paramètres de balayage.L'exécution de la simulation dans un environnement Docker est fortement recommandée car elle permet d'économiser du temps et des efforts pour installer les dépendances. Cependant, en raison des exigences d'environnement suivantes, nous sommes confrontés à des difficultés pour intégrer l'ensemble du flux (c'est-à-dire, compilation des NN Caffe dans la trace du registre NVDLA, création de points de simulation et simulation) dans une seule image Docker, de sorte que les commandes doivent être exécutées depuis 2 environnements docker différents ainsi qu'une machine hôte avec privilège sudo :
edwinlai99/advp
;edwinlai99/gem5_nvdla_env
). Heureusement, nous fournissons des images Docker avec toutes les dépendances installées et des scripts en une étape pour chaque phase (ainsi que des étapes pour créer ces images Docker dans bsc-util/nvdla_utilities/BUILD.md
), afin que les efforts manuels puissent être minimisés. Tout au long du dépôt, chaque exemple de commande sera préfixé par (docker_image_name)#
ou $
pour distinguer l'environnement d'exécution. Les lignes avec seulement un symbole #
sont des commentaires.
Gurobi doit être utilisé sur la machine hôte, puis modifier les chemins dans bsc-util/nvdla_utilities/match_reg_trace_addr/CVSRAMAlloc/Makefile
. Si elles ne sont pas installées, les stratégies d’épinglage d’activation et d’épinglage mixte ne peuvent pas fonctionner correctement.
Nous suggérons fortement de placer gem5-nvdla/
et gem5_linux_images/
juste sous le répertoire ~/
afin que les chemins dans les commandes ci-dessous et les variables de chemin dans nos images Docker prédéfinies ne nécessitent pas de modifications supplémentaires. Sinon, veuillez vérifier le fichier root/.bashrc
dans un conteneur gem5_nvdla_env
.
$ 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
Étant donné que ce framework fonctionne en mode système complet de gem5, il faut préparer un noyau Linux et une image disque. Un choix consiste à utiliser ceux fournis dans les binaires gem5 doc ARM fs. Organisez les fichiers téléchargés dans une hiérarchie ci-dessous :
~/
|-- gem5_linux_images/
|-- ubuntu-18.04-arm64-docker.img
|-- aarch-system-20220707/
|-- binaries/
|-- disks/
......
Si gem5_linux_images
n'est pas placé juste sous le répertoire ~/
:
default_kernel
et default_disk
dans configs/example/arm/fs_bigLITTLE_RTL.py
doivent également changer en conséquence.M5_PATH
dans /root/.bashrc
dans l'image docker gem5_nvdla_env
. Chaque fois qu'un nouveau conteneur est instancié, cette variable doit être modifiée ou continuer à utiliser le même conteneur.nvdla_utilities/sweep/main.py
doivent être modifiées. Les charges de travail NVDLA sont simulées dans le mode système complet de gem5, il devrait donc y avoir un binaire CPU qui appelle les accélérateurs. L'architecture utilisée pour la simulation est basée sur ARM, une compilation croisée est donc nécessaire. Les binaires, dont les codes sources sont dans bsc-util/*.c
, doivent être compilés de manière croisée avec aarch64-linux-gnu-g++-9
. De plus, un fichier d'assemblage ( util/m5/src/abi/arm64/m5op.S
) définissant les opérations spécifiques à gem5 doit également être compilé de manière croisée. On peut donc les compiler séparément dans des fichiers *.o et les relier entre eux. Un exemple de processus de compilation serait :
# 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 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
Notez que les commandes ci-dessous écriront les fichiers dans l'image disque dans 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
et collectez les résultats $ 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 ~/
Quelques résultats proches du tableau ci-dessous sont souhaités :
balayage_id | activer DMA | ajout-d'accélération-cache-privé | utiliser-faux-mem | pft-activer | nvdla_cycles[0] | cycles_mémoire[0] |
---|---|---|---|---|---|---|
0 | FAUX | FAUX | FAUX | VRAI | 113221 | 76946 |
1 | FAUX | FAUX | VRAI | VRAI | 71137 | 0 |
2 | FAUX | VRAI | FAUX | VRAI | 89407 | 48231 |
3 | VRAI | FAUX | FAUX | VRAI | 73459 | 31553 |
Pour les autres charges de travail fournies dans nos exemples, les étapes 5 à 6 doivent être répétées pour cette charge de travail. Si un nouveau NN doit être compilé, veuillez également vous référer aux sections « Compiler un NN unique » et « Compiler un NN multibatch pipeline ». Pour les utilisateurs qui souhaitent personnaliser notre chaîne d'outils, veuillez vous référer à bsc-util/nvdla_utilities/BUILD.md
.
Notre framework offre de bien meilleures performances de simulation (vitesse de simulation 18x-22x) que gem5-rtl et le flux de vérification original du verilator NVDLA, se rapprochant des performances de son modèle C. Avec un paramètre de mémoire idéal, Resnet-50 peut être simulé en 2 heures. Nos optimisations incluent :
ext/rtl/model_nvdla/verilator_nvdla/axiResponder.hh
);-O3
à la compilation .v
-> .cpp
à l'aide du verilator ;-O3 -Ofast
à .cpp
-> .a
compilation en utilisant clang ;.cpp
-> .a
à l'aide de clang (amélioration supplémentaire de 40 %) ;-Ofast
à la compilation de gem5.fast
; Cette section fournit le processus pour générer les fichiers dans 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/
Ensuite, les fichiers journaux et la trace du registre *.txn
apparaîtront dans /home/nvdla/traces/lenet/
.
Notre référentiel fournit un planificateur qui peut mapper plusieurs lots de tâches d'inférence NN d'un seul modèle sur plusieurs NVDLA simulés. Ce script, pipeline_compile.py
, permet ainsi de compiler plusieurs fichiers prototxt en même temps. Ce script attend de l'utilisateur qu'il divise manuellement un Caffe NN en plusieurs fichiers *.prototxt
(le *.caffemodel
n'a pas besoin d'être modifié), dont chacun correspond à une étape du pipeline. Ces fichiers .prototxt
doivent être fournis au script dans l'ordre des étapes du pipeline. Les utilisateurs sont censés utiliser une sous-classe de PipelineRemapper
dans match_reg_trace_addr/remap.py
lors du balayage des paramètres pour les charges de travail en pipeline. Voir ci-dessous pour l'utilisation :
$ 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/
Si vous utilisez CLion comme IDE, vous pouvez :
configs/
-> marquer le répertoire comme -> Python Namespace Package.~/gem5-nvdla/configs/
et ~/gem5-nvdla/src/python/
vers PYTHONPATH.MIT