MCU 메모리 수백 KB 안에 모델을 넣는 법 — 엣지 AI 경량화 실전 파이프라인

TinyML·ONNX·Pruning·Quantization을 학습부터 배포까지 이어붙인 엣지 AI 경량화 파이프라인과 품질 게이트, 실행 가능한 코드 예시를 정리한다

2026-08-12 · 최초 발행 2025-12-12

배터리·메모리·연결성이 항상 부족한 환경에서 실시간 추론을 돌려야 하는 게 엣지 AI의 출발점이다. 학습된 모델을 그대로 얹을 수 없으니 내보내기·경량화·배포·운영까지 전 과정을 절차로 만들어야 한다.

TinyML, ONNX, Pruning, Quantization이 각각 맡는 역할

TinyML은 수십 KB~수 MB급 메모리와 저전력 MCU·모바일·임베디드에서 ML 모델을 실행하는 접근이다. 지연시간·전력·온디바이스 개인정보 보호 요구를 동시에 만족시켜야 한다. ONNX(Open Neural Network Exchange)는 프레임워크 중립적인 모델 교환 포맷이자 런타임 생태계로, PyTorch·TF 등에서 내보낸 모델을 ONNX Runtime과 다양한 Execution Provider(EP)로 하드웨어 가속한다.

Pruning은 중요도가 낮은 가중치나 채널을 제거해 모델을 희소화하는 기법이다. 비구조화(unstructured) 방식과 구조화(channel/2:4 등) 방식이 있는데, 구조화 방식이 하드웨어 최적화에 유리하다. Quantization은 부동소수점 가중치·활성값을 INT8/UINT8 같은 저정밀도로 표현하는 기법으로, 정적(PTQ)과 학습 시 양자화(QAT), per-tensor 대 per-channel, 대칭 대 비대칭 선택이 핵심 결정 포인트다. PTQ는 사후 보정만으로 구현이 간단하고 속도 이득이 크지만 정확도 저하 위험이 있고, QAT는 학습 과정에 양자화 노이즈를 포함시켜 정확도를 잘 유지하는 대신 학습 비용이 늘어난다.

여러 갈래로 나뉘는 실행 전략

경량화 전략은 Pruning으로 파라미터·MAC을 줄이고 Quantization으로 메모리·대역폭을 절감하는 조합이 기본이다. N:M 구조화 희소성(예: 2:4)을 적용하면 TensorRT·Ampere 등에서 가속 효율이 극대화된다.

ONNX 중심 배포 체계는 학습 프레임워크 독립성을 확보하고 하드웨어별 최적 EP를 고를 수 있게 해준다. 모델 검증·A/B 전개·롤백을 단일 포맷으로 처리하니 운영 복잡도가 줄어든다.

런타임·가속기 선택은 ONNX Runtime과 TensorRT, CUDA, OpenVINO, CoreML, NNAPI, DirectML 같은 EP 조합으로 기기별 성능을 끌어올린다. 지원 연산자·opset 호환성 점검은 필수 절차다.

정확도-성능 균형 관리는 정밀도 저하 허용 한계(예: 1%p)와 지연시간·전력 SLO를 먼저 정의하고, PTQ에서 QAT로 점진 적용하며 per-channel INT8·대칭/비대칭 선택으로 품질을 맞춘다.

관측·운영은 온디바이스 텔레메트리(지연시간/온도/전력)와 샘플링 기반 정확도 모니터링, 모델 서명·무결성 검증, 점진적 롤아웃으로 이어진다.

절차와 품질 게이트

전체 흐름은 데이터/모델 학습 → ONNX 내보내기(opset 검증) → Pruning 적용 → PTQ 시도, 품질 저하 시 QAT → EP 호환성·성능 튜닝 → 온디바이스 검증·배포 순이다. 품질 게이트는 정확도 손실 ≤ 1%p, 지연시간 목표 달성(예: p95 < 20ms), 메모리 피크 ≤ 기기 한계(예: 50MB), 배터리 부담 ≤ 기준(예: 30분당 < 3% 소모)으로 건다.

