경량화에 대한 논문 찾아보다가 ICLR 2022에서 구두 페이퍼로 발표되었길래 읽어보았다. open review 가서 리뷰 코멘트들을 읽어보면 모든 리뷰어가 좋게 평가한 것은 아니고 한 리뷰어가 슈퍼 극찬을 해서 구두로 올려준것 같다(이게 되네??).

 

Introduction

사실 인트로의 경우는 특별한 내용이 있기 어려운 것같다, 대충 요약하면 이렇다.

대부분의 딥러닝 모델들은 실시간 추론이나 메모리 효율, 하드웨어 친숙성(부동소수점 연산이 불가한 환경) 등을 요구하는 분야에 적용되기에는 너무 무겁고 활용도가 제한적이다. 양자화 관련 연구들은 기존의 32bit 부동소수점으로 표현되는 모델들을 다양한 형태로 양자화함으로써 이러한 문제를 해결하고자 한다. 그러나 quantization error로 인한 성능의 저하는 피할 수 없기 때문에, 이를 해결하고자 한다. 강조하지만, 이 논문은 모든 연산이 8 bit 고정소수점으로 이루어진다. 심지어 더 정확하게.?!  

 

Contibution

컨트리뷰션은 세 가지인데, 결국은 8bit 고정소수점으로 양자화한다는 얘기고, 그걸위해서 뒷받침하는 논리나 적용하는 방법도 설명했다.

글의 구성은 전형적이면서도, 잘쓴거같다. 리뷰어들이 글은 잘썼다고 해서 얇은 귀가 동했는지도 모르겠다.

 

1) 여러 가지 실험을 통해 고정소수점만으로도 적은 오차로 기존의 부동소수점 형태의 숫자들을 양자화 할 수 있음을 증명.
2) 양자화 대상 값들의 통계적 특성에 따라서 최적의 고정소수점 포맷은 다르고 최적의 포맷은 간단히 구할 수 있음을 증명.
3) 고정소수점을 학습 과정에 적용하는 부분에 대한 기술적 방법 제안함. (기존 활성화 함수를 양자화하는 방법(PACT)과 결합, residual block과 같은 구조에도 학습할 수 있는 방법 등)

 

Details

3,4 챕터는 각각 뒷받침 논리와 적용 방법으로 세부적인 내용은 다르긴 하지만 결국 컨트리뷰션에 언급한 내용이고, 쭈욱 따라가기에 흐름이 좋은거 같아서 그냥 한꺼번에 묶어서 정리했다. 

 

1)고정소수점만으로도 적은 오차로 기존의 부동소수점 형태의 숫자들을 양자화 할 수 있다

시작 포인트는 8bit 고정소수점으로도 충분히 32비트 부동소수점 형식의 가중치들을 표현 가능한가? 이다. 얘기하고자하는 바가 8bit 고정소수점으로도 성능이 크게 떨어지지 않는 quantization가 가능하다는 것이라고 한다면, 어찌보면 가장  근원적인 질문이지 않을까?  

weight 값들을 8bit 고정소수점으로 표현했을 때 얼마만큼 정확하게 기존의 값들을 표현할 수 있는 지 알아보기 위해서, 정규 분포(평균은 0으로 고정)를 가지는 값들을 여러가지 고정소수점 형식으로 변환했을 때 발생되는 상대 오차를 구한 그림이다. (Central-Limit Theorem에 의해서 weight들의 분포는 가우시안)

상대 오차가 1에 가까운 값이 되는 것은 해당 범위의 숫자를 제대로 표현할 수 없다는 것(Underflow/Overflow)이기에 제외한다고 해도 각 형식마다 다르긴하지만 어느 정도 범위안에서는 낮은 오차로 표현가능 한걸 알 수 있다.

정리하면 첫째, 다른 포맷을 가진 고정소숫점 숫자는 각기 다른 최적 표현 범위, 최소오차 최적의 표준편차를 가진다. 둘째, 큰 fractional length를 가질 수록 작은 숫자를 표현하는 데 유리하고 작은 fractional length를 가질수록 큰 숫자를 표현하는데 유리함을 증명함.

