[CNN Networks] 8. Quantization 소개

onlybox·2021년 12월 5일
1
post-thumbnail

아래 내용은 개인적으로 공부한 내용을 정리하기 위해 작성하였습니다. 혹시 보완해야할 점이나 잘못된 내용있을 경우 메일이나 댓글로 알려주시면 감사하겠습니다.


Model Quantization

Quantization(양자화)란?

Model Quantization(양자화)는 파라미터가 사용하는 비트의 수를 줄여서 연산 효율을 높이는 방법입니다.

딥러닝에서는 숫자를 처리할 때 대부분 FP32(32-bit의 floating point)를 사용합니다. 하지만 만약 정확도를 손실하지 않는 선에서 더 낮은 비트를 사용해 숫자를 표현한다면 연산효율이 증가할 것입니다.

Quantization은 weight값을 FP32가 아닌 FP16(16-bit floating point) 또는 INT8(8-bit integer)로 Bitband를 낮춰서 표현하여 사용하여 모델의 크기를 줄이는 방법입니다.

Quantization의 장점

만약 FP32로 저장된 모델을 FP16 줄이면 메모리 사용량이 절반이 되며(32-bit → 16-bit), INT8로 줄이면 메모리 사용량이 14\frac{1}{4}이 됩니다.

또한 연산시 더 적은 비트를 사용하기 때문에 학습된 모델을 활용해 Inference할 때 동작시간을 단축할 수 있으며 에너지 효율이 증가합니다.

Dally교수님의 교육자료에서 살펴보면
INT8을 활용하면 아래와 같이 add 연산과 multiply 연산에서 에너지와 저장공간 절약을 크게 이뤄낼 수 있습니다.

INT8 Operation에너지 절약 (vs FP32)저장공간 절약 (vs FP32)
Add 연산30배116배
Multiply 연산18.5배27배

최근에는 Tensorflow, MXNet등 대부분의 딥러닝 프레임워크에서 FP16, INT8등의 Quantization을 지원하고 있기 때문에 쉽고 빠르게 사용해 볼 수 있습니다.


Quantization시 주의사항

최근엔 대부분의 딥러닝 프레임워크에서 Quantization을 지원하기 때문에 직접 Quantization을 구현할 일이 없습니다. 하지만 이론적으로 주의해야할 점을 알면 좋을듯 하여 아래 내용을 정리하였습니다.

1) Dynamic Range 와 Precision / Resolution

모델을 Quantization할 때 주의해야 할 것중 하나는 Dynamic range(숫자의 표현 범위)이고, 또 다른 하나는 Precision / Resolution(범위 내에서 얼마나 세밀하게 숫자를 나눠서 표현할 수 있는지) 입니다.

32개의 비트를 사용하는 FP32에서 dynamic range는 ±3.4x1038\pm3.4x10^{38} 입니다. 또 4.2x1094.2x10^{9}개의 숫자를 표현할 수 있습니다.
하지만 INT8에서 dynamic range는 [128127][-128 \dots 127] 이고, 2n2^{n}개의 숫자를 표현할 수 있습니다.

이렇듯 INT8이 FP32보다 적은 수의 숫자를 덜 정밀하게 표현하게 되고, 이는 모델의 성능에 영향을 줍니다.

INT8의 dynamic range를 극복하기 위해 사용하는 방법이 scale factor를 사용하는 것 입니다.

예를들어 FP32모델을 INT8로 모델을 변환한다고 가정해 보겠습니다. Layer의 weight가 모두 -1 ~ 1 사이에 있다면 원래 weight값에 127을 곱하고, weight가 -0.5 ~ 0.5 사이에 있을때는 255를 곱하여 [127127][-127 \dots 127] 사이의 숫자로 표현할 수 있습니다.
만약 weight가 -1270 ~ 1270 사이의 큰 숫자라면, 0.1을 scale factor로 사용하여 [127127][-127 \dots 127] 사이의 숫자로 표현할 수 있습니다.

숫자표현의 정밀도인 resolution을 늘리기 위해서 사용하는 방법은 layer의 weight값중 최대값과 최소값의 중간값이 0으로 오게 전체 값을 이동하는 것 입니다. 이러한 shift는 zero point 라 불리는 interger값을 더하는 것으로 구현할 수 있습니다.

이렇듯 scale factor와 zero point를 사용하면 중간 값을 더욱 정확하고 정밀하게 표현할 수 있습니다. 하지만 scale factor 및 zero point를 저장하기 위한 메모리 공간이 추가로 필요한 단점이 있습니다.

2) Overflows

Convolution 또는 Fully-connected layer는 연산하는 중간에 연산중인 값들을 누적합니다. Quantization을 사용하여 사용하는 비트가 줄어드는 경우 중간값 누적 과정에서 dynamic range를 초과하는 숫자가 발생할 수 있습니다.

