Skip to content

✍️ 필사 모드: MLX 심층 분석 — Apple Silicon용 ML 프레임워크, 통합 메모리·지연 그래프·Mac 네이티브 워크플로 (2026 핸즈온)

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

프롤로그 — Mac에서 LLM이 빨라진 진짜 이유

2023년 말, Apple ML 팀이 조용히 하나의 프레임워크를 깃허브에 올렸다. 이름은 mlx. 만든 사람들은 익숙한 얼굴이다 — PyTorch와 JAX의 핵심 기여자들. 이번에는 NVIDIA GPU도, TPU도 아니라 Apple Silicon만을 위해 다시 쓴 배열 프레임워크다.

2년이 지난 2026년, Mac에서 로컬 LLM을 돌리는 사람들의 워크플로는 거의 다 MLX로 수렴했다. LM Studio, Ollama, Hugging Face 데모, 그리고 수많은 인디 개발자들의 데스크탑 앱이 백엔드로 MLX를 쓴다.

이유는 단 하나의 명제로 요약된다.

"M 시리즈 GPU는 CPU와 같은 RAM을 쓴다. 그래서 호스트와 디바이스 사이에 복사가 없다."

이 한 문장이 PyTorch의 MPS 백엔드를 압도하는 성능 격차를 설명한다. 이 글은 그 명제를 처음부터 끝까지 펼친다 — 통합 메모리, 지연 그래프, mlx-lm·mlx-vlm, Python과 Swift, 그리고 실제 워크로드에서의 토큰/초 수치까지.


1장 · 통합 메모리 명제 — MLX의 출발점

Apple Silicon의 메모리 아키텍처는 NVIDIA와 다르다. 거기서부터 시작해야 한다.

NVIDIA 시스템에서 GPU는 자기 자신의 VRAM을 가지고 있다. CPU의 RAM과 GPU의 VRAM은 물리적으로 다른 칩이고, 둘 사이의 데이터는 PCIe를 통해 명시적으로 복사돼야 한다.

       전통적 GPU (NVIDIA)              Apple Silicon (M-series)
       ─────────────────              ────────────────────────
       ┌────┐    PCIe    ┌─────┐      ┌─────────────────────┐
       │CPU │ ◀────────▶ │ GPU │      │    CPU  +  GPU      │
       │RAM │            │VRAM │      │   같은 메모리 풀     │
       └────┘            └─────┘      └─────────────────────┘
       복사가 필요함                    복사가 없음

PyTorch의 일반적 패턴은 이 분리를 전제로 한다. x.to("cuda"), tensor.cpu() — 이 한 줄 한 줄이 PCIe를 거치는 복사다. 큰 모델에서 이 복사는 추론 지연의 상당 부분을 차지한다.

Apple Silicon에선 CPU와 GPU가 같은 메모리 풀을 본다. 즉, 같은 텐서를 CPU가 만들고 GPU가 읽을 수 있다 — 복사 없이, 포인터만으로. 이걸 통합 메모리(unified memory) 라고 한다.

MLX는 이 사실을 프레임워크의 가장 깊은 곳에 박아 넣었다. MLX에서 배열은 디바이스를 모른다 — 디바이스는 연산 시점에 결정된다.

import mlx.core as mx

a = mx.array([1.0, 2.0, 3.0])
b = mx.array([4.0, 5.0, 6.0])

# CPU에서 계산
c_cpu = mx.add(a, b, stream=mx.cpu)
# GPU에서 계산 — 같은 a, b. 복사 없음.
c_gpu = mx.add(a, b, stream=mx.gpu)

PyTorch라면 a.to("mps")가 필요했을 것이다. MLX에선 그 호출이 아예 존재하지 않는다. "디바이스로 옮긴다"는 개념 자체가 없다.

이건 단순한 API 차이가 아니다. 이건 Mac에서 LLM이 빠른 이유 그 자체다.


2장 · MLX vs PyTorch MPS vs JAX-Metal vs llama.cpp

같은 Mac에서 LLM을 돌리는 방법은 여럿이다. 각각이 어떤 명제를 가지는지부터 정리하자.