결과적으로, 각기 다른 분산을 가지고 있는 가중치 값들이라도 8-bit 고정소수점으로도 낮은 오차범위 안에서 충분히 표현 가능함.

 

2) 양자화 대상 값들의 통계적 특성에 따라서 최적의 고정소수점 포맷은 다르고 최적의 포맷은 간단히 구할 수 있다.

이 문제는 결국 두가지 질문으로 나눠 질수 있다. 첫째, 최적의 FL이 선택된다고 하면 어느 정도의 범위 안에  있는 숫자들이 낮은 오차를 가지고 양자화가 될 수 있는가? 만약 그렇다면 둘째, 최적의 FL 값이 손쉽게 구해질 수 있는가?  이 질문들에 대한 해답은 실험으로 해결했다. 

그림에서 보면, Signed 8-bit 숫자의 경우 시그마 값이 0.1부터 100 에 조금 못 미치는 숫자까지는 굉장히 작은 에러를 통해 표현할 수 있는 것을 확인 할 수 있다(논문에는 unsigned의 경우에 대해서도 그림이 삽입되어 있음). 이러한 결과를 토대로 최적의 FL과 표준편차와의 관계를 모델링 하면 우측 그림과 같이 표현될 수 있다. 결과적으로, 고정소수점을 통해 양자화 하더라도 일정 범위 안에서는 굉장히 작은 오차를 가지고 변환가능하기 때문에 성능도 손실을 최소화하면서 양자화가 가능하고, 최적의 포맷도 간단히 구할 수 있다.

 

3) 고정소수점을 학습 과정에 적용하는 부분에 대한 기술적 방법
8 bit 고정소수점이 충분히 의미있는 표현이라고 한다면, 세번째 컨트리뷰션은 이를 어떻게 적용할 수 있는가에 대한 얘기이다. 대략 세 가지정도의 테크니컬한 이야기를 진행한다.

 

첫째는 Batch Normalization에 quantization 적용이다. Batch Normalization 과정에서 계속해서 업데이트 되는 값들(µ, σ)이 존재하는데, 이 것을 단순 quantization 을 적용하면 정확도 측면에서 손실이 있다(기존 연구에서 그런듯함).  우선 quantization 과정없이 feed-forward를 우선 진행하여 배치 정규화의 파라미터들을 모두 업데이트 해주고 난 뒤, 해당 파라미터들을 기반으로 quantization을 진행하고 다시 한번 feed-forwad 과정을 진행하고, back-propagation을 진행한다. (학습 후 정해진 고정소수점 포맷은 추론 과정에서는 변하지 않습니다)

 

둘째는 Activation function을 quantization 하는 방법에 대한 내용이다. weight 값은 quantization이 되더라도 학습 과정에서  quantization error가 보정이 될 여지가 있다. 그러나, activation function 에는 학습 가능한 파라미터가 없기 때문에, 학습을 통해 보상되는 과정이 없다. 게다가, 가장 많이쓰이는 활성화 함수인  ReLU는 결과값의 범위가 정해지지 않아서, quantization을 진행하기 어렵다. 이러한 문제를 극복하기 위해서 제안된게 PACT인데, PACT 논문에서는 ReLU 값의 범위를 제한하는 파라미터(α)를 도입하여, activation function quantization에 활용하였다. α가 학습 가능하도록 고안하여, α가 back propagation을 통해 적절하게 activation function의 결과값의 범위를 정할 수 있도록 해주어 quantization error가 감소하는 효과를 얻을 수 있다. 이 논문에서는 기존의 수식에 있는 scale factor 를 고정소수점 포맷에 관한 수식으로 정리하였다. 고정소수점 포맷도 두 번째 컨트리뷰션에 나와있듯 weight들의 분산으로 정해지기 때문에, 깔끔하게 구할수 있을듯 하다. 학습 과정에서 업데이트 되는 파라미터(α)가 존재하기때문에 batch normalization과 비슷하게 quantization을 진행한다.

