Upgrade CUDA and cuDNN

Remove old version

If your graph drvier supports desire CUDA version, do not need to remove the exsiting driver.
Check the following link: https://docs.nvidia.com/deploy/cuda-compatibility/index.html

To remove CUDA Toolkit:

$ sudo apt-get --purge remove "*cublas*" "*cufft*" "*curand*" \
 "*cusolver*" "*cusparse*" "*npp*" "*nvjpeg*" "cuda*" "nsight*"

To remove NVIDIA Drivers:

$ sudo apt-get --purge remove "*nvidia*"

To clean up the uninstall:

$ sudo apt-get autoremove

From offical document: https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html

Donwload and Install CUDA and cuDNN

CUDA

https://developer.nvidia.com/cuda-11.0-update1-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1804&target_type=runfilelocal

During the installation, uncheck graph driver.

# runfile(local)
wget https://developer.download.nvidia.com/compute/cuda/11.0.3/local_installers/cuda_11.0.3_450.51.06_linux.run  
sudo sh cuda_11.0.3_450.51.06_linux.run

Environment Variable Setting

vim ~/.bashrc

export PATH=/usr/local/cuda-11.1/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-11.1/lib64:$LD_LIBRARY_PATH

Version Check

nvcc --version

Install cuDNN

The following instruction is based on zip file of linux version.

$ sudo cp cuda/include/cudnn*.h /usr/local/cuda/include
$ sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
$ sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*

Conda cudatoolkit의 차이점
conda install cudatoolkit으로 설치된 library는 apt install로 설치된 것과는 다르지만 PyTorch등의 DL Framework에서 필요로 하는 부분들은 모두 담고 있다.
nvcc compiler는 따로 설치 되지 않으므로 필요할 경우 cudatoolkit을 모두 설치해야 할 수 있음.

Check version

# Before cuDNN 8.x
cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2

# After cuDNN 8.x
cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

dpkg 설치시

dpkg -l | grep cuDNN

ii  libcudnn8                                  8.1.0.77-1+cuda11.2                   amd64        cuDNN runtime libraries
ii  libcudnn8-dev                              8.1.0.77-1+cuda11.2                   amd64        cuDNN development libraries and headers
ii  libcudnn8-samples                          8.1.0.77-1+cuda11.2                   amd64        cuDNN documents and samples

dpkg -l | grep CUDA

Change cuDNN version

$ sudo update-alternatives --config libcudnn

There is 1 choice for the alternative libcudnn (providing /usr/include/cudnn.h).

  Selection    Path                                      Priority   Status
------------------------------------------------------------
  0            /usr/include/x86_64-linux-gnu/cudnn_v8.h   80        auto mode
* 1            /usr/include/x86_64-linux-gnu/cudnn_v8.h   80        manual mode

TVM Pycharm 설정법


정상적으로 빌드해서 라이브러리 파일들을 생성한다.

아래와 같이 bashrc에 있는 환경변수들을 pycharm에서도 동일하게 수행해 주어야 한다.

PYTHONPATH 설정

Preference -> Project Interpreter

Python Console 설정

Console에서 Always show debug console 체크

Edit Config

Run -> Edit Configuration

NVCC 관련 에러가 발생하면 아래와 같이 PATH에 /usr/local/cuda/bin을 추가한다.
which nvcc를 통해서 설치된 경로를 찾을 수 있다. deafult는 위와 같은 경로이다.
system PATH가 바로 수정은 안되므로 맨 위에 Use environment variables에 PATH와 전체 경로를 복사한 후에 맨 뒤에 nvcc path를 추가하는 방식으로 설정한다.

스크린샷 2021-03-09 오후 5.34.53

정상적으로 설정하면 아래와 같이 .idea 파일에서 xml을 통해서 경로가 변경됨을 확인할 수 있다.

스크린샷 2021-03-09 오후 5.53.23

'AI > TVM' 카테고리의 다른 글

VTA on FPGA Board  (4) 2019.04.02
PYNQ: Python productivity on ZYNQ  (0) 2019.04.02
TVM 설치 방법  (0) 2019.04.02

TensorRT 개론 및 Docker기반 실행


스크린샷 2019-01-04 오후 1.31.23

Xaiver에서의 TensorRT-5

  • Volta GPU INT8 Tensor Cores (HMMA/IMMA)
  • Early-Access DLA FP 16 support
  • Updated smaples to enabled DLA
  • Fine-grained control of DLA layers and GPU Fallback
  • New APIs added to IBuilder interface:

스크린샷 2019-01-04 오후 1.43.53

Chapter 1: What is tensorRT

  • 목적은 이미 학습된 딥러닝 모델을 빠르고 효율적으로 GPU에 구동 시키는것을 목적으로한다.
  • TensorFlow는 TensorRT와 통합되어 있으므로 프레임웍 내에서 이러한 작업이 가능하다.
  • layers, kernel selection, normalization등에 맞는 precision (F32, F16, INT8)을 적절히 정해서
    • latency, throughput, efficiency를 최적화 한다.

1.4 What Capabilities Does TensorRT Provide?
C++로는 모든 플랫폼을 지원하고 Python으로 x86만을 지원한다.

  • 따라서 ARM에서 하려면 C++로 해야할듯

TensorRT의 핵심 인터페이스는 아래와 같음.

  • Network definition: 네트워크 정의와 input과 output을 정의함.
  • Builder: 최적화된 네트웤 정의를 생성하기 위한 optimized engine을 생성함.
  • Engine: inference의 실행을 application에서 가능 하도록 한다. 동기와 비동기 모두를 지원한다.
  • Caffe Parser: 카페를 위한 것
  • UFF Parser: UFF format model을 읽기 위함
  • ONNX Parser: ONNX 모델을 위한 것이다.

TensorRT 설치 (NVIDIA-Docker 활용)

Docker 기본 설치 방법

공식: https://docs.docker.com/engine/install/ubuntu/

# remove existing version
$ sudo apt-get remove docker docker-engine docker.io containerd runc
]()
# Install
$ sudo apt-get update

$ sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
pub   rsa4096 2017-02-22 [SCEA]
      9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
uid           [ unknown] Docker Release (CE deb) <docker@docker.com>
sub   rsa4096 2017-02-22 [S]
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ sudo apt-get install docker-ce=<VERSION_STRING> docker-ce-cli=<VERSION_STRING> containerd.io

NVIDIA docker 실행전에 설치 해야할 것들

최신 docker부터 nvidia-docker가 기본으로 내장 되었기에 아래의 절차만 추가로 수행해 주면 된다.
참고: https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker

distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

# Install the nvidia-docker2 package (and dependencies) after updating the package listing
sudo apt-get update
sudo apt-get install -y nvidia-docker2

# docker 재시작
sudo systemctl restart docker

# CUDA container 테스팅
sudo docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi
# Driver 결과 출력

TensorRT docker를 NGC에서 다운로드 이후에 실행

NVIDIA에서 TensorRT등의 기본 도구에 대한 Docker들을 NGC를 통해서 배포하고 있다.
또한, DockerHub를 통해서 CUDA, cuDNN 버전별로 제공 한다.

# pull tensorrt-20.12 from NGC
sudo docker pull nvcr.io/nvidia/tensorrt:20.12-py3

# image 이름 확인
sudo docker images

# 실행, -v 볼륨 마운트, --rm 종류후 이미지 삭제
sudo docker run --gpus all -it --rm -v local_dir:container_dir nvcr.io/nvidia/tensorrt:20.12-py3

#Docker 내부에서 예제 실행
cd /workspace/tensorrt/samples
make -j4
cd /workspace/tensorrt/bin
./sample_mnist

참고문헌

공식문서
https://docs.nvidia.com/deeplearning/sdk/tensorrt-install-guide/index.html

https://docs.nvidia.com/deeplearning/dgx/integrate-tf-trt/index.html

https://docs.nvidia.com/deeplearning/dgx/integrate-tf-trt-release-notes/tf-rel-1812.html#tf-rel-1812

샘플 실행, DLA 방법까지 설명됨
https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#mnist_sample

공식 TensorRT Archives
https://docs.nvidia.com/deeplearning/sdk/tensorrt-archived/index.html

미디엄 포스팅
https://medium.com/tensorflow/speed-up-tensorflow-inference-on-gpus-with-tensorrt-13b49f3db3fa
https://medium.com/kubeflow/gpu-accelerated-inference-for-kubernetes-with-the-nvidia-tensorrt-inference-server-and-kubeflow-63061305fff2


 

20.04 우분투 기반 NVIDIA GeForce RTX 3090에 CUDA, cuDNN Pytorch 설치


컴퓨터 스팩은 아래와 같으며, 오랜만에 직접 조립 했다.
몇일 써보니 호환이나 큰 문제 없이 돌아가므로 사양정보를 공유 한다.

컴퓨터 스팩

  • 그래픽카드: 갤럭시 GALAX 지포스 RTX 3090 SG D6X 24GB

 

Widnows10, ubuntu 20.04 멀티 부팅

UEFI BIOS 모드를 기준으로 설명. Legacy 방식은 다루지 않음.

Bootable USB 제작

MAC(OSX), uBuntu에서 dd 커맨드로 제작이 가능하다. 설치 과정중 기가바이트 Z490칩셋기준으로 예기치 않은 오류가 계속 발생하여, 가장 안정적인Rufus를 이용햇 제작함.

Widnows10 제작

스크린샷 2020-12-14 오후 4.42.43

참조: https://privatenote.tistory.com/67

ubuntu 20.04 제작

스크린샷 2020-12-14 오후 4.45.40

멀티 부팅 설정

Windows10 설치 후 ubuntu 20.04를 설치하는 것이 정신건강에 좋다. 두 경우 모두 아래의 이전 포스트에서 방법을 다루고 있음.

파티션 설정 및 오토 마운팅

이전 포스트 참조

ubuntu에서 3090 그래픽카드 드라이버 설치

아래와 같이 기본 우분투 소프트웨어 업데이트 도구를 이용해서 그래픽 드라이버 업데이트가 가능하다.
다만 Nouveau드라이버는 문제가 많이므로 독접에서 제공하는 NVIDIA 드라이버로 설치한다.

nvidia 드라이버 설치

설치가 완료되면 nvidia-settings 또는 아래와 같이 nvidia-smi 커맨드로 드라이버 버전과 설치된 상태를 알 수 있다.

스크린샷 2020-12-15 오전 7.22.23

CUDA 설치

3090은 CUDA 11.0 이상의 버전을 설치 해야한다. 20년 12월 기준 CUDA Toolkit 11.1 Update 1 Downloads이 최신 버전이라 해당 버전을 설치한다.

우분투 이므로 아래와 같이 설정해서 다운로드 받는다.

스크린샷 2020-12-15 오전 7.46.16

미리 그냥 wget으로 다 받아두고 설치하는게 오류도 없고 좋다.

wget https://developer.download.nvidia.com/compute/cuda/11.1.1/local_installers/cuda_11.1.1_455.32.00_linux.run sudo sh cuda_11.1.1_455.32.00_linux.run 

기존에 NVIDIA Driver가 있으므로 경고가 나온다. 일단 무시하고 진행

스크린샷 2020-12-15 오전 7.49.31


동의: accept 입력

스크린샷 2020-12-15 오전 7.49.46
  • CUDA 11 이상을 설치하려면 드라이버가 455버전 이상으로 맞춰야 한다.
  • 이전 소프트웨어 업데이트로 455.38버전을 설치 했으므로 쿠다에 동봉된 455.32버전 설치는 하지 않도록 체크를 해제한다.
  • 향후에 CCUDA를 업데이트할 때 항상 그래피카드 드라이버와의 호환 버전음 참조해서 선택을 하면된다.
  • 덮어씌우기 할경우 문제가 발생하므로 지금은 체크 해제한다.
스크린샷 2020-12-15 오전 7.49.56

환경변수 설정

CUDA 사용을 위해서 PATH등록을 한다.
runfile을 사용 할 떄 필요한 LD_LIBRARY_PATH도 같이 설정 한다.

vim ~/.bashrc export PATH=/usr/local/cuda-11.1/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-11.1/lib64:$LD_LIBRARY_PATH 

CUDA 설치 확인 및 예제 실행

환경 변수 설정이 끝나면 nvcc --version을 통해서 확인 가능함.

jemin@jemin-3090:~/NVIDIA_CUDA-11.1_Samples$ nvcc --version nvcc: NVIDIA (R) Cuda compiler driver Copyright (c) 2005-2020 NVIDIA Corporation Built on Mon_Oct_12_20:09:46_PDT_2020 Cuda compilation tools, release 11.1, V11.1.105 Build cuda_11.1.TC455_06.29190527_0 

CUDA 설치시 sample 코드도 같이 설치 했기에 $HOME/NVIDIA_CUDA-11.1_Samples디렉토리에 샘플코드가 있다.

컴파일하여 실행하면 CUDA가 정상적으로 설치된 것이다.

# 예제 코드들 /NVIDIA_CUDA-11.1_Samples$ ls 0_Simple     2_Graphics  4_Finance      6_Advanced       EULA.txt  bin 1_Utilities  3_Imaging   5_Simulations  7_CUDALibraries  Makefile  common 

이중 간단한 Simple 예제중 행렬 곱샘을 실행시켜 본다.

## 컴파일 jemin@jemin-3090:~/NVIDIA_CUDA-11.1_Samples/0_Simple/matrixMul$ make /usr/local/cuda/bin/nvcc -ccbin g++ -I../../common/inc  -m64    -gencode .. .. cp matrixMul ../../bin/x86_64/linux/release  ## 실행 jemin@jemin-3090:~/NVIDIA_CUDA-11.1_Samples/0_Simple/matrixMul$ ./matrixMul  [Matrix Multiply Using CUDA] - Starting... GPU Device 0: "Ampere" with compute capability 8.6  MatrixA(320,320), MatrixB(640,320) Computing result using CUDA Kernel... done Performance= 2235.81 GFlop/s, Time= 0.059 msec, Size= 131072000 Ops, WorkgroupSize= 1024 threads/block Checking computed result for correctness: Result = PASS  NOTE: The CUDA Samples are not meant for performancemeasurements. Results may vary when GPU Boost is enabled. 

예제들 의미 참조 (NVIDIA 공식): https://docs.nvidia.com/cuda/cuda-samples/index.html#matrix-multiplication--cuda-runtime-api-version-

cuDNN 설치

CUDA를 11.1로 설치 했으므로 이에 맞춰서 cuDNN은 8.0.5를 다운 받으며, 아래 두 가지 방법들 중 원하는 것으로 설치 한다.

스크린샷 2020-12-16 오전 12.29.18
  • cuDNN Library for Linux(x86_64)를 선택하면 tar 압축파일을 받아서 직접 복사하여 설치 하는 방식이다.

직접 복사 방법

$ sudo cp cuda/include/cudnn*.h /usr/local/cuda/include $ sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64  $ sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn* 
  • [Deb]파일 세개를 각각 받아서 debin package 설치법으로도 설치 할 수 있다.

Deb 페키지 설치 방법: 세 개 모두 설치 한다.

sudo dpkg -i libcudnn8_8.0.5.39-1+cuda11.1_amd64.deb sudo dpkg -i libcudnn8-dev_8.0.5.39-1+cuda11.1_amd64.deb sudo dpkg -i libcudnn8-samples_8.0.5.39-1+cuda11.1_amd64.deb 

설치를 확인 하기 위해서 예제코드를 실행한다.
Deb 페키지를 이용해서 설치할 경우에만 sample코드가 정상적으로 설치된다.
/usr/src/cudnn_samples_v8내부에 여러 예제들 중에서 mnistCUDNN를 실행 한다.

cd /usr/src/cudnn_samples_v8/mnistCUDNN make clean && make ./mnistCUDNN 

아래와 같이 나오면 설치가 성공한 것이다.

Resulting weights from Softmax: 0.0000000 0.0000008 0.0000000 0.0000002 0.0000000 1.0000000 0.0000154 0.0000000 0.0000012 0.0000006  Result of classification: 1 3 5  Test passed! 

cuDNN 설치법 공식문서: https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#installlinux-tar

Pytorch 설치 및 확인

설치

Stable(1.7.1) Pytorch 버전을 설치 했다.

pip install torch==1.7.1+cu110 torchvision==0.8.2+cu110 torchaudio===0.7.2 -f https://download.pytorch.org/whl/torch_stable.html 

CUDA 버전에 맞춰서 설치 하면된다. cuda를 11.1로 설치 했지만 코드들은 정상 동작한다.
공식 문서: https://pytorch.org/get-started/locally/

실행

간단하게 아래와 같이 torch가 import되고 사용가능한 cuda가 print되면 정상 설치 된 것이다.

import torch x = torch.rand(5, 3) print(x)  import torch torch.cuda.is_available() 

Pytorch.org/tutorials에 가면 많은 예제들이 있고 그 중 cifar10 예제는 아래와 같다.
https://github.com/pytorch/tutorials/blob/master/beginner_source/blitz/cifar10_tutorial.py

아래와 같이 cuda:0까지 나오면 모두 설치가 정상이다.

python3 cifar10_tutorial.py Files already downloaded and verified Files already downloaded and verified   car horse   dog  deer [1,  2000] loss: 2.182 [1,  4000] loss: 1.810 [1,  6000] loss: 1.682 [1,  8000] loss: 1.605 [1, 10000] loss: 1.514 [1, 12000] loss: 1.516 [2,  2000] loss: 1.408 [2,  4000] loss: 1.405 [2,  6000] loss: 1.381 [2,  8000] loss: 1.346 [2, 10000] loss: 1.333 [2, 12000] loss: 1.304 Finished Training GroundTruth:    cat  ship  ship plane Predicted:    cat   car   car  ship Accuracy of the network on the 10000 test images: 53 % Accuracy of plane : 55 % Accuracy of   car : 77 % Accuracy of  bird : 35 % Accuracy of   cat : 39 % Accuracy of  deer : 44 % Accuracy of   dog : 49 % Accuracy of  frog : 63 % Accuracy of horse : 56 % Accuracy of  ship : 76 % Accuracy of truck : 40 % cuda:0 