옵션명제장점단점
MLXApple Silicon만을 위한 네이티브 프레임워크통합 메모리·지연 그래프·풀 GPU 활용Apple Silicon 전용·생태계 작음
PyTorch MPSPyTorch에 Metal 백엔드를 추가기존 PyTorch 코드 거의 그대로CUDA-스타일 어댑테이션·4GB 텐서 캡·느림
JAX-MetalJAX의 실험적 Metal 백엔드JAX 코드 재사용실험적·기능 갭·갱신 느림
llama.cppC++ 기반 추론 엔진(Metal/CPU/CUDA)어디서나 동작·작은 푸트프린트추론만·미세조정 안 됨

PyTorch MPS는 어디까지 "괜찮은가"

PyTorch의 Metal Performance Shaders 백엔드는 CUDA-스타일 연산을 Metal에 어댑테이션한다. 이게 두 가지 문제를 만든다.

  1. 메모리 모델이 통합 메모리에 최적화돼 있지 않다. PyTorch는 여전히 "디바이스 메모리"라는 개념으로 텐서를 본다. 그래서 통합 메모리의 이점을 충분히 활용하지 못한다.
  2. 텐서 크기 제한이 있다. PyTorch MPS는 약 4GB의 텐서 캡이 있어, 약 2k 토큰 이상의 컨텍스트에서 자주 OOM이 난다.

벤치마크에서 차이가 극명하게 드러난다 — Llama 추론에서 MLX는 약 230 토큰/초, PyTorch MPS는 7~9 토큰/초 수준으로 보고된다(같은 칩, 같은 모델). 한 자릿수 vs 세 자릿수다.

언제 PyTorch MPS로 충분한가: 학습 코드를 빠르게 옮겨와서 작은 실험만 할 때, 또는 CUDA를 가진 클러스터로 옮기기 전 단계의 프로토타이핑. 프로덕션 로컬 추론에는 안 맞는다.

JAX-Metal — 흥미롭지만 실험적

Apple의 JAX-Metal 플러그인은 존재한다. 작동도 한다. 그런데 실험적이고, JAX의 모든 기능을 지원하지 않으며, 갱신이 느리다. 이미 JAX로 쓴 코드를 Mac에서 돌리고 싶을 때만 의미가 있다.

llama.cpp — CPU만으로 충분할 때

llama.cpp는 C++로 쓴 추론 엔진이다. Metal·CUDA·CPU 어디서나 돌고, 푸트프린트가 작고, 양자화 모델 포맷(gguf)이 사실상의 표준이 됐다.

llama.cpp가 더 나은 시나리오:

  • 임베디드/CLI 환경에서 작은 푸트프린트로 추론만 하고 싶을 때.
  • Mac과 Linux를 동시에 지원해야 할 때.
  • 미세조정은 다른 곳에서 하고, 로컬은 추론만 할 때.

MLX가 더 나은 시나리오:

  • 미세조정도 같은 Mac에서 하고 싶을 때.
  • Swift 앱(iOS/macOS)에 내장하고 싶을 때.
  • Python에서 텐서를 직접 다루고 새로운 모델 구조를 실험할 때.

3장 · 지연 계산 그래프 — JAX의 후예

MLX의 또 다른 핵심 설계 결정은 지연(lazy) 평가다. 같은 팀이 JAX에서 가져온 아이디어다.

PyTorch의 기본 동작은 즉시(eager) 다. a + b를 부르면 그 자리에서 계산이 일어난다. MLX는 그렇지 않다 — mx.add(a, b)계산 그래프 노드만 만들고, 실제 연산은 결과가 필요한 시점에 한다.

import mlx.core as mx

a = mx.array([1.0, 2.0, 3.0])
b = mx.array([4.0, 5.0, 6.0])

# 이 시점에는 아직 아무것도 계산되지 않았다
c = a + b           # 그래프 노드만 생성
d = c * 2.0          # 또 다른 노드

# 결과를 "구체화"할 때 비로소 계산이 일어난다
mx.eval(d)
# 또는 print(d) 같은 호출이 암묵적으로 eval을 부른다

왜 이게 좋은가:

  1. 연산 융합(operator fusion)a + bc * 2.0을 하나의 Metal 커널로 합칠 수 있다. 메모리 왕복이 줄고, GPU 점유율이 올라간다.
  2. 메모리 할당 최적화 — 중간 결과를 실제로 메모리에 안 만들 수도 있다.
  3. 그래프 단위 최적화 — JAX의 jit과 같은 컴파일이 가능하다(MLX의 mx.compile).

