brunch

You can make anything
by writing

C.S.Lewis

by Extreme Code Jun 23. 2021

빠른 속도의 Sparse Neural Network

딥러닝 모델 속도를 개선할 수 있는 Google AI의 기술

  머신러닝, 특히 딥러닝의 단점 중 하나는 속도입니다. 기존의 많은 머신러닝에 알고리즘에 비해서 모델 규모가 크다 보니 속도가 굉장히 느립니다. 이를 보완하기 위해 GPU를 사용하기도 하지만, GPU는 매우 비싼 장비이므로 학습을 제외하곤 쉽게 쓰기 힘듭니다. 특히나 모바일에서 딥러닝 모델을 돌릴 때는 더 문제가 되죠.


이를 개선하기 위해서 모델 경량화, 최적화 등 다양하게 많은 방법들이 있는데요, 몇 개월 전에 Google AI 에서 공개XNNPACK acceleration library 의 경우 network 을 sparse 하게 만드는 sparsify 라이브러리입니다. network에서 노드 연결을 줄이는 pruning 계열 알고리즘이라고 볼 수 있을 것 같습니다. 




Sparse Neural Network

  모바일 디바이스에서는 heavy 한 딥러닝 모델을 inference하는게 굉장히 힘들기 때문에, on-device 딥러닝 모델의 속도 개선 및 사이즈 개선등을 위해 sparsify 라이브러리를 개발하였습니다. Sparse한 Neural Network의 경우 많은 weight가 0 이 되므로 모델 사이즈가 작아지고 곱셈/덧셈 연산이 줄어들기 때문에 inference 속도를 늘릴 수 있습니다. 다만, 이러한 테크닉을 쓰는게 그리 간단하지는 않습니다. 따라서, 구글에서는 DeepMind와의 협업을 통해 Tensorflow Lite 와 XNNPACK 에 해당 기능을 추가했다고 합니다. 그리고 밑에서 언급하겠지만 MediaPipe 라이브러리에도 이미 적용을 했습니다.


이를 통하여 성능의 손해가 거의 없이 모델의 사이즈는 거의 반절로 줄어들고 속도는 1.2 ~ 2.4 배 가량 개선했다고 합니다. 그리고 누구든 해당 기능을 쉽게 사용해서 sparsify 할 수 있도록 공개해 놓았습니다.



Sparsify 기술의 구조

  대부분의 딥러닝 아키텍쳐는 Depthwise convolution layer를 사용합니다. 근데 일반적으로 측정을 해 보면 1x1 conv 에서 보통 65% 이상의 연산시간이 소요된다고 합니다. XNNPACK과 같은 inference engine 은 HWC tensor layout 에 의존하는데요 (input image의 height, width, channel 에 tensor dimension이 대응된다는 의미) 이는 inference engine이 각각의 spatial location에 채널별로 프로세싱할 때 parallel 하게 가능하도록 합니다. 하지만 tensor를 정렬하는 것은 sparse inference에는 잘 맞지 않습니다. 왜냐면 channel 을 innermost dimension으로 설정하여 하기 때문에 연산비용이 늘어나게 됩니다.


따라서 이번에 라이브러리에는 XNNPACK에서 model 이 sparse 한지를 알 수 있는 기능이 추가되었습니다. 이렇게 하면 dense inference mode에서 sparse inference mode로 변경 한 후 CHW layout (channel, height, width 순서) 형태로 사용이 가능하게 됩니다.


이렇게 하면 몇가지 장점이 있습니다.

모든 tensor의 spatial slice 는 해당 채널의 weight 가 0이면 skip하게 됩니다.

채널의 weight가 0 이 아니라면 이웃하고 있는 픽셀값을 같은 메모리 유닛 내에 로딩하여 연산을 더 효율적으로 할 수 있습니다. 이는 각각의 연산이 몇개의 쓰레드에서 병렬로 동작하도록 하여 여러 픽셀이 동시에 연산되도록 합니다.

이로 인해 최소 80%의 weight가 0으로 되고 여기서 1.8~2.4배 속도 향상을 얻을 수 있습니다.


또한, sparse inference에 유리한 CHW layout 연산 이후에 다시 HWC layout으로 바뀌고 하는 것들을 방지하기 위해서 XNNPACK 에 몇가지 CNN 연산에 대해서 CHW layout에서도 효율적으로 계산하는 구현도 추가해 놓았다고 합니다.


또한 원문에는 Sparse Neural Network 학습 가이드라인도 제시하고 있습니다.

Dense version을 학습할 때 점차적으로 일부분의 weight를 0으로 만드는 것이 좋습니다. (Pruning)

다양한 Pruning 테크닉 중 Magnitude based pruning 을 추천한다고 합니다. (말 그대로 값이 아주 작은애들을 삭제하는 심플한 방법입니다.) 해당 기능은 TF model optimization toolkit에서 지원한다고 합니다.

Sparse Network 은 hyperparameter 값에 따라서 달라지는 Tensorflow pruning API 에서 좋은 예제와 팁을 제공하니 참고하면 좋다고 하며 hyperparameter search 기능도 제공하니 이를 돌려보는 걸 추천한다고 합니다.



테스트 결과

  해당 기술을 실제 App 에서 테스트 해 보면 용량에서 많은 이점 뿐 아니라 sparsity level에 따라 속도 개선도 많다고 합니다. Sparsity 관련해서는 inverted residual block 을 사용하는 아키텍쳐 (대표적으로 MobileNet V2, V3 와 EfficientNetLiet 등) 에서 가장 좋은 결과를 보인다고 하며 sparsify 해서 학습을 하면 따로 설정을 하지 않아도 XNNPACK이 알아서 해준다고 합니다. 


Sparse의 경우 용량이 50%이상 줄어듭니다.


Inference 시간과 성능 사이의 관계

위의 결과에서는 sparsity level이 35% 정도까지는 성능이 큰 차이가 없는 케이스입니다. 거의 같은 성능을 유지할 때는 속도는 많이 개선은 안된 것 처럼 보이긴 하는데, 모델에 따라서 더 많이 개선된 경우도 있는 듯 하네요.


MediaPipe 개선

1) 기존  2) distillation 3) sparsify

  위에서 소개한 기술을 기술을 활용해서 MediaPipe 의 속도도 개선했다고 합니다. MediaPipe도 따로 소개할 일이 있을지 모르겠는데, 구글이 비디오에서 적용할 수 있는 몇가지 딥러닝 모델을 쉽게 사용할 수 있도록 해 놓은 굉장히 잘 만든 라이브러리 입니다.


MediaPipe에는 굉장히 유용한 라이브러리들을 매우 쉽게 사용할 수 있는데 Sparsify 기술을 활용해 속도도 더 개선해 놓은 상태라고 하네요. 예전에는 MediaPipe에 있는 기술 한가지만 제대로 구현하려고 해도 엄청난 시간과 노력이 들어갔을 텐데, 요즘에는 이렇게 최적화까지 다 해놓은 잘 만들어놓은 라이브러리 등이 있어서 쉽게 가져다 쓸 수 있으니 세상이 정말 좋아진 것 같습니다.




써볼 일이 없어서 해당 기술을 직접 적용해 보지는 않았지만, On-device 에서 tensorflow 기반으로 CNN 기반의 딥러닝 모델을 돌린다면 사용을 고려해 볼 만한 좋은 내용인 것 같습니다. 이 내용은 CNN 기반 네트워크에만 적용되지만, 앞으로 더 많은 경량화 기술들과 툴들이 개발되고 공개될 것입니다. 앞으로가 많이 기대됩니다!





브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari