목차

Intro

머신러닝 모델 경량화는 다양한 edge 디바이스 위에서 추론 모델을 빠르게 동작시키기 위한 기술입니다. 지난 뉴스레터에서는 노타가 활용하는 여러 경량화 기법 중 하나인 pruning을 소개드렸습니다. 이번 뉴스레터에서는 또다른 경량화 기법인 양자화(quantization)를 소개드리겠습니다.

Number Representations in Computer Systems

많은 수학 공식에서는 정수와 소수를 합친 형태로 숫자가 구성되어 있습니다. 수학에서는 이러한 숫자를 실수(real)라고 부르며 여러 실수의 예는 다음과 같습니다.

$$ 3.14159265... = \pi \\
2.71828... = e \\ 0.001 $$

인간이 사용하는 숫자와 컴퓨터가 이해할 수 있는 숫자는 그 표현 형식이 다르기 때문에, 인간이 사용하는 실수 표현을 컴퓨터가 메모리에 저장하고 처리하기 위해서는 미리 정해진 규약을 따라 그 표현을 바꾸어 줄 필요가 있습니다. 이러한 변환 과정, 즉 연속적(continuous)이고 무한(infinite)한 범위에 있는 실수값들을 분리(discrete)되어 있고 유한(finite)한 값들로 변환하는 과정을 양자화(quantization)라고 합니다. 컴퓨터에서 사용하는 실수 표현으로는 IEEE 754 규약에 따른 부동소수점 방식이 널리 사용되는데, 이 방식은 1980년대 이후에 만들어진 거의 모든 컴퓨터에 공통적으로 반영되어 있습니다. 이렇게 미리 정의된 규약을 채용함으로써, 컴퓨터는 다양한 종류의 숫자 표현을 빠르게 처리할 수 있게 됩니다.

IEEE 754 32bit 부동소수점 표현 방식 (source: https://wikipedia.org/wiki/Single-precision_floating-point_format)

IEEE 754 32bit 부동소수점 표현 방식 (source: https://wikipedia.org/wiki/Single-precision_floating-point_format)

컴퓨터의 실수 표현 방식은 여러가지가 있는데 소수점의 이동 가능 유무에 따라 크게 부동소수점 (floating-point)과 고정소수점(fixed-point) 표현 방식으로 구분할 수 있습니다. 부동소수점 표현은 사람이 인식하는 숫자 형태에 더 가깝기 때문에 사용하기 편리하며, 고정소수점 방식보다 더 넓은 범위의 실수를 표현할 수 있다는 장점이 있습니다. 그러나 부동소수점 표현을 처리하기 위해서는 복잡한 계산을 수행할 수 있는 하드웨어가 필요하며, 고정소수점 연산보다 속도가 느리고 전력을 많이 소비하는 단점이 있습니다. 따라서 연산 속도를 더 빠르게 하거나 전력 소비를 낮춰야 할 필요가 있을 때는 고정소수점 방식을 사용합니다. 고정소수점 방식은 단순한 하드웨어로도 처리가 가능하기 때문에 처리 속도가 빠르고 전력을 덜 소비한다는 장점이 있습니다. 동시에 부동소수점 형태에 비해 표현 가능한 숫자의 범위가 좁고 정밀도가 제한적이기 때문에 정확도가 떨어질 수 있으며, 사용에 주의가 필요합니다.

이렇게 컴퓨터에서 사용하는 숫자 표현 방식은 크게 부동소수점 방식과 고정소수점 방식 두가지로 나누어 볼 수 있으며 각각의 장단점이 뚜렷하기 때문에, 목적에 따라 선택적으로 사용하는 것이 중요합니다.

Reduced Precision in Deep Learning

앞 절에서는 컴퓨터의 실수 표현 두 가지를 알아보았습니다. 딥 뉴럴 네트워크(Deep Neural Network, DNN) 역시 상당한 분량의 실수 연산을 기반으로 하는 알고리즘이기 때문에 컴퓨터에서 신경망 알고리즘을 수행하기 위해서는 이러한 숫자 표현 과정을 주의깊게 살펴보아야 합니다.

딥러닝 연산이 기본적으로 사용하는 숫자 형식은 IEEE 754 32bit 부동소수점 방식(FP32)입니다. FP32 방식은 실수를 잘 표현하는 일반적인 방식이므로 정확도를 최대한으로 이끌어낼 수 있습니다. 그러나 FP32를 지원하는 하드웨어는 연산 속도가 늦고 전력 소비가 크기 때문에 핸드폰과 같이 계산 자원이 충분하지 않은 환경에서는 기존의 부동소수점 방식으로 동작하는 것이 불리한 면이 있습니다. 따라서 대량의 부동소수점 연산을 고정소수점 형태로 바꾸어 빠르고 가볍게 동작하도록 하는 방법들이 많이 연구되어 왔고, 고정소수점 연산 중에서도 연산에 사용되는 bit 갯수를 줄이거나 고정소수점 표현 형식을 다양화 하는 등의 연구들이 진행되어 왔습니다. 일반적인 quantization이 연속적이고 무한한 값을 분리된 유한한 값으로 변환하는 것과는 달리, 딥러닝에서의 quantization은 FP32를 고정소수점 형태로 바꾸거나 더 낮은 bit 를 사용하는 기능을 의미합니다. 또한 고정소수점 형식은 빠른 속도를 보장하지만 정확도가 떨어질 수 있는 단점이 있기 때문에 부동소수점을 사용했을 때의 높은 정확도는 최대한 그대로 유지하면서 실행 속도를 빠르게 하는 것이 딥러닝 quantization의 목표입니다.

quantization (부동소수점→고정소수점) 과정 (source: https://nervanasystems.github.io/distiller/algo_quantization.html)

quantization (부동소수점→고정소수점) 과정 (source: https://nervanasystems.github.io/distiller/algo_quantization.html)

위와 같은 목표를 달성하기 위해 quantization 분야의 다양한 연구가 수행되었습니다. 딥 뉴럴 네트워크는 파라미터(weight)들과 네트워크 내부에서 연쇄적으로 계산되는 활성값(activation)으로 구성되어 있는데, 파라미터와 활성값은 서로 다른 특징을 가지고 있기 때문에 각각에 적용되는 quantization 방법은 문제에 접근하는 관점이 서로 다르며 네트워크 값의 특징을 최대한 활용하면서도 정확도를 떨어뜨리지 않는 방향으로 연구가 진행되고 있습니다.

딥러닝 계산은 크게 학습(training)과 추론(inference), 두 과정으로 구분해 볼 수 있습니다. 우리가 학교에서 여러 지식을 배우는 것처럼 딥 뉴럴 네트워크도 데이터를 통해 훈련하는 과정이 첫째로 필요하며, 이것을 다른 말로 학습 이라고 합니다. 이렇게 학습한 지식을 실제 상황에서 활용할 수 있도록 새로운 데이터에 대한 판단 결과를 도출하는 것이 추론 과정입니다. 딥 뉴럴 네트워크가 학습을 수행하는지 추론을 수행하는지에 따라 또 여러 종류의 quantization기법을 사용하게 되며, 학습 과정에 quantization을 적용할 수 있는지의 여부에 따라 구체적인 알고리즘과 계산 결과가 크게 달라지게 됩니다. 학습 과정에서 data 를 사용해 학습과 quantization을 동시에 진행하는 것을 양자화 인식 훈련 (quantization-aware training)이라 하며, 학습이 이미 끝난 네트워크에 대해 데이터 없이 또는 데이터를 조금만 사용하여 quantization을 진행하는 것을 학습 후 양자화(post-training quantization)라고 합니다.

Quantization Research in Nota