1. ONNX Runtime Mobile C++ API 기반 크로스 플랫폼 On-Device AI 구축 배경
모바일 및 엣지 디바이스 환경에서 딥러닝 모델을 구동할 때 OS별(Android, iOS)로 추론 엔지니어링을 따로 구현하는 방식은 파편화와 유지보수 비용 증가를 초래합니다. Android의 NNAPI/TFLite와 iOS의 CoreML/MPSgraph 프레임워크를 각각 다루는 방식은 최적화 로직과 후처리 코드가 중복되는 문제가 발생합니다.
ONNX Runtime Mobile은 단일 C++ API 레이어를 통해 이러한 파편화 이슈를 해결합니다. 플랫폼 종속성을 제거하고 공통 C++ 엔진을 구축함으로써 iOS(CoreML execution provider)와 Android(NNAPI/NNAPI EP)의 하드웨어 가속기(NPU, GPU)를 동일한 코드베이스로 제어할 수 있습니다. 본 가이드는 ONNX Runtime Mobile C++ API를 활용하여 모바일 디바이스에서 고성능 크로스 플랫폼 추론 파이프라인을 구축하는 가이드를 제공합니다.
2. ONNX Runtime Mobile 핵심 기술 요약 (Technical Summary)
- Cross-Platform C++ Core Engine: Ort::Env 및 Ort::Session C++ API를 활용하여 Android와 iOS에서 동일한 딥러닝 추론 파이프라인을 동작시킵니다.
- Hardware Acceleration Provider Integration: Android 환경에서는 OrtSessionOptionsAppendExecutionProvider_Nnapi를 사용하고, iOS 환경에서는 OrtSessionOptionsAppendExecutionProvider_CoreML을 통해 NPU/GPU 가속을 활성화합니다.
- ORT Format Optimization: 메모리 사용량을 절감하기 위해 .onnx 모델을 모바일 최적화 포맷인 .ort 파일로 변환하여 런타임 이니셜라이제이션 성능을 극대화합니다.
3. ONNX Runtime Mobile C++ API 상세 분석 및 모바일 연동 구현
ONNX Runtime Mobile 실행 파이프라인 아키텍처
ONNX Runtime Mobile의 C++ 파이프라인은 세션 환경 설정(Ort::Env), 옵션 초기화 및 Execution Provider 추가(Ort::SessionOptions), 모델 로딩(Ort::Session), 그리고 텐서 입력/출력 매핑(Ort::Value)의 순서로 진행됩니다.
[ONNX / ORT Model File]
│
▼
Ort::Env Engine ───► Ort::SessionOptions (EP Configuration: NNAPI / CoreML)
│
▼
Ort::Session ───► Allocator / Memory Info Setup
│
▼
Ort::Value ───► Session.Run() ───► Output Tensors
Execution Provider(EP) 백엔드 비교 및 모바일 최적화 특징
| 평가 항목 (Feature) | Android (NNAPI Execution Provider) | iOS (CoreML Execution Provider) | CPU Fallback |
| 하드웨어 가속기 | NPU / DSP / GPU (Qualcomm Hexagon, Mali, Adreno) | Apple Neural Engine (ANE) / Apple GPU | CPU (XNNPACK / ARM NEON) |
| API 함수 | OrtSessionOptionsAppendExecutionProvider_Nnapi | OrtSessionOptionsAppendExecutionProvider_CoreML | 기본 적용 (Default) |
| 추론 속도 (Latency) | 매우 빠름 (HW 드라이버 지원 시) | 매우 빠름 | 보통 |
| 메모리 오버헤드 | 중간 (Driver 컴파일 비용 발생) | 작음 | 최소 |
ONNX Runtime C++ API 추론 엔진 파이프라인 소스코드 분석
다음 예제는 Android NDK Native Layer 및 iOS C++ Framework 레벨에서 공통으로 실행 가능한 C++ 추론 파이프라인 구현 코드입니다.
#include <iostream>
#include <vector>
#include <onnxruntime_cxx_api.h>
// Include Execution Provider headers based on platform
#if defined(__ANDROID__)
#include <onnxruntime_c_api.h>
#elif defined(__APPLE__)
#include <coreml_provider_factory.h>
#endif
class OnnxInferenceEngine {
private:
Ort::Env env;
Ort::SessionOptions sessionOptions;
Ort::Session* session = nullptr;
Ort::MemoryInfo memoryInfo = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
public:
OnnxInferenceEngine() : env(ORT_LOGGING_LEVEL_WARNING, "MobileInference") {}
~OnnxInferenceEngine() {
if (session) {
delete session;
}
}
void InitializeEngine(const char* modelPath) {
// Enable basic optimizations
sessionOptions.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
#if defined(__ANDROID__)
// Append NNAPI Execution Provider for Android NPU acceleration
uint32_t nnapi_flags = 0;
OrtStatus* status = OrtSessionOptionsAppendExecutionProvider_Nnapi(sessionOptions, nnapi_flags);
if (status != nullptr) {
std::cerr << "Failed to append NNAPI Execution Provider." << std::endl;
}
#elif defined(__APPLE__)
// Append CoreML Execution Provider for iOS ANE acceleration
uint32_t coreml_flags = 0;
OrtStatus* status = OrtSessionOptionsAppendExecutionProvider_CoreML(sessionOptions, coreml_flags);
if (status != nullptr) {
std::cerr << "Failed to append CoreML Execution Provider." << std::endl;
}
#endif
// Create Ort::Session
session = new Ort::Session(env, modelPath, sessionOptions);
}
std::vector<float> RunInference(const std::vector<float>& inputData, const std::vector<int64_t>& inputShape) {
const char* inputNames[] = {"input"};
const char* outputNames[] = {"output"};
// Create Input Tensor from vector
size_t inputTensorSize = inputData.size();
Ort::Value inputTensor = Ort::Value::CreateTensor<float>(
memoryInfo,
const_cast<float*>(inputData.data()),
inputTensorSize,
inputShape.data(),
inputShape.size()
);
// Execute Model Inference
auto outputTensors = session->Run(
Ort::RunOptions{nullptr},
inputNames,
&inputTensor,
1,
outputNames,
1
);
// Extract Output Tensor Data
float* floatArray = outputTensors[0].GetTensorMutableData<float>();
size_t outputSize = outputTensors[0].GetTensorTypeAndShapeInfo().GetElementCount();
return std::vector<float>(floatArray, floatArray + outputSize);
}
};
4. ONNX Runtime Mobile 실무 연동 및 최적화 개발 팁
- ORT Format Model Conversion: 모바일 빌드에서는 바이너리 용량을 줄이고 로딩 속도를 올리기 위해 기존 .onnx 포맷을 .ort 포맷으로 변환해야 합니다. Python 환경에서 onnxruntime.tools.convert_onnx_models_to_ort CLI 명령어를 수행하여 경량화 포맷으로 변환 후 연동하세요.
- CPU Fallback 옵션 구성: 하드웨어 가속기(NNAPI/CoreML)에서 지원하지 않는 커스텀 연산자(Custom Operator)가 모델에 포함된 경우 에러가 발생할 수 있습니다. EP 초기화 함수 실패 시 즉시 CPU 백엔드로 롤백되는 예외 처리 로직을 구현하세요.
- Inference Memory Pool Reuse: Ort::Value 생성 시 매 추론마다 메모리를 동적 할당하지 않고, 사전 할당된 버퍼(Pre-allocated Memory)를 사용하도록 처리하여 GC(Garbage Collection) 및 Heap overhead를 제거하세요.
5. ONNX Runtime Mobile 적용 시 흔히 하는 실수 및 예외 해결법
- Tensor Shape Mismatch (ORT_INVALID_ARGUMENT):
- 에러 예시: OnnxRuntimeError: Invalid rank for input
- 원인: C++ 백엔드로 넘겨주는 inputShape 벡터의 차원 값이나 요소 개수가 모델 초기 설정과 일치하지 않는 경우 발생합니다.
- 해결법: session->GetInputTypeInfo(0).GetTensorTypeAndShapeInfo().GetShape() API를 사용하여 모델이 기대하는 Shape 정보를 명확히 검증 후 텐서를 입력하세요.
- Execution Provider 가속 실패 및 Crash:
- 에러 예시: NNAPI EP driver missing or invalid node
- 원인: Android OS 버전이 낮거나 NPU 드라이버 지원 범위 밖에 있는 딥러닝 레이어가 모델에 존재할 때 발생합니다.
- 해결법: OrtSessionOptionsAppendExecutionProvider_Nnapi 실행 후 반환되는 OrtStatus*를 검사하고 status != nullptr인 경우 해당 EP 세션을 해제하고 기본 CPU 세션으로 세이프티 가드를 작성하세요.
- iOS Bitcode 및 Framework Symbol Missing:
- 원인: Xcode 빌드 환경에서 ONNX Runtime Static C++ Framework 링크 누락으로 인해 C++ 내 static symbol을 참조하지 못하는 현상입니다.
- 해결법: Xcode Build Settings에서 Other Linker Flags 항목에 -ObjC 및 -all_load 옵션을 지정하고 ONNX Runtime C++ Header Path가 정상인지 확인하세요.
6. ONNX Runtime Mobile C++ 연동 결론
ONNX Runtime Mobile의 C++ API를 활용하면 iOS와 Android 디바이스 모두에서 동등한 성능과 높은 일관성을 가진 On-Device AI 추론 파이프라인을 구축할 수 있습니다. NNAPI 및 CoreML Execution Provider를 효율적으로 활성화하고 .ort 최적화 포맷을 적용하여 모바일 엣지 환경에서 실시간 AI 서비스를 성공적으로 구현하기 바랍니다.
'Edge AI & Cloud > On-Device AI & Edge Hardware' 카테고리의 다른 글
| Arm Cortex-M55 및 Ethos-U55 NPU 분석: 초저전력(uW) 엣지 AI 및 Helium MVE 활용 가이드 (0) | 2026.08.14 |
|---|---|
| OpenCV NPU 가속 기법: 엣지 AI 영상 전처리(Image Preprocessing) 최적화 가이드 (0) | 2026.08.11 |
| Knowledge Distillation (지식 증류): Teacher-Student 모델 기반 On-Device AI 경량화 기법 (0) | 2026.08.08 |
| On-Device AI 모델 역공학 방지: PUF 기반 펌웨어 암호화 및 NPU 가중치 보호 기법 (0) | 2026.08.05 |
| MobileNet V3 구조 및 Hardware-Aware NAS 엣지 AI 지연 시간 최적화 분석 (0) | 2026.08.02 |