양자화(Quantization)는 딥러닝 모델의 weights와 activations 값 표현 정밀도를 낮추는 기법입니다. 일반적으로는 부동소수점(예: 32-bit float, FP32)에서 더 낮은 비트의 정수(예: 8-bit integer, INT8)로 변환하는 과정을 말합니다. 이를 통해 모델 크기를 줄이고, 추론 속도를 높이며, 전력 소모를 감소시킬 수 있어 특히 엣지 디바이스나 모바일 환경에 모델을 배포할 때 유용합니다. 또한 inference에는 고 정밀도가 필요하지 않은 경우가 많아 모델 정확도를 유지할 수 있습니다.
PTQ (Post-Training Quantization, 학습 후 양자화)
PTQ는 이미 학습된 부동소수점 모델을 가져와 양자화하는 방식입니다. 학습 과정은 건드리지 않고, 학습이 완료된 모델에 대해 양자화 변환만 수행합니다. 기존 학습된 모델을 그대로 사용하므로 적용이 추가적인 학습이나 학습 파이프라인 수정이 필요 없습니다. 하지만 양자화 과정에서 정보 손실이 발생하여 모델의 정확도가 떨어질 수 있고, 레이어의 오차 전파로 오차 누적 현상이 심해질 수 있습니다.
- 작동 방식:
- 미리 학습된 FP32 모델을 준비, 모델의 가중치를 INT8과 같은 낮은 정밀도로 변환
- Activation 값의 경우, 일반적으로 calibration 과정을 통해 값의 범위(최소, 최대)를 결정하고 이를 기반으로 양자화.
- Weight 값은 이미 모델에 고정된 값이기 때문에 calibration 데이터 없이도 바로 quantize 가능
Quantization 방식: Scale과 Zero-point
양자화는 연속적인 부동소수점 값을 이산적인 정수값으로 표현하는 과정입니다. 이를 위해 가장 일반적으로 사용하는 방식은 Affine Quantization이며, 이 방식은 다음과 같은 수식을 기반으로 합니다:
- x_fp: 부동소수점 값 (float)
- x_int: 양자화된 정수값 (예: INT8)
- scale: 부동소수점 → 정수로 변환할 때 사용하는 배율
- zero_point: 0을 정수 범위 내에서 표현하기 위한 기준값
이 수식을 기반으로 부동소수점 값을 정수로 압축할 수 있으며, 정수로 연산한 후에는 다시 dequantize 과정을 통해 부동소수점 값으로 복원할 수 있습니다:
scale은 보통 해당 텐서의 최대값과 최소값을 기준으로 다음과 같이 계산됩니다:
그리고 zero_point는 일반적으로 다음과 같이 계산되며, 정수 범위 내 가장 가까운 정수로 반올림됩니다:
Scale과 zero-point를 구하는 단위는 layer-wise, operator-wise, per-tensor, per-channel 등 다양할 수 있습니다.
Calibration
Calibration은 activation 값의 정규화된 스케일 정보를 얻는 과정입니다. FP 값을 정수에 매핑할 때 필요한 zero_point와 scale 값을 찾습니다. 일반적으로 소량의 대표 입력 데이터셋을 통해 수행됩니다. 이 데이터셋은 전체 학습 데이터의 일부로 구성되며, 모델에 이 데이터를 통과시켜 각 layer의 activation 값 분포를 관찰하고, 해당 분포를 기반으로 quantization에 필요한 scale과 zero-point를 추정합니다. Activation의 최댓값과 최솟값을 측정하여 이를 정수 표현 범위(예: -128 ~ 127)에 맞게 매핑하는 방식이 일반적입니다.
Calibration 방식은 다음과 같은 기준으로 분류될 수 있습니다.
- 어떻게 zero-point/scale 값을 추정하느냐: min-max 방식, percentile 방식 등
- 어떤 시점에 calibration 값을 적용하느냐: static quant., dynamic quant.
- activation의 경우 inference 시점에 scale을 계산할 수 있고, 이를 dynamic quantization이라고 말합니다.
QAT (Quantization-Aware Training, 양자화 인식 학습)
QAT는 모델 학습 과정 중에 양자화로 인한 영향을 미리 시뮬레이션하여, 모델이 양자화된 상태에서도 성능 저하를 최소화하도록 학습하는 방식입니다. 학습 과정에서 양자화 효과를 반영하므로 PTQ에 비해 모델의 정확도를 더 잘 유지할 수 있습니다. 따라서 PTQ 보다 더 낮은 비트로 양자화에도 상대적으로 강인합니다.
- 작동 방식:
- 학습 파이프라인에 “가짜 양자화(Fake Quantization)” 연산을 추가
- Forward pass에서는 weight와 activation을 양자화했다가 다시 부동소수점으로 변환(dequantize)하여 양자화로 인한 오차를 모델이 학습하도록 함
- Backward pass에서는 부동소수점 값을 사용하여 계산하고 가중치를 업데이트
QAT vs. Low-precision Floating-Point
그렇다면 training 중 양자화 시뮬레이션을 하는 것과 더 낮은 정밀도의 부동소수점(Low Precision Floating Point)를 사용하는 것의 차이점은 무엇일까요.
QAT - Fake Quantization
Fake quantization은 실제 정수 연산을 하지 않으면서도, 정수로 양자화했을 때 발생할 수 있는 정보 손실을 시뮬레이션하는 기법입니다. 훈련은 여전히 부동소수점(float)으로 진행되지만, 정수 표현에 맞게 값의 범위를 제한하고 반올림(rounding), 클램핑(clamping, 값의 범위를 제한)을 적용하는 연산을 삽입함으로써 정수 양자화와 유사한 조건에서 모델이 학습되도록 유도, 양자화 오차에 강인해지도록 학습됩니다. 역전파 시에는 여전히 고정밀도(FP32) 값을 사용합니다.
이렇게 학습된 모델은 나중에 실제 정수 연산만 지원하는 하드웨어(예: NPU, 특정 DSP, Edge TPU 등)에서 실행될 때 원래 FP32 모델과 유사한 정확도를 유지할 가능성이 커집니다. 즉, QAT는 INT8 추론을 위한 최적화 기법입니다. 훈련이 끝난 후 실제 추론시에는 INT8 타입으로 동작합니다.
낮은 정밀도 부동소수점(Low-Precision Floating-Point)
단순히 낮은 정밀도의 부동소수점(예: FP16, bfloat16)을 사용하는 것은 여전히 부동소수점 연산의 범주에 속합니다. 이는 메모리 사용량을 줄입니다. 정수 변환에서 오는 비선형적인 정보 손실(반올림, 클램핑)을 직접적으로 시뮬레이션하지는 않습니다. 낮은 정밀도로 인한 수치적 불안정성을 관리하기 위해 혼합 정밀도 학습(Mixed Precision Training)과 같은 기법이 사용될 수 있습니다.
정수 연산의 장점
QAT 를 통해 INT8 연산을 할 경우, 모델의 크기가 FP32 대비 약 4배 감소합니다. 많은 하드웨어(CPU, GPU, NPU, TPU 등)에는 INT8 정수 연산에 특화된 가속 유닛이 있어 FP32나 FP16 연산보다 훨씬 빠른 추론 속도를 제공할 수 있습니다. 또한 정수 연산은 부동소수점 연산보다 일반적으로 전력 소모가 적다는 장점도 갖고 있습니다.
QAT 사용은 INT8 하드웨어 연산기의 이점에 달려있는 듯 합니다. INT8 연산기는 하드웨어 설계 측면에서 FP16 연산기에 비해 여러 가지 이점을 가집니다. 회로 구조가 단순하고 작기 때문에 실리콘 면적과 전력 소비가 적습니다. TPU 논문은 TPU가 성공한 이유 중 하나를 양자화된 애플리케이션에 의해 8비트 정수가 사용되었다는 점을 뽑습니다. 8비트 정수 곱셈은 IEEE 754 16비트 부동 소수점 곱셈보다 에너지 소모가 6배 적고 면적이 6배 작으며, 정수 덧셈의 경우 에너지에서 13배, 면적에서 38배 유리하다고 합니다.
애초에 정수 타입으로 training 할 수 없을까?
머신 러닝의 gradient 연산 때문에 “정수 기반 학습"을 하기는 어렵고 비효율적입니다. 학습은 FP32/FP16으로 추론만 INT8, INT4 등으로 하는 경우가 많다고 합니다.