본문 바로가기
C.W.K.
Stream
Lesson 04 of 06 · published

엣지 배포: ExecuTorch, Core ML, MLX

~14 min · executorch, coreml, mlx, edge

Level 0텐서 탐구자
0 XP0/62 lessons0/13 achievements
0/120 XP to next level120 XP to go0% complete

서버 GPU를 벗어나는 세 가지 경로

서버 추론만이 유일한 배포 방식은 아니야. 모바일과 엣지 환경은 요구 사항이 크게 다르며 PyTorch 생태계에는 이를 위한 전용 도구가 있어:

  • ExecuTorch: PyTorch의 모바일·엣지 실행 환경이야. iOS, Android, 마이크로컨트롤러를 대상으로 하며 기존 PyTorch Mobile의 후속 경로야.
  • Core ML: Apple의 기기 내 머신러닝 프레임워크야. iOS와 macOS에서 높은 성능을 내며 coremltools를 통해 PyTorch 모델을 변환할 수 있어.
  • MLX: Apple Silicon을 위해 Apple이 만든 네이티브 머신러닝 프레임워크야. 통합 메모리 구조를 중심으로 설계되어 Mac이나 iPhone에서 성능을 끝까지 끌어내고 싶을 때 적합해.

변환 흐름

ExecuTorch와 Core ML의 현대적인 경로는 비슷해. 먼저 torch.export로 그래프를 포착한 뒤 실행 환경에 맞는 형식으로 변환해. ExecuTorch는 앱에 넣을 .pte 파일을 만들고 Core ML은 .mlpackage를 만들어.

MLX에서는 PyTorch 가중치를 MLX 형식으로 변환하거나 모델을 MLX로 직접 다시 구현하는 두 방법이 있어. 가중치 변환은 여러 구조에서 작동하고, 직접 구현하면 이식 노력이 들지만 가장 좋은 성능을 얻을 수 있어.

Code

ExecuTorch: 모바일용 내보내기·python
# pip install executorch
import torch
from executorch.exir import to_edge

class TinyMLP(torch.nn.Module):
    def __init__(self): super().__init__(); self.fc = torch.nn.Linear(10, 4)
    def forward(self, x): return self.fc(x)

model = TinyMLP().eval()
example = torch.randn(1, 10)

# 1. Export with torch.export
exported = torch.export.export(model, (example,))

# 2. Lower to ExecuTorch's edge IR
edge = to_edge(exported)

# 3. Optimize and serialize
et_program = edge.to_executorch()
with open('/tmp/tiny.pte', 'wb') as f:
    f.write(et_program.buffer)

# .pte ships with your iOS / Android app
Core ML: Apple 장치 배포·python
# pip install coremltools
import torch
import coremltools as ct

class TinyMLP(torch.nn.Module):
    def __init__(self): super().__init__(); self.fc = torch.nn.Linear(10, 4)
    def forward(self, x): return self.fc(x)

model = TinyMLP().eval()
example = torch.randn(1, 10)

# Trace the model (CoreML's converter still uses tracing under the hood)
traced = torch.jit.trace(model, example)

mlmodel = ct.convert(
    traced,
    inputs=[ct.TensorType(shape=example.shape, name='x')],
    convert_to='mlprogram',                # modern MLProgram format
    minimum_deployment_target=ct.target.macOS14,
)
mlmodel.save('/tmp/tiny.mlpackage')

# Drop the .mlpackage into Xcode and you have a CoreML model
MLX: 네이티브 Apple Silicon, 두 경로·python
# pip install mlx mlx-lm
import mlx.core as mx
import mlx.nn as nn

# Path 1: re-implement in MLX (best performance)
class MLXMLP(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc = nn.Linear(10, 4)
    def __call__(self, x):
        return self.fc(x)

model = MLXMLP()
x = mx.random.normal((1, 10))
y = model(x)                                  # eager-style execution
mx.eval(y)                                     # force evaluation
print(y.shape)                                 # (1, 4)

# Path 2: load PyTorch weights into MLX
# Many community projects (mlx_lm) support direct loading of HF checkpoints.
# from mlx_lm import load
# model, tokenizer = load("mlx-community/Llama-3.2-3B-Instruct-4bit")
하드웨어별 배포 정답 고르기·python
# A quick decision table:
#
# Target               | Recommended path
# --------------------- | ----------------------------------------------------
# iOS / iPadOS         | CoreML (best Apple integration) or ExecuTorch
# Android              | ExecuTorch (with NNAPI / Vulkan delegate)
# macOS (Apple Silicon)| MLX (native) or CoreML
# Linux server (GPU)   | torch.compile + bf16, or vLLM for LLMs
# Linux server (CPU)   | torch.compile + ONNX Runtime, OpenVINO
# NVIDIA Jetson / edge | TensorRT (via ONNX export)
# Browser              | ONNX Runtime Web, transformers.js

External links

Exercise

TinyMLP 모델을 ExecuTorch(.pte), Core ML(.mlpackage) 두 형식으로 내보내고, Apple Silicon을 사용한다면 MLX로도 다시 구현해 봐. 파일 크기를 비교하고 같은 입력에서 각 구현이 같은 출력을 내는지 검증해. 이 연습을 통해 PyTorch 모델을 다른 실행 환경으로 옮기는 전체 과정을 익힐 수 있어.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.