TFLite 뽀개기 (4) XNNPACK 이해 및 성능 비교

2022. 8. 10. 00:35·AI Engineering/TensorFlow

1. XNNPACK이란?

XNNPACK은 아래와 같은 다양한 device(architecture)를 위해 floating-point neural netowrk의 inference operator를 최적화한 library입니다. (floating-point란 fp32, fp16 모델만 가속화 가능하다는 뜻입니다.) 한마디로 DL 모델의 inference속도를 가속화 해주는 library입니다. 

 

Desktop기준으로 XNNPACK을 사용하기 위해서는 bazel build할때 XNNPACK사용에 대한 명시를 해주어야 합니다. 그리고 TFLite모델에만 사용이 가능합니다.  또 다른 특징으로는 XNNPACK은 PAD operator와 CONV_2D operator(with VALID padding)을 감지하여 하나의 convolution operator로 fusing해주는 역할도 합니다.

1.1 Supported architectures

  • ARM64 on Android, Linux, macOS, and IOS
  • ARMv6 (with VFPv2) on Linux
  • x86 and x86-64 (up to AVX512) on Windows, Linux, macOs, Android, and IOS simulator
  • WebAssembly MVP and SIMD
  • RISC-V
  • ...

위와 같이 XNNPACK의 지원범위는 넓네요. ARM CPU, Intel CPU, Chrome과 같이 web에서 사용되는 WebAssembly 심지어 축소된 명령어 세트로만 설계된 RISC-V에도 XNNPACK이 사용가능합니다. (XNNPack이 구현되어있는 neural network operator는 공식 repo 참고하세요! CNN계열은 거의 다 있네요...) 다양한 device환경에서 모두 사용될 수 있다는 점에서 generality가 좋고 실제로 사용해보면 inference time성능이 매우 좋아집니다. 

 

이번 글에서는 benchmark tool 를 통해 XNNPACK을 사용하였을 때와 아닐 때를 비교하며 inference time에 대한 성능비교를 해보겠습니다.

2. XNNPACK 성능 비교

2.1 Environment Setting

2.1.1 Docker environment

bazel build를 통해 TFLite모델을 benchmark할 수 있는 환경을 docker image로 만들어놓았습니다. 해당 benchmark tool을 통해 XNNPACK사용 했을 경우와 아닌경우의 inference time차이를 볼것이며 profiling기능까지 제공하므로 profile을 통해 각 모델에 대한 inference time에 대한 분석 또한 해보겠습니다.

 

docker image는 아래 명령어로 받을 수 있습니다.

docker pull da2so/tf_bazel:latest

해당 image를 다운받으셨다면 아래 명령어를 통해 container를 만들어 들어가서 benchmark tool을 실행 해봅시다!

# Option 1: GPU 있을 시 
docker run -it -d --gpus '"device=0"' --ipc=host --name da2so_test -p 3322:3322 -v /test/:/usr/src/app da2so/tf_bazel:latest /bin/bash
# Option 2: GPU 없을 시
docker run -it -d --ipc=host --name da2so_test -p 3322:3322 -v /test/:/usr/src/app da2so/tf_bazel:latest /bin/bash

docker attach da2so_test

# in container
cd tensorflow_src
bazel-bin/tensorflow/lite/tools/benchmark/benchmark_model --help

정상적으로 동작했다면 아래와 같을 것입니다. 저는 GPU를 사용하는 option으로 docker container를 생성하였습니다.

check benchmark tool
check benchmark tool

2.1.2 Models

XNNPACK inference time성능 비교에 사용된 TFLite 모델은 다음과 같습니다.

  • Classification
    • MobileNetv2, v3 모두 depth multiplier 0.75사용
Model (data type) Model size (MB)
MobileNetv2 (FP32) 10.6
MobileNetv2 (FP16) 5.3
MobileNetv3 (FP32) 16.0
MobileNetv3 (FP16) 8.1
EfficientNetv2_B0 (FP32) 28.5
EfficientNetv2_B0 (FP16) 14.3
  • Object detection
Model (data type) Model size (MB)
yolov5s (FP32) 29.0
yolov5s (FP16) 14.5
yolov7 (FP32) 147.7
yolov7 (FP16) 73.9

모든 모델은 여기서 다운받을 수 있습니다.

