Skip to main content

엣지 배포

엣지 배포(Edge Deployment)는 학습된 모델을 서버가 아닌 엣지 디바이스(Jetson, 모바일, 임베디드 보드)에서 직접 실행하는 전략입니다. 네트워크 지연 없이 실시간 추론이 가능하며, 프라이버시와 오프라인 환경에서도 동작합니다.
1
엣지 배포 전략 수립
2
3
디바이스GPU추천 런타임모델 포맷대표 활용NVIDIA JetsonGPU 내장TensorRT.engine산업용 실시간 추론AndroidGPU/NPUTFLite, ONNX RT.tflite, .onnx모바일 앱iOSNeural EngineCoreML.mlmodeliOS 앱Raspberry Pi없음ONNX Runtime.onnxIoT, 프로토타입
4
경량 모델 선택
5
엣지 환경에서는 경량 아키텍처를 사용하면 속도와 정확도를 균형 있게 확보할 수 있습니다.
6
import timm

# 경량 분류 모델 비교
lightweight_models = {
    'mobilenetv3_small_100': '2.5M params, 모바일 최적화',
    'mobilenetv3_large_100': '5.5M params, 모바일 고성능',
    'efficientnet_lite0': '4.7M params, 엣지 최적화',
    'efficientnet_b0': '5.3M params, 범용 경량',
}

for model_name, desc in lightweight_models.items():
    model = timm.create_model(model_name, pretrained=True, num_classes=5)
    params = sum(p.numel() for p in model.parameters()) / 1e6
    print(f"{model_name}: {params:.1f}M 파라미터 — {desc}")
7
모델파라미터ImageNet Top-1추론 속도 (CPU)추천 환경MobileNetV3-Small2.5M67.4%매우 빠름모바일, IoTMobileNetV3-Large5.5M75.2%빠름모바일 고성능EfficientNet-Lite04.7M75.1%빠름엣지 범용EfficientNet-B05.3M77.1%보통서버/엣지YOLOv11n2.6M-매우 빠름엣지 탐지
8
NVIDIA Jetson 배포
9
Jetson은 GPU가 내장된 엣지 컴퓨터로, TensorRT를 사용하면 최대 성능을 끌어낼 수 있습니다.
10
# Jetson에서 YOLO 모델 배포
from ultralytics import YOLO

# 1. TensorRT 엔진 생성 (Jetson에서 실행)
model = YOLO('yolo11n.pt')
model.export(
    format='engine',
    imgsz=640,
    half=True,      # FP16 (Jetson GPU 지원)
    device=0,
)

# 2. TensorRT 엔진으로 추론
engine_model = YOLO('yolo11n.engine')
results = engine_model('image.jpg')

# 3. 실시간 카메라 추론
import cv2

cap = cv2.VideoCapture(0)  # CSI 카메라 또는 USB 카메라
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    results = engine_model(frame, verbose=False)
    annotated = results[0].plot()

    cv2.imshow('Jetson Inference', annotated)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
11
# Jetson 환경 확인 명령어
# JetPack 버전 확인
cat /etc/nv_tegra_release

# GPU 사용률 모니터링
tegrastats

# CUDA 버전 확인
nvcc --version
12
Jetson에서 TensorRT 엔진은 해당 디바이스에서 직접 빌드해야 합니다. 호스트 PC에서 생성한 .engine 파일은 Jetson에서 동작하지 않습니다.
13
ONNX Runtime 배포 (범용)
14
ONNX Runtime은 CPU, GPU, NPU 등 다양한 하드웨어에서 범용적으로 사용할 수 있습니다.
15
import onnxruntime as ort
import numpy as np
import cv2

# Execution Provider 확인
print(ort.get_available_providers())
# CPU: ['CPUExecutionProvider']
# GPU: ['CUDAExecutionProvider', 'CPUExecutionProvider']

# 세션 생성 (디바이스에 맞는 Provider 자동 선택)
providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
session = ort.InferenceSession('model.onnx', providers=providers)

# 입력 정보 확인
input_info = session.get_inputs()[0]
print(f"입력 이름: {input_info.name}")
print(f"입력 형태: {input_info.shape}")
print(f"입력 타입: {input_info.type}")

