이전 글에서 양자화의 핵심 수식 $ 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 일반 레이어
범위: [0, 5.8]
→ Asymmetric (z = -128)
→ 정수 범위 [-128, 127] 전체 활용
범위: [-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으로 복원, 그리고 최종 오차 분석까지 전 과정을 손으로 직접 따라가며 양자화의 실전 작동 원리를 체득하는 시간을 가져보겠습니다.
'Model Lightening > Model Compression' 카테고리의 다른 글
| AI 모델 양자화 기초 [6] - 실전: Transformer (0) | 2026.02.17 |
|---|---|
| AI 모델 양자화 기초 [5] - 실전: Convolutional Layer (0) | 2026.02.16 |
| AI 모델 양자화 기초 [3] - Affine Quantization의 수학적 원리 (0) | 2026.02.15 |
| AI 모델 양자화 기초 [2] - 양자화란 무엇인가? (0) | 2026.02.15 |
| AI 모델 양자화 기초 [1] - 왜 양자화가 필요한가 (0) | 2026.02.15 |