2.1.3 Device info

Inference에 사용되는 device정보는 다음과 같습니다.

  • CPU: Intel(R) Xeon(R) Gold 5120 CPU @ 2.20GHz (56 core)

 

2.2 Benchmark tool로 inference time 측정 예시

Benchmark tool로 yolov5s (fp32) 모델의 inference time을 측정하는 예시를 보여드립니다. bazel-bin/tensorflow/lite/benchmark/benchmark_model 명령어로 모델의 inference time을 측정가능합니다. 아래에서는 XNNPACK을 사용하지 않았으며 warm up으로 10번 후, average inference time을 재기위해 100번 inference진행하였습니다. 

 

Benchmark tool result

위의 결과를 보시면 yolov5s의 model path, model size, inference time, memory footprint까지 출력되는 것을 알 수 있습니다.  CPU로 측정된 yolov5s (fp32)의 average inference time은 513.534ms (0.5초정도) 인것을 확인가능합니다. 

 

※ 참고로 use_gpu옵션을 주어 gpu acceleration을 할 수 있는 데 gpu acceleration은 Android 또는 iOS platform에서 사용가능하다고 하네요.

GPU delegate is only supported on specific platforms

2.3 XNNPACK 성능비교

아래 명령어를 통해 위에서 언급드린 TFLite모델들에 대해 XNNPACK을 사용했을 경우와 아닌 경우에 대한 inference time 성능 비교를 해보겠습니다. 추가로 thread수를 늘렸을 때 성능또한 어떻게 변화하는 지 알아보도록 하죠!

bazel-bin/tensorflow/lite/tools/benchmark/benchmark_model \
--graph=${model_path} \
--use_xnnpack=true (or false) \
--warmup_runs=10 \
--num_runs=100 \
--num_threads=1 (or 2, 4)

 

2.3.1 Classifcation Results

아래는 thread수를 1기준으로 측정하였습니다.

Model (data type, model size) USE_XNNPACK Inference time (ms)
MobileNetv2 (FP32, 10.6MB) True 11.746 ± 0.1
MobileNetv2 (FP32, 10.6MB) False 24.344 ± 2.5
MobileNetv2 (FP16, 5.3MB) True 11.745 ± 0.3
MobileNetv2 (FP16, 5.3MB) False 23.677 ± 1.5 
MobileNetv3 (FP32, 16MB) True 10.346 ± 0.3
 MobileNetv3 (FP32, 16MB) False 20.946 ± 1.1
MobileNetv3 (FP16, 8.1MB) True 10.444 ± 0.4
MobileNetv3 (FP16, 8.1MB) False 20.745 ± 1.3
EfficientNetv2_B0 (FP32, 28.5MB) True 38.183 ± 3.1
EfficientNetv2_B0 (FP32, 28.5MB) False 68.230 ± 3.2
EfficientNetv2_B0 (FP16, 14.3MB) True 37.895 ± 1.0
EfficientNetv2_B0 (FP16, 14.3MB) False 69.594 ± 2.7

위의 결과에서 분석 내용은 다음과 같습니다.

  • XNNPACK을 사용하였을때 2배이상 inference 속도가 빨라짐을 확인
  • FP32와 FP16간의 model size는 차이가 많이 나지만 실제 inference 속도는 거의 비슷함
  • MobileNetv3가 MobileNetv2에 비해 model size는 더 크지만 inference 속도가 더 빠름

 

2.3.2 Object detection Results

Model (data type, model size) USE_XNNPACK Inference time (ms)
yolov5s (FP32, 29.0MB) True 403.578 ± 5.5
yolov5s (FP32, 29.0MB) False 512.900 ± 19.9
yolov5s (FP16, 14.5MB) True 407.494 ± 18.5
yolov5s (FP16, 14.5MB) False 516.036 ± 34.6 
yolov7 (FP32, 147.7MB) True 2420.893 ± 41.0
yolov7 (FP32, 147.7MB ) False 2199.132 ± 41.1
yolov7 (FP16, 73.9MB) True 2424.714 ± 41.3
yolov7 (FP16, 73.9MB) False 2232.653 ± 54.3