n-bit int(n개의 비트를 가진 정수) 끼리의 곱셈의 경우 최대 2n2n개의 비트가 필요합니다. 따라서 overflow를 피하기 위해서는 중간 누적값을 저장하는 공간을 충분한 수의 비트를 사용해야 합니다.

예를들어 Convolution layer의 경우 곱셈연산후 값 누적을 ck2c \cdot k^{2}번 수행합니다. (cc는 채널 수, kk는 커널 크기 입니다.) 따라서 overflow를 피하기 위해서는 2n+log2(ck2)2n+log_{2}(c \cdot k^{2})-bit를 사용해야 합니다.


Quantization 기법들

아래 내용은 Lei Mao님 블로그의 내용 중 Dynamic/Static quantization 부분만 참고하여 정리하였습니다. 이 글에서는 분량이 과도해지는것을 피하기 위해 양자화 연산의 수식적인 정리가 부족한데, Lei Mao님 블로그에 보다 상세한 내용이 정리되어 있으니 더 깊이 공부하실분은 참고해 주시기 바랍니다.

Quantization ModesData RequirementsInference LatencyInference Accuracy Loss
Dynamic QuantizationNo DataUsually FasterSmallest
Static QuantizationUnlabeled DataFastestSmaller
Quantization Aware TrainingLabeled DataFastestSmaller

1) Post-Training Quantization

Dynamic quantization

Dynamic quantization이란 weight는 항상 양자화 하고, activation은 inference할 때 양자화 하는 방법입니다.
따라서 activation은 메모리에 저장될 때 floating-point형태로 저장됩니다.

어떠한 값을 floating에서 integer로 양자화 할 때 값의 범위를 맞추기 위해 weight들의 중간값을 0으로 보정하기 위한 zero-point와 min/max값을 사용하는 비트의 최대숫자에 맞추기 위한 scale factor가 필요합니다.

앞에서 말했듯 Dynamic quantization은 Activation이 Floating-point로 저장됩니다. 따라서 우리는 Inference할 때 activation을 양자화 하기 위한 scale factor와 zero-point(bias)값을 알지 못하고 Inference할 때 마다 scale factor와 zero-point를 동적으로 계산을 해줘야 합니다.

하지만 이러한 Dynamic quantization은 fine-turning이나 calibration을 위한 추가적인 데이터가 불필요하며 정확도 손실이 적은 장점이 있습니다.

Static quantization

Static quantization은 weight와 activation을 모두 양자화 하는 방법입니다.

Static quantization은 Dynamic quantization과 다르게 activation의 scale factor와 zero point를 계산할 필요가 없어 연산이 빠른 장점이 있습니다.

또한 Convolution, Activation, Batch Normalization모두 같은 비트수를 사용하여 숫자를 표현하기 때문에 각 layer를 융합할 수 있습니다. 융합한 layer는 병렬연산이 용이해지기 때문에 연산 효율이 증가합니다.

Static quantization에서 고정된 scale factor와 zero-point는 inference하는 데이터에 잘 맞지 않을 수 있습니다. 따라서 정확도 손실을 최소화 하기위한 calibration(보정) 작업을 수행합니다.

Calibration을 위해서는 Unlabeled Data가 필요합니다. 만약 Unlabeled Data를 사용하지 않는다면, scale factor와 zero point가 부정확해질 것이며(inference할 데이터에 맞게 보정되지 않으며) inference했을 때 feature값이 실제 값과 차이가 발생하여 정확도 손실이 발생할 것 입니다.

2) Quantization Aware Training

앞에서 정리된 방법은 모두 Post-Training Quantization, 즉 학습이 완료된 모델의 양자화 방법에 대해 정리한 내용입니다.

Post-Training Quantization은 32bit를 사용하여 저장한 floating-point형 숫자를 더 낮은 비트를 사용하여 표현하는 방법입니다. 따라서 숫자를 저장할때 정확도 손실이 발생하며, 이 모델로부터 다시 원래 숫자를 복원할 때 양자화 하기 전의 값과 차이가 발생합니다. 이 차이로부터 모델 전체의 성능저하가 발생하게 됩니다.

Quantization Aware Training은 학습 할 때 Inference시 양자화로인한 영향을 미리 모델링 하는 방법입니다.

Post-Training Quantization은 큰 모델을 양자화 할 때 비해 양자화 모델의 성능하락을 최소화 할 수 있는 장점이 있습니다.


참고자료

딥 러닝 모델의 경량화 기술 동향
Learning both Weights and Connections for Efficient Neural Networks
Neural Network Distiller Document
Lei Mao님 블로그
Jinsol Kim님의 블로그
네이버 포스트
jooh95님의 블로그
Pytorch document
Towards Data Science

profile
ML하는 개발자

0개의 댓글