전처리/증강검증 정확도 = 기준검증 정확도 < 기준연산자 호환성 검사 통과미지원 연산자 발생희소성 목표 달성정확도 급락 발생정확도 손실 <= 1%p정확도 손실 1%pEP 가용성 OKEP 미가용: 대체 EP 선택성능 기준 충족기준 미달: 튜닝/재학습입력: 학습 데이터/모델아키텍처처리: 모델 학습검증(PyTorch/TF)처리: ONNX 내보내기(opset검증)처리: Pruning적용(구조화/비구조화)처리:Quantization(PTQ→QAT)처리: 호환성 검사(연산자/EP)처리: 성능·정확도 평가(p95지연시간, 전력)출력: 엣지 배포(ONNXRuntime + EP)

무엇을 골라야 하는가

접근 성능(지연시간) 확장성 일관성 안정성 운영 편의
FP32 베이스라인 1.0x 기준, CPU 지연 높음 보편적 높음 높음 단순함
Pruning 50% 1.3~2.0x, 하드웨어 의존
PTQ INT8 24x, 메모리 34x 절감 높음 높음
QAT INT8 2~5x, 정확도 유지 우수 높음
ORT + EP(TensorRT/OpenVINO/NNAPI) 3~10x, 플랫폼 최적 높음 드라이버/런타임 관리 필요

실제 배치는 표의 한 줄만 고르기보다 Pruning + PTQ/QAT + ORT/EP를 조합하는 편이 낫다.

최소 구성으로 직접 돌려보기

전제조건은 Python 3.10, PyTorch 2.3+, onnx 1.16+, onnxruntime 1.19+(필요 시 onnxruntime-gpu/-tensorrt/-openvino)와 CUDA 12.x 또는 해당 플랫폼 런타임이다.

먼저 작은 CNN을 만들고 비구조화 L1 Pruning으로 50%를 솎아낸다.

# pip install torch torchvision onnx onnxruntime onnxruntime-tools onnxruntime-extensions onnxruntime-gpu
import torch, torch.nn as nn, torch.nn.utils.prune as prune

class SmallCNN(nn.Module):
    def __init__(self, num_classes=10):
        super().__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(1, 16, 3, padding=1), nn.ReLU(),
            nn.Conv2d(16, 16, 3, padding=1), nn.ReLU(),
            nn.AdaptiveAvgPool2d(1)
        )
        self.fc = nn.Linear(16, num_classes)

    def forward(self, x):
        x = self.conv(x).view(x.size(0), -1)
        return self.fc(x)

model = SmallCNN().eval()
# 간단한 Pruning: 비구조화 L1 50%
parameters_to_prune = [(model.conv[0], 'weight'), (model.conv[2], 'weight'), (model.fc, 'weight')]
for m, name in parameters_to_prune:
    prune.l1_unstructured(m, name=name, amount=0.5)
# 실제 가중치에 마스크 적용 고정
for m, name in parameters_to_prune:
    prune.remove(m, name)

ONNX로 내보내고 checker로 검증한다.

import onnx
dummy = torch.randn(1, 1, 28, 28)
torch.onnx.export(
    model, dummy, "model.fp32.onnx", opset_version=17,
    input_names=['input'], output_names=['logits'],
    dynamic_axes={'input': {0: 'batch'}, 'logits': {0: 'batch'}}
)
onnx.checker.check_model(onnx.load("model.fp32.onnx"))
print("Exported:", "model.fp32.onnx")

PTQ(동적 양자화)를 적용한다.

from onnxruntime.quantization import quantize_dynamic, QuantType
quantize_dynamic(
    model_input="model.fp32.onnx",
    model_output="model.int8.onnx",
    weight_type=QuantType.QInt8  # 가중치 INT8, 활성값은 런타임 계산
)
print("Quantized:", "model.int8.onnx")

마지막으로 가용 EP를 자동 선택하고 폴백까지 갖춘 추론 코드다.