CVPR2020 양자화 논문 실행: https://github.com/amirgholami/ZeroQ
2080ti랑 비교하여 학습과 검증시 체감 효과는 크지는 않았다. 다른 벤치마크가 필요할 것 같다.

jemin@jemin-3090:~/development/ZeroQ/classification$ python3 uniform_test.py --dataset imagenet --model resnet50 --batch_size 64 --test_batch_size 128 ****** Full precision model loaded ****** ****** Data loaded ****** ****** Zero Shot Quantization Finished ****** Testing |################################| (391/391) | ETA: 0:00:01 | top1: 0.75844 Final acc: 75.84% (37922/50000) 

문제 해결

Nouveau 드라이버 문제

기존 설치 제거 방법

드라이버 삭제

  1. apt --installed list | grep nvidia-driver
  2. -> sudo apt remove --autoremove nvidia-*
    -> sudo apt remove --autoremove nvidia-cuda-toolkit

 

AI 컴파일러 NXP elQ (Glow 컴파일러 파생)


NXP semiconductor에서 Glow compiler를 수정해서 자체적인 MCU 하드웨어 보드를 지원하는 컴파일러 도구인 elQ를 선보임.

  • 관련기사: 1
  • 공식홈페이지: 1, 2

arm-m 프로세서 계열과 DSP로 만들어진 임베디드 보드를 위한 컴파일러를 제공함.
기존 Glow를 이용해서 수정하여 elQ 컴파일러를 생성.
윈도우용 실행 파일을 제공함으로써 지원함.

elQ 온라인 세미나 자료

스크린샷 2020-09-03 오전 9.50.12
NXP는 여러 AI 컴파일러들 중에서 Glow가 가장 완성도가 높아서 이것을 선택함.

스크린샷 2020-09-03 오전 9.17.38

스크린샷 2020-09-03 오전 9.19.31

스크린샷 2020-09-03 오전 9.20.21

스크린샷 2020-09-03 오전 9.23.46

스크린샷 2020-09-03 오전 11.09.53

스크린샷 2020-09-03 오전 9.28.28

스크린샷 2020-09-03 오전 9.27.56

스크린샷 2020-09-03 오전 9.27.03
Graph IR단계에서 HiFi4노드로 대체함 이것을 이용해서 DSP 가속 기능을 달성함.

스크린샷 2020-09-03 오전 9.26.06

스크린샷 2020-09-03 오전 9.25.11

스크린샷 2020-09-03 오전 9.24.38

스크린샷 2020-09-03 오전 9.24.20

관련 논문

아래 관련 논문에서 성능 부분을 실험함.

스크린샷 2020-09-13 오후 1.11.12

스크린샷 2020-09-13 오후 1.12.04

관련논문: Image Classification on NXP i.MX RT1060 using Ultra-thin MobileNet DNN


'AI > Embedded Deep learning' 카테고리의 다른 글

MLPerf  (0) 2020.07.01
ONNX  (4) 2020.05.04
Glow 설치법  (1) 2019.11.19
Coral Dev Board (Google Edge TPU) 설정 및 사용후기  (2) 2019.08.13
Glow: graph lowering compiler for hardware accelerators  (0) 2019.02.07

factor level 수정 melt (reshape시 발생하는 문제 해결)



data frame에서 각각의 column의 factor level을 확장하는 방법


DF[2:3] <- lapply(DF[2:3], factor, levels=letters)
melt(DF, id.vars="id", factorsAsStrings=F)$value
[1] a b c z y x
Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z

If however we reset the factors to have the same levels and only then melt:

DF[2:3] <- lapply(DF[2:3], factor, levels=letters)
melt(DF, id.vars="id", factorsAsStrings=F)$value


Assert 

# Assert 개발 -- 위코드에 추가함 

assert("A Poisson random number is non-negative", {

  x = rpois(1, 10)

  (x >= 11)

  (x > -1)  # () is optional because it's the last expression

})



'AI > R Basic' 카테고리의 다른 글

R Studio Server Install in Ubuntu Server  (3) 2018.07.04
Jupyter Notebook으로 R 실행  (2) 2018.04.15
Data Transformation: dplyr package  (0) 2018.04.14
두 개 데이터 프레임 병합, 빼기  (0) 2018.03.04
R Factor 검색  (0) 2017.11.13

MLPerf

--

영상: https://youtu.be/JU0gCTFe3Bg 

목적

Scenario

Metrics

Divisions

카테고리

튜토리얼 실행 ResNet-v1.5-50 -Fake Imagenet

실행결과

/run_local.sh onnxruntime resnet50 cpu --accuracy
INFO:main:Namespace(accuracy=True, backend='onnxruntime', cache=0, config='../mlperf.conf', count=None, data_format=None, dataset='imagenet', dataset_list=None, dataset_path='fake_imagenet', find_peak_performance=False, inputs=None, max_batchsize=32, max_latency=None, model='model/resnet50_v1.onnx', model_name='resnet50', output='/Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/output/onnxruntime-cpu/resnet50', outputs=['ArgMax:0'], profile='resnet50-onnxruntime', qps=None, samples_per_query=None, scenario='SingleStream', threads=12, time=None)
INFO:imagenet:loaded 8 images, cache=0, took=0.0sec
INFO:main:starting TestScenario.SingleStream
TestScenario.SingleStream qps=25.31, mean=0.0356, time=0.316, acc=75.000%, queries=8, tiles=50.0:0.0355,80.0:0.0360,90.0:0.0365,95.0:0.0370


Imagenet2012 validation set

Imagenet은 torrent로 다운받는다. 공식 사이트는 인증 관련해서 변경사항이 있어서 쉽게 다운로드가 되지 않는다.

imagenet2012.tar는 디텍토리가 없으므로 잘 지정해서 압축을 해제한다. 5만장의 이미지들로 구성되어 있음.

tar xvf ILSVRC2012_img_val.tar -C /root/Desktop/folder

Validation set 정리

bash shell을 이용한 방법
아래의 스크립트로 이미지들을 label에 맞게 디렉토리를 생성해서 분류해줘야한다. 하지만 mlperf에서는 val_map.txt로 동작하기 때문에 기존의 validation set 정제 작업은 필요하지 않다.

wget -qO- https://raw.githubusercontent.com/soumith/imagenetloader.torch/master/valprep.sh | bash

Python 코드를 이용한 방법
원본 주소: https://github.com/tensorflow/models/blob/master/research/inception/inception/data/preprocess_imagenet_validation_data.py