즉시 평가가 그리울 때는 언제인가: 디버깅. print(x)로 매 단계 값을 보고 싶을 때는 PyTorch가 더 직관적이다. MLX에선 mx.eval(x)을 명시적으로 호출하거나 print/numpy 변환을 통해 값을 강제로 구체화해야 한다.

이건 트레이드오프지만, 로컬 LLM처럼 같은 그래프를 반복 실행하는 워크로드에선 지연 평가의 이점이 압도적이다.


4장 · mlx-lm — LLM 추론과 미세조정의 표준 도구

MLX 자체는 저수준 배열 라이브러리다. LLM을 직접 쓰려면 mlx-lm을 깐다.

pip install mlx-lm

이걸로 할 수 있는 것:

  • HuggingFace 모델 다운로드와 변환 — Llama·Qwen·DeepSeek·Phi·Mistral 등 거의 모든 트랜스포머 계열.
  • 양자화 — 4비트/8비트로 줄여 메모리에 맞춘다.
  • 로컬 추론 — CLI 한 줄, 또는 Python에서.
  • OpenAI 호환 서버 모드mlx_lm.server로 띄우면 OpenAI SDK가 그대로 붙는다.
  • LoRA·QLoRA·DoRA 미세조정 — 같은 명령으로.

CLI로 Llama 3.x 돌리기

# 4비트 양자화 Llama 3.1 8B를 다운로드하고 추론
mlx_lm.generate \
  --model mlx-community/Meta-Llama-3.1-8B-Instruct-4bit \
  --prompt "Apple Silicon이 LLM에 유리한 이유를 한 단락으로." \
  --max-tokens 256

이 한 줄로 모델 다운로드, 변환, 양자화 적용, 토큰 생성이 다 끝난다. 처음 실행할 때만 모델을 받고, 그 뒤로는 캐시를 쓴다.

Python에서 직접

from mlx_lm import load, generate

model, tokenizer = load("mlx-community/Qwen2.5-7B-Instruct-4bit")

response = generate(
    model,
    tokenizer,
    prompt="MLX의 통합 메모리 이점을 3줄로.",
    max_tokens=256,
    temp=0.7,
)
print(response)

load()는 모델과 토크나이저를 함께 반환한다. generate()는 텍스트를 만든다. 이게 사실상 끝이다 — 별도의 .to(device)도, .eval() 모드 전환도 없다.

OpenAI 호환 서버

mlx_lm.server --model mlx-community/Meta-Llama-3.1-8B-Instruct-4bit --port 8080

띄워두면 OpenAI Python SDK가 base_url="http://localhost:8080/v1"만 바꿔서 그대로 붙는다. 데스크탑 앱이나 LangChain/LangGraph 같은 프레임워크에서 로컬 Mac을 추론 백엔드로 쓸 때 이 패턴을 가장 많이 본다.


5장 · mlx-vlm — 비전-언어 모델

텍스트만으로는 부족할 때, mlx-vlm이 있다.

pip install mlx-vlm

지원 모델은 LLaVA, Qwen-VL, Phi-Vision, Idefics, PaliGemma 등 주요 VLM 패밀리들. 사용법은 mlx-lm과 흡사하다.

from mlx_vlm import load, generate

model, processor = load("mlx-community/Qwen2-VL-7B-Instruct-4bit")

response = generate(
    model,
    processor,
    image="./screenshot.png",
    prompt="이 화면에 표시된 에러 메시지를 한국어로 요약해라.",
    max_tokens=256,
)
print(response)

왜 Mac에서 VLM이 의미 있나: 스크린샷·문서·UI 캡처를 다루는 로컬 워크플로(노트 앱, 자동화 도구, 접근성 보조)에선 이미지를 클라우드로 보내지 않아도 되는 게 큰 가치다. 그리고 통합 메모리 덕에 큰 이미지를 GPU에 복사하는 오버헤드가 없다.


6장 · Python과 Swift — 같은 코어, 다른 입구

MLX의 코어는 C++로 짜였고, 그 위에 Python과 Swift 두 개의 고수준 API가 있다. (C와 C++ 핵심 연산도 노출돼 있다.)

   ┌─────────────────────────────────────────┐
   │  Python API     │     Swift API         │
   │  (Jupyter,       │   (iOS·macOS·         │
   │   연구·서버)      │    visionOS 앱)        │
   ├─────────────────────────────────────────┤
   │              MLX 코어 (C++)              │
   │      배열·자동미분·지연 그래프            │
   ├─────────────────────────────────────────┤
   │            Metal 백엔드                  │
   │   (M 시리즈 GPU·Neural Accelerators)    │
   └─────────────────────────────────────────┘

