본문 바로가기
Model Lightening/Model Compression

AI 모델 양자화 기초 [4] - Scale과 Zero-point의 비밀

by Sangwoo Seo 2026. 2. 16.

이전 글에서 양자화의 핵심 수식 $ x_q = \text{round}(x/s) + z $를 배웠습니다. 이제 가장 중요한 질문에 답할 차례입니다.

 

"실제로 $ s $와 $ z $를 어떻게 계산하는가?"

 

이 글에서는 구체적인 숫자를 대입하며 직접 계산해보겠습니다. 수식을 보고 "아, 그렇구나"로 끝나는 것이 아니라, 손으로 직접 풀어보면서 완전히 이해하는 것이 목표입니다.

1. Scale(s): 실수를 정수 범위로 맞추기

Scale이 정확히 무엇을 하는가?

Scale은 두 범위의 크기 비율입니다.

[실수 범위 크기] / [정수 범위 크기] = Scale

 

더 정확하게는,

$$ s = \frac{q_{\max}​ − q_{\min}}{​x_{\max} ​− x_{\min}}​​ $$

여기서:

  • : 실수 값의 최대/최소
  • $ ⁡q_{\max}, q_{\min} $: 정수 값의 최대/최소 (INT8이면 127, -128)

직관적 의미

실수 범위 10을 정수 범위 255로 매핑한다면,

  • 실수 1단위 = 정수 25.5단위
  • Scale $ s = 10/255 \approx 0.039 $

실수 값 1을 변환하면:

  • $ x_q = \text{round}(1/0.039) \approx 26 $

구체적 예시: 숫자로 계산하기

문제: Conv 레이어 출력값이 [-5.0, 5.0] 범위에 분포. INT8로 양자화하라.

주어진 정보:

  • 실수 범위: $x_{\min} = -5.0 $, $ x_{\max} = 5.0 $
  • 정수 범위: $ q_{\min} = -128 $, $ q_{\max} = 127 $ (INT8 signed)

Step 1: Scale 계산

$$ s = \frac{x_{\max} - x_{\min}}{q_{\max} - q_{\min}} = \frac{5.0 - (-5.0)}{127 - (-128)} = \frac{10.0}{255} = 0.0392156... $$

실무에서는 보통 소수점 6~7자리까지만 사용합니다. $ s \approx 0.0392 $

의미 해석:

  • 실수 1.0 → 정수 약 25.5 (= 1/0.0392)
  • 실수 0.0392 → 정수 1
  • "실수 0.0392마다 정수 1칸씩 이동"

Step 2: 실제 값 변환해보기

이제 몇 가지 실수 값을 INT8로 변환해봅시다. (일단 $ z=0 $이라고 가정)

 

예시 1: $ x = 2.5 $

$$ x_q = \text{round}\left(\frac{2.5}{0.0392}\right) + 0 = \text{round}(63.78) = 64 $$

 

예시 2: $ x = -3.7 $

$$ x_q = \text{round}\left(\frac{-3.7}{0.0392}\right) + 0 = \text{round}(-94.39) = -94 $$

 

예시 3: $ x = 0.1 $

$$ x_q = \text{round}\left(\frac{0.1}{0.0392}\right) + 0 = \text{round}(2.55) = 3 $$

 

예시 4: $ x = 5.0 $(최대값)

$$ x_q = \text{round}\left(\frac{5.0}{0.0392}\right) + 0 = \text{round}(127.55) = 128 $$

 

예시 4의 경우, 128은 INT8 범위를 벗어났습니다. (INT8은 -128~127) 이것이 clipping(클리핑)이 필요한 이유입니다.

$$ x_q = \text{clip}(\text{round}(x/s) + z, -128, 127) = 127 $$

Scale이 정밀도와 범위를 결정하는 방식

작은 Scale의 효과

$ s = 0.01 $이라면:

  • 실수 0.01 → 정수 1
  • 매우 정밀함. 소수점 둘째자리까지 구분
  • 하지만 표현 가능한 실수 범위: 0.01 × 255 = 2.55만 가능

큰 Scale의 효과

$ s = 1.0 $이라면:

  • 실수 1.0 → 정수 1
  • 넓은 범위: 1.0 × 255 = 255까지 표현
  • 하지만 정밀도 낮음: 소수점 이하는 다 사라짐

핵심 트레이드오프

