1. 서론: Edge AI 개발 현장의 '현실적인 과제'
Edge AI 기기(카메라, 차량용 장치, 산업용 센서 단말 등)를 개발할 때, 추론 모델 자체보다도 **'모델 전후의 데이터 전처리 및 후처리 로직 변경'**이 가장 운영 비용을 높이는 요인입니다.
과제 1: OTA 업데이트의 거대화 (Bloat)
전처리 필터 처리를 네이티브 C++ 애플리케이션에 통합하면, 로직 변경할 때마다 시스템 전체의 펌웨어 또는 거대한 바이너리(수십 MB~수 GB)를 Over-The-Air(OTA)로 전송해야 합니다.
과제 2: HW/FW 팀과 AI 팀의 밀접한 결합 (Tight Coupling)
AI 엔지니어가 전처리(크기 조정, 정규화, NMS: Non-Maximum Suppression 등)를 미세하게 조정하고 싶어도 임베디드 엔지니어의 빌드 및 검증 파이프라인을 거쳐야 하므로 릴리스 주기가 병목 현상을 일으킵니다.
과제 3: 보안과 안정성의 상충 관계 (Trade-off)
동적 라이브러리(.so)를 이용한 플러그인 메커니즘을 사용하면, 서드파티 또는 업데이트된 처리 로직이 메모리 손상(Segfault)을 일으켰을 때 시스템 전체가 함께 다운될 위험이 있습니다.
본 기사에서는 이러한 과제를 해결하기 위해 **'Host (C++ / ONNX Runtime) + Plugin (WasmEdge / WebAssembly)'**라는 하이브리드 아키텍처를 제안하고, 실용적인 구현 예시와 그 평가, 프로젝트 관리상의 이점까지 설명합니다.
2. 제안 아키텍처: WasmEdge + ONNX Runtime
전체 구조는 다음과 같습니다. 무거운 AI 추론 엔진(ONNX Runtime C++ API)은 호스트의 C++ 프로세스 측에 고정적으로 유지하고, 가볍고 빈번하게 변경되는 '전처리/후처리 로직'을 WebAssembly (Wasm)로 샌드박스 실행합니다.
+-------------------------------------------------------------------
| Linux Edge Host Application (C++) |
| |
...
왜 WasmEdge인가?
경량 및 고속: JIT 컴파일(AOT화)을 통해 네이티브 C++에 가까운 속도로 동작합니다.
메모리 공간의 안전한 분리: Wasm 모듈 내부에서의 영역 외 접근이나 메모리 누수가 호스트 프로세스를 붕괴시키지 않습니다.
극소의 풋프린트: Wasm 바이너리 자체는 수 KB~수 MB에 불과하여 OTA 전송 비용이 크게 감소합니다.
3. 구현 가이드: C++ 호스트와 Wasm 플러그인 연동
(1) 호스트 측: C++ (WasmEdge C API & ONNX Runtime)
먼저 호스트 측에서 WasmEdge VM을 구동하고, 카메라 입력 데이터를 WASM 선형 메모리(linear memory)로 전송하며, 전처리된 텐서를 받는 최소 구성 코드 예시입니다.
// main.cpp
#include <iostream>
#include <vector>
...
(2) 플러그인 측: C / Rust (Wasm으로 컴파일)
AI 엔지니어는 C++나 Rust 등으로 전처리 로직을 독립적으로 작성하고, Wasm 바이너리를 생성합니다. 아래는 C 언어를 이용한 구현 예시입니다.
// preprocess_plugin.c
// Compile: clang --target=wasm32 -O3 -nostdlib -Wl,--no-entry -Wl,--export-all -o preprocess.wasm preprocess_plugin.c
#define TARGET_SIZE 224
...
4. 성능 평가와 오버헤드
임베디드 Linux(Raspberry Pi 4 / Cortex-A72) 환경에서, 1080p (1920x1080) RGB 입력 이미지에 대한 전처리(224x224로 크기 조정 + 정규화) 처리 시간을 비교했습니다.
| 방법 | 실행 시간 (ms) | 메모리 사용량 (MB) | 플러그인 크기 | 안전성 / 샌드박스 |
|---|
| 네이티브 C++ (.so) | 4.2 ms | 1.1 MB | 120 KB | ❌ SEGV로 본체 충돌 |
| Python C-API (PyBind11) | 28.5 ms | 45.0 MB | 15 MB (Python 환경) | ⚠️ GIL 잠금 및 무거움 |
| WasmEdge (AOT 컴파일) | 5.1 ms | 2.3 MB | 18 KB | ✅ 완전 보호 (Sandbox) |
WasmEdge를 AOT(Ahead-Of-Time) 컴파일하여 사용함으로써, 네이티브 C++와 비교했을 때 성능 저하를 약 20% 내외로 유지하면서도, Python에 비해 훨씬 적은 메모리를 사용하고 빠르게 동작시킬 수 있습니다.
5. PM 및 개발 프로세스 관점의 혁신
이 기술 스택은 단순한 기술적 흥미를 넘어, **'임베디드 AI 프로젝트의 조직 구조와 개발 프로세스'**에 극적인 변화를 가져옵니다.
【기존 접근 방식】
[AI팀: Python/PyTorch] ──(사양서 전달)──> [FW팀: C++ 임베디드 포팅] ──(통합 테스트)──> [대형 FW OTA]
※ 재작업 시 리드 타임: 2주 ~ 1개월
...
- 팀 간 인터페이스의 명확한 분리 (계약 주도 개발)
Wasm의 함수 정의(입력: uint8_t 포인터, 출력: float 포인터`)를 'API 계약'으로 고정함으로써, FW팀과 AI/데이터 사이언스팀 간의 의존 관계를 완전히 끊어낼 수 있습니다. -
안전한 원격 OTA 테스트
만일 AI팀이 만든 전처리 Wasm 코드에 '0 나누기'나 '무한 루프' 같은 버그가 숨어 있더라도, WasmEdge 런타임이 이를 감지하고 에러 핸들링을 수행하기 때문에, 장비가 조용히 재부팅되거나 '벽돌화(Watchdog Reset 연쇄)'될 위험을 회피할 수 있습니다.
6. 요약
임베디드 Linux 환경에서의 Edge AI 개발은 **'로직의 유연성 (Agility)'**과 **'임베디드 특유의 안전성 및 저자원 사용 (Robustness)'**이라는 두 가지 상반된 문제에 직면합니다.
ONNX Runtime
(추론 가속화)와 WasmEdge
(안전하고 경량인 포터블 로직)을 결합하는 접근 방식은 차세대 Edge AI 아키텍처로서 매우 강력한 선택지가 됩니다.
- '전처리나 후처리 로직 변경이 잦아 OTA가 어렵다'
- 'AI 로직의 충돌로 시스템 전체를 다운시키고 싶지 않다'
와 같은 과제를 안고 있는 현장의 엔지니어 및 PM분들은 꼭 PoC(개념 증명)부터 시도해 보시길 바랍니다!
Discussion