Quantization in Neural Network
신경망에서의 양자화(Quantization)에 대해 알아보도록 하겠습니다.
Reference
- Compressing Deep Convolutional Networks using Vector Quantization(관련 링크)
- Quantization Networks(관련 링크)
- Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference(관련 링크)
- Integer Quantization for Deep Learning Inference: Principles and Empirical Evaluation(관련 링크)
- 관련 블로그 1
- 관련 블로그 2
- 관련 블로그 3
Background
좋은 정확도를 보이며 제시되는 딥러닝 모델들은 점차 그 크기가 커지고 있습니다. 이러한 모델의 학습과 추론을 위해서는 고성능의 GPU가 주로 사용됩니다.
하지만 우리 주변에서 실제 머신러닝을 응용할 때 항상 고성능의 GPU 사용을 기대하기는 어렵습니다. 예를 들면 고성능의 GPU에서 높은 정확도와 빠른 속도를 내는 모델을 일반 공장 제조단계에서 사용하기에는 비용적인 부담이 크겠죠. 이렇게 무거운 모델들은 높은 성능을 보임에도 실용성 측면에서는 아쉬움이 있습니다.
즉, 실제 많은 딥러닝 모델들은 모바일, 임베디드 플랫폼과 같이 메모리나 CPU 성능에 제약이 존재하는, resource-constraint environment에서 사용이 어렵다는 문제가 있습니다.
양자화(quantization)은 model compression 기법 중 하나며 이 model compression은 모델의 경량화를 통해 모바일, 임베디드 플랫폼과 같은 엣지 디바이스에서 딥러닝 모델을 사용할 수 있게 하는 테크닉입니다. 기타 모델 경량화 방법으로는 효율적인 모델 아키텍처 설계, 모델 아키텍처와 하드웨어의 co-design, pruning, knowledge distilation 등 다양한 방법이 있습니다.
What is Quantization?
우리가 일반적으로 알고있는 신경망 모델을 간단하게 표현하면 weight, bias, activation function 이렇게 구성되어있습니다. 그리고 모델의 성능을 높이기 위해 주로 32bit float로 표현됩니다.
하나의 모델은 수많은 weight, bias, activation function들로 이뤄져 있기에 결국 용량이 커집니다. 예를 들어 ResNet-50의 경우 26M 개의 weights와 16M 개의 activations로 구성되는데 32bit float를 사용하는 경우 168MB의 메모리를 요구합니다.
Quantization은 용량이 큰 32bit 대신 16bit float, 8bit int 타입을 사용해 모델의 크기를 줄이는 방법입니다. 8bit로 변환한다고 해도 러프하게 가정하면 약 4X 만큼 줄어듭니다.
이렇게 quantization을 통해 모델의 크기를 줄이고, 계산 복잡도를 낮추고, 메모리 latency를 줄이고, 또 전력 소모량까지 줄일 수 있습니다. 이렇게 모델을 압축해서 다양한 플랫폼에서 사용이 가능하게 하는 겁니다.
다만 quantization은 학습 단계에서는 적용하지 않고 inference 단계에서만 적용합니다.
Quantization Mapping
32bit float로 표현된 수를 8bit 정수로 변환하기 위해서는 값에 대한 변환이 필요합니다. 이를 quantization mapping이라고 합니다.
위 그림은 quantization mapping을 나타내는 예시입니다.
아래 수식들을 통해 과정을 살펴보도록 하겠습니다.
$$ x \in [\alpha , \beta ] \rightarrow x_q \in [\alpha _q, \beta _q] $$
양자화를 통해 \( x \in [\alpha, \beta] \) 의 실수 영역에 포함된 x를 b-bit 영역의 \( x_q \) 로 매핑하겠습니다.
양자화 방법은 아래 수식과 같으며 뒤에서 다시 설명하겠지만 c는 scale을 의미하며 d는 zero point를 의미합니다.
$$ x_q = round(\frac{1}{c}x-d) $$
앞서 \([\alpha , \beta ] \rightarrow [\alpha_q, \beta _q]\) 매핑을 \(alpha \rightarrow \alpha_q\), \(beta \rightarrow \beta _q\) 로 나눠서 풀면 아래와 같이 표현이 가능합니다.
$$ \alpha_q = \frac{1}{c}\alpha -d $$
$$ \beta_q = \frac{1}{c}\beta -d $$
연립하면 아래와 같이 다시 정리해 c와 d를 각각 구할 수 있습니다.
$$ c = \frac{\beta -\alpha }{\beta_q - \alpha_q} $$
$$ d = \frac{\alpha \beta_q - \beta \alpha_q}{\beta -\alpha } $$
실제 양자화를 적용할 때는 양자화 이후 실수 0이 error 없이 표현될 수 있도록 적용합니다.
$$ x_q = round(\frac{1}{c}x-d) $$
$$ = round(-d) $$
$$ = -round(d) $$
$$ = -d $$
여기서 \( round(d) = d \) 가 성립하는 이유로는 앞서 양자화 이후 실수 0이 error 없이 표현되기 때문입니다.