$$ \text{정밀도} \propto \frac{1}{s},\quad \text{범위} \propto s $$

작은 $ s $는 정밀하지만 좁은 범위, 큰 $ s $는 넓은 범위지만 낮은 정밀도입니다.

2. Zero-point(z): 0을 어디에 매핑할 것인가?

Zero-point의 필요성

Scale만으로는 충분하지 않습니다. 왜냐하면 실수 범위가 항상 0을 중심으로 대칭적이지 않기 때문입니다.

 

문제 상황:

ReLU 활성화 함수를 통과한 값들은 모두 양수입니다:

  • 실수 범위: [0, 10]
  • 정수 범위: [-128, 127]

Scale만 사용하면

$$ s = \frac{10 - 0}{127 - (-128)} = \frac{10}{255} = 0.0392 $$

실수 0을 변환하면

$$ x_q = \text{round}(0 / 0.0392) = 0 $$

문제: 정수 범위 [-128, -1]을 전혀 사용하지 않습니다! 256개 중 128개를 낭비하는 셈이죠.

해결책: Zero-point를 도입하여 실수 0을 정수 -128로 매핑합니다.

Zero-point 계산 방법

Zero-point는 실수 0이 어떤 정수에 대응되어야 하는가를 결정합니다.

$$ z = q_{\min} - \text{round}\left(\frac{x_{\min}}{s}\right) $$

또는 동등하게

$$ z = q_{\max} - \text{round}\left(\frac{x_{\max}}{s}\right) $$

두 식은 이론적으로 같은 값을 줘야 하지만, 반올림 오차로 인해 약간 다를 수 있습니다. 보통 첫 번째 식을 사용합니다.

구체적 예시 1: 대칭적 범위 (Symmetric)

문제: 가중치 범위가 [-2.5, 2.5]

주어진 정보:

  • $ x_{\min} = -2.5 $ $ x_{\max} = 2.5 $
  • $ q_{\min} = -128 $, $ q_{\max} = 127 $

Step 1: Scale 계산

$$ s = \frac{2.5 - (-2.5)}{127 - (-128)} = \frac{5.0}{255} = 0.0196 $$

Step 2: Zero-point 계산

$$ z = q_{\min} - \text{round}\left(\frac{x_{\min}}{s}\right) = -128 - \text{round}\left(\frac{-2.5}{0.0196}\right) $$

$$ = -128 - \text{round}(-127.55) = -128 - (-128) = 0 $$

 

결과: $ z = 0 $

이것은 zero-point를 0으로 설정하는 Symmetric quantization(대칭 양자화)입니다. 실수 0이 정수 0으로 매핑됩니다.

 

검증

실수 0을 변환하면: $ x_q = \text{round}(0 / 0.0196) + 0 = 0 $ ✓

실수 -2.5를 변환하면: $ x_q = \text{round}(-2.5 / 0.0196) + 0 = \text{round}(-127.55) = -128 $ ✓

실수 2.5를 변환하면: $ x_q = \text{round}(2.5 / 0.0196) + 0 = \text{round}(127.55) = 128 → \text{clip to } 127 $ ✓

구체적 예시 2: 비대칭적 범위 (Asymmetric)

문제: ReLU 출력 범위가 [0, 6.0]

주어진 정보:

  • $ x_{\min} = 0 $, $x_{\max} = 6.0 $
  • $ q_{\min} = -128 $, $ q_{\max} = 127 $

Step 1: Scale 계산

$$ s = \frac{6.0 - 0}{127 - (-128)} = \frac{6.0}{255} = 0.0235 $$

Step 2: Zero-point 계산

$$ z = q_{\min} - \text{round}\left(\frac{x_{\min}}{s}\right) = -128 - \text{round}\left(\frac{0}{0.0235}\right) $$

$$ =−128−0=−128 $$

 

결과: $ z = -128 $

이것은 Asymmetric quantization(비대칭 양자화)입니다. 실수 0이 정수 -128로 매핑됩니다.

 

검증:

실수 0을 변환하면: $ x_q = \text{round}(0 / 0.0235) + (-128) = 0 - 128 = -128 $ ✓

실수 3.0을 변환하면: $ x_q = \text{round}(3.0 / 0.0235) + (-128) = \text{round}(127.66) + (-128) = 128 - 128 = 0 $ ✓

실수 6.0을 변환하면: $ x_q = \text{round}(6.0 / 0.0235) + (-128) = \text{round}(255.32) + (-128) = 255 - 128 = 127 $ ✓