# 이미지 전처리
def preprocess(image_path, input_size=(224, 224)):
    """추론용 이미지를 전처리합니다."""
    img = cv2.imread(image_path)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = cv2.resize(img, input_size)
    img = img.astype(np.float32) / 255.0

    # ImageNet 정규화
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    img = (img - mean) / std

    # (H, W, C) -> (1, C, H, W)
    img = np.transpose(img, (2, 0, 1))
    img = np.expand_dims(img, axis=0).astype(np.float32)
    return img

# 추론 실행
input_data = preprocess('image.jpg')
outputs = session.run(None, {input_info.name: input_data})
predictions = outputs[0]
predicted_class = np.argmax(predictions, axis=1)[0]
confidence = np.max(predictions)
print(f"예측 클래스: {predicted_class}, 신뢰도: {confidence:.4f}")
16
TFLite 변환 (모바일 배포)
17
# PyTorch → ONNX → TFLite 변환 파이프라인
import torch

# 1. PyTorch 모델 로드
model = timm.create_model('mobilenetv3_small_100', pretrained=True, num_classes=5)
model.eval()

# 2. ONNX 변환
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
    model, dummy_input, 'mobilenet.onnx',
    input_names=['input'], output_names=['output'],
    opset_version=13,
)

# 3. ONNX → TFLite (onnx2tf 패키지 사용)
# pip install onnx2tf
# onnx2tf -i mobilenet.onnx -o tflite_model

# 4. Ultralytics YOLO는 직접 TFLite Export 지원
from ultralytics import YOLO

yolo = YOLO('yolo11n.pt')
yolo.export(format='tflite', imgsz=320)  # 모바일용 작은 해상도
18
성능 벤치마크 비교
19
import time
import numpy as np

def benchmark_inference(model_fn, input_data, n_warmup=10, n_runs=100):
    """추론 성능을 벤치마크합니다."""
    # 워밍업
    for _ in range(n_warmup):
        model_fn(input_data)

    # 측정
    latencies = []
    for _ in range(n_runs):
        start = time.perf_counter()
        model_fn(input_data)
        latencies.append((time.perf_counter() - start) * 1000)

    latencies = np.array(latencies)
    print(f"평균: {latencies.mean():.2f} ms")
    print(f"중간값: {np.median(latencies):.2f} ms")
    print(f"95th: {np.percentile(latencies, 95):.2f} ms")
    print(f"FPS: {1000 / latencies.mean():.1f}")

# ONNX Runtime 벤치마크
input_data = np.random.randn(1, 3, 224, 224).astype(np.float32)
benchmark_inference(
    lambda x: session.run(None, {'input': x}),
    input_data,
)

디바이스별 배포 가이드

항목Jetson Orin NanoRaspberry Pi 5모바일 (Android)
런타임TensorRTONNX RuntimeTFLite
정밀도FP16FP32/INT8FP16/INT8
추천 모델YOLOv11sYOLOv11nMobileNetV3
입력 크기640x640320x320224x224
예상 FPS30~605~1515~30
전력 소비7~15W3~5W배터리 의존

엣지 배포 최적화 체크리스트

엣지 디바이스는 메모리와 연산 자원이 제한적입니다. 서버에서 잘 동작하던 모델도 엣지에서는 OOM(Out of Memory)이 발생할 수 있으므로, 반드시 대상 디바이스에서 직접 테스트하세요.
GPU가 필요한 딥러닝 추론(YOLO, 세그멘테이션 등)에는 Jetson을 추천합니다. 경량 분류나 간단한 이미지 처리만 필요하다면 Raspberry Pi가 비용 면에서 유리합니다. Jetson Orin Nano는 약 199,RaspberryPi5는약199, Raspberry Pi 5는 약 60입니다.
입력 해상도를 줄이면 추론 속도는 크게 향상되지만, 작은 객체 탐지 성능이 저하될 수 있습니다. 640x640에서 320x320으로 줄이면 속도가 약 4배 빨라지지만, mAP는 5~15% 감소할 수 있습니다. 대상 환경에서 요구하는 정확도 기준에 맞춰 조정하세요.