| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
- onnx
- 인공지능
- 딥러닝 추론 최적화
- 파이썬
- git
- C++ 기초
- 산업적용
- 앱테크
- stable diffusion
- 시스템관리
- yolo11
- 비전AI
- 생성형AI
- 프로그래밍
- 리눅스
- Python
- 스마트팩토리
- 파이썬 클래스
- 오픈소스
- github
- YOLO
- pytorch
- comfyui
- tensorRT
- 딥러닝
- Vision AI
- 생성형 AI
- AI
- 머신러닝
- Windows
- Today
- Total
너도 할 수 있는, 너도밤나무 코딩
ONNX Runtime에서 CUDA Execution Provider 적용하기 (C++ GPU 추론) 본문
ONNX Runtime에서 CUDA Execution Provider 적용하기 (C++ GPU 추론)
곡마일장 2025. 8. 24. 17:21딥러닝 모델을 실제 서비스 환경에 올리다 보면, 단순히 모델을 학습시키는 것보다 추론 속도와 효율성이 훨씬 중요하다는 걸 체감하게 됩니다.
특히 ONNX Runtime을 사용할 때 Execution Provider(EP) 선택이 성능에 직결되는데, CPU만 쓰는 기본 설정과 GPU를 제대로 활용하는 설정은 속도 차이가 어마어마합니다.
이번 글에서는 제가 ONNX Runtime CUDA Execution Provider를 적용하면서 정리한 노하우를 공유합니다.
단순히 “어떻게 추가한다” 수준이 아니라, 실제 현업에서 쓰이는 최적화 옵션과 실패 시 디버깅 포인트까지 담아봤습니다.
ONNX Runtime Execution Provider 개념
ONNX Runtime은 기본적으로 CPU에서 동작합니다. 하지만 ONNX의 강점은 여러 하드웨어 백엔드를 지원한다는 점입니다. 대표적으로:
- CPU EP (기본)
- CUDA EP (NVIDIA GPU)
- TensorRT EP (NVIDIA GPU 고속 최적화)
- OpenVINO EP (Intel CPU/GPU)
- DirectML EP (Windows 전용, 다양한 GPU 지원)
여기서 NVIDIA GPU를 쓰는 환경이라면 CUDA EP 또는 TensorRT EP를 반드시 고려해야 합니다.
제가 테스트했을 때, 같은 모델을 CPU EP와 CUDA EP에서 실행하면 3~10배 이상 속도 차이가 났습니다.
C++에서 CUDA Execution Provider 적용하기
ONNX Runtime을 C++로 사용할 때, CUDA EP를 추가하는 방법은 아주 단순합니다.
기본 예제 코드
#include <onnxruntime_cxx_api.h>
int main() {
Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "onnxruntime");
Ort::SessionOptions session_options; // CPU 스레드 최적화 (fallback 대비)
session_options.SetIntraOpNumThreads(4); session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL); // CUDA EP 적용 (GPU 0번 사용)
session_options.AppendExecutionProvider_CUDA(0); // 세션 생성
Ort::Session session(env, L"model.onnx", session_options);
return 0;
}
여기서 AppendExecutionProvider_CUDA(0) 한 줄이면 GPU 환경을 사용할 수 있습니다.
0은 GPU ID로, 다중 GPU 서버라면 원하는 GPU 번호를 지정하면 됩니다.
CUDA Provider 옵션 튜닝하기
실무에서는 단순히 GPU만 붙이는 걸로 끝나지 않습니다. cuDNN의 Convolution 알고리즘 검색 방식이나 메모리 제한을 조정해야 더 안정적인 퍼포먼스를 낼 수 있습니다.
OrtCUDAProviderOptions options;
options.device_id = 0;
options.cudnn_conv_algo_search = OrtCudnnConvAlgoSearchExhaustive; // EXHAUSTIVE / HEURISTIC / DEFAULT options.gpu_mem_limit = SIZE_MAX; // GPU 메모리 제한 없음
options.arena_extend_strategy = 0;
OrtSessionOptionsAppendExecutionProvider_CUDA(session_options, &options);
cuDNN 알고리즘 검색 방식
- EXHAUSTIVE: 모든 알고리즘을 탐색해서 최적의 속도를 보장. 다만 초기화 시간이 길다.
- HEURISTIC: 기본값. 빠른 초기화, 보통은 충분히 빠른 알고리즘 선택.
- DEFAULT: cuDNN 기본 설정.
개인적으로는 서버에서 장시간 돌리는 서비스라면 EXHAUSTIVE,
짧게 여러 번 로딩하는 경우라면 HEURISTIC 를 추천합니다.
성능 최적화 팁
CUDA EP를 붙였다고 끝이 아닙니다. ONNX Runtime에서 GPU 성능을 극대화하려면 몇 가지 추가 최적화가 필요합니다.
1. TensorRT EP 고려하기
CUDA EP도 충분히 빠르지만, TensorRT EP를 쓰면 FP16/INT8 최적화가 가능해서 속도를 훨씬 더 끌어올릴 수 있습니다.
단, 모델에 따라 지원되지 않는 연산이 있을 수 있으니 fallback 경로도 준비해야 합니다.
session_options.AppendExecutionProvider_TensorRT(0);
2. 메모리 최적화 옵션
session_options.EnableCpuMemArena();
session_options.EnableMemPattern(); // 입력 shape 고정일 때 효과적
- 입력 텐서 shape가 고정이라면 EnableMemPattern() 이 메모리 재사용을 최적화해줍니다.
3. FP16 변환
모델을 FP16으로 변환하면 속도와 메모리 사용량이 크게 개선됩니다.
디버깅 포인트
CUDA EP 적용 시 자주 겪는 이슈도 몇 가지 정리해봤습니다.
- CUDA/cuDNN 버전 불일치
→ ONNX Runtime 빌드 시 지원하는 CUDA/cuDNN 버전을 반드시 맞춰야 합니다. - GPU 메모리 부족
→ 기본적으로 메모리 풀을 관리하지만, 큰 모델은 OOM이 발생할 수 있으니 gpu_mem_limit 옵션을 조정하세요. - 예외 발생
→ C API는 OrtStatus*를 반환하므로 수동 체크가 필요하지만, C++ API(Ort::SessionOptions)는 예외를 던지므로 try/catch로 잡아야 합니다.
마무리
정리하자면,
- ONNX Runtime에서 CUDA Execution Provider를 추가하면 GPU 가속으로 추론 속도가 크게 향상됩니다.
- AppendExecutionProvider_CUDA(0) 한 줄이면 기본 사용 가능.
- 실무에서는 OrtCUDAProviderOptions 로 알고리즘 탐색 방식, GPU 메모리 제한을 세밀하게 조정하는 게 좋습니다.
- 장기 서비스 환경이면 EXHAUSTIVE, 빠른 초기화가 필요하면 HEURISTIC 설정을 추천합니다.
- 가능하다면 TensorRT EP + FP16 최적화 조합이 가장 강력합니다.
'인공지능(AI, Artificial Intelligence)' 카테고리의 다른 글
| Midjourney란? 개념 알아보기 (0) | 2025.12.14 |
|---|---|
| [Perplexity] Comet 브라우저 프로 사용하는 방법 (0) | 2025.10.21 |
| Perplexity AI vs Grok AI 완전 비교 (2025년 최신판) (0) | 2025.10.20 |
| Unsupervised Learning (비지도 학습) 알고리즘 정리 (0) | 2025.10.12 |