The Beautiful Future

gemmlowp 본문

DNN/Quantization

gemmlowp

Small Octopus 2020. 8. 24. 21:03

https://github.com/google/gemmlowp/blob/master/doc/quantization.md

 

google/gemmlowp

Low-precision matrix multiplication. Contribute to google/gemmlowp development by creating an account on GitHub.

github.com

Overview

gemmlowp 은 내부적으로 32bit accumulator을 사용하고 최종으로는 8bit 출력을 내보낸다.

 

Quantization as an affine map

$$ real value = A * quantized value + B $$

$$ real value = C * (quantized value + D) $$

 

Domain-specific constraint: the real value 0 must be exactly representable.

퀀타이제이션 텐서에 컨볼루션, 폴링 같은 연산이 수행될때 정확히 0이 표현되면 연산 오차도 없고 

같은 0을 나타내는 값으로 패딩해서 사용하면 된다.

 

The final form of the quantization equation

r: real value, R > r

q: quantized value, Q > q

q_min = min(Q),  q_max = max(Q)

q_range = q_max - q_min

r_min = min(R), r_max = max(R)

r_range = r_max - r_min

r = (q - q_min)*(r_range/q_range) + r_min = q*(r_range/q_range) - q_min*(r_range/q_range) + r_min

q = (r - r_min)*(q_range/r_range) + q_min = r*(q_range/r_range) - r_min*(q_range/r_range) + q_min

    = r*(q_range/r_range) + zero_point , zero_point = - r_min*(q_range/r_range) + q_min

r = (q - zero_point)*(r_range/q_range)

zero_point 는 Q의 원소이다.

 

Quantizing a matrix multiplication

두 매트릭스의 콴타이제이션에서 리얼벨류로 변환되는 과정은 아래와 같다.

lhs_real_value[i] = lhs_scale * (lhs_quantized_value[i] - lhs_zero_point)

rhs_real_value[i] = rhs_scale * (rhs_quantized_value[i] - rhs_zero_point)

행렬곱은 아래와 같이 정리된다. equation(4)

result_real_value

= Sum_over_i(lhs_real_value[i] * rhs_real_value[i])

= Sum_over_i( lhs_scale * (lhs_quantized_value[i] - lhs_zero_point) * rhs_scale * (rhs_quantized_value[i] - rhs_zero_point) )

= lhs_scale * rhs_scale * Sum_over_i( (lhs_quantized_value[i] - lhs_zero_point) * (rhs_quantized_value[i] - rhs_zero_point) )

equation(4) 에서 lhs_quantized_value[i] - lhs_zero_point) * (rhs_quantized_value[i] - rhs_zero_point) 이 부분은 콴타이제이션 연산만으로 이루어져있음으로 소기의 목적을 달성하였다. 그러나 어차피 다음 연산으로 넘어 갈때 equation(4)의 result_real_value는 다시콴타이즈 되어야한다.

equation(4)을 equation(3)과 같이 스케일과 제로 포인트로 리얼밸류로 복원시키는 아래아 같은 식으로 만들어야한다.

result_quantized_value 는 콴타이즈된 텐서만으로 연산이 이뤄져야하는 제한이 있다.

result_real_value = result_scale * (result_quantized_value - result_zero_point)
result_quantized_value = result_real_value / result_scale + result_zero_point
result_real_value
= result_scale * (result_quantized_value - result_zero_point)
= lhs_scale * rhs_scale * Sum_over_i( (lhs_quantized_value[i] - lhs_zero_point) * (rhs_quantized_value[i] - rhs_zero_point) )

result_quantized_value
= lhs_scale * rhs_scale / result_scale * Sum_over_i( (lhs_quantized_value[i] - lhs_zero_point) * (rhs_quantized_value[i] - rhs_zero_point) ) + result_zero_point

 

 

 

 

Comments