위의 결과에서 분석 내용은 다음과 같습니다.

  • yolov5s 모델의 경우 XNNPACK을 사용했을 때 inference 속도가 빨라짐
    • classification모델의 경우 2배정도 inference time이 줄었는데 모델이 커져서 XNNPACK의 효과가 작아진 건가..?
  • yolov7 모델의 경우는 XNNPACK의 효과가 없는 것으로 보임
    • 모델이 너무 커서 그런것인가..?

 

2.3.3 Thread 수에 따른 inference time results

thread 수에 따른 inference time을 비교하기 위해 yolov5s 모델 기준으로 측정해보았습니다.

Model (data type, model size) USE_XNNPACK / Thread num Inference time (ms)
yolov5s (FP32, 29.0MB) True / 1 403.578 ± 5.5
yolov5s (FP32, 29.0MB) True / 2 228.207 ± 16.8
yolov5s (FP32, 29.0MB) True / 4 142.095 ± 11.6
yolov5s (FP32, 29.0MB) False / 1 1022.063 ± 7.5
yolov5s (FP32, 29.0MB) False / 2 733.723 ± 17.7
yolov5s (FP32, 29.0MB) False / 4 513.892 ± 15.0
yolov5s (FP16, 14.5MB) True / 1 407.494 ± 18.5
yolov5s (FP16, 14.5MB) True / 2 231.054 ± 10.7
yolov5s (FP16, 14.5MB) True / 4 138.392 ± 8.2
yolov5s (FP16, 14.5MB) False / 1 1020.223 ± 6.4 
yolov5s (FP16, 14.5MB) False / 2 734.001 ± 21.5
yolov5s (FP16, 14.5MB) False / 4 506.902 ± 15.4

위의 결과에서 분석 내용은 다음과 같습니다.

  • (A) XNNPACK을 사용하지 않고 thread를 4개를 쓴 경우가 (B) XNNPACK을 사용하고 thread수가 1일경우보다 inference time오래 걸림을 알 수 있음 
    • (A)'s inference time: 513.892 ± 15.0 (FP32), 506.902 ± 15.4 (FP16)
    • (B)'s inference time: 403.578 ± 5.5 (FP32), 407.494 ± 18.5(FP16)
  • XNNPACK을 사용하고 thread num이 4인경우가 가장 inference time 성능이 가장 좋음 (초록색)

 

 

 

반응형
저작자표시 (새창열림)

'AI Engineering > TensorFlow' 카테고리의 다른 글

TensorFlow.js (4) YOLOv5 Live demo  (7) 2022.04.11
TensorFlow.js (3) TensorFlow.js 변환  (0) 2022.04.03
TensorFlow.js (2) - WebGL 기반 hand pose detection  (2) 2022.03.23
TensorFlow.js (1) - TensorFlow.js 이해 및 detection 예제  (1) 2022.03.17
Mediapipe (2) - custom segmentation model with mediapipe  (0) 2022.03.14
'AI Engineering/TensorFlow' 카테고리의 다른 글
  • TensorFlow.js (4) YOLOv5 Live demo
  • TensorFlow.js (3) TensorFlow.js 변환
  • TensorFlow.js (2) - WebGL 기반 hand pose detection
  • TensorFlow.js (1) - TensorFlow.js 이해 및 detection 예제
Sin-Han Kang
Sin-Han Kang
Explainable AI (XAI), Model Compression, Image and Video Encoding and NAS
    250x250
  • Sin-Han Kang
    da2so
    Sin-Han Kang
  • 전체
    오늘
    어제
    • 분류 전체보기 (78)
      • AI Engineering (40)
        • TensorFlow (10)
        • PyTorch (6)
        • MLOps (15)
        • NVIDIA (5)
        • OpenVINO (3)
      • AI paper review (6)
        • Explainable AI (5)
        • Model Compression (10)
        • Mobile-friendly (7)
      • Computer Science (6)
      • 일상 (4)
  • 블로그 메뉴

    • Home
    • About me
    • Guest book
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    pytorch
    docker
    object detection
    style transfer
    TFLite
    Airflow
    Python
    Model Compression
    OpenVINO
    TensorFlow.js
    Mediapipe
    kubernetes
    Explainable AI
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Sin-Han Kang
TFLite 뽀개기 (4) XNNPACK 이해 및 성능 비교
상단으로

티스토리툴바