import onnxruntime as ort, numpy as np, time
all_eps = [
    "TensorrtExecutionProvider", "CUDAExecutionProvider",
    "OpenVINOExecutionProvider", "CoreMLExecutionProvider",
    "DmlExecutionProvider", "NNAPIExecutionProvider",
    "CPUExecutionProvider"
]
available = [ep for ep in all_eps if ep in ort.get_available_providers()]
sess = ort.InferenceSession("model.int8.onnx", providers=available)
print("Using EPs:", sess.get_providers())

x = np.random.randn(1,1,28,28).astype(np.float32)
for _ in range(3):
    t0 = time.time()
    y = sess.run(["logits"], {"input": x})
    print("latency_ms:", (time.time()-t0)*1000)

미지원 연산자가 나오면 onnxruntime-tools의 op 변환이나 모델 재구성, opset 하향/상향을 검토한다. 정확도가 급락하면 per-channel 양자화, 대칭/비대칭 재설정, QAT 전환 순으로 대응한다. EP 초기화가 실패하면 우선순위 리스트 기반 폴백을 두고 CPU EP는 항상 보장해둔다.

보안·운영에서 놓치기 쉬운 부분

모델 무결성·비밀성은 서명/검증(Ed25519)과 암호화 저장(AES-GCM), 부트 체인 신뢰 확보가 기본이다. 다만 시작 지연과 키 관리 복잡도가 늘어나는 트레이드오프가 따른다. 온디바이스 프라이버시는 민감 데이터를 로컬에서만 추론하고 원천 데이터는 전송하지 않는 원칙을 지키되, 통계적 텔레메트리만 업링크하면 원격 디버깅이 제한된다는 대가가 있다. 롤아웃은 1%→10%→100%로 점진 배포하고 성능·정확도 가드레일 기반 자동 롤백을 두는데, 이 역시 배포 속도를 늦춘다. 모니터링은 p95/p99 지연, 온도/전력, 메모리 피크를 추적하고 모델·런타임 버전 핑거프린트를 수집해 재현성을 보장한다.

현장 사례

제조 비전 검사는 고장·불량 탐지 CNN을 Pruning + INT8 PTQ로 경량화한 뒤 Jetson/NUC에 배포하고, ONNX Runtime + TensorRT/OpenVINO로 30fps 이상 실시간 검사를 달성한다. 라인이 바뀌면 소량 데이터로 QAT 파인튜닝을 돌려 정확도를 회복하고 동적으로 재배포한다.

음성 키워드 감지(Always-on)는 1D CNN/DS-CNN을 TinyML 규모(수백 KB)로 축소해 MCU·모바일에서 상시 대기시킨다. PTQ로 지연을 5~10ms 범위에 묶고 배터리 소모를 최소화하며, 노이즈 환경이 바뀌면 온디바이스 임계값 조정과 경량 리트레이닝으로 대응한다.

스마트 미터·센서 이상탐지는 시계열 오토인코더/TCN 모델을 구조화 Pruning + INT8로 배포해 엣지에서 이상점만 전송한다. 이것만으로 네트워크 부하가 80% 이상 줄고, 펌웨어 OTA와 함께 모델 롤업데이트를 통합 운영한다.

실측 개선 폭

Pruning 50% + INT8 기준으로 파라미터 수는 2배 줄고 모델 파일은 34배 작아진다(예: 20MB → 57MB). 지연시간은 CPU 기준 24배, 하드웨어 가속 시 310배 개선된다(예: 40ms → 1015ms, FPS 35배 증가). 연산·메모리 대역폭 절감으로 전력은 3070% 줄고, 셀룰러 송신 데이터가 줄면서 통신비도 함께 내려간다. 품질 면에서 QAT 적용 시 정확도 손실은 00.5%p 수준으로 유지되고, PTQ만 쓰면 0~2%p 범위를 기대할 수 있다.

엣지 AI 도입의 병목은 결국 기기 제약과 운영 복잡성이다. ONNX 파이프라인 위에 Pruning·Quantization을 표준 절차로 내재화하고 EP 기반 하드웨어 최적화를 병행하면 성능·비용·품질의 균형을 맞출 수 있다. PTQ에서 QAT로 단계적으로 옮겨가면서 품질 게이트와 롤아웃 자동화를 함께 구축하는 순서를 권한다.

엣지AITinyMLONNX모델경량화양자화