셋째는 여러 개의 하위 레이어를 가지는 경우 quantization 적용이다. 각 레이어는 각 레이어에 최적화된 α값과 고정소수점 형식을 가지고 있다. 따라서, 연속된 레이어에서 앞선 레이어의 결과는 뒤따라오는 레이어의 고정소수점 형식으로 변환되어야 한다. 해당 연산이 부동 소수점 연산이기 때문에, 논문에서는 해당 과정을 앞선레이어 마지막 quantization 과정에 포함하여 이뤄 질 수 있도록 수식적으로 정리하였다. 이 때문에,  앞선 레이어의 결과를 계산하는데에 뒤따라오는 레이어에 관련된 파라미터들이 필요하게됨.

일반적으로 레이어가 하나하나씩 순차적으로 구성되어있으면 문제가 없겠지만,  그림과 같이 여러 개의 하위 레이어를 가지고 있는 경우에는 학습을 진행하면서 문제가 생길 수 있다. 자세히 기술되어 있지는 않지만, 학습 과정에서 일관성없는 값(각기 다른 하위 레이어 파라미터)들에 의해 상위 레이어의 학습이 잘 이루어지지 않는 문제가 있을 것 같다. 동일한 상위 레이어를 가지고 있는 경우에는 하나의 레이어를 마스터 레이어로 지정하여 해당 레이어의  파라미터를 동일한 레벨의 하위 레이어들이 공유함으로써 해결 했다. 그러나, 모든 파라미터를 공유할 경우 각 레이어의 값들을 표현하기에 적절한 비트 수가 차이가 날 때, 성능이 크게 하락한다고 한다. 아마, 다른 포맷으로 quantization이 진행되어서 underflow, overflow가 날 수 있을 거 같다. 결과적으론, α 값만 공유하도록 하였다. 실제로 α값을 제외하면 2의 자승 꼴을 가진 값들이기 때문에 약간의 비트 시프트 정도의 영향 밖에 없다고 하는데, 명확히 와닿지는 않는다. 

 

Experiments

그림은 미리 학습된 MobileNet V2의 각 레이어의 가중치 값의 분포와 , 제안하는 방법이 적용했을 때 선택된 FL을 나타낸다. weight 값들은 레이어마다 굉장히 다르지만 0.1 ~ 부터 4까지 다양한 값들을 가지고 있다. 논문에 제안된 방법을 적용할 경우 대부분 6,7,8,이긴 하지만 다양한 FL 표현이 될 수 있는 것을 볼 수 있다. 아마 리뷰 내용 중에 weight가 가지는 값의 범위가 거의 정해져있으니 대충  6,7,8로 선택지를 줄여서 하면 되지 않느냐는 기조의 질문도 있었던 거 같은데, 저자들이 실제로 해보니 그러면 성능 드랍이 꽤 컸다고 한다. 

이외에, 다양한 네트워크 구조에 대하여 진행한 실험 결과를 보면, 성능이 거의 감소하지 않거나 오히려 오르기도 한다.(타겟 : 이미지넷 데이터 분류)결과적으로, 이 방법은 각 레이어와 activation function에 최적화된 quantization으로 오리지널 부동소수점 표현 값과 유사한 값으로 표현을 가능하게 해서 이러한 결과를 얻어낸 것 같다. 성능이 오른건 좀 신기하긴 하다.

Wrap-up

논문 읽으며 좀 살펴보니 quantization awrae training 같은 경우에는 성능이 크게 저하되지 않는 수준까지 온 것 같다. 

다소 아쉬운 점은, 아마도 저자가 강조하고 싶었던 부분이  '기존의 방법보다 정확한 표현을 통해 성능 저하를 막을 수 있다' 와 같은 기조이기 때문이겠지만, 추론 속도와 같은 실험 결과가 없는 것이다. 대부분의 리뷰어들도 이러한 부분을 지적했던거 같다. 코멘트에 대한 답변을 살펴보면, 단일 레이어에 대해서 실험했을 때 약 6~12(%) 정도의 향상이 있다고는 하지만 전체 레이어에 적용했을 때는 따로 언급이 없었다. 인트로에서는 부동소수점 연산이 불가능한 하드웨어에 대한 얘기를 두어번씩 하며 강조하더니, 그런 하드웨어에서 실험도 해주었으면 얼마나 좋았을까 싶다. 논문의 코드는 깃허브에 공개되었기 때문에, 적용하여 추론속도나 메모리에 대한 영향을 확인해 볼 수는 있을 것 같다.

+ Recent posts