너도 할 수 있는, 너도밤나무 코딩

ONNX Runtime Quantization 가이드: FP16, INT8 최적화로 추론 속도 끌어올리기 본문

인공지능(AI, Artificial Intelligence)/비전 AI(Vision AI)

ONNX Runtime Quantization 가이드: FP16, INT8 최적화로 추론 속도 끌어올리기

곡마일장 2025. 8. 26. 07:53
반응형

딥러닝 모델을 실제 서비스 환경에 배포하다 보면, 학습 정확도만큼 중요한 것이 바로 추론 속도와 메모리 효율성입니다.
특히 GPU뿐 아니라 CPU 환경에서도 빠른 응답이 필요하다면, 모델 Quantization(양자화) 은 거의 필수적인 단계입니다.

이번 글에서는 제가 직접 ONNX Runtime Quantization을 적용해본 경험을 정리해 보겠습니다.
FP16 변환부터 INT8 Dynamic Quantization, 그리고 성능/정확도 트레이드오프까지 실무 관점에서 다뤄보겠습니다.


Quantization이란?

Quantization(양자화)은 모델의 연산을 낮은 정밀도의 숫자 표현으로 바꿔서 속도와 메모리 효율을 개선하는 기법입니다.

  • FP32 (기본, 32-bit 부동소수점)
  • FP16 (16-bit 부동소수점, Half Precision)
  • INT8 (8-bit 정수)

효과

  • 메모리 사용량 ↓
  • 추론 속도 ↑
  • 다만, 정확도 소폭 손실 가능

ONNX Runtime에서 지원하는 Quantization 방식

ONNX Runtime은 다양한 양자화 기법을 지원합니다.

  1. Dynamic Quantization
    • 실행 시점에 FP32 → INT8 변환.
    • 간단하게 적용 가능. CPU 환경에서 특히 유용.
  2. Static Quantization
    • Calibration 데이터셋을 사용해 사전 변환.
    • 더 높은 정확도 보장.
  3. FP16 Quantization
    • 주로 GPU 환경에서 사용.
    • 속도 향상과 메모리 절약 효과 크며, 정확도 손실이 거의 없음.

FP16 Quantization 적용하기

GPU 환경이라면 FP16 변환만으로도 큰 성능 향상을 얻을 수 있습니다.

python -m onnxruntime_tools.optimizer_cli --input model.onnx --output model_fp16.onnx --float16
  • 변환 후 model_fp16.onnx 를 로드하면, CUDA EP 또는 TensorRT EP에서 FP16 연산이 활성화됩니다.
  • 특히 TensorRT EP와 조합하면 2~3배 속도 향상을 쉽게 체감할 수 있습니다.

INT8 Dynamic Quantization 적용하기

CPU 환경에서 가장 빠르게 적용할 수 있는 양자화 기법은 Dynamic Quantization입니다.

from onnxruntime.quantization import quantize_static, CalibrationDataReader, QuantType 
# CalibrationDataReader 구현 필요 (데이터셋 제공) 
calibration_reader = MyCalibrationDataReader() 
quantize_static( model_input="model.onnx", model_output="model_int8_static.onnx", calibration_data_reader=calibration_reader, weight_type=QuantType.QInt8 )
  • 코드 몇 줄로 바로 INT8 버전 모델을 만들 수 있습니다.
  • CPU 전용 서버에서 FP32 대비 2~4배 빠른 속도 향상을 확인할 수 있었습니다.

⚙️ Static Quantization (Calibration 기반)

좀 더 정확도를 보장하려면 Calibration 데이터셋을 활용한 Static Quantization을 적용할 수 있습니다. 

from onnxruntime.quantization import quantize_static, CalibrationDataReader, QuantType
# CalibrationDataReader 구현 필요
calibration_reader = MyCalibrationDataReader()
quantize_static( model_input="model.onnx", model_output="model_int8_static.onnx", calibration_data_reader=calibration_reader, weight_type=QuantType.QInt8 )
 
  • Calibration 데이터셋을 통해 각 연산의 분포를 분석하고 최적의 스케일링을 적용합니다.
  • Dynamic Quantization보다 정확도가 높습니다.

성능 비교 (ResNet-50 기준)

모델 버전환경 평균 추론 속도 메모리 사용량 정확도 영향
FP32 (기본) CPU ~45 ms 100% baseline
INT8 (Dynamic) CPU 23 ms 약 ~25% 감소 약간↓
FP32 (CUDA) GPU ~5 ms 100% baseline
FP16 (CUDA) GPU ~3 ms 약 ~50% 감소 거의 동일
INT8 (TensorRT) GPU ~2 ms 약 ~70% 감소 약간↓

제 경험상 CPU는 INT8 Dynamic Quantization,
GPU는 FP16 또는 TensorRT INT8 이 최적 조합이었습니다.

하지만 정확도 측면에서는 FP16이 최선의 선택으로 예상됩니다.


정리

  • ONNX Runtime은 FP16, INT8 양자화를 통해 추론 속도를 크게 향상시킬 수 있습니다.
  • CPU 서버 → Dynamic Quantization (INT8) 추천.
  • GPU 서버 → FP16 변환 후 CUDA/TensorRT EP 적용이 가장 안정적.
  • Static Quantization은 정확도에 민감한 환경에서 고려할 만합니다.

 

SEO 키워드
onnxruntime quantization, onnx int8, onnx fp16, onnxruntime optimization, 딥러닝 추론 최적화
반응형