"""Process the ImageNet Challenge bounding boxes for TensorFlow model training.
Associate the ImageNet 2012 Challenge validation data set with labels.
The raw ImageNet validation data set is expected to reside in JPEG files
located in the following directory structure.
 data_dir/ILSVRC2012_val_00000001.JPEG
 data_dir/ILSVRC2012_val_00000002.JPEG
 ...
 data_dir/ILSVRC2012_val_00050000.JPEG
This script moves the files into a directory structure like such:
 data_dir/n01440764/ILSVRC2012_val_00000293.JPEG
 data_dir/n01440764/ILSVRC2012_val_00000543.JPEG
 ...
where 'n01440764' is the unique synset label associated with
these images.
This directory reorganization requires a mapping from validation image
number (i.e. suffix of the original file) to the associated label. This
is provided in the ImageNet development kit via a Matlab file.
In order to make life easier and divorce ourselves from Matlab, we instead
supply a custom text file that provides this mapping for us.
Sample usage:
  ./preprocess_imagenet_validation_data.py ILSVRC2012_img_val \
  imagenet_2012_validation_synset_labels.txt
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import os
import errno
import os.path
import sys


if __name__ == '__main__':
  if len(sys.argv) < 3:
    print('Invalid usage\n'
          'usage: preprocess_imagenet_validation_data.py '
          '<validation data dir> <validation labels file>')
    sys.exit(-1)
  data_dir = sys.argv[1]
  validation_labels_file = sys.argv[2]

  # Read in the 50000 synsets associated with the validation data set.
  labels = [l.strip() for l in open(validation_labels_file).readlines()]
  unique_labels = set(labels)

  # Make all sub-directories in the validation data dir.
  for label in unique_labels:
    labeled_data_dir = os.path.join(data_dir, label)
    # Catch error if sub-directory exists
    try:
      os.makedirs(labeled_data_dir)
    except OSError as e:
      # Raise all errors but 'EEXIST'
      if e.errno != errno.EEXIST:
        raise

  # Move all of the image to the appropriate sub-directory.
  for i in range(len(labels)):
    basename = 'ILSVRC2012_val_000%.5d.JPEG' % (i + 1)
    original_filename = os.path.join(data_dir, basename)
    if not os.path.exists(original_filename):
      print('Failed to find: %s' % original_filename)
      sys.exit(-1)
    new_filename = os.path.join(data_dir, labels[i], basename)
    os.rename(original_filename, new_filename)

스크립트를 실행하면 아래와 같이 이미지들이 분류 된다.
스크린샷 2020-04-01 오후 6.21.04
스크린샷 2020-04-01 오후 6.21.16

val_map.txt 생성 방법

MLPerf실행을 위해서는 val_map.txt 생성이 필요하다. 생성 방법은 아래와 같다.
Collective Knowlege Framework을 이용해서 처리한다.

관련 issue

$ python -m pip install ck --user
$ ck pull repo:ck-env
$ ck install package --tags=image-classification,dataset,imagenet,aux
#실행 옵션
--profile
resnet50-onnxruntime
--config
/Users/jeminlee/development/mlperf_inference/v0.5//mlperf.conf
--model
/Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/model/resnet50_v1.onnx
--dataset-path
/Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/imagenet2012
--output
/Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/output/resnet-onnxruntime-cpu_real/results.json
--time
10
--max-latency
0.2
--accuracy

실행 결과

/Users/jeminlee/anaconda3/envs/pytorch/bin/python /Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/python/main.py --profile resnet50-onnxruntime --config /Users/jeminlee/development/mlperf_inference/v0.5//mlperf.conf --model /Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/model/resnet50_v1.onnx --dataset-path /Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/imagenet2012 --output /Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/output/resnet-onnxruntime-cpu_real/results.json --time 10 --max-latency 0.2 --accuracy
INFO:main:Namespace(accuracy=True, backend='onnxruntime', cache=0, config='/Users/jeminlee/development/mlperf_inference/v0.5//mlperf.conf', count=None, data_format=None, dataset='imagenet', dataset_list=None, dataset_path='/Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/imagenet2012', find_peak_performance=False, inputs=None, max_batchsize=32, max_latency=0.2, model='/Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/model/resnet50_v1.onnx', model_name='resnet50', output='/Users/jeminlee/development/mlperf_inference/v0.5/classification_and_detection/output/resnet-onnxruntime-cpu_real/results.json', outputs=['ArgMax:0'], profile='resnet50-onnxruntime', qps=None, samples_per_query=None, scenario='SingleStream', threads=12, time=10)
INFO:imagenet:loaded 50000 images, cache=0, took=889.9sec
INFO:main:starting TestScenario.SingleStream
TestScenario.SingleStream qps=1601.22, mean=0.0370, time=31.226, acc=76.456%, queries=50000, tiles=50.0:0.0355,80.0:0.0373,90.0:0.0393,95.0:0.0427,99.0:0.0746,99.9:0.1191

Process finished with exit code 0

ONNX


Microsoft에서 개발된 모든 딥러닝 프레임워크에들에서 교환 가능하도록 개발된 모델 포멧이다.

ONNX 모델 로딩 및 검증

import onnx
from onnx import numpy_helper
from onnx import helper

# Load the ONNX model
model = onnx.load("onnx/stc_yolo2.onnx")
# Print a human readable representation of the graph
print(onnx.helper.printable_graph(model.graph))

# Check the model
onnx.checker.check_model(onnx_model)
print('The model is checked!')

ONNX 모델 실행

onnxruntime 이용

onnxruntime을 이용해서 직접 inference가 가능하다.

import numpy as np
import onnxruntime as ort

img = np.load("./assets/image.npz").reshape([1, 784])  
sess_ort = ort.InferenceSession("./output/mnist1.onnx")
res = sess_ort.run(output_names=[output_tensor.name], input_feed={input_tensor.name: img})
print("the expected result is \"7\"")
print("the digit is classified as \"%s\" in ONNXRruntime"%np.argmax(res))

pytorch 공식홈페이지 기준 onnxruntime을 이용한 추론

Torch로 저장 TensorFlow로 실행

Shape inference

Shape Inference
Shape Inference API

중간 Tensor들의 shape을 알기위한 shae inference의 기능
아래 처럼 실행 하면 실제 shape모양을 알 수 있다.

from onnx import helper, shape_inference
model = onnx.load("reshape.onnx")

onnx.checker.check_model(inferred_model)
inferred_model = shape_inference.infer_shapes(model)

ONNX 모델의 중간 결과값 추출

기본 ONNX에 중간 Intermidiate Node를 삽입해서 중간결과값이 저장되도록 한다.

기존 노드를 변경함

intermediate_layer_value_info = onnx.helper.ValueInfoProto()
intermediate_layer_value_info.name = "_defaultpreprocess0_broadcast_minus0"
model.graph.output.append(intermediate_layer_value_info)
onnx.save(model, "./test.onnx")

수정된 test를 실행하면 결과값을 두 개 얻을 수 있고, 그 중 하나가 중간 결과 값이 저장된 것이다.

model = onnx.load(onnx_path)

# Load the ONNX model
ort_session = ort.InferenceSession(onnx_path)

print("onnx output\n")

input_name = ort_session.get_inputs()[0].name
label_name_1 = ort_session.get_outputs()[0].name
label_name_2 = ort_session.get_outputs()[1].name

print(label_name_1, label_name_2)

outputs = ort_session.run(None, {onnx_input_name: intput_txt.astype(np.float32)})

print(outputs[0])
print(outputs[1])

스크린샷 2020-10-27 오후 3.47.46

참고 자료


Fast Convolution


기본 convolution 연산 방법

아래와 같다고 했을때 convolution은 7중 loop로 구현 된다.
N: number of images
K: kernel size (assumed square)
W: input width
H: input height
C: number of input channels
D: number of output channels
스크린샷 2020-02-12 오후 2.40.48
위 loop중에서 1,2,3,4는 병렬로 실행 가능하고 5-7은 변수를 아래 연산에서 서로 공유하므로 병렬 실행이 불가능하다.

만약, batch를 고려하지 않아서 image를 1개로 생각한다면 아래와 같은 loop로 처리된다.
또한, stride를 고려할 경우에도 아래와 같은 loop가 된다.
스크린샷 2020-02-12 오후 2.36.36

im2col, GEMM 스타일로 변경하여 Conv연산

위와 같이 loop로 구현하면 연산속도가 매우 느리게 된다. 비록 메모리 사용량은 Feature map 측면에서 많지만 아래와 같이 matrix multiplication 방식으로 구현하면 200배 이상의 성능 향상을 가져온다.

Convolution_With_Im2col

먼저 커널의 경우 커널의 숫자 D와 커널의 사이즈 KKC로 결정된다. 즉 여기서 필터가 96개라고 한다면 [96x(11*11*3)]으로 [96x363]이 된다.

그 다음 Feature map의 경우 [커널사이즈x최종아웃풋 크기(N)]이다. 이 작업을 im2col이라 한다. 아래 그림과 같이 수행한다.

im2col_operation

최종 아웃풋 크기 N의 경우 아래와 같이 계산한다.

  • 입력 이미지를 [227x227x3]
  • stride: 4
  • filter: [11x11x3] = 363
  • output feature map: ((227-11)/4)+1 = 55
    이면, 55*55=3025이다.
    즉, Feature map은 [363x3025]가 된다.

최종 연산 결과 matrix는
[96x363] * [363x3025] = [96x3025]이다.
그리고 [96x3025]은 reshape되어 [55x55x96]으로 변환 된다. 이러한 reshape 과정을 col2im이라 한다.

여기서 loop로 구현 했을 때와 비교 했을 때 발생하는 메모리 overhead는 (227x227x3) - (363x3025) = 943,488 이다.

결국 이 방법은 데이터는 반복해서 메모리에 올라가지만 연산자의 수는 적기 때문에 throughput은 올라가는 이점이 있다.

스크린샷 2020-02-12 오후 5.41.52

Winograd Convolution

발표논문: Lavin, CVPR 2016[4]

  • 장점: 2.25x 성능향상 3x3 filter 일 때
  • 단점: 필터 사이즈에 의존된 특별한 연산. 필터사이즈가 맞지 않으면 연산상의 이득이 줄어듬

Strassen Algorithm

발표논문: Mathieu, ICLR 2014

  • 장점: $O(N^{3})$
    에서 $O(N^{2.807})$으로 복잡도가 감소
  • 단점: 산술적인 안전성이 떨어짐

Fast Fourier Transform (FFT)

발표논문: Mathieu, ICLR 2014

  • 장점: $O(N_{o}^{2}N_{f}^{2})$ to $O(N_{o}^{2}\log_{2}N_{o})$ 으로 복잡도가 감소
    • 단점: storage쪽 부담이 증가

참고문헌


'AI > Theory' 카테고리의 다른 글

Loss functions  (0) 2018.08.09
Feature (Attribute) Selection  (0) 2015.09.15
Ensemble Method  (0) 2015.09.15
Active Learning  (0) 2015.08.19
기계학습을 구현하기 위해서 어떤 언어가 좋은가?  (0) 2015.07.11

Glow 설치법 및 활용


Glow는 하드웨어 가속기를 위한 머신러닝 컴파일러이자 실행 엔진이다.

ubuntu 18.04 기준 설치

소스 다운

git clone git@github.com:pytorch/glow.git  # or: git clone https://github.com/pytorch/glow.git
cd glow

#submodules 다운
git submodule update --init --recursive

# 필요 package들 설치
sudo apt-get install clang clang-8 cmake graphviz libpng-dev \
    libprotobuf-dev llvm-8 llvm-8-dev ninja-build protobuf-compiler wget \
    opencl-headers libgoogle-glog-dev

# update-alternatives to manage the version of clang/clang++:
sudo update-alternatives --install /usr/bin/clang clang \
    /usr/lib/llvm-8/bin/clang 50
sudo update-alternatives --install /usr/bin/clang++ clang++ \
    /usr/lib/llvm-8/bin/clang++ 50

# Glow uses the system default C/C++ compiler (/usr/bin/C++), and so you may also want to switch your default C/C++ compiler to clang:
sudo update-alternatives --config cc
    # Select the option corresponding to /usr/bin/clang ...
sudo update-alternatives --config c++
    # Select the option corresponding to /usr/bin/clang++ ...

아래와 같이 clang compiler를 선택 한다.

스크린샷 2019-07-17 오후 4.20.37

ProtoBuf 설치법

최신 버전은 git clone으로 다운 받고 정해진 버전은 아래와 같이 release tag를 이용해서 다운 받는다.
https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1

Git 경우

$ sudo apt-get install autoconf automake libtool curl make g++ unzip
$ git clone https://github.com/protocolbuffers/protobuf.git
$ cd protobuf
$ git submodule update --init --recursive
$ ./autogen.sh

$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig # refresh shared library cache.
./configure --prefix=/usr

Glow 최종 컴파일 및 실행 파일

Debug mode 컴파일

mkdir build_Debug
cd build_Debug
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
ninja all

Release mode 컴파일
-DCMAKE_BUILD_TYPE=Release ..

실행

아래와 같이 최종적으로 tests에 테스팅 가능한 실행 파일들이 존재한다. 각각 실행해 보면 정상적으로 설치가 되었는지 확인 가능하다.

스크린샷 2019-07-17 오후 5.02.46

bin 디렉터리 안에는 아래와 같이 다양한 실행파일들이 존재한다. --help 옵션을 넣어서 어떠한 인자들을 넣어야 실행 가능한지 알 수 있다.

실행 가능 파일

InstrGen  fr2en             mnist         resnet-runtime   tracing-compare
NodeGen   image-classifier  model-runner  resnet-training
char-rnn  include-bin       png2bin       resnet-verify
cifar10   lenet-loader      ptb           text-translator

테스팅과 실행: Unit tests

ninja test를 통해서 모든 테스트들을 실행 할 수 있다.
Debug 또는 Release로 빌드를 수행한 디렉토리에서 수행한다.
결과는 아래와 같다.

jemin@jemin:~/development/glow/build_Debug$ ninja test
[0/1] Running tests...
Test project /home/jemin/development/glow/build_Debug
      Start  1: BackendCorrectnessTest
 1/35 Test  #1: BackendCorrectnessTest ..............   Passed   11.51 sec
      Start  2: BackendTest
 2/35 Test  #2: BackendTest .........................   Passed    1.35 sec
      Start  3: BasicIRTest
 3/35 Test  #3: BasicIRTest .........................   Passed    0.14 sec
      Start  4: Caffe2ImporterTest
 4/35 Test  #4: Caffe2ImporterTest ..................   Passed    1.93 sec
      Start  5: DeviceManagerTest
 5/35 Test  #5: DeviceManagerTest ...................   Passed    0.39 sec
      Start  6: ThreadPoolExecutorTest
 6/35 Test  #6: ThreadPoolExecutorTest ..............   Passed    1.43 sec
      Start  7: Float16Test
 7/35 Test  #7: Float16Test .........................   Passed    0.00 sec
      Start  8: GemmTest
 8/35 Test  #8: GemmTest ............................   Passed    0.09 sec
      Start  9: GlowOnnxifiManagerTest
 9/35 Test  #9: GlowOnnxifiManagerTest ..............   Passed    0.09 sec
      Start 10: GradCheckTest
10/35 Test #10: GradCheckTest .......................   Passed    3.63 sec
      Start 11: GraphGradTest
11/35 Test #11: GraphGradTest .......................   Passed    0.07 sec
      Start 12: GraphOptzTest
12/35 Test #12: GraphOptzTest .......................   Passed    0.11 sec
      Start 13: GraphSchedulerTest
13/35 Test #13: GraphSchedulerTest ..................   Passed    0.01 sec
      Start 14: GraphTest
14/35 Test #14: GraphTest ...........................   Passed    0.45 sec
      Start 15: HostManagerTest
15/35 Test #15: HostManagerTest .....................   Passed    3.94 sec
      Start 16: HyphenTest
16/35 Test #16: HyphenTest ..........................   Passed    0.83 sec
      Start 17: IROptTest
17/35 Test #17: IROptTest ...........................   Passed    0.01 sec
      Start 18: ImageTest
18/35 Test #18: ImageTest ...........................   Passed    0.24 sec
      Start 19: LLVMIRGenTest
19/35 Test #19: LLVMIRGenTest .......................   Passed    0.04 sec
      Start 20: MLTest
20/35 Test #20: MLTest ..............................   Passed   17.52 sec
      Start 21: MemoryAllocatorTest
21/35 Test #21: MemoryAllocatorTest .................   Passed    0.14 sec
      Start 22: OnnxImporterTest
22/35 Test #22: OnnxImporterTest ....................   Passed    0.30 sec
      Start 23: OnnxExporterTest
23/35 Test #23: OnnxExporterTest ....................   Passed    0.06 sec
      Start 24: OperatorGradTest
24/35 Test #24: OperatorGradTest ....................   Passed    0.04 sec
      Start 25: OperatorTest
25/35 Test #25: OperatorTest ........................   Passed    6.80 sec
      Start 26: PartitionerTest
26/35 Test #26: PartitionerTest .....................   Passed    0.11 sec
      Start 27: RecommendationSystemTest
27/35 Test #27: RecommendationSystemTest ............   Passed  226.65 sec
      Start 28: ProvisionerTest
28/35 Test #28: ProvisionerTest .....................   Passed    0.54 sec
      Start 29: QuantizationTest
29/35 Test #29: QuantizationTest ....................   Passed    3.96 sec
      Start 30: TensorsTest
30/35 Test #30: TensorsTest .........................   Passed    0.17 sec
      Start 31: TensorPoolTest
31/35 Test #31: TensorPoolTest ......................   Passed    0.01 sec
      Start 32: ThreadPoolTest
32/35 Test #32: ThreadPoolTest ......................   Passed    0.01 sec
      Start 33: TraceEventsTest
33/35 Test #33: TraceEventsTest .....................   Passed    6.74 sec
      Start 34: TypeAToTypeBFunctionConverterTest
34/35 Test #34: TypeAToTypeBFunctionConverterTest ...   Passed    0.05 sec
      Start 35: UtilsTest
35/35 Test #35: UtilsTest ...........................   Passed    0.01 sec

100% tests passed, 0 tests failed out of 35

Label Time Summary:
EXPENSIVE    = 226.65 sec*proc (1 test)

Total Test time (real) = 289.40 sec

C++ API examples

example 디렉터리에 각종 예제가 존재 한다.

MAC-OS (10.14.6 Mojave)

다운

git clone git@github.com:pytorch/glow.git  # or: git clone https://github.com/pytorch/glow.git
cd glow
git submodule update --init --recursive

필수 페키지 설치

brew install cmake graphviz libpng ninja protobuf wget glog autopep8
brew install llvm@7

링크

ln -s "/usr/local/opt/llvm@7/bin/clang-format" "/usr/local/bin/clang-format"
ln -s "/usr/local/opt/llvm@7/bin/clang-tidy" "/usr/local/bin/clang-tidy"

Mac OS 10.14 (Mojava)의 경우 ninja all시 header 파일 몇개가 없어서 빌드가 실패 한다.
아래와 같이 CLT을 실행해서 추가적으로 설치 한다.

open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

설치 명령어

mkdir build_Debug
cd ./build_Debug
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_DIR=/usr/local/opt/llvm@7/lib/cmake/llvm ..

#결과
-- Found glog with new-style glog target.
-- Found LLVM 7.1.0
-- Using LLVMConfig.cmake in: /usr/local/opt/llvm@7/lib/cmake/llvm
Adding CPU backend.
Adding Interpreter backend.
--
-- ******** Summary ********
--   CMake version         : 3.13.4
--   CMake command         : /usr/local/Cellar/cmake/3.13.4/bin/cmake
--   System                : Darwin
--   C++ compiler          : /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
--   C++ compiler version  : 10.0.1.10010046
--   CXX flags             :  -Wall -Wnon-virtual-dtor -fno-exceptions -fno-rtti -Wnon-virtual-dtor
--   Build type            : Debug
--   Compile definitions   : GIT_SHA1="cd686e48";GIT_DATE="2019-07-26";WITH_PNG;GLOW_WITH_LLVMIRCODEGEN=1;GLOW_WITH_CPU=1;GOOGLE_PROTOBUF_NO_RTTI;ONNX_NAMESPACE=glow_onnx
--   CMAKE_PREFIX_PATH     :
--   CMAKE_INSTALL_PREFIX  : /usr/local
--   CMAKE_MODULE_PATH     : /Users/jeminlee/development/glow/cmake/modules
--
--   ONNX version          : 1.5.0
--   ONNX NAMESPACE        : glow_onnx
--   ONNX_BUILD_TESTS      : OFF
--   ONNX_BUILD_BENCHMARKS : OFF
--   ONNX_USE_LITE_PROTO   : OFF
--   ONNXIFI_DUMMY_BACKEND : OFF
--   ONNXIFI_ENABLE_EXT    : OFF
--
--   Protobuf compiler     : /usr/local/bin/protoc
--   Protobuf includes     : /usr/local/include
--   Protobuf libraries    : /usr/local/lib/libprotobuf.dylib
--   BUILD_ONNX_PYTHON     : OFF
-- Failed to find LLVM FileCheck
-- git Version: v1.5.0
-- Version: 1.5.0
-- Performing Test HAVE_THREAD_SAFETY_ATTRIBUTES -- failed to compile
-- Performing Test HAVE_STD_REGEX -- success
-- Performing Test HAVE_GNU_POSIX_REGEX -- failed to compile
-- Performing Test HAVE_POSIX_REGEX -- success
-- Performing Test HAVE_STEADY_CLOCK -- success
Skipping adding test en2gr_cpu_test because it requires a models directory. Configure with -DGLOW_MODELS_DIR.
Skipping adding test en2gr_quantization_test because it requires a models directory. Configure with -DGLOW_MODELS_DIR.
Skipping adding test en2gr_cpu_partition_test because it requires a models directory. Configure with -DGLOW_MODELS_DIR.
Skipping adding test en2gr_cpu_config_test because it requires a models directory. Configure with -DGLOW_MODELS_DIR.
Skipping adding test resnet_runtime_test because it requires a models directory. Configure with -DGLOW_MODELS_DIR.
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/jeminlee/development/glow/build_Debug
$ ninja all

[1/300] Running gen_proto.py on onnx/onnx.in.proto
Processing /Users/jeminlee/development/glow/thirdparty/onnx/onnx/onnx.in.proto
Writing /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx_glow_onnx-ml.proto
Writing /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx_glow_onnx-ml.proto3
Writing /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx-ml.pb.h
generating /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx_pb.py
[5/300] Running gen_proto.py on onnx/onnx-operators.in.proto
Processing /Users/jeminlee/development/glow/thirdparty/onnx/onnx/onnx-operators.in.proto
Writing /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx-operators_glow_onnx-ml.proto
Writing /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx-operators_glow_onnx-ml.proto3
Writing /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx-operators-ml.pb.h
generating /Users/jeminlee/development/glow/build_test/lib/Importer/build_onnx/onnx/onnx_operators_pb.py
[42/300] InstrGen: Generating instructions.
Writing instr descriptors to:
    /Users/jeminlee/development/glow/build_test/glow/AutoGenInstr.h
    /Users/jeminlee/development/glow/build_test/glow/AutoGenInstr.cpp
    /Users/jeminlee/development/glow/build_test/glow/AutoGenInstr.def
    /Users/jeminlee/development/glow/build_test/glow/AutoGenIRBuilder.h
    /Users/jeminlee/development/glow/build_test/glow/AutoGenIRBuilder.cpp
    /Users/jeminlee/development/glow/build_test/glow/AutoGenIRGen.h
[45/300] NodeGen: Generating nodes.
Writing node descriptors to:
    /Users/jeminlee/development/glow/build_test/glow/AutoGenNodes.h
    /Users/jeminlee/development/glow/build_test/glow/AutoGenNodes.cpp
    /Users/jeminlee/development/glow/build_test/glow/AutoGenNodes.def
[300/300] Linking CXX executable tests/RuntimeBench

문제해결 (Troubleshooting)

git pull 후 tests/googletest/googletest/CMakeLists.txt:133 (cxx_library) 관련 에러

Glow는 Thirdparty library들이 많이 엮여 있다. 따라서 관련 라이브러리들도 모두 업데이트 해야한다.

해결 방법

git submodule sync
Synchronizing submodule url for 'tests/OutputCheck'
Synchronizing submodule url for 'tests/googlebenchmark'
Synchronizing submodule url for 'tests/googletest'
Synchronizing submodule url for 'thirdparty/foxi'
Synchronizing submodule url for 'thirdparty/fp16'
Synchronizing submodule url for 'thirdparty/onnx'
Synchronizing submodule url for 'thirdparty/pybind11'

git submodule update --init --recursive
Submodule path 'tests/googletest': checked out '703bd9caab50b139428cea1aaff9974ebee5742e'
Submodule path 'thirdparty/foxi': checked out '97fe555430a857581b9b826ecd955e4f0a3653f0'

llvm 경로 문제

보통 자동 설치하면 llvm 경로는 알아서 잡힌다.

경로가 잡히지 않으면 아래와 같이 DLLVM_DIR 옵션을 준다.

cmake -G Ninja ../glow \
    -DCMAKE_BUILD_TYPE=Debug \
    -DLLVM_DIR=/usr/local/opt/llvm@7/lib/cmake/llvm


'AI > Embedded Deep learning' 카테고리의 다른 글

MLPerf  (0) 2020.07.01
ONNX  (4) 2020.05.04
Coral Dev Board (Google Edge TPU) 설정 및 사용후기  (2) 2019.08.13
Glow: graph lowering compiler for hardware accelerators  (0) 2019.02.07
TensorFlow Lite 예제 실행  (2) 2017.12.05

Coral Dev Board (Google Edge TPU) 설정 및 사용후기


Google의 Edge TPU를 포함한 임베디드 보드인 Coral Dev Board의 설정법과 딥러닝 모델을 실행시키는 예제를 다룬다.
처음에 보드를 실행하면 u-boot만 설절된 상태이다. 따라서 제공하는 mendel linux를 퓨징해야 여타 예제들이 실행 가능하다.

준비물

  • ubuntu 18.04환경에서 실행한다. (MAC도 지원 한다.)
  • USB typeB 케이블: 보드의 시리얼 포트와 호스트 PC를 연결하기 위함
  • USB typeC 케이블: data port 연결을 위한 것으로 추후에 퓨징시에 사용한다. (fastboot)
  • 2-3A (5v) USB typeC 파워 서플라이: 폰 충전기도 사용 가능하다. 필자는 그냥 C케이블에 전원 허브 연결한곳에 꽂아서 사용했다.
  • 이더넷 케이블 또는 Wi-Fi connection: Wi-Fi 커넥션은 모듈은 내장된 것 같고 별도의 설정이 필요한 것 같다. 필자는 그냥 케이블 이용 했다.
  • 시리얼 콘솔 프로그램: screen 사용. 우분투 환경이므로 설치해서 사용 했다.

    sudo apt install screen

  • 최신 버전의 fastboot: Android SDK Platform-tools이므로 따로 다운받은 후에 PATH 설정 한다.

보드에 이미지 플래쉬

아래와 같이 eMMC mode 인지 확인한다.
이 설정 시에는 반드시 모든 연결선을 해제한 후에 핀 설정을 수행 한다.

devboard-bootmode-emmc

필자의 경우 택배 받을 떄 부터 이 상태여서 따로 핀 설정은 하지 않았다.

udev rule을 호스트 컴퓨터에 설치 한다.

sudo sh -c "echo 'SUBSYSTEM==\"usb\", ATTR{idVendor}==\"0525\", MODE=\"0664\", \
GROUP=\"plugdev\", TAG+=\"uaccess\"' >> /etc/udev/rules.d/65-edgetpu-board.rules"

sudo udevadm control --reload-rules && udevadm trigger

시리얼포트를 연결한다. 단, 이때 파워는 아직 연결하면 안된다. 파워 연결하면 오랜지 레드 LED가 꺼지므로 안 된다.
devboard-serial-co
위와 같이 시리얼만 연결한 상태에서 아래와 같이 잘 되었는지 확인 한다.

dmesg | grep ttyUSB

[96434.235923] usb 1-14: cp210x converter now attached to ttyUSB0
[96434.237250] usb 1-14: cp210x converter now attached to ttyUSB1

# 잘 되었으면 screen으로 연결 한다.
sudo screen /dev/ttyUSB0 115200

전원 케이블을 연결한다. 컴퓨터와 연결하는 방식으로 전원을 공급하면 안된다.
devboard-serial-power-co
screen terminal에서 아래와 같은 메시지를 확인 할 수 있어야 한다.

U-Boot SPL 2017.03 (Dec 06 2018 - 19:26:58)
power_bd71837_init
pmic debug: name=BD71837
Board id: 2
check ddr4_pmu_train_imem code
check ddr4_pmu_train_imem code pass
check ddr4_pmu_train_dmem code
check ddr4_pmu_train_dmem code pass
Training PASS
Training PASS
check ddr4_pmu_train_imem code
check ddr4_pmu_train_imem code pass
check ddr4_pmu_train_dmem code
check ddr4_pmu_train_dmem code pass
Training PASS
Normal Boot
Trying to boot from MMC1


U-Boot 2017.03 (Dec 06 2018 - 19:26:58 +0000)

CPU:   Freescale i.MX8MQ rev2.0 1500 MHz (running at 1000 MHz)
CPU:   Commercial temperature grade (0C to 95C) at 32C
Reset cause: POR
Model: Freescale i.MX8MQ Phanbell
DRAM:  1 GiB
Board id: 2
Baseboard id: 1
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial

 BuildInfo:
  - ATF
  - U-Boot 2017.03

flash target is MMC:0
Net:   
Error: ethernet@30be0000 address not set.
No ethernet found.
Fastboot: Normal
Hit any key to stop autoboot:  0


**********************************************************************
Welcome to your new Coral EdgeTPU Development Board!
**********************************************************************

To get started, you need to download and flash the latest firmware.
Please follow the instructions at g.co/coral/setup.


u-boot=>

u-boot에서 fastboot 0을 입력한다.
그럼 대기 모드로 진입 한다.

아래와 같이, USBtypeC케이블도 연결한다.
devboard-serial-power-data-co

준비사항으로 android sdk의 fastboot를 환경설정 잘 했다면, host 컴퓨터에서 fastboot를 사용할 수 있다.
TypeC 케이블이 정상적으로 연결 되었다면 아래와 같은 메시지를 확인 할 수 있다.

jemin@jemin:~/development/coral-dev$ fastboot devices

050a49d6ef944d3f    fastboot

mendel linux 다운로드 후 퓨징
호스트 컴퓨터에서 아래와 같이 mendel 파일을 다운받고 퓨징을 수행 한다.

#다운로드
curl -O https://dl.google.com/coral/mendel/enterprise/mendel-enterprise-chef-13.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  432M  100  432M    0     0  10.6M      0  0:00:40  0:00:40 --:--:-- 11.1M

#압축 풀기
unzip mendel-enterprise-chef-13.zip
Archive:  mendel-enterprise-chef-13.zip
 inflating: mendel-enterprise-chef-13/boot_arm64.img  
 inflating: mendel-enterprise-chef-13/flash.sh  
 inflating: mendel-enterprise-chef-13/partition-table-16gb.img  
 inflating: mendel-enterprise-chef-13/partition-table-64gb.img  
 inflating: mendel-enterprise-chef-13/partition-table-8gb.img  
 inflating: mendel-enterprise-chef-13/recovery.img  
 inflating: mendel-enterprise-chef-13/rootfs_arm64.img  
 inflating: mendel-enterprise-chef-13/u-boot.imx  
 inflating: mendel-enterprise-chef-13/README  

# 플러쉬
jemin@jemin:~/development/coral-dev/mendel-enterprise-chef-13$ ./flash.sh
Sending 'bootloader0' (1006 KB)                    OKAY [  0.056s]
Writing 'bootloader0'                              OKAY [  0.234s]
Finished. Total time: 0.311s
Rebooting into bootloader                          OKAY [  0.025s]
Finished. Total time: 0.226s
< waiting for any device >
Sending 'gpt' (33 KB)                              OKAY [  0.017s]
Writing 'gpt'                                      OKAY [  0.362s]
Finished. Total time: 0.398s
Rebooting into bootloader                          OKAY [  0.022s]
Finished. Total time: 0.273s
< waiting for any device >
Erasing 'misc'                                     OKAY [  0.071s]
Finished. Total time: 0.081s
Sending 'boot' (131072 KB)                         OKAY [  5.014s]
Writing 'boot'                                     OKAY [  4.163s]
Finished. Total time: 9.227s
Sending sparse 'rootfs' 1/3 (397265 KB)            OKAY [ 15.286s]
Writing 'rootfs'                                   OKAY [ 29.069s]
Sending sparse 'rootfs' 2/3 (408325 KB)            OKAY [ 15.656s]
Writing 'rootfs'                                   OKAY [ 56.172s]
Sending sparse 'rootfs' 3/3 (352960 KB)            OKAY [ 13.574s]
Writing 'rootfs'                                   OKAY [101.246s]
Finished. Total time: 231.033s
Rebooting                                          OKAY [  0.005s]
Finished. Total time: 0.155s

타겟에서의 serial consol화면

# 퓨징 과정
[   52.001636] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready

# 로그인
Mendel GNU/Linux (chef) orange-yarn ttymxc0
orange-yarn login: mendel
Password: mendel

mendel@orange-yarn:~$

위와 같이 screen에서 발생된 화면에서 로그인이 정상적으로 수행되면 mendel linux가 정상적으로 퓨징된 것이다.

타겟보드의 인터넷 연결 및 페키지 업데이트 (Dev-board)

Dev-board의 package들의 업데이트를 위해서 아래와 같이 유선이던지 무선이던지 network과 연결시켜 준다.

mendel@orange-yarn:~$ nmcli connection show
NAME                UUID                                  TYPE            DEVICE
Wired connection 1  729a235d-a3c0-361b-8742-67a167f8f027  802-3-ethernet  eth0   
usb0                61b97cdc-20b5-4599-8bca-de1f90c72d13  802-3-ethernet  usb0

업데이트

echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
sudo apt-get update
sudo apt-get dist-upgrade

MDT를 이용한 호스트에서 타겟으로의 연결

Mendel Development Tool (MDT)를 통해서 Dev-board와 쉽게 호스트는 연결 가능하다.
맨 처음에 u-boot 연결시에만 typeB 케이블이 필요하며 mendel linux 퓨징후에는 더이상 필요는 없다.

호스트에 MDT 설치
호스트에서 실행

pip3 install --user model-development-tool

맨 처음에 딱 한 번은 USB-typeC를 통해서 호스트와 타겟 보드를 연결해야 한다.

#!/usr/bin/env bash
jemin@jemin:~/development/coral-dev$ mdt devices
orange-yarn        (192.168.100.2)
jemin@jemin:~/development/coral-dev$ mdt shell
Waiting for a device...
Connecting to orange-yarn at 192.168.100.2
Key not present on orange-yarn -- pushing
Linux orange-yarn 4.9.51-imx #1 SMP PREEMPT Fri Apr 5 00:17:46 UTC 2019 aarch64

The programs included with the Mendel GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Mendel GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Apr 19 22:59:36 2019
mendel@orange-yarn:~$
mendel@orange-yarn:~$
mendel@orange-yarn:~$ ls
mendel@orange-yarn:~$ ls -al
total 24
drwxr-xr-x 3 mendel mendel 4096 Aug 13 09:59 .
drwxr-xr-x 3 root   root   4096 Nov  3  2016 ..
-rw-r--r-- 1 mendel mendel  220 Nov  3  2016 .bash_logout
-rw-r--r-- 1 mendel mendel 3526 Nov  3  2016 .bashrc
-rw-r--r-- 1 mendel mendel  675 Nov  3  2016 .profile
drwx------ 2 mendel mendel 4096 Aug 13 09:59 .ssh

그 다음 부터 LAN이나 Wi-Fi로도 연결 가능하다.

MDT를 사용하지 않고 일반 ssh를 이용하기 위해선 pulbickey를 board로 push 해야한다.
이를 위해서 아래와 같이 호스트에서 실행 한다.

ssh-keygen
# Follow steps to create key
mdt pushkey ~/.ssh/id_rsa.pub
ssh mendel@192.168.100.2

데모 실행 결과

영상에서 object detection 하기

mdt shell
edgetpu_demo --stream

host에서 192.168.100.2:4664로 접속하면 아래와 같이 영상에서 object detection을 수행하는 화면을 볼 수 있다.

스크린샷, 2019-08-13 19-04-31

MobileNet과 SSD가 조합된 object detection 알고리즘이다.

Image Classification

Edge TPU Python Library에서는 Image Classification도 간단하게 지원한다.

host board에서 아래와 같이 실행한다.

cd ~

wget https://dl.google.com/coral/canned_models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
https://dl.google.com/coral/canned_models/inat_bird_labels.txt \
https://coral.withgoogle.com/static/docs/images/parrot.jpg

cd /usr/lib/python3/dist-packages/edgetpu/demo/

python3 classify_image.py \
--model ~/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
--label ~/inat_bird_labels.txt \
--image ~/parrot.jpg

# 실행 결과
INFO: Initialized TensorFlow Lite runtime.
---------------------------
Ara macao (Scarlet Macaw)
Score :  0.761719

참고자료


'AI > Embedded Deep learning' 카테고리의 다른 글

ONNX  (4) 2020.05.04
Glow 설치법  (1) 2019.11.19
Glow: graph lowering compiler for hardware accelerators  (0) 2019.02.07
TensorFlow Lite 예제 실행  (2) 2017.12.05
TensorFlow Lite 개발자 프리뷰 공개  (0) 2017.12.01

TensorFlow GPU (2080ti)버전 우분투 18.04 설치 하기


본 포스트에서 사용한 그래픽카드는 기가바이트 RTX 2080ti를 사용 했다.

우분투 이미지를 생성하는 방법은 이전 블로그를 참조
우분투 18.04 USB 이미지 생성

1. 그래픽카드 드라이버 설치

2080ti 경우 ubuntu 18.04.2로 설치해도 드라이버가 설치가 되지 않는다.
직접 다운받아 설치 한다.

1_LP4iAyT_aFiW2QkE0LRcYQ

nouveau kernel문제 회피법
터미널 모드 진입

  • ctrl+alt+F1
  • lightdm 끄기
    • sudo /etc/init.d/lightdm stop
chmod +x NVIDIA-Linux-x86_64-418.56.run
sudo ./NVIDIA-Linux-x86_64-418.56.run

설치 과정중 여러가지 경고창이 나오지만 추천 선택을 기준으로 선택해서 넘어간다.

정상적으로 설치되면 nvidia-settings 커맨드를 입력하면 설정과 드라이버 관련 정보를 GUI로 볼 수 있다.

nvidia-smi를 통해서도 콘솔로 아래와 같이 내용을 확인 할 수 있다.

  • 드라이버 버전 418.56
  • CUDA 10.1 (추후 설치)
    스크린샷 2019-05-03 오전 10.59.59

2. CUDA 설치

TensorFlow의 경우 19년 4월 기준 CUDA-10.0까지만 지원하므로 legacy로 접속해서 해당 버전을 다운 받는다.

스크린샷 2019-04-05 오후 2.41.13

2.1 2080ti 드라이버와의 충돌문제 해결

쿠다를 설치할 때 기존에 그래픽카드 드라이버와 자동으로 설치된 쿠다버전과 충돌이 발생한다. 이것을 잘 해결해 주지 않으면 X-windos로 아에 접속이 안되므로 주의해야 한다.

nouveau display diver blacklist 설정

  • blacklist-nouveau.conf 파일 생성
    아래와 같이 vim이던 gedit이던 편한 것으로 사용자 계정 home directory에 생성한다.
    blacklist nouveau
    options nouveau modeset=0
    

GUI 환경에서 logout

  • logout GUI with ctrl+alt+f1
  • Back to the GUI ctrl+alt+f7

    f1~f7 각자 사용자 환경에 따라 IO가 다르므로 약간 차이가 있을 수 있다. 중간의 키값을 한 번씩 다 눌러보면 알 수 있다.

nvidia-cuda 삭제

드라이버와 함께 설치된 쿠다를 제거한다.

sudo apt-get purge nvidia-cuda*

disable X-server

  • sudo service lightdm stop (in black screen terminal)

super user modeset

  • sudo -i

2.2 CUDA 설치 시작

sudo dpkg -i cuda-repo-ubuntu1804_10.1.105-1_amd64.deb
sudo apt-key adv --fetch-keys <generated_code>
sudo apt-get update
sudo apt-get install cuda
sudo apt-get install -y cuda
..
..
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

done.
done.

콘솔로 설치 과정 중 fail이 발생하면 그래픽 드라이버를 설치하지 않는것으로 disable시킨 상태에서 다시 시도 한다.

3. cuDNN 설치

설치한 쿠다 버전과 맞는것을 설치 한다.
스크린샷 2019-04-05 오후 3.25.57

ubuntu기준으로 cuDNN library for Linux를 다운받는다.
deb의 경우 자동 설치이긴 하지만 오류를 많이 발생 시키므로 직접 파일 복사 방식으로 설치하는 방법을 따른다.

설치방법은 계속 조금씩 변경 되므로 cuDNN library for Linux클릭 했을 때 나오는 설명을 기준으로 수행한다.

4. Anaconda 설치 (optional)

jemin@jemin:~/다운로드$ sudo ./Anaconda3-2018.12-Linux-x86_64.sh

5. TensorFlow 설치

pip install tensorflow-gpu

6. 테스트

jemin@jemin:~$ python -c "import tensorflow as tf; print(tf.__version__)"
1.13.1

간단한 MNIST CNN 모델 성능 테스트

참고자료


윈도우 GPU tensorflow 설치 및 그래픽카드별 성능 비교


한국 시간으로 2016년 11월 29일 저녁
TensorFlow v0.12.0 RC0가 업데이트 되었다.

아래 실험은 TF 1.4.0에서 테스트 한것이다.
현재는 1.6까지 나온듯 하다 (2018-03.27).

핵심 변경 사항 중 Window에서 GPU 버전의 TensorFlow를 지원한다는 부분이 있다.
이제 Docker를 쓰지 않고 CPU 버전을 설치 할 수 있는것은 물론 Ubuntu에서만 가능하던 GPU 버전도 설치가 가능하다.
설치방법과 Window GPU 버전 텐서플로의 학습 속도를 분석해 본다.

설치방법

여러 방법이 있으나 필자는 Anaconda를 이용한 방법으로 설치한다. 가장 간단한다. 추가로 딱히 Window에선 Python 다른 응용을 개발하지 않으므로 특별히 conda 또는 virtualenv를 설정하지않고 global에 직접 설치한다. 기존 시스템과의 충돌을 걱정한다면 가상환경을 만들고 설치하길 권장한다.
방법: https://www.tensorflow.org/versions/r0.12/get_started/os_setup.html#pip-installation-on-windows

1. Anaconda 4.2.0 설치

NumPy, SciPy, Pandas, Matplotlib 등의 과학연산에 필요한 Python package들을 통합했으며 Jupyter Notebook을 제공하는 환경이다.

Window TensorFlow는 Python 3.5 이상부터 동작하므로 해당 Anaconda 관리자 권한으로 설치한다.

모든 작업을 anaconda만 설치하면 환경변수등 자동으로 설정 되므로 pip명령어를 이용해서 하나하나 설치하는것 보다 훨씬 효율적이다.

다운로드: https://www.continuum.io/downloads

2. CUDA 8.0.44 -win 10 설치

Tensorflow v0.12.0 RC0는 CUDA 8.0이상을 권장하므로 이것을 설치한다.
Network버전은 설치가 오래걸리므로 local버전 1.2GB 상당을 직접 다운받아서 설치한다.

다운로드 https://developer.nvidia.com/cuda-downloads

필자의 Window환경 컴퓨터의 GPU 스팩이다.

name: GeForce GTX 745
major: 5 minor: 0 memoryClockRate (GHz) 1.0325

3. CuDNN 5.1 설치

Deep Learning을 위해서 엔비디아에서 제공하는 추가 라이브러리 꾸러미이다.
다운로드: https://developer.nvidia.com/cudnn

CUDA 8.0 cuDNN 5.1을 설치해야한다.
회원 가입을 하고 다운 받는다.

다운받으면 그냥 압축 파일이므로 압축해제후 CUDA 설치 경로에 붙여넣기 해야한다.
CUDA 설치 경로 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0

4. TensorFlow-GPU 설치

윈도우 버전은 파이썬 3.5 에서 하다.
0.12 RC0 버전 부터는 텐서플로우 패키지가 PyPI 에 업로드되어 있어 pip 명령으로 간단히 설치할 수 있게 되었다.

처음 설치

pip install tensorflow-gpu

업데이트 방법 (추후에 새로운 버전이 나왔을 때)

pip install --upgrade https://storage.googleapis.com/tensorflow/windows/gpu/tensorflow_gpu-0.12.0rc1-cp35-cp35m-win_amd64.whl

최근에 RC0에서 RC1로 업데이트 되었다. 기존 RC0사용자라면 버그가 고쳐진 새로운 버전으로 업데이트 할 때 위 명령어를 이용 한다.

설치확인
Anaconda prompt를 관리자 권한으로 실행한다.
python을 실행하고 아래의 script를 실행해 본다.

>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
Hello, TensorFlow!

Jupyter Notebook에서의 실행결과
Anaconda를 설치하면 자동으로 Jupyter Notebook이 설치된다.
Jupyter Notebook을 실행해서 아래의 코드를 실행해보자.
정상적으로 수행되면 설치 성공이다.


성능 테스트

간단한 MNIST 셋의 CNN을 이용한 손글씨 인식을 학습해 본다.

CNN구조는 아래와 같다.

자세한 코드는 이전 POST를 참조한다.

소스코드 위치: https://github.com/leejaymin/TensorFlowLecture/tree/master/5.CNN
해당 repo를 clone해서 그 안에 CNNforMNIST.py를 실행 한다.
실행이 끝나면 경과된 시간이 출력 된다.

CNN으로 평가한 컴퓨터 환경들은 아래와 같다.

i7, 10 GFLOPS

105분 31초

GTX 745, 793 GFLOPS

36분 30초

K520, 2448*2 GFLOPS

22분 4초

GTX 970, 3.4 TFLOPS

9분 10초

GTX 1060 3GB, 3.9TFLOPS

8분 5초

GTX 1080, 8.87 TFLOPS

5분 27초

Tesla P100, 9.3 TFlops

4분 57초

Tesla P100, 9.3 TFlops (8개)

실험 예정

RTX 2080ti, 13.4 TFLOPS

스크린샷 2019-04-09 오후 5.50.17
`4분 6초``

결론

I7-CPU (6331초)를 기준으로 비교했을 때 각각의 성능 향상은 아래와 같다.

  • GTX 745는 2.89x
  • K520은 4.78x
  • GTX 970 11.5x
  • GTX 1060 13x
  • GTX 1080 19.3x
  • P100 21.3x
  • RTX 2080ti 25.7x

VTA on FPGA Board


사전 설치 사항

TVM llvm활성 상태에서 빌드한 후 Path설정을 모두 완료한 상태

PYNQ 보드에 기반한 TVM의 VTA 실행 환결 설정 및 결과

OSX 환경에서의 SSHFS 설치

  • Mount Remote File Systems

brew install SSHFS로 설치 후 fuse를 다운 받아서 설치 한다.

설치가 완료되면 파일 시스템을 마운트한 상태에서는 host target의 데이터가 자동으로 sync된다.

  • sshfs xilinx@192.168.0.3:/home/xilinx pynq-z1-tvm

컴파일 순서

git clone --recursive https://github.com/dmlc/tvm
ssh xilinx@192.168.0.3

xilinx@pynq:~/tvm$ mkdir build
xilinx@pynq:~/tvm$ cp cmake/config.cmake build/
xilinx@pynq:~/tvm$ cp vta/config/pynq_sample.json build/vta_config.json
xilinx@pynq:~/tvm$ cd ./build/
xilinx@pynq:~/tvm/build$ cmake ..
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test SUPPORT_CXX11
-- Performing Test SUPPORT_CXX11 - Success
-- Build with RPC support...
-- Build with Graph runtime support...
-- Use VTA config /home/xilinx/tvm/build/vta_config.json
-- Build VTA runtime with target: pynq
-- Build with contrib.hybriddump
-- Configuring done
-- Generating done
-- Build files have been written to: /home/xilinx/tvm/build

make runtime vta -j2

Scanning dependencies of target tvm_runtime
[  0%] Building CXX object CMakeFiles/tvm_runtime.dir/src/runtime/builtin_fp16.cc.o
[  0%] Building CXX object CMakeFiles/tvm_runtime.dir/src/runtime/c_dsl_api.cc.o
[ 14%] Building CXX object CMakeFiles/tvm_runtime.dir/src/runtime/c_runtime_api.cc.o
...
...
[100%] Built target tvm_runtime
Scanning dependencies of target runtime
[100%] Built target runtime
Scanning dependencies of target vta
[  0%] Building CXX object CMakeFiles/vta.dir/vta/src/device_api.cc.o
[ 50%] Building CXX object CMakeFiles/vta.dir/vta/src/runtime.cc.o
[ 50%] Building CXX object CMakeFiles/vta.dir/vta/src/pynq/pynq_driver.cc.o
[100%] Linking CXX shared library libvta.so
[100%] Built target vta

Run a RPC server

xilinx@pynq:~/tvm$ sudo ./apps/pynq_rpc/start_rpc_server.sh
[sudo] password for xilinx:
INFO:RPCServer:bind to 0.0.0.0:9091

Terminate this RPC server with Ctrl+c

host 환경변수 설정

# On the Host-side
export VTA_PYNQ_RPC_HOST=192.168.2.99
export VTA_PYNQ_RPC_PORT=9091

호스트 PC에서 target을 pynq라고 설정하는 방법은 그냥 json설정 파일을 복사하면 된다.

 # On the Host-side
 cd <tvm root>
 cp vta/config/pynq_sample.json vta_config.json

test_program_rpc.py를 실행해서 FPGA를 굽는다.

  • VTA bitstream을 프로그램화
  • VTA runtime을 빌드

vta_config.json과 매칭되어지는 pre-compiled bitstream을 VTA bitstream repository에서 다운로드 받는다.

만약 vta_config.json을 수정한다면 30초 정도 걸리는 VTA runtime generation 과정을 다시 수행하게 된다.

python <tvm root>/vta/tests/python/pynq/test_program_rpc.py

실행 결과

아래는 간단한 benchmark 예제인 test_benchmark_topi_conv2d.py의 실행 결과를 host target에서 각각 나온것을 나타낸다.

host

 (tvm-vta) ➜  tvm git:(master) python ./vta/tests/python/integration/test_benchmark_topi_conv2d.py
 key=resnet-cfg[1]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=64, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.254753 sec/op, 0.90759 GOPS
 key=resnet-cfg[2]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=64, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=1, wstride=1)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.0364432 sec/op, 0.704936 GOPS
 key=resnet-cfg[3]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=128, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.12858 sec/op, 0.899091 GOPS
 key=resnet-cfg[4]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=128, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.0159981 sec/op, 0.802913 GOPS
 key=resnet-cfg[5]
 Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=128, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.25949 sec/op, 0.891023 GOPS
 key=resnet-cfg[6]
 Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=256, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.131113 sec/op, 0.881722 GOPS
 key=resnet-cfg[7]
 Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=256, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.0139933 sec/op, 0.917941 GOPS
 key=resnet-cfg[8]
 Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=256, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.265993 sec/op, 0.869237 GOPS
 key=resnet-cfg[9]
 Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=512, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.13347 sec/op, 0.866153 GOPS
 key=resnet-cfg[10]
 Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=512, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.0184653 sec/op, 0.695634 GOPS
 key=resnet-cfg[11]
 Conv2DWorkload(batch=1, height=7, width=7, in_filter=512, out_filter=512, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
 ----- CONV2D CPU End-to-End Test-------
     Time cost = 0.435112 sec/op, 0.531383 GOPS
 key=resnet-cfg[0]
 Conv2DWorkload(batch=1, height=224, width=224, in_filter=16, out_filter=64, hkernel=7, wkernel=7, hpad=3, wpad=3, hstride=2, wstride=2)
 ----- CONV2D End-to-End Test-------
     Time cost = 0.101999 sec/op, 12.3414 GOPS
 key=resnet-cfg[1]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=64, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
 ----- CONV2D End-to-End Test-------
     Time cost = 0.0229889 sec/op, 10.0575 GOPS
 key=resnet-cfg[2]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=64, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=1, wstride=1)
 ----- CONV2D End-to-End Test-------
     Time cost = 0.0194093 sec/op, 1.3236 GOPS
 key=resnet-cfg[3]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=128, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2)
 ----- CONV2D End-to-End Test-------
     Time cost = 0.00972201 sec/op, 11.8911 GOPS
 key=resnet-cfg[4]
 Conv2DWorkload(batch=1, height=56, width=56, in_filter=64, out_filter=128, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2)
 ----- CONV2D End-to-End Test-------
     Time cost = 0.00962549 sec/op, 1.33448 GOPS
 key=resnet-cfg[5]
 Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=128, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
 ----- CONV2D End-to-End Test-------
     Time cost = 0.0136985 sec/op, 16.8786 GOPS
  key=resnet-cfg[6]
  Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=256, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2)
  ----- CONV2D End-to-End Test-------
      Time cost = 0.011236 sec/op, 10.2889 GOPS
  key=resnet-cfg[7]
  Conv2DWorkload(batch=1, height=28, width=28, in_filter=128, out_filter=256, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2)
  ----- CONV2D End-to-End Test-------
      Time cost = 0.00486118 sec/op, 2.64238 GOPS
  key=resnet-cfg[8]
  Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=256, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
  ----- CONV2D End-to-End Test-------
      Time cost = 0.0140004 sec/op, 16.5147 GOPS
  key=resnet-cfg[9]
  Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=512, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=2, wstride=2)
  ----- CONV2D End-to-End Test-------
      Time cost = 0.0111904 sec/op, 10.3308 GOPS
  key=resnet-cfg[10]
  Conv2DWorkload(batch=1, height=14, width=14, in_filter=256, out_filter=512, hkernel=1, wkernel=1, hpad=0, wpad=0, hstride=2, wstride=2)
  ----- CONV2D End-to-End Test-------
      Time cost = 0.00519472 sec/op, 2.47272 GOPS
  key=resnet-cfg[11]
  Conv2DWorkload(batch=1, height=7, width=7, in_filter=512, out_filter=512, hkernel=3, wkernel=3, hpad=1, wpad=1, hstride=1, wstride=1)
  ----- CONV2D End-to-End Test-------
      Time cost = 0.0104386 sec/op, 22.1496 GOPS
  Save memoize result to .pkl_memoize_py3/vta.tests.test_benchmark_topi.conv2d.verify_nhwc.get_ref_data.pkl

target RPC server

NFO:RPCServer:Finish serving ('192.168.0.2', 51718)
INFO:RPCServer:connection from ('192.168.0.2', 51733)
INFO:root:Program FPGA with 1x16x16_8bx8b_15_15_18_17_100MHz_8ns_v0_0_0.bit
INFO:RPCServer:Finish serving ('192.168.0.2', 51733)
INFO:RPCServer:connection from ('192.168.0.2', 51737)
INFO:root:Skip reconfig_runtime due to same config.
INFO:RPCServer:Finish serving ('192.168.0.2', 51737)
INFO:RPCServer:connection from ('192.168.0.2', 51738)
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpmsdnt4p7/conv2d.o
Initialize VTACommandHandle...
Close VTACommandhandle...
INFO:RPCServer:Finish serving ('192.168.0.2', 51738)
INFO:RPCServer:connection from ('192.168.0.2', 51740)
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
Initialize VTACommandHandle...
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
INFO:root:Loading VTA library: /home/xilinx/tvm/vta/python/vta/../../../build/libvta.so
INFO:RPCServer:load_module /tmp/tmpvu58ss03/conv2d.o
Close VTACommandhandle...
INFO:RPCServer:Finish serving ('192.168.0.2', 51740)

VTA FPGA Toolchain Installiation

만약 FPGA에 올라가는 합성 코드 자체를 수정하고 싶으면 Xilinx IDE를 설치해야 하므로 아래의 문서를 참조해서 절차를 따른다.
https://docs.tvm.ai/vta/install.html#vta-fpga-toolchain-installation

Troubleshooting

Cannot find the files: libtvm.dylib

python3 vta/tests/python/pynq/test_program_rpc.py
에러 메시지

Traceback (most recent call last):
  File "vta/tests/python/pynq/test_program_rpc.py", line 2, in <module>
    import tvm
  File "/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/__init__.py", line 5, in <module>
    from . import tensor
  File "/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/tensor.py", line 4, in <module>
    from ._ffi.node import NodeBase, NodeGeneric, register_node, convert_to_node
  File "/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/_ffi/node.py", line 8, in <module>
    from .node_generic import NodeGeneric, convert_to_node, const
  File "/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/_ffi/node_generic.py", line 7, in <module>
    from .base import string_types
  File "/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/_ffi/base.py", line 48, in <module>
    _LIB, _LIB_NAME = _load_lib()
  File "/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/_ffi/base.py", line 39, in _load_lib
    lib_path = libinfo.find_lib_path()
  File "/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/_ffi/libinfo.py", line 93, in find_lib_path
    raise RuntimeError(message)
RuntimeError: Cannot find the files.
List of candidates:
/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/libtvm.dylib
/Users/jeminlee/development/pynq-z1-tvm/tvm/build/libtvm.dylib
/Users/jeminlee/development/pynq-z1-tvm/tvm/build/Release/libtvm.dylib
/Users/jeminlee/development/pynq-z1-tvm/tvm/lib/libtvm.dylib
/Users/jeminlee/development/pynq-z1-tvm/libtvm.dylib
/Users/jeminlee/development/pynq-z1-tvm/tvm/python/tvm/libtvm_runtime.dylib
/Users/jeminlee/development/pynq-z1-tvm/tvm/build/libtvm_runtime.dylib
/Users/jeminlee/development/pynq-z1-tvm/tvm/build/Release/libtvm_runtime.dylib
/Users/jeminlee/development/pynq-z1-tvm/tvm/lib/libtvm_runtime.dylib
/Users/jeminlee/development/pynq-z1-tvm/libtvm_runtime.dylib

시도한 방법들
conda python3.7 설치 후 실행
tvm on host의 컴파일을 llvm-6으로 변경후에 다시 실행

no module named vta.testing

에러 메시지
python ./vta/tests/python/integration/

test_benchmark_topi_conv2d.py
Traceback (most recent call last):
  File "./vta/tests/python/integration/test_benchmark_topi_conv2d.py", line 10, in <module>
    import vta.testing
ModuleNotFoundError: No module named 'vta.testing'

해결 방법
그냥 쉘에서 아래를 실행하고 실행 한다.
export PYTHONPATH=/Users/jeminlee/development/pynq-z1-tvm/tvm/vta/python:${PYTHONPATH}

환경 변수 설정이 잘못 되었었음.

  • 수정전: /Users/jeminlee/development/pynq-z1-tvm/tvm/vta/tests/python
  • 수정후: /Users/jeminlee/development/pynq-z1-tvm/tvm/vta/python:

참고문헌

미니컴 설정 방법
https://www.nengo.ai/nengo-pynq/connect.html


'AI > TVM' 카테고리의 다른 글

TVM Pycharm 설정법  (0) 2021.03.09
PYNQ: Python productivity on ZYNQ  (0) 2019.04.02
TVM 설치 방법  (0) 2019.04.02

PYNQ: Python productivity on ZYNQ


기본적인 설명

The PYNQ-Z1 board is designed to be used with PYNQ, a new open-source framework that enables embedded programmers to exploit the capabilities of Xilinx Zynq All Programmable SoCs (APSoCs) without having to design programmable logic circuits.

  • YNQ XC7Z020-1CLG400C

    • 650MHz dual-core Cortex-A9 processor
    • DDR3 memory controller with 8 DMA channels and 4 High Performance AXI3 Slave ports
    • High-bandwidth peripheral controllers: 1G Ethernet, USB 2.0, SDIO
    • Low-bandwidth peripheral controller: SPI, UART, CAN, I2C
    • Programmable from JTAG, Quad-SPI flash, and microSD card
    • Programmable logic equivalent to Artix-7 FPGA
      • 13,300 logic slices, each with four 6-input LUTs and 8 flip-flops
      • 630 KB of fast block RAM
      • 4 clock management tiles, each with a phase-locked loop (PLL) and mixed-mode clock manager (MMCM)
      • 220 DSP slices
      • On-chip analog-to-digital converter (XADC)
  • 512 MB DDR3

  • Wide range of USB, Ethernet, Video and Audio connectivity
  • Arduino shield and Pmod connectors for adding-on hardware devices
  • Programmable from JTAG, Quad-SPI flash, and microSD card

  • Key FPGA Specifications
    스크린샷 2019-03-14 오전 9.54.17

스크린샷 2019-03-19 오전 9.24.28

다른 비싼것 FPGA 성능
ZYNQ-ZCU104 (약 100만원)

  • Logic slices 504,000
  • memory 38MB
  • DSP slices 1,728

ZYNQ-ZCU104 (약 1,000만원)

  • Logic slices 930,000
  • memory 60.5B
  • DSP slices 4,272

보드 이미지 다운로드
http://www.pynq.io/board

보드 비교
스크린샷 2019-03-11 오후 8.07.32

dd command를 이용한 Disk image fussing on micro sd card

공식문서
https://pynq.readthedocs.io/en/v1.3/17_appendix.html

확인 및 unmount
diskutil list
`diskutil unmountDisk /dev/disk``

플래시 방법
sudo dd bs=1m if=pynq_z1_v2.4.img of=/dev/rdisk4

중간 중간 progress확인은 ctrl+t (SIGINFO signal)을 이용해서 확인 한다.

load: 7.21  cmd: dd 6329 uninterruptible 0.00u 0.00s
30+0 records in
29+0 records out
30408704 bytes transferred in 3.649711 secs (8331812 bytes/sec)
load: 7.21  cmd: dd 6329 uninterruptible 0.00u 0.01s
36+0 records in
35+0 records out
36700160 bytes transferred in 4.396652 secs (8347297 bytes/sec)
load: 5.83  cmd: dd 6329 uninterruptible 0.00u 0.29s
1033+0 records in
1032+0 records out
1082130432 bytes transferred in 128.452542 secs (8424360 bytes/sec)
load: 6.31  cmd: dd 6329 uninterruptible 0.00u 0.53s
1885+0 records in
1884+0 records out
1975517184 bytes transferred in 235.902680 secs (8374289 bytes/sec)
5401+1 records in
5401+1 records out
5664169984 bytes transferred in 679.525499 secs (8335478 bytes/sec)

정상적으로 했다면 아래와 같이 변경된다.
diskutil list

/dev/disk4 (internal, physical):
  #:                       TYPE NAME                    SIZE       IDENTIFIER
  0:     FDisk_partition_scheme                        *7.8 GB     disk4
  1:                 DOS_FAT_32                         7.8 GB     disk4s1
/dev/disk4 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *7.8 GB     disk4
   1:             Windows_FAT_32 NO NAME                 104.9 MB   disk4s1
   2:                      Linux                         5.6 GB     disk4s2

Getting Started with PYNQ support

설치후 OS 버전 정보

xilinx@pynq:~$ lsb_release -a
No LSB modules are available.
Distributor ID:    pynqlinux
Description:    PYNQ Linux, based on Ubuntu 18.04
Release:    v2.4
Codename:    provo

접속 기본 정보

공식 사이트: https://pynq.readthedocs.io/en/latest/getting_started.html

공유기에 따라서 IP Address는 다름

초기 계정 비번 xilinx / xilinx

jupyter notebook 가능

SAMBA 공유 파일 시스템 접속 방법 (OSX)

고유 연결 방법 Finder에서 이동->연결->URL 입력

  • mac/linux: smb://pynq/xilinx

스크린샷 2019-03-13 오후 2.57.44

참고 사이트

  • pynq.io
  • pynq.readthedocs.org
  • github.com/Xilinx/pynq
  • digilentinc.com/pynq
  • pynq.io/support


'AI > TVM' 카테고리의 다른 글

TVM Pycharm 설정법  (0) 2021.03.09
VTA on FPGA Board  (4) 2019.04.02
TVM 설치 방법  (0) 2019.04.02

TVM 설치 방법


서브모듈까지 모두 다운받기 위해서 --recursive 옵션을 사용한다.

git clone --recursive https://github.com/dmlc/tvm

Build the Shared Library

여기선 shared libaries를 빌드하는 것이 목적
각각의 운영체제에 따라서 지원하는 공유라이브러리가 다르다.

Linux: libtvm.so, libtvm_topi.so
OSX: libtvm.dylib, libtvm_topi.dylib
Windows: libtvm.dll, libtvm_topi.dll

sudo apt-get update
sudo apt-get install -y python python-dev python-setuptools gcc libtinfo-dev zlib1g-dev build-essential cmake

설치전 최소 요구사항

  • C++11 (g++ 4.8 or higher)
  • Cmake 3.5 or higher

    cmake --version

  • LLVM 설치 (Build)
  • CUDA or openCL을 사용한다면 LLVM을 설치하지 않아도 된다.
  • NNVM compiler를 사용하고 싶다면 LLVM을 설치 해야함.

Build Libary config.

  • config.cmake파일을 수정해서 빌드에 사용할 libary들을 선택 한다.
  • macOS의 경우 에러가 발생하면 XCdoe에서 어쩌면 LDFLAGS에 -lc++abi를 추가하면 된다.
  • CUDA backend를 사용하고 싶으면, set(USE_CUDA_OFF) set(USE_CUDA_ON)으로 변경 한다.

LLVM 의존성
apt로 설치하면 4.0보다 낮은 버전이 설치되므로 사용을 위해선 직접 빌드해서 써야한다.

빌드에 오랜 시간이 걸리므로 pre-build를 아래 링크에서 다운 받는다.

unzip후 build/config.cmake set(USE_LLVM /path/to/your/llvm/bin/llvm-config)

1080 PC 에서

default mode
-> LLVM 없는 상태

실행 로그

jemin@jemin-desktop:~/Users/jemin/tvm$ make -j4
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test SUPPORT_CXX11
-- Performing Test SUPPORT_CXX11 - Success
-- Build with RPC support...
-- Build with Graph runtime support...
-- Build VTA runtime with target: sim
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jemin/Users/jemin/tvm/build
...
...
...
[ 99%] Building CXX object CMakeFiles/nnvm_compiler.dir/nnvm/src/top/vision/yolo/reorg.cc.o
[100%] Linking CXX shared library libnnvm_compiler.so
make[3]: 디렉터리 '/home/jemin/Users/jemin/tvm/build' 나감
[100%] Built target nnvm_compiler
make[2]: 디렉터리 '/home/jemin/Users/jemin/tvm/build' 나감
make[1]: 디렉터리 '/home/jemin/Users/jemin/tvm/build' 나감

LLVM ON

-- Build with RPC support...
-- Build with Graph runtime support...
-- Build VTA runtime with target: sim
-- Use llvm-config=/home/jemin/Users/jemin/clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-16.04/bin/llvm-config
-- /home/jemin/Users/jemin/clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-16.04/include
-- Found LLVM_INCLUDE_DIRS=/home/jemin/Users/jemin/clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-16.04/include
-- Found LLVM_DEFINITIONS= -DNDEBUG -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-- Found TVM_LLVM_VERSION=70
-- Build with LLVM
-- Set TVM_LLVM_VERSION=70
-- Configuring done
-- Generating done
-- Build files have been written to: /home/jemin/Users/jemin/tvm/build

Xavier에서 CUDA ON

nvidia@jetson-0423718017159:~/tvm$ make -j4
-- The C compiler identification is GNU 7.3.0
-- The CXX compiler identification is GNU 7.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test SUPPORT_CXX11
-- Performing Test SUPPORT_CXX11 - Success
-- Build with RPC support...
-- Build with Graph runtime support...
-- Build VTA runtime with target: sim
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Looking for pthread_create
-- Looking for pthread_create - not found
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE
-- Found CUDA_TOOLKIT_ROOT_DIR=/usr/local/cuda-10.0
-- Found CUDA_CUDA_LIBRARY=/usr/local/cuda-10.0/lib64/stubs/libcuda.so
-- Found CUDA_CUDART_LIBRARY=/usr/local/cuda-10.0/lib64/libcudart.so
-- Found CUDA_NVRTC_LIBRARY=/usr/local/cuda-10.0/lib64/libnvrtc.so
-- Found CUDA_CUDNN_LIBRARY=/usr/lib/aarch64-linux-gnu/libcudnn.so
-- Found CUDA_CUBLAS_LIBRARY=/usr/local/cuda-10.0/lib64/libcublas.so
-- Build with CUDA support
-- Configuring done
-- Generating done
....
....
[ 99%] Building CXX object CMakeFiles/nnvm_compiler.dir/nnvm/src/top/vision/yolo/reorg.cc.o
[100%] Linking CXX shared library libnnvm_compiler.so
make[3]: Leaving directory /home/nvidia/tvm/build
[100%] Built target nnvm_compiler
make[2]: Leaving directory /home/nvidia/tvm/build
make[1]: Leaving directory /home/nvidia/tvm/build

OSX에 설치하기

llvm을 프리 빌드 버전을 다운받는다.
7.0 버전: http://releases.llvm.org/7.0.0/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz
압축푼 경로에서 bin/llvm-config가 정상적으로 동작 하는지를 파악한다.

mkdir Build
cp cmake/config.cmake build
cd build
cmake ..
-- The C compiler identification is AppleClang 10.0.0.10001044
-- The CXX compiler identification is AppleClang 10.0.0.10001044
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test SUPPORT_CXX11
-- Performing Test SUPPORT_CXX11 - Success
-- Build with RPC support...
-- Build with Graph runtime support...
-- Build VTA runtime with target: sim
-- Use llvm-config=/Users/jeminlee/development/llvm/clang+llvm-7.0.0-x86_64-apple-darwin/bin/llvm-config
-- /Users/jeminlee/development/llvm/clang+llvm-7.0.0-x86_64-apple-darwin/include
-- Found LLVM_INCLUDE_DIRS=/Users/jeminlee/development/llvm/clang+llvm-7.0.0-x86_64-apple-darwin/include
-- Found LLVM_DEFINITIONS= -DNDEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
-- Found TVM_LLVM_VERSION=70
-- Build with LLVM
-- Set TVM_LLVM_VERSION=70
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/jeminlee/development/tvm/build

make -j8
Scanning dependencies of target vta
Scanning dependencies of target tvm_runtime
Scanning dependencies of target tvm
[  0%] Building CXX object CMakeFiles/vta.dir/vta/src/device_api.cc.o
[  1%] Building CXX object CMakeFiles/vta.dir/vta/src/sim/sim_driver.cc.o
...
...
[ 99%] Building CXX object CMakeFiles/nnvm_compiler.dir/nnvm/src/top/vision/ssd/mutibox_op.cc.o
[100%] Building CXX object CMakeFiles/nnvm_compiler.dir/nnvm/src/top/vision/yolo/region.cc.o
[100%] Building CXX object CMakeFiles/nnvm_compiler.dir/nnvm/src/top/vision/yolo/reorg.cc.o
[100%] Linking CXX shared library libtvm_topi.dylib
[100%] Built target tvm_topi
[100%] Linking CXX shared library libnnvm_compiler.dylib
[100%] Built target nnvm_compiler

단 llvm을 사용해서 nnvm을 활성화 하는 방법은 build 디렉터리내의 cofnig.cmake를 수정해서 set(USE_LLVM 경로)를 삽입한다.

Python Package Installation

tvm/python에 위치한 python package를 설치하는 방법으로 두 가지 방법이 존재 한다.

방법 1 (개발자)

  • export TVM_HOME=/path/to/tvm
  • export PYTHONPATH=$TVM_HOME/python:$TVM_HOME/topi/python:$TVM_HOME/nnvm/python:${PYTHONPATH}

방법 2

Python dependencies

  • Necessary dependencies
    • pip install --user numpy decorator
  • RPC Tracker
    • pip install --user tornado
  • Auto-tuning module
    • pip install --user tornado psutil xgboost

Troubleshooting

tensor error
Python 3.x 버전으로 변경한다.

모델 컴파일 에러
llvm 6.0.1에 최적화 되어 있으므로 7버전의 것을 사용하지 않는다.


'AI > TVM' 카테고리의 다른 글

TVM Pycharm 설정법  (0) 2021.03.09
VTA on FPGA Board  (4) 2019.04.02
PYNQ: Python productivity on ZYNQ  (0) 2019.04.02

TensorRT이용한 Xavier DLA (NVDLA) 실행


공식 문서의 챕터6을 토대로 실행본 것을 정리함.

Chapter 6: Working with DLA

trtexec에서 사용 가능한 option

  • --avgRuns=100
  • --deploy=resnet50.prototxt
  • --fp16
  • --batch=8
  • --iterations=10000
  • --output=prob
  • --useDLACore=1
  • --useSpinWait: multi-process execution을 할 때 multiple inference sessions이 in parallel하게 실행되면 성능 저하를 발생 시킨다. 이러한 문제를 해결하기 위한 한 방법이 cudaEventBlockingSync대신에 --useSpinWait를 사용해서 spin-wait based synchronization을 수행 하는 것이다.

  • --allowGPUFallback: 아래 네 가지 경우에 대해서 DLA로 실행 불가능 할 때 GPU로 동작

    • Thelayer operation is not supported on DLA.
    • The parameters specified are out of supported range for DLA.
    • The given batch size exceeds the maximum permissible DLA batch size. For more information, see DLA Supported Layers.
    • A combination of layers in the network causes the internal state to exceed what the DLA is capable of supporting.
  • Multiple instances of trtexec can be launched simultaneously in this fashion for concurrent execution of the GPU and DLA’s.

  • DLA supports a maximum batch size of 32 depending on the network, while the GPU can run higher batch sizes concurrently.

6.2. DLA Supported Layers
This section lists the layers supported by DLA along with the constraints associated with each layer.

  • Generic restrictions while running on DLA (applicable to all layers)

    • Max batch size supported is 32.
    • Note: Batch size for DLA is the product of all index dimensions except the CHW dimensions. For example, if input dimensions are NPQRS, the effective batch size is N*P.
    • Input and output tensor data format should be FP16.
  • Layer specific restrictions

    • Convolution, Deconvolution, and Fully Connected Layers
    • Convolution and Deconvolution Layers
    • Width and height of kernel size must be in the range [1, 32]
    • Width and height of padding must be in the range [0, 31]
    • Width and height of stride must be in the range [1,8] for Convolution Layer and [1,32] for Deconvolution layer
    • Number of output maps must be in the range [1, 8192]
    • Axis must be 1
    • Grouped and dilated convolution supported. Dilation values must be in the range [1,32]
    • Pooling Layer
    • Operations supported: kMIN, kMAX, kAVERAGE
    • Width and height of the window size must be in the range [1, 8]
    • Width and height of padding must be in the range [0, 7]
    • Width and height of stride must be in the range [1, 16]
    • Activation Layer
    • Functions supported: ReLU, Sigmoid, Hyperbolic Tangent
    • Negative slope not supported for ReLU
    • ElementWise Layer
    • Operations supported: Sum, Product, Max, and Min
    • Scale Layer
    • Mode supported: Uniform, Per-Channel, and Elementwise
    • LRN (Local Response Normalization) Layer
    • Window size is configurable to 3, 5, 7, or 9
    • Normalization region supported is: ACROSS_CHANNELS
    • Concatenation Layer
    • DLA supports concatenation only along the channel axis

https://docs.nvidia.com/deeplearning/sdk/pdf/TensorRT-Release-Notes.pdf
DLA: Activiation, Concatenation, Convolution, Deconvolution, ElementWise, FullyConnected, LRN, Poolling, and Scale.

Alexnet, GoogleNet, ResNet-50, LeNet for MNIST.

trtexec, --useDLACore=N 0 or 1, --fp16
MNIST에 대해서는

./trtexec --deploy=data/mnist/mnist.prototxt --output=prob --useDLACore=0 --
fp16 --allowGPUFallback

trtexec는 아직 ONNX model을 DLA에서는 지원하지 않음

AlexNet 실행 결과

With DLA

sudo ./trtexec --deploy=/usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt --output=fc8 --fp16 --useDLACore=1
deploy: /usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt
output: fc8
fp16
useDLACore: 1
Input "data": 3x227x227
Output "fc8": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=fc8, bindingIndex=1, buffers.size()=2
Average over 10 runs is 6.7926 ms (host walltime is 6.98827 ms, 99% percentile time is 11.3653).
Average over 10 runs is 6.27773 ms (host walltime is 6.415 ms, 99% percentile time is 6.33238).
Average over 10 runs is 6.34808 ms (host walltime is 6.51361 ms, 99% percentile time is 6.4911).
Average over 10 runs is 6.44476 ms (host walltime is 6.61664 ms, 99% percentile time is 6.55571).
Average over 10 runs is 6.46809 ms (host walltime is 6.63325 ms, 99% percentile time is 6.5311).
Average over 10 runs is 6.39661 ms (host walltime is 6.61909 ms, 99% percentile time is 6.51162).
Average over 10 runs is 6.3873 ms (host walltime is 6.92348 ms, 99% percentile time is 6.56896).
Average over 10 runs is 6.3655 ms (host walltime is 6.60092 ms, 99% percentile time is 6.47475).
Average over 10 runs is 6.42326 ms (host walltime is 6.57476 ms, 99% percentile time is 6.58432).
Average over 10 runs is 6.4514 ms (host walltime is 6.60459 ms, 99% percentile time is 6.53622).

Without DLA

sudo ./trtexec --deploy=/usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt --output=fc8 --fp16 --useDLACore=0
deploy: /usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt
output: fc8
fp16
useDLACore: 0
Input "data": 3x227x227
Output "fc8": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=fc8, bindingIndex=1, buffers.size()=2
Average over 10 runs is 6.37521 ms (host walltime is 6.55121 ms, 99% percentile time is 7.07267).
Average over 10 runs is 6.43402 ms (host walltime is 6.61367 ms, 99% percentile time is 6.53213).
Average over 10 runs is 6.59314 ms (host walltime is 6.7674 ms, 99% percentile time is 6.8311).
Average over 10 runs is 6.46851 ms (host walltime is 6.63689 ms, 99% percentile time is 6.53619).
Average over 10 runs is 6.49032 ms (host walltime is 6.67388 ms, 99% percentile time is 6.56176).
Average over 10 runs is 6.50446 ms (host walltime is 6.66483 ms, 99% percentile time is 6.76147).
Average over 10 runs is 6.47384 ms (host walltime is 6.66675 ms, 99% percentile time is 6.61805).
Average over 10 runs is 6.45161 ms (host walltime is 6.63162 ms, 99% percentile time is 6.62525).
Average over 10 runs is 6.59969 ms (host walltime is 6.9295 ms, 99% percentile time is 8.73366).
Average over 10 runs is 6.48038 ms (host walltime is 6.63838 ms, 99% percentile time is 6.52291).

GPU-INT8

sudo ./trtexec --avgRuns=100 --deploy=/usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt --output=fc8 --batch=8 --iterations=10 --int8 --useSpinWait
avgRuns: 100
deploy: /usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt
output: fc8
batch: 8
iterations: 10
int8
useSpinWait
Input "data": 3x227x227
Output "fc8": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=fc8, bindingIndex=1, buffers.size()=2
Average over 100 runs is 19.2004 ms (host walltime is 19.2577 ms, 99% percentile time is 27.2834).
Average over 100 runs is 4.89694 ms (host walltime is 4.91578 ms, 99% percentile time is 5.99552).
Average over 100 runs is 4.86918 ms (host walltime is 4.88175 ms, 99% percentile time is 4.96976).
Average over 100 runs is 4.87189 ms (host walltime is 4.8947 ms, 99% percentile time is 5.45152).
Average over 100 runs is 4.8832 ms (host walltime is 4.89491 ms, 99% percentile time is 6.77392).
Average over 100 runs is 4.87852 ms (host walltime is 4.89489 ms, 99% percentile time is 6.14464).
Average over 100 runs is 4.88434 ms (host walltime is 4.89542 ms, 99% percentile time is 6.13763).
Average over 100 runs is 4.86638 ms (host walltime is 4.87723 ms, 99% percentile time is 4.8999).
Average over 100 runs is 4.87463 ms (host walltime is 4.89783 ms, 99% percentile time is 5.61664).
Average over 100 runs is 4.87941 ms (host walltime is 4.89598 ms, 99% percentile time is 6.0657).

GPU-FP16

usr/src/tensorrt/bin$ ./trtexec --avgRuns=100 --deploy=/usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt --output=fc8 --batch=8 --iterations=10 --fp16 --useSpinWait
avgRuns: 100
deploy: /usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt
output: fc8
batch: 8
iterations: 10
fp16
useSpinWait
Input "data": 3x227x227
Output "fc8": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=fc8, bindingIndex=1, buffers.size()=2
Average over 100 runs is 19.9483 ms (host walltime is 19.9793 ms, 99% percentile time is 26.7212).
Average over 100 runs is 17.2459 ms (host walltime is 17.2622 ms, 99% percentile time is 26.3752).
Average over 100 runs is 5.80046 ms (host walltime is 5.81265 ms, 99% percentile time is 8.1817).
Average over 100 runs is 5.09872 ms (host walltime is 5.11733 ms, 99% percentile time is 6.23514).
Average over 100 runs is 5.10308 ms (host walltime is 5.11465 ms, 99% percentile time is 6.37568).
Average over 100 runs is 5.1078 ms (host walltime is 5.12036 ms, 99% percentile time is 6.38995).
Average over 100 runs is 5.09496 ms (host walltime is 5.11859 ms, 99% percentile time is 5.84192).
Average over 100 runs is 5.10623 ms (host walltime is 5.11759 ms, 99% percentile time is 6.30518).
Average over 100 runs is 5.08028 ms (host walltime is 5.09227 ms, 99% percentile time is 5.1617).
Average over 100 runs is 5.0951 ms (host walltime is 5.11809 ms, 99% percentile time is 5.82054).

Avgrun 100으로 변경
DLA=1

nvidia@jetson-0423718017159:/usr/src/tensorrt/bin$ sudo ./trtexec --avgRuns=100 --deploy=/usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt --output=fc8 --batch=8 --iterations=10000 --fp16 --useDLACore=1
avgRuns: 100
deploy: /usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt
output: fc8
batch: 8
iterations: 10000
fp16
useDLACore: 1
Input "data": 3x227x227
Output "fc8": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=fc8, bindingIndex=1, buffers.size()=2
Average over 100 runs is 43.3741 ms (host walltime is 43.542 ms, 99% percentile time is 48.9472).
Average over 100 runs is 43.452 ms (host walltime is 43.6448 ms, 99% percentile time is 46.4364).
Average over 100 runs is 43.381 ms (host walltime is 43.5552 ms, 99% percentile time is 43.9859).
Average over 100 runs is 43.3211 ms (host walltime is 43.4982 ms, 99% percentile time is 43.649).
Average over 100 runs is 43.3026 ms (host walltime is 43.561 ms, 99% percentile time is 43.691).
Average over 100 runs is 43.2974 ms (host walltime is 43.4682 ms, 99% percentile time is 43.607).
Average over 100 runs is 43.2615 ms (host walltime is 43.4367 ms, 99% percentile time is 43.5681).
Average over 100 runs is 43.3321 ms (host walltime is 43.5066 ms, 99% percentile time is 43.6695).
Average over 100 runs is 43.3151 ms (host walltime is 43.4987 ms, 99% percentile time is 44.1478).
Average over 100 runs is 43.2724 ms (host walltime is 43.4773 ms, 99% percentile time is 43.5927).

DLA=0

nvidia@jetson-0423718017159:/usr/src/tensorrt/bin$ sudo ./trtexec --avgRuns=100 --deploy=/usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt --output=fc8 --batch=8 --iterations=10 --fp16 --useDLACore=0
avgRuns: 100
deploy: /usr/src/tensorrt/data/AlexNet/alexnet_noprob.prototxt
output: fc8
batch: 8
iterations: 10
fp16
useDLACore: 0
Input "data": 3x227x227
Output "fc8": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=fc8, bindingIndex=1, buffers.size()=2
Average over 100 runs is 43.958 ms (host walltime is 44.1817 ms, 99% percentile time is 46.4005).
Average over 100 runs is 43.8673 ms (host walltime is 44.0831 ms, 99% percentile time is 44.4324).
Average over 100 runs is 43.82 ms (host walltime is 44.0434 ms, 99% percentile time is 44.3187).
Average over 100 runs is 43.8821 ms (host walltime is 44.1185 ms, 99% percentile time is 46.3073).
Average over 100 runs is 43.8871 ms (host walltime is 44.0772 ms, 99% percentile time is 50.0316).
Average over 100 runs is 43.8578 ms (host walltime is 44.0774 ms, 99% percentile time is 44.4027).
Average over 100 runs is 43.8086 ms (host walltime is 44.0573 ms, 99% percentile time is 45.2116).
Average over 100 runs is 43.8388 ms (host walltime is 44.0205 ms, 99% percentile time is 46.1998).
Average over 100 runs is 43.8302 ms (host walltime is 44.0014 ms, 99% percentile time is 44.331).
Average over 100 runs is 43.8718 ms (host walltime is 44.0618 ms, 99% percentile time is 46.211).

ResNet-50을 이용한 테스트

모델 다운로드
https://github.com/KaimingHe/deep-residual-networks

https://developer.nvidia.com/embedded/jetson-agx-xavier-dl-inference-benchmarks

For GPU
$ ./trtexec --avgRuns=100 --deploy=resnet50.prototxt --int8 --batch=8 --iterations=10000 --output=prob --useSpinWait

For DLA (Core 0)
$ ./trtexec --avgRuns=100 --deploy=resnet50.prototxt --fp16 --batch=8 --iterations=10000 --output=prob --useDLACore=0 --useSpinWait --allowGPUFallback

For DLA (Core 1)
$ ./trtexec --avgRuns=100 --deploy=resnet50.prototxt --fp16 --batch=8 --iterations=10000 --output=prob --useDLACore=1 --useSpinWait --allowGPUFallback

실험결과
GPU 실행 FP16

./trtexec --avgRuns=100 --deploy=../data/ResNet-50-deploy.prototxt --fp16 --batch=8 --iterations=10 --output=prob --useSpinWait
avgRuns: 100
deploy: ../data/ResNet-50-deploy.prototxt
fp16
batch: 8
iterations: 10
output: prob
useSpinWait
Input "data": 3x224x224
Output "prob": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=prob, bindingIndex=1, buffers.size()=2
Average over 100 runs is 14.4263 ms (host walltime is 14.443 ms, 99% percentile time is 53.3525).
Average over 100 runs is 12.3128 ms (host walltime is 12.3288 ms, 99% percentile time is 14.1207).
Average over 100 runs is 12.3141 ms (host walltime is 12.3274 ms, 99% percentile time is 14.1016).
Average over 100 runs is 12.3157 ms (host walltime is 12.3302 ms, 99% percentile time is 14.3564).
Average over 100 runs is 12.2982 ms (host walltime is 12.3208 ms, 99% percentile time is 14.1487).
Average over 100 runs is 12.3076 ms (host walltime is 12.3231 ms, 99% percentile time is 14.0421).
Average over 100 runs is 12.2918 ms (host walltime is 12.3147 ms, 99% percentile time is 13.8296).
Average over 100 runs is 12.3104 ms (host walltime is 12.325 ms, 99% percentile time is 13.8336).
Average over 100 runs is 12.2957 ms (host walltime is 12.3222 ms, 99% percentile time is 13.9811).
Average over 100 runs is 12.3071 ms (host walltime is 12.3208 ms, 99% percentile time is 13.9845).

GPU 실행 INT8

nvidia@jetson-0423718017159:/usr/src/tensorrt/bin$ ./trtexec --avgRuns=100 --deploy=../data/ResNet-50-deploy.prototxt --int8 --batch=8 --iterations=10 --output=prob --useSpinWait
avgRuns: 100
deploy: ../data/ResNet-50-deploy.prototxt
int8
batch: 8
iterations: 10
output: prob
useSpinWait
Input "data": 3x224x224
Output "prob": 1000x1x1
name=data, bindingIndex=0, buffers.size()=2
name=prob, bindingIndex=1, buffers.size()=2
Average over 100 runs is 8.23188 ms (host walltime is 8.24839 ms, 99% percentile time is 24.6174).
Average over 100 runs is 7.36899 ms (host walltime is 7.38346 ms, 99% percentile time is 8.7689).
Average over 100 runs is 7.36345 ms (host walltime is 7.38333 ms, 99% percentile time is 8.55971).
Average over 100 runs is 7.3687 ms (host walltime is 7.3814 ms, 99% percentile time is 8.87165).
Average over 100 runs is 7.34474 ms (host walltime is 7.36685 ms, 99% percentile time is 7.89891).
Average over 100 runs is 7.37816 ms (host walltime is 7.3919 ms, 99% percentile time is 9.41402).
Average over 100 runs is 7.35202 ms (host walltime is 7.36458 ms, 99% percentile time is 8.94925).
Average over 100 runs is 7.3375 ms (host walltime is 7.35933 ms, 99% percentile time is 7.93171).
Average over 100 runs is 7.36859 ms (host walltime is 7.38325 ms, 99% percentile time is 9.11626).
Average over 100 runs is 7.3404 ms (host walltime is 7.35386 ms, 99% percentile time is 7.42304).

useDLACore=0

./trtexec --avgRuns=100 --deploy=../data/ResNet-50-deploy.prototxt --fp16 --batch=8 --iterations=10 --output=prob --useDLACore=0 --useSpinWait --allowGPUFallback
avgRuns: 100
deploy: ../data/ResNet-50-deploy.prototxt
fp16
batch: 8
iterations: 10
output: prob
useDLACore: 0
useSpinWait
allowGPUFallback
Input "data": 3x224x224
Output "prob": 1000x1x1
Default DLA is enabled but layer prob is not running on DLA, falling back to GPU.
name=data, bindingIndex=0, buffers.size()=2
name=prob, bindingIndex=1, buffers.size()=2
Average over 100 runs is 49.0278 ms (host walltime is 49.155 ms, 99% percentile time is 50.5068).
Average over 100 runs is 48.9775 ms (host walltime is 49.0705 ms, 99% percentile time is 49.794).
Average over 100 runs is 48.9935 ms (host walltime is 49.0898 ms, 99% percentile time is 49.5647).
Average over 100 runs is 49.006 ms (host walltime is 49.1076 ms, 99% percentile time is 51.2941).
Average over 100 runs is 48.9827 ms (host walltime is 49.0781 ms, 99% percentile time is 49.2135).
Average over 100 runs is 48.9586 ms (host walltime is 49.0567 ms, 99% percentile time is 49.1777).
Average over 100 runs is 48.9577 ms (host walltime is 49.0548 ms, 99% percentile time is 49.793).
Average over 100 runs is 48.9677 ms (host walltime is 49.062 ms, 99% percentile time is 49.1632).
Average over 100 runs is 48.9815 ms (host walltime is 49.0734 ms, 99% percentile time is 50.0357).
Average over 100 runs is 48.9672 ms (host walltime is 49.0723 ms, 99% percentile time is 49.3834).

useDLACore=1

./trtexec --avgRuns=100 --deploy=../data/ResNet-50-deploy.prototxt --fp16 --batch=8 --iterations=10 --output=prob --useDLACore=1 --useSpinWait --allowGPUFallback
avgRuns: 100
deploy: ../data/ResNet-50-deploy.prototxt
fp16
batch: 8
iterations: 10
output: prob
useDLACore: 1
useSpinWait
allowGPUFallback
Input "data": 3x224x224
Output "prob": 1000x1x1
Default DLA is enabled but layer prob is not running on DLA, falling back to GPU.
name=data, bindingIndex=0, buffers.size()=2
name=prob, bindingIndex=1, buffers.size()=2
Average over 100 runs is 48.7231 ms (host walltime is 48.8172 ms, 99% percentile time is 53.6832).
Average over 100 runs is 48.6207 ms (host walltime is 48.7205 ms, 99% percentile time is 49.832).
Average over 100 runs is 48.5483 ms (host walltime is 48.6472 ms, 99% percentile time is 48.8971).
Average over 100 runs is 48.5748 ms (host walltime is 48.6652 ms, 99% percentile time is 49.6947).
Average over 100 runs is 48.603 ms (host walltime is 48.695 ms, 99% percentile time is 51.5523).
Average over 100 runs is 48.5622 ms (host walltime is 48.6576 ms, 99% percentile time is 49.5412).
Average over 100 runs is 48.5704 ms (host walltime is 48.6607 ms, 99% percentile time is 48.9002).
Average over 100 runs is 48.5734 ms (host walltime is 48.6943 ms, 99% percentile time is 49.1745).
Average over 100 runs is 48.5792 ms (host walltime is 48.6702 ms, 99% percentile time is 48.9667).
Average over 100 runs is 48.5813 ms (host walltime is 48.6755 ms, 99% percentile time is 48.8755).

포럼에서 나온 내용으로 NVDLA를 실행해본 결과

TensorRT 5 docs and examples -soloved

Jetson-Inference를 통해서 DLA를 실행하는 코드를 얻을 수 있다. dev brnach UFF SSD에서 이러한 GPU/DLA코드를 포함하는 작업을 수행한다.

예제는 공식문서 chapter6에서 확인할 수 있다.
AlexNet과 같은 정보들은 https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet 에서 모델을 다운로드할 수 있다.

포럼에 나의 정보를 공유함. 다른 사람과 다르게 DLA의 유무에 상관없이 실행 시간이 비슷하게 나온다.


NVDLA: NVIDIA Deep Learning Accelerator (DLA) 개론


공식(Deep Dive)
http://nvdla.org/primer.html

무료 공개 아키텍쳐이다.
이것을 통해 딥러닝 추론 가속기의 디자인 표준을 제공하는 목적을 가진다.

Accelerating Deep Learning Inference using NVDLA

NVDLA 하드웨어는 다음의 컴포넌트들을 포함하고 있다.

  • Convolution Core

  • Single Data Processor

  • Planar Data Processor

  • Channel Data Processor

  • Dedicated Memory and Data Reshape Engines

정보

Deep Learning Accelerator
The other accelerators on-die is the deep learning accelerator (DLA) which is actually a physical implementation of the open source Nvidia NVDLA architecture. Xavier has two instances of NVDLA which can offer a peak theoretical performance of 5.7 teraFLOPS (half precision FP) or twice the throughput at 11.4 TOPS for int8.

Throughput
11.4 TOPS (int8)
5.7 TFLOPS (FP16)

https://en.wikichip.org/wiki/nvidia/tegra/xavier

Sample Platforms

Simulation

FPGA

Amazon EC2 F1 environment

Xavier

실제 Product로 검증되어서 출시된것이 Jetson Xavier이다.
DLA (FP16 at this time)을 지원하며 이것을 TensorRT에서 사용할 수 있도록 지원 한다.

공식 문서

공식문서 컨텐츠
http://nvdla.org/contents.

  • software와 하드웨어 메뉴얼 등등이 수록되어 있음

공식 사이트: http://nvdla.org/

포럼 DLA 사용

https://devtalk.nvidia.com/default/topic/1045030/tensorrt/sample_mnist-segmentation-faults-on-dla-on-xavier/

./sample_mnist --useDLACore=1

 jsteward@jetson-0423718016929:~/Work/tensorrt/bin$ ./sample_mnist --useDLACore=1
 Building and running a GPU inference engine for MNIST
 WARNING: Default DLA is enabled but layer prob is not running on DLA, falling back to GPU.
 WARNING: Default DLA is enabled but layer (Unnamed Layer* 9) [Constant] is not running on DLA, falling back to GPU.
 WARNING: (Unnamed Layer* 10) [ElementWise]: DLA cores do not support SUB ElementWise operation.
 WARNING: Default DLA is enabled but layer (Unnamed Layer* 10) [ElementWise] is not running on DLA, falling back to GPU.
 Segmentation fault (core dumped)

Working with DLA 보면 코드가 있다.
즉 CUDA와 다르게 막 쓸 수는 없고 DLA는 TensorRT를 통해서만 사용할 수 있다.
https://docs.nvidia.com/deeplearning/sdk/tensorrt-developer-guide/index.html#dla_topic

Jetpack에 있는 Doc.을 보고 TensorRT에서 어떻게 NVDLA를 사용할 수 있는지 알 수 있다.
https://devtalk.nvidia.com/default/topic/1041768/jetson-agx-xavier/tensorrt-5-docs-and-examples/post/5284437/#5284437

하드웨어 구성요소

  • Convolution Core: 서로 다른 크기로 지원
  • Single Data Point Processor: activation function을 위한 방법이다. linear와 non-linear모두를 지원한다.
  • Planar Data Processor: pooling을 위한것
  • Cross-Channel Data Processor: local normalization을 위한것 같다.
  • Data Reshape Engines: 텐서 복사나 리쉐입을 위한 memory to meory transformation acceleration. 즉, splitting, slicing, merging, contraction, reshape transpose.
  • Bridge DMA: 시스템 DRAM사이에서의 데이터 전송을 관장한다.

스크린샷 2019-01-15 오후 4.39.14

  • 출처: 공식문서

스크린샷 2019-02-08 오전 11.07.33

  • 출처: SysML 18: Bill Dally, Hardware for Deep Learning

소프트웨어

  • Compilation tools: (model conversion).
  • Runtime environment: (run-time software to load and execute entworks on NVDLA).

Xavier DLA는 코딩이 가능한가?
https://devtalk.nvidia.com/default/topic/1041868/jetson-agx-xavier/nvdla-programming-interface/

NVDLA의 전력 소모

스크린샷 2019-02-08 오전 11.09.54

  • 출처: SysML 18: Bill Dally, Hardware for Deep Learning

참고자료

[1] 공식 깃허브: https://github.com/nvdla/

[2] DEVIEW2018: https://tv.naver.com/v/4580068

[3] NVidia TensorRT: High-performance deep learning inference accelerator (TensorFlow Meets): https://www.youtube.com/watch?v=G_KhUFCUSsY


Glow: graph lowering compiler for hardware accelerators

Youtube Link

여러 프레임월을 지원하기위한 컴파일러 기술

상위 레벨에서 IR로 변환하며 그것을 처리함

결국은 모든 상위 레벨의 Framework operation들을 다 지원하기는 어렵기 때문에 primitive operations들로 exchange되어 진다. 이러한 경우 original code 보다 느려질 수 있지만 이것은 전통적인 compiler의 문제이므로 해결할 방법은 모두 나와 있으므로 문제가 될 것이 없다.

스크린샷 2019-02-07 오후 2.42.11
스크린샷 2019-02-07 오후 2.54.40
스크린샷 2019-02-07 오후 2.56.49
스크린샷 2019-02-07 오후 2.57.17
스크린샷 2019-02-07 오후 2.58.30
스크린샷 2019-02-07 오후 2.59.26

Quantization

neural network은 resilient가 있기 때문에 reduced bit-width로 동작할 수 있다.

Quantization is the process of converting the network to integer arithmetic.

Profile Guided Quantization

스크린샷 2019-02-07 오후 3.12.19

More Information

Participate on Github
Glow: Compiler for Neural Network Hardware Accelerators

  • https;//github.com/pytorch/glow

arxiv publication
Glow: Graph Lowering Compiler Techniques for Neural Networks

@Scale 2018 Keynote
Glow: A community-driven approach to AI
https://atscaleconference.com/videos/scale-2018-keynote-glow-a-community-driven-approach-to-ai/


'AI > Embedded Deep learning' 카테고리의 다른 글

ONNX  (4) 2020.05.04
Glow 설치법  (1) 2019.11.19
Coral Dev Board (Google Edge TPU) 설정 및 사용후기  (2) 2019.08.13
TensorFlow Lite 예제 실행  (2) 2017.12.05
TensorFlow Lite 개발자 프리뷰 공개  (0) 2017.12.01

NVIDIA AI Tech Workshop at NIPS 2018 -- Session3: Inference and Quantization


youtube link

What is quantization for inference?

4-bit Quantization

$$ \begin{pmatrix} -1.54 & 0.22 \ -0.026 & 0.65 \end{pmatrix} \times \begin{pmatrix} 0.35 \ -0.51 \end{pmatrix} = \begin{pmatrix} -0.65 \ -0.423 \end{pmatrix}$$

스크린샷 2019-02-06 오전 9.16.19

위와 같이 각각을 Quantization하게 된다.
각각의 행렬을 다른 범위로 양자화해도 상관 없다.
이 때 중요한것은 FP범위로 봤을 때 [-2, 2)인 것을 정밀하게 분포로 표현하고 해당 눈끔을 8개로 쪼개서 [-8, 8)로 표현한다. 그다음 각각을 가장 근접한 INT8 숫자로 변환하면 된다. 왜냐하면 4bit로 표현할 수 있는 숫자의 범위가 [-8, 8)이기 때문이다.

1bit: signed
3bit: number

스크린샷 2019-02-06 오전 9.35.44

위와 같이 나머지들도 각각 변환해 준다. 두 번째 matrix의 경우 [-1,1)의 범위 레인지를 잡고 양자화 시켰다.

결국 두 행렬은 각각 스케일 x4, x8을 한 것이다. 연산을 수행하고 나온 결과를 다시 복구 하기위해서 32의 최종 스케일 값으로 나누면 된다.
결과가 약간 다르지만 얼추 비슷하면 딥러닝에선 잘 동작하게 된다.

Important takeaways

  • A centered quantization scheme is equivalent to sacle, then round
  • An uncentered quantization scheme is equivalent to scale-plus-shift, then round
  • It is possible to take the output and either dequantize-to-float or directly requantize at the appropirate scale for the next operation
    • This is straightforward for scale-only, a little tricky for scale-and-shift
      However, the output must initially have a wider type than the inputs

Quantizing for accuracy and speed

Quantized Network Accuracy
스크린샷 2019-02-06 오전 10.18.28

Sacle-only quantization
스크린샷 2019-02-06 오전 10.20.01

Per-channel scaling
스크린샷 2019-02-06 오전 10.20.41

Training for Quantization
스크린샷 2019-02-06 오전 10.21.22

Conclusion

  • Quantization is not magic, but instead simply a matter of choosing min/max values and mapping weights/activation to index of nearest presentable value
  • Turing has extensive support for accelerating INT8 networks and experimental support for really accelerating INT4 and INT1 models
  • Prefer sacle-only (centered) quantization for performance
  • Fine-grained (per-channel) scaling of wieghts is good for accuracy

Post-Training calibration

자동을 통해서 잘 처리 한다. 하지만 아래와 같은 특수한 상황이 존재 한다면:

  • You already know the dynamic range?
  • You only want to quantize part of the network?
  • It dosn't work?

A Harder case

Yolov1을 가지고 실험 했을 때 int8로 단순히 Quantization을 수행하면 아래와 같은 문제가 발생함.

스크린샷 2019-02-06 오전 9.51.34

정확도 Drop이 발생했음을 분석함

스크린샷 2019-01-11 오전 11.25.26

  • 먼저 각각의 tensor에서의 activiation의 분포를 분석
  • 그리고 어디서 cutoff할지를 파악한다. 최대한 original distribution과 최대한 비슷한지를 파악하게 됨. metric으론 KL Divergence를 이용하게 됨.
    • 근데 이 때 각각의 tensor에 따라 loss를 최소로 하는 Dynamic-Range를 적용하게 됨.
    • 이것이 각각 Calibration-Cache에 저장되게 됨.
    • 이러한 값들은 tensor별로 저장되며 hex로 저장됨. 이것은 Human-Readable 하지는 않다. 그렇다고 심하게 obfuscation되어 있지도 않다.

Mixed Precision networks
하나의 전략은 앞쪽레이어에서는 INT 8을 쓰고 뒤로 갈수록 높은 precision을 사용 한다. 왜냐하면, Later Layers are more sensitive to Noise 이기 때문이다.

for(<all lauers)
  layer -> setprecision(DataType::INT8)

fc25 -> setPrecision(DataType:FP16)
fc26 -> setPrecision(DataType::FP16)

이렇게 해도 잘 안나와서 디버깅을 해보면
First layer의 dynamic range는
Calibration cache

  • conv1: 18.1006
  • relu1: 13.2026
    이건 예상치 못한 결과이다. 왜냐하면 tensorRT는 scale-only calibration을 사용하게 된다.

이때 리키 렐루를 사용하게 되면 마이너스 값이 생기고
이게 비대칭이기 때문에 레프트 사이드가 아래와 같이 왜곡되어 버린다.
스크린샷 2019-02-06 오전 9.53.01
위 그래프 처럼 conv의 경우 nice bell-shaped을 나타낸다.
하지만 ReLU의 경우 모든 negative value들이 squashed되어 왼쪽에 몰려 있는것을 볼 수 있다.

YOLOv1에서 사용하는 Leaky ReLU (Parametric ReLU)의 값은 0.1을 가진다. 즉, 나누기 10을 한 것과 같다.
참조: https://medium.com/tinymind/a-practical-guide-to-relu-b83ca804f1f7

원하는 ReLU의 분포가 다르게 나타난다.

TensorRTv5에서 지원하는 것이 Bring your own Calibration

for(<each leaky relu){
  float c = <conv dynamic range>;
  leakyRelu->setDynamicRange(-c,c);
}

이렇게 각각의 렐루를 다르게 quant.하면 아래와 같이 어느정도 복구가 된다.
스크린샷 2019-02-06 오전 9.58.46

요약
Getting the bset from INT8

  • Dynamic Range from Training:
    • ITensor::setDynamicRange()
  • Mixed Precision is easy to try
    • IBuilder::setStrictTypeConstraints()
    • ILayer:setPrecision()
  • TRT Calibration makes local decisions
  • Improve using insights from:
    • Calibration Cache
    • Network structure
    • Operator properties
  • Try the Legacy Calibrator (requires a parameter sweep, but then works for YOLOv1.)

Also In TensorRT
TensorRT 5:

  • New Python API
  • Global Plugin Registry
  • Integrated ONNX Parser
  • Devices: Xavier, Turing
  • DLA FP16
  • Windows

Comming Soon:

  • Reinforcement Learning Support
  • Plugins & Parsers --> OSS
  • DLA INT8

TensorFlow backend with tensorRT 공식 Github: https://github.com/tensorflow/tensorrt

TensorRT 부분

스크린샷 2019-01-11 오후 12.09.33

스크린샷 2019-01-11 오후 3.49.37

스크린샷 2019-01-11 오후 4.03.54


DeepStream을 통한 low precision YOLOv3 실행


소스코드 다운로드 방법

공식 홈페이지에서 다운

Github 에서 다운은 최신이긴 하나 여러 platform 빌드가 섞여있어서 compile이 쉽지는 않다.

trt-yolo는 github에 저장됨

DeepStream SDK 3.0 EA on Jetson AGX Xavier

  • DeepStream SDK 3.0 EA on Jetson AGX Xavier
    Whatʼs new in this release Support for multi-stream applications: DeepStream 3.0 on Jetson AGX Xavier supports a new set of plugins and functionality for natively managing and batching multiple video streams in a single application for efficient memory management.

  • Extending with data analytics: DeepStream application capabilities can be extended with stream and batch processing framework for processing of the metadata to gain rich insights. The SDK’s new plugins and reference application framework recipe can be used to seamlessly integrate these capabilities.

  • An end-to-end deep learning solution for IVA with support for Transfer Learning Toolkit: Accelerate deep learning training by deploying high-performance pre-trained models optimized for NVIDIA Volta GPUs on AGX Xavier with DeepStream 3.0.
    Quick Start Instructions
    The DeepStream SDK requires:

NVIDIA® JetPack 4.1.1 or NVIDIA® Linux for Tegra (L4T) R31.1 on Ubuntu 18.04 or 16.04

  • NVIDIA® Jetson AGX Xavier™ Developer Kit
  • The DeepStream SDK package, including:
  • binaries (deepstream_sdk_on_jetson.tbz2)
  • sources (apps/ select plugins and libraries)
  • samples (config files, models, video streams)

Additional components be installed on the target:

  • CUDA 10.0
  • cuDNN 7.3
  • TensorRT 5.0
  • OpenCV 3.3.1
  • VisionWorks 1.6
  • librdkafka (for messaging with the Cloud)

DeepStream을 이용해서 TensorRT로 최적화된 YOLOv3인 trt-yolo 실행하기

deepstream plugin github 코드를 다운 받음
yolo model weights를 다운 받음
data/yolo쪽으로 저장한다.

Repo root 디렉터리에서 아래와 같이 설정 후 실행
Makefile.config

CUDA_VER:=10.0
PLATFORM:=Tegra

cd source/apps/trt-yolo
make && sudo make install이후에 bin 디렉터리에 실행파일이 이동 된다. 따라서 trt-yolo-app명령어가 등록되어 진다.

내부적으로 보면 config/yolov3.txt를 수정하면 테스트 이미지를 볼 수 있다.

data/yolo에 weight값과 cfg파일 값 모두를 저장한다.

test_image.txt는 경로를 의미한다.

trt-yolo-app --flagfile=./config/yolov3.txt

Low-Precision 종류들

  • kFLOAT (32 floating pointing)
  • kHALF (16 floating pointing)
  • kINT8 (integer pointing)

TRT-YOLOv3: kFLOAT

Using previously generated plan file located at data/yolo/yolov3-kFLOAT-batch1.engine
Loading TRT Engine...
Loading Complete!
Total number of images used for inference : 1
[======================================================================] 100 %
Network Type : yolov3Precision : kFLOAT Batch Size : 1 Inference time per image : 221.405 ms

32

TRT-YOLOv3: kHALF

Using previously generated plan file located at data/yolo/yolov3-kHALF-batch1.engine
Loading TRT Engine...
Loading Complete!
Total number of images used for inference : 1
[======================================================================] 100 %
Network Type : yolov3Precision : kHALF Batch Size : 1 Inference time per image : 83.944 ms

16

TRT-YOLOv3: kINT8, 실패

File does not exist : data/yolo/yolov3-kINT8-batch1.engine
Unable to find cached TensorRT engine for network : yolov3 precision : kINT8 and batch size :1
Building the TensorRT Engine...
New calibration table will be created to build the engine
Unable to open image : /path/to/image1.jpg
trt-yolo-app: ds_image.cpp:54: DsImage::DsImage(const string&, const int&, const int&): Assertion 0 failed.
Aborted (core dumped)

Xavier에 기본 YOLOv3

`./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg`
Loading weights from yolov3.weights...Done!
data/dog.jpg: Predicted in  `0.164729` seconds.

Geforce-1080에 기본 YOLOv3

Loading weights from yolov3.weights...Done!
data/dog.jpg: Predicted in 0.051647 seconds.


YOLOv3 on Jetson AGX Xavier 성능 평가


18년 4월에 공개된 YOLOv3를 최신 embedded board인 Jetson agx xavier에서 구동시켜서 FPS를 측정해 본다.
그리고 tegra코어가 아닌 Geforece 1080과의 성능 비교도 수행해 본다.

YOLOv3 관련 정보

SSD가 주류가되고 약간 비주류가된 deep learning기반 object detection 알고리즘이다. 하지만 다른 프레임워크를 쓰지않고 독자적이며 의존성이 거의없는 깔끔한 코드이므로 향후 분석하기 용이하므로 이것을 사용 한다.

pretrained weights들은 아래의 표와 같고 각각은 Link에서 다운로드 할 수 있다.
스크린샷 2019-01-10 오후 3.03.00

NVIDIA Jetson Xavier에서 YOLOv3 다운 및 컴파일

소스 및 모델 다운

우선, 아래주소에서 소스코드와 모델 웨이트를 다운로드한다.

git clone https://github.com/pjreddie/darknet # 코드 다운로드
cd darknet
wget https://pjreddie.com/media/files/yolov3.weights # weights 다운로드

Makefile 수정

그 다음 Makefile을 수정한다. 이 때 CUDA Compute Capability를 맞춰서 수행 해야한다.

NVIDIA GPU: CUDA Compute Capability의 이해
CUDA를 활성화해서 컴파일 할 경우 Compute Capability의 이해를 필요로 한다.
허용하지 않는 아키텍쳐라면 아래와 같은 에러를 발생 시킨다.

  • nvcc fatal: Unsupported gpu architecture 'compute_XX'
    해결방법은 nvcc 컴파일을 수행 할 때 FLAG를 넣으면 된다.
  • -gencode arch=compute_XX, code=[sm_XX, compute_XX]이다.

원하는 장치에 맞춰서 적한한 코드를 NVIDIA CUDA-GPUs찾아서 넣으면 된다. GeForece-1080의 경우 6.1이므로-gencode arch=compute_61, code=[sm_61, compute_61]으로
삽입해서 넣으면 된다.
사용할 보드는 tegra 게열인데 Jetson Xavier는 아직 검색이 안 된다.
포럼에서 찾아본 결과 코드는 -gencode arch=compute_72,code=sm_72이다.

추가로, 어떤 머신에서 정확히 돌지 모른다면 여러개를 지원하도록 설정하여 컴파일 할 수도 있다.
아래와 같은 형태가 YOLOv3의 makefile의 구조이다. 사용할 Jetson Xavier용은 없으므로 추가해 주자.

ARCH= -gencode arch=compute_30,code=[sm_30,compute_30] \
      -gencode arch=compute_35,code=[sm_35,compute_35] \
      -gencode arch=compute_50,code=[sm_50,compute_50] \
      -gencode arch=compute_52,code=[sm_52,compute_52] \
      -gencode arch=compute_61,code=[sm_61,compute_61] \
      -gencode arch=compute_72,code=[sm_72,compute_72]

상단의 OPENCV=1 GPU=1 CUDNN=1 이 세개 모두 활성화 한다.
속도를 위해선 gpu cudnn을 활성화하고 real-time 데모를 위해서 opencv도 활성화한다.

컴파일

동작 속도를 빠르게 설정

sudo nvpmodel -m 0
jetson_clocks.sh

make -j4 명령어 수행

nvidia@jetson-0423718017159:~/Computer_Vision_Project/yolov3$ make -j4
mkdir -p obj
mkdir -p backup
mkdir -p results
gcc -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN -c ./src/gemm.c -o obj/gemm.o
gcc -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN -c ./src/utils.c -o obj/utils.o
gcc -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN -c ./src/cuda.c -o obj/cuda.o
gcc -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN -c ./src/deconvolutional_layer.c -o obj/deconvolutional_layer.o
./src/gemm.c: In function ‘time_gpu’:
./src/gemm.c:232:9: warning: ‘cudaThreadSynchronize’ is deprecated [-Wdeprecated-declarations]
         cudaThreadSynchronize();
         ^~~~~~~~~~~~~~~~~~~~~
In file included from /usr/local/cuda/include/cuda_runtime.h:96:0,
                 from include/darknet.h:11,
                 from ./src/utils.h:5,
                 from ./src/gemm.c:2:
/usr/local/cuda/include/cuda_runtime_api.h:947:57: note: declared here
 extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaThreadSynchronize(void);
                                                         ^~~~~~~~~~~~~~~~~~~~~
gcc -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN -c ./src/convolutional_layer.c -o obj/convolutional_layer.o
...
...
...
bj/col2im_kernels.o obj/blas_kernels.o obj/crop_layer_kernels.o obj/dropout_layer_kernels.o obj/maxpool_layer_kernels.o obj/avgpool_layer_kernels.o
gcc -Iinclude/ -Isrc/ -DOPENCV `pkg-config --cflags opencv`  -DGPU -I/usr/local/cuda/include/ -DCUDNN  -Wall -Wno-unused-result -Wno-unknown-pragmas -Wfatal-errors -fPIC -Ofast -DOPENCV -DGPU -DCUDNN obj/captcha.o obj/lsd.o obj/super.o obj/art.o obj/tag.o obj/cifar.o obj/go.o obj/rnn.o obj/segmenter.o obj/regressor.o obj/classifier.o obj/coco.o obj/yolo.o obj/detector.o obj/nightmare.o obj/instance-segmenter.o obj/darknet.o libdarknet.a -o darknet -lm -pthread  `pkg-config --libs opencv` -lstdc++ -L/usr/local/cuda/lib64 -lcuda -lcudart -lcublas -lcurand -lcudnn -lstdc++  libdarknet.a

빌드가 완료되면 data 디렉터리 안에 몇개의 샘플 이미지들이 존재한다.
이것들을 가지고 테스트 할 수도 있고 비디오 영상을 다운받아서 할 수도 있다.

실행 및 성능 테스트

이미지 테스팅

아래는 하나의 이미지에 대해서 xaiver geforece에서 각각 수행해본 결과이다.

  • Xavier: 0.164729
  • Geforce-1080: 0.051647

그냥