정수 범위 [-128, 127]을 완전히 사용합니다!

Symmetric vs Asymmetric: 언제 무엇을 쓰는가?

Symmetric Quantization ($ z = 0 $) :

장점:

  • 계산이 간단함: xq=round(x/s)x_q = \text{round}(x/s) (덧셈 불필요)
  • 하드웨어 구현이 효율적
  • 대부분의 NPU/가속기가 선호

단점:

  • 비대칭 범위에서는 정수 범위를 비효율적으로 사용

사용 시기:

  • 가중치 (보통 0 근처에 대칭적으로 분포)
  • 학습 과정에서 배치 정규화를 사용한 경우

Asymmetric Quantization ($ z \neq 0 $) :

장점:

  • 정수 범위를 최대한 효율적으로 활용
  • 비대칭 분포에 최적

단점:

  • 계산이 복잡함: 덧셈/뺄셈 연산 추가 필요
  • 하드웨어 오버헤드

사용 시기:

  • ReLU 이후의 활성화 값 (항상 양수 또는 0)
  • Sigmoid/Softmax 출력 (0~1 범위)
  • 범위가 한쪽으로 치우친 경우

실무 예시: ReLU 이후 vs 일반 레이어

ReLU 이후 활성화 값:
범위: [0, 5.8]
→ Asymmetric (z = -128)
→ 정수 범위 [-128, 127] 전체 활용
 
BatchNorm 이후 활성화 값:
범위: [-3.2, 3.1] (거의 대칭)
→ Symmetric (z = 0)
→ 계산 효율적
 
가중치:
범위: [-1.5, 1.7] (거의 대칭)
→ Symmetric (z = 0)
→ 하드웨어 최적화 용이

Zero-point의 물리적 의미

Zero-point는 좌표계의 원점 이동입니다.

$ z = 0$ 일 때 :

실수: ... -2  -1  0  1  2 ...
               ↓ ↓ ↓ ↓ ↓
정수: ... -2  -1  0  1  2 ...

원점이 그대로 유지됨

 

$ z = −128 $일 때:

실수:       0  1  2  3  4  5  6
            ↓  ↓  ↓  ↓  ↓  ↓  ↓
정수: -128 -85 -43 0 43 85 127

원점(실수 0)을 정수 -128로 이동

 

이렇게 원점을 이동시킴으로써 정수 범위를 낭비 없이 사용할 수 있습니다.

 

이제 우리는 양자화의 핵심 파라미터인 Scale($ s $)과 Zero-point($ z $)를 직접 계산하는 방법을 완전히 이해했습니다.

 

Scale은 실수 범위와 정수 범위의 크기 비율로, 정밀도와 표현 범위의 트레이드오프를 결정합니다.

작은 Scale은 높은 정밀도를 제공하지만 좁은 범위만 표현할 수 있고, 큰 Scale은 넓은 범위를 표현하지만 정밀도가 낮아집니다.

 

Zero-point는 실수 0이 정수 어디에 매핑되는지를 결정하며, 정수 범위의 활용 효율성을 좌우합니다.

$$ z = q_{\min} - \text{round}\left(\frac{x_{\min}}{s}\right) $$

 

Symmetric quantization($ z=0 $)은 계산이 간단하고 하드웨어 친화적이어서 주로 가중치에 사용되며, Asymmetric quantization($ z \neq 0 $)은 정수 범위를 최대한 활용하여 ReLU 이후 활성화 값처럼 비대칭적인 분포에 적합합니다.

 

하지만 지금까지는 이론과 간단한 숫자 몇 개를 변환해봤을 뿐입니다. 실제 신경망 레이어에는 수백만 개의 가중치와 활성화 값이 있습니다. 하나의 Conv 레이어를 통째로 양자화한다면 어떻게 될까요? 각 단계에서 정확히 무슨 일이 일어나며, 양자화 오차는 얼마나 발생할까요?

다음 글에서는 실제 Conv 레이어를 처음부터 끝까지 완전히 양자화해보겠습니다. 가중치 분포 분석, Scale과 Zero-point 계산, 수백 개의 값을 일괄 변환, Dequantization으로 복원, 그리고 최종 오차 분석까지 전 과정을 손으로 직접 따라가며 양자화의 실전 작동 원리를 체득하는 시간을 가져보겠습니다.