edgde device에는 gpu가 없는 경우가 많다. cpu는 int8
을 활용하는데 cpu에 모델을 실으려면 모델이 가진 자료형을 조작해야 한다. 이 과정을 quantization
이라고 한다. 세상에 없던 기술이 뿅하고 나온 것은 아니고 이미지를 압축하는 원리를 가져와서 응용했다.
전통적으로 범위가 인 를 quantization
하는 공식은 이렇다.
는 입력값, 는 우리가 찾아야 하는 변수다. quantization
을 하고나면 의 범위는 로 정해진다. 이렇게 압축을 해놨으면 푸는 일도 있을 텐데 dequantization
이라고 부른다. 방법은 아래와 같다.
여기까지 왔으면 우리는 와 , 와 의 관계를 구할 수 있다.
이제 방정식 2개가 나왔으므로 우리는 변수 와 를 연립방정식으로 풀 수 있게 됐다.
이 점을 기본으로 깔고 quantization
을 다시 보면 좋을 것 같다.
Konwledge Distillation은 teacher model을 통해 student model의 학습에 영향을 미치는 반면 Quantization은 모델의 weight에 직접적으로 손을 댄다. wieght를 uint8
으로 바꾸는 방법은 아래와 같다.
는 quantize해야 할 target, 는 각각 step size, center, bit-width에 해당한다. 이걸 하나씩 차근차근 살펴보면 앞으로 quantization 연구를 읽을 때 수월하지 않나 싶다.
이건 쉽게 말해 precision이다. 일반적으로 weight를 구성하고 있는 자료형은 float32
다. int32
도 을 범위로 하는 정수값을 가지는데 실수라면 정수 사이사이를 채워야 하는만큼 메모리 공간도 많이 차지하고 연산비용도 크다. model의 크기를 줄이고 연산 속도를 높이려고 모델의 bit-width을 16 bit나, 8 bit 좀더 공격적으로는 4 bit로 낮추려고 시도한다.
정수는 어떤 수를 다른 수와 구분하는 간격이 1이다. 실수라고 하더라도 컴퓨터가 어떤 두 수를 구분하는 간격이 있는데 이 간격을 step size라고 부른다. quantization 연구에서 이 부분을 명확하게 설명하지 않아서 답답했다. 앞에서 살펴본 방법을 써도 되지만 cpu제조사에서 사용하는 알고리즘을 활용하는 추세인 것 같다.
uint8
으로 바꾸면 범위는 로 정해지는데 이 때는 크게 걱정안 해도 된다. int8
으로 바꾸면 범위가 이므로 중간값을 좀 생각해야 한다. weight의 분포를 따라갈 건지, 아니면 강제로 중간 값을 0으로 고정할 건지 정해야 하고 전자를 asymetric, 후자를 symetric이라고 부른다. weight의 분포를 따라가는게 일반적으로 더 좋은 성능을 가진다.
weight의 범위를 조절하고 나서도 element를 보면 이런 식으로 decimal이 남는데 로 한 번 정리하고 bit width에 들지 않는 범위에 있는 수는 으로 보정해준다. RoI pooling에서 그랬듯이 와 을 거치고 나면 원본 wieght와는 차이가 날 수밖에 없는데 이 차이를 최대한 줄이는 알고리즘이 좋은 성능을 낸다.
전체적인 과정은 여기를 참고하면 된다.
이제 기본은 뗐다. 이후에 할 수 있는 이야기는 에서 더 좋은 는 어떻게 찾을 건지, outlier는 어떻게 처리할 건지, quantization은 channel별로 따로 진행할 건지, quantization이 끝나고 시뮬레이션은 어떻게 할 건지, 학습 후에 quantization을 할 건지(Post Training Quantization), 아니면 quantization을 하고 학습을 할 건지(Quantization Aware Trainig) 같은 게 있다.