텐서플로우에서의 양자화 (Quantize) 시키는 방법

[이글은 https://www.tensorflow.org/performance/quantization 의 내용을 한글로 번역/의역한 내용입니다. 주관적 의견이 첨가되었으니 잘못된 해석이 있다면 지적하여 주시면 감사하겠습니다.]


뉴럴넷 이 처음 개발되었을때, 가장 큰 이슈는 어떻게든 동작하게 하는 것이여서, training  정확도와 속도는 뒷전이였다. 그래서 그 당시, 뉴럴넷을 training 시킬 때, 정확도와 속도는 그리 좋지 않았었다.

정확도를 유지하기 위한 가장 쉬운 방법은 소숫점 (floating point) 연산을 사용하는 것이였고, GPU 를 통해 그런 연산들의 속도를 가속화하기만 하여서, 다른 numerical format 을 사용하는 것에는 큰 관심이 없는건 어찌보면 당연하였다.

하지만 요즘에는 상용모델 (GPU가 없는 스마트폰, IoT 기기) 들에 적용되는 다양한 뉴럴넷 모델들이 실재한다. 그러면, 그런 뉴럴넷 training 을 위한 연산 요구량은 연구자들의 숫자에 비례하여 증가하고, 실제 추론을 위해 필요한 뉴럴넷 연산은 사용자에 비례하여 증가하게 된다. 즉, 매우 많은 연산량을 요구하는 뉴럴넷을 최근의 상용 기기들에 기존의 추론 방식을 사용한다면, 그 효율은 매우 나쁠 것이고 이런 연산량을 경감 시키기 위한 노력이 필요하게 되었다.

이게 Quantization 이 필요한 이유이다. 

좀더 자세히 말하면, Quantization 은 32 bit 소숫점 보다 좀더 compact 하게 저장하고 연산하기 위한 뭔가 다른 방법들을 포괄하는 개념이다. 그런 이유로, 우리는 8 bit fixed point 에 집중하여 detail 들을 살펴보고자 한다.

그러면, 왜 Quantization 이 동작하는가..

뉴럴넷을 training 시킨다는 것은 weight 들에 많은 조그마한 변이들을 적용함으로 이루어지는 것이고, 이런 조그마한 변이들은 보통 동작되기 위해서는 소숫점의 정확도를 요구하기 마련이다.

미리 훈련된 모델을 사용하여 실제 추론을 하는 것은 그 둘의 환경이 매우 다를수 있기 때문에 보통 잘 동작 안될 수 있다. 하지만, 딥뉴럴넷의 마법같은 장점 중에 하나는 그들의 입력들에 높은 수준의 Noise (training 과 실제 추론시 환경 차이점들 중 무의미한 것들) 에도 매우 잘 대처하는 경향이 있다는 것이다.

만약 당신이 방금 찍었던 사진들의 object 를 인식하려 한다면, 뉴럴넷은 모든 CCD 잡음, 조광 변화, 이전에 봐왔던 training 예제들과 현재의 object 사이의 불필요한 차이점들을 무시하고, 대신에 중요한 유사성들에 집중해야 할 것이다.

다시 말해, 이런 능력들은 noise 와 같은 source 들에는 낮은 정확도 연산을 적용하여
적은 정보를 가지고도 여전히 정확한 결과들을 생산해 내는 것을 의미한다.

왜 양자화 인가?

뉴럴넷 모델들은 많은 메모리를 차지한다. 예를 들면, original AlexNet 은 200MB 넘게 요구한다. 단 하나의 모델에서도 수백만 뉴럴넷 연결이 존재하기 때문에, 그 커다란 뉴럴넷 크기의 대부분은 그런 weight 들 로 채워진다. 게다가, 그들 모두는 조금씩 다른 소숫점 숫자들이기 때문에, zip 과 같은 간단한 압축 형태로는 전혀 그것들을 압축할 수 없다. 그것들은 커다란 각 계층 안에서 정규분포를 가지면서 배열, 분포된다.

Quantization 을 사용해야 하는 가장 간단한의 이유는, 각 계층의 최소/최대 값을 저장하고 각각의 소수 값을 일정 범위 안에서 256 개 의 선형 집합 안에 가장 가까운 실수를 나타내는 8-bit 정수로 압축함으로서, 파일 크기들을 줄일 수 있다는 것이다. 예를 들면, -3.0 부터 6.0 까지의 범위에 걸쳐 있다면, 0 는 -3.0을 나타내고, 255 는 6.0 을 나타내며 128 은 1.5를 나타내게 된다.

이 방식을 사용한다면, 약 75%의 메모리 감소 효과를 볼 수 있다.

Quantization 사용해야 하는 또다른 이유는 8 bit 입/출력을 가진 뉴럴넷을 실행시킴으로서, 추론 계산을 하는데 필요한 연산 자원을 아낄 수 있다는 것이다.

8 bit 값을 사용하는 데에는 소숫점 메모리 요구량의 단 25% 만을 사용하면되므로, 더 나은 캐쉬 사용과 RAM 접근에 있어 병목현상을 피할수 도 있고, 가용 DSP 칩도 더 확보할 수 있다.

이런 Quanitization 에 기반한 소숫점 연산은 특히 IoT Embedded System 들에게 유용하게 사용될 수 있을 것이다.

그럼, Lower Precision 을 Train 시킬 때에도 쓰지를 않는가 ?

적은 bit 수 로 뉴럴넷을 training 시키는 실험을 해봤는데, 아쉽게도 back propagation 과 gradient 를 다루는 데에는 8-bit 보다 더 많은 bit 수를 요구했었다. 이런 결과들은 training 을 좀 더 복잡한 구현을 하게 만들긴 하지만, 추론이 효과적으로 실행될 수 있게 한다.

그러면, 어떻게 뉴럴넷을 Quantize 시킬 수 있겠는가 ?

텐서플로우는 내재된 8 bit 연산에 대해서 상품 수준의 지원을 하고 있다. 즉, 소숫점에서 train 되는 추론 모델들을 Quantize 연산을 통한 동일한 Graph 로의 변환 과정을 갖는다. 예를 들면, GoogLeNet 모델을 8-bit 연산을 사용하면 91MB 에서 23MB 로 줄일 수 있다.


그럼, 텐서플로우에서 제공하는 Quantize 관련 함수를 알아보자.

[1] tf.quantize


Arguments :


- input
  + float32 타입의 입력 Tensor
  + 소숫점 타입의 'input' tensor 를 'T' 타입의 'output' 으로 Quantize 수행

- [min_range, max_range] : 최소/최대 값을 통해 'input' data 의 소숫점 범위 표시
  + min_range : float32 타입의 Tensor. Quantize 연산을 위한 최소값
  + max_range : float32 타입의 Tensor. Quantize 연산을 위한 최대값

- T
  + Quantization 수행 타입 : tf.DType
  + tf.qint8, tf.quint8, tf.qint32, tf.qint16, tf.quint16 중에 하나

- mode (수행될 양자화 연산)
  + 입력 소숫점 값 에서 Quantized 값으로 변환시, 어떤 연산으로 맵핑될지 기술
  + 다음 중 하나의 string 타입으로 입력
     = MIN_COMBINED : (Default 값)
     = MIN_FIRST :
     = SCALED :


만약, 위 mode = 'MIN_COMBINED' 로 입력 시, 다음의 연산데로 TENSOR 값이 입력된다.


out[i] = (in[i] - min_range) * range(T) / (max_range - min_range) if T == qint8, out[i] -= (range(T) + 1) / 2.0
out[i] = (in[i] - min_range) * range(T) / (max_range - min_range) if T == qint8, out[i] -= (range(T) + 1) / 2.0
만약, 위 mode = 'MIN_FIRST' 로 입력 시, 다음의 연산데로 TENSOR 값이 입력된다.



만약, 위 mode = 'SCALED' 로 입력 시, output 타입의 전체 범위를 쓰지 않고 Symmetric 하게 숫자를 선택.
예를 들면, 8 bit quantization 을 수행한다면 -128 ~ 127 이 아니라, -127 ~ 127 로 함.


- round_mode : 소숫점 값들을 quantized 값으로 근사화 시, 어떤 연산을 사용할지 기술





- round_mode : 다음 중 하나의 string 타입으로 입력
   + HALF_AWAY_FROM_ZERO : (Default)
   + HALF_TO_EVEN :

- name : 동작을 위한 이름 (없어도 됨)

Returns :

- Tensor 객체들의 tuple 로서 다음의 세가지 리턴

- output : type T 의 tensor
- output_min : float32 타입의 tensor
- output_max : float32 타입의 tensor




댓글

  1. Harrah's Philadelphia Casino to begin gradual reopening
    Harrah's 천안 출장안마 Philadelphia 제천 출장마사지 Casino in Philadelphia is 창원 출장샵 to begin 경상남도 출장마사지 gradual reopening on July 오산 출장마사지 3, 2020, Harrah's Philadelphia Casino Philadelphia announced today.

    답글삭제

댓글 쓰기

이 블로그의 인기 게시물

INQ (Incremental Network Quantization)