gem5-NVDLA é uma versão especializada do gem5-RTL projetada para ser usada com o modelo verilog NVDLA. Para a estrutura gem5 + RTL na qual este projeto se baseia, consulte seu repositório original gem5-RTL. Aqui estamos mostrando a citação para gem5 + RTL, mas reescrevemos o processo de instalação para torná-lo mais amigável para iniciantes.
Além da adaptação especializada do sistema de memória gem5 para NVDLA, este projeto também permite a conversão de qualquer modelo caffe NN suportado por NVDLA para rastreamentos de transação de registro NVDLA (ou seja, algo como input.txn aqui). O código e o uso detalhado deste utilitário de conversão podem ser encontrados em bsc-util/nvdla_utilities
.
O NVDLA (NVIDIA Deep Learning Accelerator) é um utilitário full-stack que demonstra como funciona um acelerador de nível industrial. Com sua manutenção interrompida em 2018, o público fica por conta própria para fazê-lo funcionar desde a compilação até a execução. Anteriormente, a única maneira de executar o NVDLA era instanciar em um FPGA e executar NNs fisicamente a bordo, usando o compilador e o tempo de execução fornecidos com o NVDLA. Isto, no entanto, deixa os arquitetos de memória incapazes de explorar o subsistema de memória em sistemas aceleradores de IA, uma vez que necessitam de um simulador para obter estatísticas com diferentes configurações de memória. O objetivo deste repo é, portanto, preencher essa lacuna. Por um lado, ele integra soluções para todos os bugs e usos não documentados necessários para executar o compilador, tempo de execução e plataforma virtual NVDLA. Por outro lado, fornece novas capacidades para executar NVDLA em um simulador, ou seja, para aplicar algoritmos de escalonamento, alocação de SPM e mecanismos de pré-busca, o que permite maior exploração com NVDLA.
Aqui listamos a estrutura dos códigos além do esqueleto gem5:
ext/rtl/model_nvdla/
inclui a classe wrapper de NVDLA e SPM incorporado ( wrapper_nvdla.cc
) e a lógica de conversão entre pacotes gem5 e solicitações NVDLA AXI ( axiResponder.cc
);src/rtl/rtlNVDLA.cc
coloca o comportamento do NVDLA como um objeto gem5, por exemplo, enviando e recebendo solicitações de memória;src/dev/dma_nvdla.cc
descreve o comportamento do mecanismo DMA;bsc-util/
coloca todos os escalonadores para invocar NVDLA em simulação;bsc-util/nvdla_utilities/
coloca todos os itens relacionados à compilação para NVDLA, incluindo scripts de compilação de NVDLA único e multi-NVDLA.bsc-util/nvdla_utilities/sweep/
inclui scripts para varreduras de parâmetros e coleta de dados.bsc-util/nvdla_utilities/example_usage/
inclui modelos caffe, rastreamentos de registro compilados e outros arquivos de log para vários casos de teste e exemplos de arquivos JSON de configuração de parâmetros abrangentes.A execução da simulação em um ambiente docker é altamente recomendada, pois economiza tempo e esforço para instalar dependências. No entanto, devido aos seguintes requisitos de ambiente, enfrentamos dificuldades para integrar todo o fluxo (ou seja, compilar NNs Caffe em rastreamento de registro NVDLA, criação de ponto de simulação e simulação) em uma imagem docker, de modo que os comandos tenham que ser executados a partir de 2 ambientes docker diferentes, bem como uma máquina host com privilégio sudo:
edwinlai99/advp
;edwinlai99/gem5_nvdla_env
). Felizmente, fornecemos imagens do Docker com todas as dependências instaladas e scripts de uma etapa para cada fase (e também etapas para construir essas imagens do Docker em bsc-util/nvdla_utilities/BUILD.md
), para que os esforços manuais possam ser minimizados. Ao longo de todo o repositório, cada comando de exemplo será prefixado com (docker_image_name)#
ou $
para distinguir o ambiente em execução. Linhas com apenas o símbolo #
são comentários.
Gurobi precisa ser usado na máquina host e, em seguida, modificar os caminhos em bsc-util/nvdla_utilities/match_reg_trace_addr/CVSRAMAlloc/Makefile
. Se não forem instaladas, as estratégias de fixação de ativação e fixação mista não poderão ser executadas corretamente.
Sugerimos fortemente colocar gem5-nvdla/
e gem5_linux_images/
logo abaixo do diretório ~/
para que os caminhos nos comandos abaixo e as variáveis de caminho em nossas imagens docker pré-construídas não precisem de modificação extra. Caso contrário, verifique o arquivo root/.bashrc
em um contêiner 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
Como esta estrutura é executada no modo de sistema completo do gem5, é necessário preparar um kernel Linux e uma imagem de disco. Uma opção é usar aqueles fornecidos nos binários gem5 doc ARM fs. Organize os arquivos baixados em uma hierarquia abaixo:
~/
|-- gem5_linux_images/
|-- ubuntu-18.04-arm64-docker.img
|-- aarch-system-20220707/
|-- binaries/
|-- disks/
......
Se gem5_linux_images
não for colocado logo abaixo do diretório ~/
:
default_kernel
e default_disk
em configs/example/arm/fs_bigLITTLE_RTL.py
também devem ser alteradas de forma correspondente.M5_PATH
em /root/.bashrc
na imagem docker gem5_nvdla_env
. Cada vez que um novo container é instanciado, esta variável deve ser modificada, ou continuar utilizando o mesmo container.nvdla_utilities/sweep/main.py
devem ser alterados. As cargas de trabalho NVDLA são simuladas no modo de sistema completo do gem5, portanto, deve haver um binário de CPU que invoque os aceleradores. A arquitetura usada para simulação é baseada em ARM, portanto a compilação cruzada é necessária. Os binários, cujos códigos-fonte estão em bsc-util/*.c
, devem ser compilados de forma cruzada com aarch64-linux-gnu-g++-9
. Além disso, um arquivo assembly ( util/m5/src/abi/arm64/m5op.S
) que define as operações específicas do gem5 também deve ser compilado cruzadamente. Portanto, pode-se compilá-los separadamente em *.o e vinculá-los. Um exemplo de processo de compilação seria:
# 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
Observe que os comandos abaixo gravarão arquivos na imagem de disco em 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
e colete os resultados $ 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 ~/
Alguns resultados próximos à tabela abaixo são desejados:
varredura_id | habilitar dma | add-accel-private-cache | use-mem falso | habilitar pft | nvdla_cycles[0] | ciclos_de_memória[0] |
---|---|---|---|---|---|---|
0 | FALSO | FALSO | FALSO | verdadeiro | 113221 | 76946 |
1 | FALSO | FALSO | verdadeiro | verdadeiro | 71137 | 0 |
2 | FALSO | verdadeiro | FALSO | verdadeiro | 89407 | 48231 |
3 | verdadeiro | FALSO | FALSO | verdadeiro | 73459 | 31553 |
Para outras cargas de trabalho fornecidas nos nossos exemplos, os passos 5 a 6 devem ser executados novamente para essa carga de trabalho. Se um novo NN for compilado, consulte também as seções "Compilar um único NN" e "Compilar um NN multibatch em pipeline". Para usuários que desejam personalizar nosso conjunto de ferramentas, consulte bsc-util/nvdla_utilities/BUILD.md
.
Nossa estrutura oferece desempenho de simulação muito melhor (velocidade de simulação de 18x-22x) do que gem5-rtl e o fluxo de verificação do verilador NVDLA original, aproximando-se do desempenho de seu modelo C. Sob uma configuração de memória ideal, o Resnet-50 pode ser simulado em 2 horas. Nossas otimizações incluem:
ext/rtl/model_nvdla/verilator_nvdla/axiResponder.hh
);-O3
à compilação .v
-> .cpp
usando verilator;-O3 -Ofast
a .cpp
-> .a
compilação usando clang;.cpp
-> .a
usando clang (melhoria extra de 40%);-Ofast
à compilação de gem5.fast
; Esta seção fornece o processo para gerar os arquivos em 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/
Em seguida, os arquivos de log e o rastreamento de registro *.txn
aparecerão em /home/nvdla/traces/lenet/
.
Nosso repositório fornece um agendador que pode mapear vários lotes de tarefas de inferência NN de um único modelo em vários NVDLAs simulados. Este script, pipeline_compile.py
, ajuda a compilar vários arquivos prototxt ao mesmo tempo. Este script espera que o usuário divida manualmente um Caffe NN em vários arquivos *.prototxt
(o *.caffemodel
não precisa ser modificado), cada um dos quais corresponde a um estágio de pipeline. Esses arquivos .prototxt
devem ser fornecidos ao script na ordem dos estágios do pipeline. Espera-se que os usuários usem uma subclasse de PipelineRemapper
em match_reg_trace_addr/remap.py
ao fazer varreduras de parâmetros para cargas de trabalho em pipeline. Veja abaixo o uso:
$ 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/
Se você usar o CLion como seu IDE, você poderá:
configs/
-> marque o diretório como -> Pacote de Namespace Python.~/gem5-nvdla/configs/
e ~/gem5-nvdla/src/python/
para PYTHONPATH.MIT