Python API — 연구와 서버 쪽

mlx.core로 배열·연산을 쓰고, mlx.nn으로 모듈을 만들고, mlx.optimizers로 옵티마이저를 쓴다. PyTorch와 거의 1:1로 대응되는 API라 마이그레이션 비용이 낮다.

import mlx.core as mx
import mlx.nn as nn

class SmallModel(nn.Module):
    def __init__(self, dim=128):
        super().__init__()
        self.linear1 = nn.Linear(dim, dim)
        self.linear2 = nn.Linear(dim, dim)
    def __call__(self, x):
        x = mx.maximum(self.linear1(x), 0.0)  # ReLU
        return self.linear2(x)

model = SmallModel()
x = mx.random.normal((4, 128))
y = model(x)
mx.eval(y)

Swift API — iOS·macOS·visionOS 앱

mlx-swift는 같은 코어를 Swift로 노출한다. 이게 흥미로운 이유: 학습은 Python에서 하고, 같은 가중치를 Swift 코드에서 그대로 로드해서 iOS 앱에 임베드할 수 있다. PyTorch라면 onnx/CoreML 변환이라는 추가 단계가 필요한 자리에, MLX는 같은 포맷·같은 코어를 쓴다.

import MLX
import MLXNN

let model = SmallModel()
let x = MLXRandom.normal([4, 128])
let y = model(x)
eval(y)

Mac·iPhone·iPad·Vision Pro에서 같은 모델 코드가 돈다. 이게 PyTorch나 JAX로는 흉내내기 힘든 자리다.


7장 · Metal 후드 — TensorOps와 Neural Accelerators

MLX의 GPU 백엔드는 Metal이다. Apple의 자체 그래픽·컴퓨트 API. CUDA에 직접 대응되는 자리.

M5 칩부터는 Metal 4의 TensorOpsMetal Performance Primitives 프레임워크를 통해 Neural Accelerators의 텐서 연산을 직접 노출한다. MLX는 이 위에서 행렬곱·attention·convolution 같은 핵심 연산을 받는다.

개발자 입장에서 알아야 할 것:

  • MLX 사용자는 Metal 코드를 직접 쓸 일이 거의 없다. 다만 새로운 연산을 추가하고 싶을 때 Metal shader를 작성할 수 있다.
  • 양자화는 MLX 내부에서 처리된다. 4비트/8비트 양자화가 Metal 커널 레벨에서 최적화돼 있다.
  • M2 → M3 → M4 → M5로 갈수록 GPU 코어, 메모리 대역폭, Neural Accelerators가 늘어난다. MLX 코드는 다시 컴파일할 필요 없이 새 칩에서 즉시 더 빨라진다.

8장 · 작은 미세조정 — M 시리즈에서 LoRA 한 바퀴

이론은 그만하고, 실제로 미세조정을 한 번 돌려보자. 시나리오: 5,000개 정도의 도메인 특화 Q&A로 Llama 3.1 8B를 LoRA 어댑테이션하기.

데이터 준비

mlx-lm의 LoRA는 JSONL 포맷을 받는다. 한 줄에 하나의 예시:

{"text": "<s>[INST] 질문 [/INST] 답변 </s>"}

또는 chat 템플릿을 그대로 쓰는 경우:

{"messages": [{"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}

data/ 디렉터리에 train.jsonl, valid.jsonl을 둔다.

LoRA 학습 명령

mlx_lm.lora \
  --model mlx-community/Meta-Llama-3.1-8B-Instruct-4bit \
  --train \
  --data ./data \
  --batch-size 4 \
  --lora-layers 16 \
  --iters 1000 \
  --learning-rate 1e-4 \
  --adapter-path ./adapters

4비트 양자화 모델에 --train 플래그를 같이 주면 자동으로 QLoRA가 된다 — 베이스 가중치는 4비트로 고정, LoRA 어댑터만 full precision으로 학습한다. M2 Pro에서 7B 모델·500 예시는 약 20~25분. M3 Max·128GB라면 70B 모델까지 QLoRA가 들어간다.

학습 후 추론

mlx_lm.generate \
  --model mlx-community/Meta-Llama-3.1-8B-Instruct-4bit \
  --adapter-path ./adapters \
  --prompt "도메인 질문..." \
  --max-tokens 256

학습 처리량의 현실

NVIDIA H100과 비교하면 학습 처리량은 한참 작다 — 대략 13 tok/s vs 3050 tok/s 수준. 즉, 시간 단위의 학습을 분 단위로 줄여주는 건 아니다. Apple Silicon에서의 미세조정은 다음과 같은 자리에 어울린다.

  • 프로토타이핑: 새 데이터셋·새 프롬프트 포맷 실험.
  • 실험과 학습: 미세조정 파이프라인의 동작을 익힐 때.
  • 소규모 도메인 어댑테이션: 수천수만 예시·7B32B 모델.

진짜 큰 작업은 여전히 클라우드 H100/A100이 더 경제적이다. MLX의 미세조정은 로컬 워크플로 안에서 닫힌 루프를 만들 때 진가가 발휘된다.


9장 · 성능 — M 시리즈별 토큰/초

벤치마크는 항상 모델·양자화·컨텍스트 길이·온도에 따라 다르다. 다만 2026년 5월 시점에서 자주 인용되는 대략적 수치는 다음과 같다(공개 보고들의 중앙값 근사).

모델M2 ProM3 MaxM4 MaxM2/M3 Ultra
Llama 3.1 8B (4bit)30~40 t/s60~85 t/s80~110 t/s100~140 t/s
Qwen 2.5 7B (4bit)30~45 t/s65~90 t/s90~120 t/s110~150 t/s
Qwen3 0.6B (4bit)~250 t/s~400 t/s~525 t/s~600 t/s
Llama 3.1 70B (4bit)(OOM)8~12 t/s10~15 t/s15~22 t/s

같은 PyTorch MPS 백엔드와 비교하면 MLX 쪽이 한 자릿수 이상 빠른 경우가 흔하다. 보고된 사례 중에는 같은 칩에서 MLX 230 t/s vs PyTorch MPS 79 t/s 같은 극단적 차이도 있다.

가장 강력한 명제: 미세조정과 추론을 같은 Mac에서, 같은 코드로 닫힌 루프로 돌릴 수 있다. 이게 NVIDIA 클라우드 워크플로에 비해 사라지지 않는 이점이다.


10장 · 실제 워크로드 — Llama·Qwen·DeepSeek 로컬

시나리오 1 — 노트북에서 코딩 어시스턴트

  • M3 Pro·36GB.
  • Qwen 2.5 Coder 7B·4bit.
  • mlx-lm 서버를 OpenAI 호환 모드로 띄우고, 에디터의 LLM 통합을 localhost:8080으로 향하게.
  • 토큰 약 50~70 t/s. 인터넷 없이도 동작.

시나리오 2 — 영업 노트 요약·로컬

  • M2 Air·16GB.
  • Llama 3.2 3B·4bit. (8B는 메모리 빠듯)
  • Python 스크립트가 회의 노트를 받아서 요약·다음 액션을 추출.
  • 모든 데이터가 디바이스 밖으로 나가지 않음.

시나리오 3 — 70B 추론 워크스테이션

  • Mac Studio M2 Ultra·192GB.
  • DeepSeek 70B·4bit 또는 Llama 3.1 70B·4bit.
  • mlx-lm 서버를 사내 네트워크에 노출. 팀 단위의 비용 효율 좋은 추론 백엔드.

시나리오 4 — VLM·문서 OCR/요약

  • M3 Max·64GB.
  • mlx-vlm + Qwen2-VL 7B·4bit.
  • 스크린샷·PDF 페이지 이미지를 받아서 텍스트 추출과 요약.

이 네 시나리오의 공통점: 모델·데이터·추론이 전부 한 박스 안에서 닫힌다. Mac이라는 폼팩터에서 이게 자연스러운 자리에 MLX가 있다.


11장 · 의사결정 프레임워크 — 언제 MLX, 언제 다른 것

                  로컬 추론이 필요한가?
                ┌─────────┴─────────┐
                ▼                   ▼
            예 (Mac)            아니오 (서버)
                │                   │
                ▼                   ▼
        미세조정도 같은 곳?       PyTorch + CUDA
        ┌───────┴───────┐
        ▼               ▼
       예              아니오
        │               │
        ▼               ▼
       MLX           추론만이면 → llama.cpp / Ollama
                     아직 PyTorch만 → MPS (성능 감수)
   iOS/Swift 통합 필요?
   ┌────┴────┐
   ▼         ▼
  예        아니오
   │         │
   ▼         ▼
 mlx-swift  Python MLX

빠른 의사결정 표

상황추천
Mac에서 로컬 LLM 추론 (개인용)MLX 또는 llama.cpp 기반 도구(Ollama, LM Studio)
Mac에서 로컬 미세조정 + 추론MLX (mlx-lm)
같은 모델을 iOS·macOS·visionOS 앱에 임베드MLX (mlx-swift)
기존 PyTorch 코드 빠르게 Mac에서 돌려보기PyTorch MPS (단, 한계 인지)
Mac과 Linux를 동시에 지원하는 추론 엔진llama.cpp
대규모 분산 학습NVIDIA + CUDA + PyTorch
JAX 코드를 Mac에서 굳이 돌려야 함JAX-Metal (실험적)

12장 · 한계와 트레이드오프

MLX는 마법이 아니다. 솔직하게 짚어야 한다.

Apple Silicon 전용

MLX는 Intel Mac에서도, Linux/Windows에서도 동작하지 않는다. 이건 디자인 결정이다 — Apple Silicon의 통합 메모리를 최적화하기 위해 만든 프레임워크니까. 같은 코드를 Linux 서버에서도 돌리려면 PyTorch나 JAX로 코드를 갖춰야 한다.

생태계가 PyTorch보다 작다

PyTorch의 huggingface, accelerate, deepspeed, axolotl 같은 거대한 생태계가 MLX엔 없다. mlx-community 허브에 변환된 모델이 많지만, 최신 모델이 PyTorch보다 며칠~몇 주 늦게 들어오는 일은 흔하다. 다만 mlx-lm이 Hugging Face 체크포인트를 자동으로 변환할 수 있어 갭이 빠르게 줄고 있다.

분산 학습 미성숙

여러 노드에 걸친 분산 학습은 MLX가 강한 자리는 아니다. 단일 Mac 또는 클러스터 내에서 같은 시스템의 GPU 자원을 활용하는 형태가 주 사용 자리다. 대규모 사전학습은 여전히 NVIDIA 클러스터의 영역이다.

디버깅의 미묘함

지연 평가는 가끔 헷갈린다. print(x)로 값을 보고 싶을 때, 사실은 그 시점까지 미뤄둔 그래프 전체가 한 번에 실행된다. 큰 그래프에선 디버그 시점이 곧 비용 시점이다. 명시적인 mx.eval()을 가끔 끼워 넣는 습관이 도움이 된다.

학습 처리량은 H100을 못 따라간다

미세조정 처리량은 H100의 한 자릿수 분의 일 수준이다. 큰 작업은 클라우드가 여전히 경제적이다.

Windows·Linux 워크플로와의 격차

팀의 메인 워크플로가 Linux Docker·NVIDIA·PyTorch라면, MLX를 핵심에 두기는 어렵다. 일부 멤버의 Mac 워크스테이션에서 보조적 도구로 두는 게 현실적이다.


13장 · MLX와 Mac 네이티브 미래 — 6개월 전망

2026년 후반 시점에서 보이는 트렌드:

  1. M5 세대와 TensorOps 활용 확대 — MLX는 이미 M5의 텐서 가속을 활용하고, 추가 성능 향상이 분기 단위로 나오고 있다.
  2. Ollama·LM Studio의 MLX 백엔드 통합 — Mac 사용자라면 MLX를 직접 안 써도 사실상 쓰게 되는 상황.
  3. mlx-vlm의 빠른 성장 — 멀티모달 모델이 Mac에서 1급 시민이 되는 중.
  4. Swift 진영의 강화 — mlx-swift-lm, 그리고 iOS/Vision Pro에서 LLM을 임베드하는 패턴.
  5. OpenAI 호환 서버 표준화 — 로컬 추론 백엔드가 사실상 OpenAI API로 노출되는 게 표준이 됨.

큰 그림에서 보면, MLX는 "Mac에서 ML을 하는 방식"의 기본 인프라가 되고 있다. 의식적으로 안 쓰는 게 더 어색해지는 자리.


에필로그 — Mac이 ML 워크스테이션이 된 진짜 이유

NVIDIA가 ML 인프라의 표준이 된 자리는 20년이 걸렸다. Apple Silicon이 ML 워크스테이션으로 자리 잡은 데는 2~3년이 걸렸다. 차이를 만든 건 두 가지였다 — 통합 메모리라는 하드웨어 명제, 그리고 그 명제를 정확히 끄집어내는 프레임워크(MLX).

"PyTorch의 MPS는 NVIDIA의 도식을 Metal에 흉내낸다. MLX는 Apple Silicon의 도식 그 자체다. 같은 GPU·다른 프레임워크·다른 결과."

같은 모델을 Mac에서 돌릴 때, MLX는 거의 항상 가장 빠르고, 거의 항상 가장 자연스럽다. 그리고 이 자연스러움이 미세조정·VLM·iOS 임베드 같은 자리까지 그대로 이어진다.

MLX 도입 체크리스트

  1. Apple Silicon (M1 이상) Mac이 있는가?
  2. pip install mlx mlx-lm은 됐는가? (Python 3.9+)
  3. 메모리는 충분한가? (8B 4bit은 16GB, 70B 4bit은 64GB+, 100B+은 192GB Studio)
  4. 추론만 할지, 미세조정도 할지 정했는가?
  5. 결과를 OpenAI 호환 서버로 노출할 계획이 있는가?
  6. 같은 가중치를 iOS/macOS 앱에서 쓸 계획이 있는가?
  7. PyTorch 기존 코드와의 격차를 인지하고 있는가?
  8. 디바이스 외부로 데이터가 안 나가는 게 중요한 워크로드인가?
  9. 디버그용 mx.eval() 사용 시점을 정리했는가?
  10. 모델 라이선스(Llama, Qwen, DeepSeek 등)를 확인했는가?

안티패턴 10가지

  1. MLX를 Linux 서버에 깔려고 하기 — 디자인이 다른 프레임워크. Apple Silicon 전용이다.
  2. PyTorch MPS로 큰 컨텍스트 추론을 시도 — 4GB 텐서 캡으로 OOM. MLX로 옮겨라.
  3. 모든 텐서를 한 번에 eval — 큰 그래프를 한 번에 평가하면 메모리·시간 모두 폭발. 단계적 평가.
  4. 양자화 없이 70B 모델을 16GB Mac에 띄우려 시도 — 안 됨. 4bit + 64GB 이상이 현실선.
  5. MLX와 NumPy/PyTorch 텐서를 무분별하게 섞기 — 변환 비용·디바이스 헷갈림. 경계를 명확히.
  6. 새 모델이 안 들어왔다고 곧장 PyTorch로 도주 — mlx-lm의 자동 변환이 대부분 모델을 다 받는다.
  7. Mac에서 H100급 학습 처리량을 기대 — 미세조정 처리량은 한참 작다. 큰 학습은 클라우드.
  8. OpenAI 호환 서버 없이 직접 API를 짜기 — 그냥 mlx_lm.server를 쓰자.
  9. Swift 진영의 mlx-swift 가능성을 무시 — iOS·visionOS의 가치가 거기 있다.
  10. MLX를 "PyTorch 대체품"으로 평가 — MLX는 Apple Silicon에 특화된 도구다. 가치 명제가 다르다.

다음 글 예고

다음 글 후보: 로컬 LLM 서빙 아키텍처 — Ollama vs LM Studio vs mlx-lm 서버 비교 심층, iOS에서 LLM 임베드 — mlx-swift로 노트 앱에 어시스턴트 넣기, 양자화 심층 — 4bit/8bit/QLoRA가 정확도에 미치는 영향 측정.

"M 시리즈 GPU는 CPU와 같은 RAM을 쓴다. 그래서 MLX는 빨라야 한다. 그리고 실제로 빠르다."

— MLX 심층 분석, 끝.


참고 / References

현재 단락 (1/269)

2023년 말, Apple ML 팀이 조용히 하나의 프레임워크를 깃허브에 올렸다. 이름은 `mlx`. 만든 사람들은 익숙한 얼굴이다 — PyTorch와 JAX의 핵심 기여자들. 이...

작성 글자: 0원문 글자: 12,959작성 단락: 0/269