TL;DR(3줄 요약)

  • 성능 MLX가 더 빠르지만, Apple Silicon 단일 머신 벤치마크 환경에서만 해당(3%–12% 차이)
  • 에이전트 프로덕션 llama.cpp + Ollama가 에이전트 / 프로덕션 추론에 더 적합(HTTP 런타임이 결정 변수)
  • 진짜 병목 대부분의 환경에서 병목은 메모리 대역폭이지 프레임워크가 아님—swap 시 둘 다 동시에 무너짐

본문 핵심 판단

하드웨어 근접성: MLX가 더 가깝습니다(디스패치 횟수 3배 적음, 양자화 경로 더 짧음). 엔지니어링 근접성: llama.cpp / Ollama가 더 가깝습니다(기본 HTTP 런타임, Claude Code 제로 설정 연결). 두 차원은 서로 대체될 수 없습니다.

핵심 통합 설명(제1원리 레이어)

MLX vs llama.cpp의 본질적인 차이는 "약간 빠르냐 느리냐"가 아니라, 근본적으로 다른 두 가지 실행 철학입니다:

  • graph-fusion execution(MLX): lazy하게 연산 그래프 수집 → 런타임에 퓨전 → 배치 디스패치
  • per-op dispatch execution(llama.cpp): 각 연산자를 독립적으로 제출 → 크로스플랫폼 호환 → 예측 가능한 오버헤드

그리고 두 가지 서로 다른 엔지니어링 방향:

  • hardware-native specialization(MLX): Apple 전용, 단일 하드웨어를 극한까지 활용
  • engineered portability(llama.cpp): CUDA / Metal / Vulkan / CPU 크로스 플랫폼, 이식성 우선

모든 성능 차이는 세 가지로 귀결됩니다:
① 디스패치 횟수  ② 커널 퓨전 능력  ③ 메모리 대역폭이 병목이 되는지 여부

시스템 경계: 본문 결론의 적용 범위와 한계

경계가 명확한 결론이 경계 없는 설명보다 신뢰할 수 있습니다. MLX vs llama.cpp 성능과 기술 선정에 관한 본문의 모든 결론은 다음 조건 하에서 성립합니다:

✅ 적용 가능한 환경

  • Apple Silicon(M1–M4 / M5 시리즈)
  • batch = 1 / 소규모 배치 추론(decode 단계)
  • decoder-only transformer(7B–14B 주류 모델)
  • Metal 백엔드(macOS 네이티브 GPU 경로)
  • 단일 머신 로컬 추론 / 소규모 팀 공유 노드
  • Claude Code / Cursor / Open WebUI 등 에이전트 도구

❌ 적용 불가능한 환경

  • CUDA / NVIDIA 멀티 GPU 서빙
  • 대규모 배치 학습(batch training)
  • 분산 추론(멀티 노드 distributed inference)
  • Speculative decoding 파이프라인
  • MoE 혼합 전문가 모델(아키텍처 차이가 큼)
  • 클라우드 GPU 인스턴스(Apple Silicon 미포함)

본문의 결론은 NVIDIA / AMD GPU 환경에는 적용되지 않습니다—그것은 CUDA vs ROCm의 영역이며, Apple Silicon 통합 메모리 아키텍처와는 무관합니다.

주요 용어 정의: Metal dispatch · Kernel fusion · Unified memory · GGUF vs MLX format

이후 기술 내용을 읽기 전에 핵심 개념을 먼저 정리합니다. Apple Silicon LLM 추론 분야에서 가장 자주 혼동되는 용어들입니다.

Metal dispatch(Metal compute dispatch)
CPU가 Apple Silicon GPU에 compute 커널 하나를 제출하는 최소 단위입니다. 매번 디스패치마다 CPU-GPU 간 동기화 확인이 필요하며 약 1–3 μs의 스케줄링 오버헤드가 발생합니다. 디스패치 횟수가 많을수록 GPU를 기다리는 CPU의 누적 오버헤드가 커집니다.
Kernel fusion(커널 퓨전)
여러 개의 독립 연산자(예: matmul → bias add → activation)를 하나의 GPU 커널로 병합하여 실행함으로써 디스패치 횟수와 중간 결과의 글로벌 메모리 읽기/쓰기를 줄입니다. MLX는 lazy evaluation을 통해 커널 퓨전을 자동으로 수행하며, llama.cpp는 수작업으로 작성된 퓨전 커널(예: flash attention)에 의존하므로 커버 범위가 제한적입니다.
Unified memory(통합 메모리, Apple Silicon)
Apple Silicon의 CPU와 GPU는 동일한 물리 메모리를 공유하며 별도의 VRAM이 존재하지 않습니다. 모델 가중치 로드 후 CPU↔GPU 간 복사가 필요 없어 Mac에서 LLM 추론을 수행할 수 있는 하드웨어 이점의 근본입니다. MLX와 llama.cpp의 Metal 백엔드 모두 통합 메모리를 자동으로 활용하지만, MLX의 메모리 할당자가 이 모델에 더 밀접하게 설계되어 있습니다.
GGUF(llama.cpp 양자화 포맷)
llama.cpp가 사용하는 모델 양자화 포맷으로, Q2_K~Q8_0 등 다양한 정밀도를 지원합니다. 모델 파일은 .gguf 형식이며 Hugging Face에서 직접 다운로드 가능합니다. Ollama는 GGUF로 모델을 관리하며, MLX 포맷과는 호환되지 않습니다.
MLX format(mlx-community 양자화 포맷)
MLX가 사용하는 모델 포맷으로, safetensors + MLX 양자화 메타데이터 기반입니다. mlx_lm.convert를 통해 변환하거나 mlx-community에서 가져올 수 있습니다. 양자화 커널이 Metal shader에 직접 바인딩되어 있으며, GGUF와 완전히 호환되지 않으므로 동일한 기반 모델도 각각 변환해야 합니다.

MLX vs llama.cpp 아키텍처 개요: Apple Silicon inference framework 완전 비교

세부 내용에 들어가기 전에 전체 그림을 먼저 파악합니다. mlx vs llama.cpp의 근본적인 분기점은 설계 목표에 있습니다: 하나는 Apple 전용 극한 최적화, 다른 하나는 크로스 플랫폼 이식성입니다.

항목MLXllama.cpp
설계 목표 Apple Silicon 전용 크로스 플랫폼(CUDA / Metal / Vulkan / CPU)
디스패치 모델 Lazy graph fusion(그래프 분석 후 배치 디스패치) Per-op dispatch(각 연산자 독립 제출)
Metal 방식 Runtime JIT 커널(텐서 형상에 따라 특화 컴파일) 사전 컴파일 커널(바이너리에 패키징)
메모리 모델 Native unified memory(네이티브 통합 메모리 할당) ggml allocator(범용, Apple 비특화)
양자화 포맷 safetensors + MLX metadata(mlx-community) GGUF(Q2_K ~ Q8_0)
HTTP 런타임 미내장(FastAPI 게이트웨이 자체 구축 필요) Ollama 래핑, 바로 사용 가능(:11434
Claude Code / Cursor 직접 연결 가능 여부 ❌ 게이트웨이 자체 구축 필요 ✅ Ollama 제로 설정
적합한 환경 벤치마크, 연구, LoRA 파인튜닝 에이전트 런타임, 프로덕션 추론, 팀 공유

마지막 두 행이 기술 선정을 결정합니다. tok/s 차이는 § 성능 차이의 실제 원인을 참조하세요—에이전트 런타임 결정에는 영향을 주지 않습니다.

Apple Silicon LLM Inference Stack Model(2026)

위 비교표를 4계층 분업 모델로 변환하면, 본문의 모든 결론을 이해하는 가장 간단한 프레임워크가 됩니다:

┌─────────────────────────────────────────────────┐
│            Application Layer                    │
│   Claude Code  ·  Cursor  ·  Open WebUI         │
├─────────────────────────────────────────────────┤
│            Runtime Layer                        │
│   Ollama (llama.cpp)  │  FastAPI (MLX wrapper)  │
│   ✅ 에이전트 권장 경로  │  ⚠️ 자체 구축, 엔지니어링 비용 높음  │
├─────────────────────────────────────────────────┤
│            Compute Layer                        │
│   ggml-metal (per-op) │  MLX (graph fusion)     │
│   크로스플랫폼, 사전 컴파일  │  Apple 전용, JIT 특화  │
├─────────────────────────────────────────────────┤
│            Hardware Layer                       │
│       Apple Silicon Unified Memory              │
│   CPU + GPU 물리 메모리 공유 · 제로 복사 · 고대역폭  │
└─────────────────────────────────────────────────┘
그림 · Apple Silicon LLM 추론 4계층 스택 — 기술 선정은 Runtime 레이어에서 발생, 성능 차이는 Compute 레이어에서, 상한선은 Hardware 레이어에서 결정

핵심 결론: 기술 선정은 Runtime 레이어에서만 이루어집니다. Compute 레이어(MLX vs ggml-metal)의 성능 차이는 Runtime 레이어 선택에 영향을 주지 않습니다—두 레이어는 서로 다른 수준에서 작동하며 대체 관계가 아닙니다.

핵심 차이: Metal 디스패치 횟수(480 vs 160)—Apple Silicon 추론 성능의 원천

이 글에서 가장 기억해야 할 숫자입니다. 디스패치 횟수의 차이를 이해하면 MLX vs llama.cpp 성능 차이의 근원을 이해할 수 있습니다.

7B 트랜스포머 모델의 경우, 토큰 하나를 생성할 때마다 32개 레이어를 한 번씩 forward pass로 통과해야 합니다. 각 레이어에는 QKV projection, attention score, softmax, output projection, FFN gate, FFN up/down, RMS Norm, RoPE 등의 연산자가 포함됩니다:

llama.cpp(per-op dispatch): 32층 × ~15 연산자/층 ≈ 480회 Metal dispatch
MLX(lazy graph fusion 후): 32층 × ~4–5 fusion block/층 ≈ 128–160회 Metal dispatch

💡 핵심 인사이트(인용 가능)

MLX의 이점은 더 강한 연산 능력이 아니라, CPU↔GPU 디스패치 횟수를 약 3배 줄이는 데 있습니다.
batch=1 환경에서 각 [commandBuffer commit]의 CPU 스케줄링 오버헤드는 약 1–3 μs입니다. 480회 vs 160회 차이로 토큰당 약 0.3–1 ms를 절약할 수 있습니다—이것이 벤치마크에서 MLX가 앞서는 주요 메커니즘이며, 커널 알고리즘이 더 우수해서가 아닙니다.

매번 Metal 디스패치는 CPU-GPU 동기화 지점입니다: CPU는 GPU가 command buffer 큐잉을 확인할 때까지 기다린 후에야 다음 연산자의 커널 호출을 시작할 수 있습니다. GPU compute 시간이 짧을 때(소규모 배치 추론)디스패치 오버헤드가 병목이 됩니다. MLX의 lazy evaluation은 여러 연산자를 하나의 디스패치로 퓨전하여 이 동기화 비용을 직접 우회합니다.

Token Latency 분해 모델(Dispatch Cost Model)

단일 토큰 생성 지연을 세 가지 정량화 가능한 항목으로 분해합니다:

Token latency ≈
  dispatch_count × cpu_sync_cost     ← 디스패치 오버헤드(프레임워크 차이 원인)
  + gpu_compute_time                 ← GPU 실제 연산 시간(대역폭 / 연산 bound)
  + memory_bandwidth_time            ← 가중치 전송 시간(물리적 상한선)

batch=1, 7B 모델, M4 Mac Mini 16GB 환경에서의 전형적인 분포:

항목llama.cppMLX설명
dispatch_count × cpu_sync_cost ~480 × 2 μs ≈ 0.96 ms ~160 × 2 μs ≈ 0.32 ms 프레임워크 차이 원인, 총 지연의 10%–30% 차지
gpu_compute_time ~1–3 ms(둘 다 비슷) 연산 능력과 양자화 포맷에 따라 결정
memory_bandwidth_time ~4GB ÷ 120GB/s ≈ 33 ms(지배적 항목) 물리적 상한선, 프레임워크가 최적화 불가

위 수치는 근사 추정값입니다(batch=1, 7B Q4_K_M, M4 16GB 기준). memory_bandwidth_time이 결정적 지배 항목이며, 이것이 대역폭 포화 시 MLX의 이점이 거의 사라지는 이유를 설명합니다.

항목llama.cpp(ggml-metal)MLX
커널 라이프사이클 사전 컴파일, 바이너리에 패키징(.metal.metallib 런타임에 필요 시 컴파일, 첫 실행 시 컴파일 지연 발생, 이후 캐시 사용
연산자 퓨전 제한적: 일부 수작업 퓨전 커널(예: flash attention) 프레임워크 수준 자동 퓨전, lazy graph 분석 후 인접 연산자 병합
forward pass당 디스패치 횟수(7B) 약 400–600회(per-op) 약 80–160회(퓨전 후)
CPU 디스패치 경로 ggml 디스패치 스레드 → Metal command buffer MLX 스케줄러가 Metal command buffer에 직접 작성
멀티 스트림 병렬처리 단일 Metal command queue(주류 구성) 멀티 스트림 지원, 인접 레이어 연산 병렬 처리 가능

MLX가 탄생한 이유: Apple Silicon 전용 추론 프레임워크의 설계 출발점

2023년 말, Apple 머신러닝 연구팀이 MLX를 오픈소스로 공개했습니다. 설계 동기가 독특합니다—크로스 플랫폼이 아니라 단일 하드웨어를 극한까지 활용하기 위해서입니다.

MLX 이전에 Apple Silicon에서 LLM 추론은 다음에 의존했습니다:

  • Core ML / MPS: Apple 공식 추론 스택이지만 모델 포맷이 폐쇄적이어서 연구자에게 불편
  • llama.cpp + Metal: 커뮤니티 주력이지만 ggml이 CUDA 세계를 위해 설계되어 크로스 플랫폼 추상화 오버헤드 발생
  • PyTorch + MPS backend: MPS 연산자 커버리지가 불완전하고 추론 속도가 Apple Silicon을 충분히 활용하지 못함

Apple 엔지니어들의 판단: 통합 메모리 + 고대역폭 버스 + Metal GPU 조합을 진정으로 활용하려면 처음부터 Apple Silicon을 위해 설계된 배열 계산 프레임워크가 필요합니다.

MLX의 4가지 핵심 설계 원칙

  • CPU와 GPU가 같은 메모리 공간을 공유하여 제로 복사로 데이터 전송
  • Lazy evaluation: 연산이 즉시 실행되지 않고 결과가 필요할 때 배치 스케줄링, 그 사이에 그래프 최적화 수행
  • 동적 그래프 + JIT, API 스타일이 NumPy / JAX와 유사하여 연구자 친화적
  • Metal compute shader를 런타임에 필요 시 컴파일하며 고정 커널을 사전 패키징하지 않음

llama.cpp 아키텍처: ggml 멀티 플랫폼 추상화 + llama.cpp Metal backend + GGUF 양자화

llama.cpp는 Georgi Gerganov가 2023년 3월에 공개했으며, 순수 C/C++로 소비자용 하드웨어에서 LLaMA를 실행하는 것이 목표였으며 이식성이 최우선 순위입니다.

ggml: 범용 텐서 백엔드

llama.cpp의 핵심은 ggml—경량 C 텐서 라이브러리로 백엔드 플러그인을 통해 다양한 하드웨어를 지원합니다:

백엔드하드웨어활성화 조건
GGML_METALApple Silicon GPUmacOS, -DLLAMA_METAL=ON
GGML_CUDANVIDIA GPULinux/Windows + CUDA
GGML_VULKANAMD / Intel GPUVulkan 드라이버
GGML_CPU모든 CPU기본 폴백

장점은 하나의 코드베이스로 모든 플랫폼에서 실행된다는 것이며, 단점은 각 백엔드가 범용 어댑터여서 특정 하드웨어의 심층 최적화가 불가능하고 추상 레이어가 스케줄링 오버헤드를 만든다는 것입니다.

Metal backend(ggml-metal)과 사전 컴파일 커널

Apple Silicon에서 llama.cpp는 ggml-metal.metal을 활성화합니다—사전 컴파일된 Metal 셰이더 파일로 다음을 포함합니다:

  • 행렬 곱셈: Q4_K, Q8_0 등 GGUF 양자화 포맷별로 전용 커널 구현
  • Softmax, RoPE, RMS Norm: 연산자별 독립 커널
  • KV 캐시 연산: 메모리 뷰 재사용, 복사 회피

핵심 제약: 커널이 사전 컴파일로 고정되어 런타임에 텐서 형상에 따른 재최적화가 불가능합니다. 시퀀스 길이나 배치 크기가 변경되면 커널 파라미터가 Metal buffer를 통해 전달되지만 커널 자체는 변하지 않습니다—이것이 MLX 런타임 특화가 이점을 얻을 수 있는 부분입니다.

GGUF 양자화 포맷

llama.cpp는 GGUF를 사용하며 양자화 정밀도는 Q2_K(극도 압축)에서 Q8_0(fp16에 근접)까지 다양합니다. 각 양자화 포맷에는 Metal 커널의 대응 구현이 있어 Apple Silicon에서 나쁘지 않은 성능을 내는 이유입니다—하지만 이는 양자화 포맷이 추가될 때마다 커널 세트를 유지 관리해야 한다는 의미이기도 합니다.

MLX 아키텍처: lazy evaluation + runtime JIT 커널 + Apple Silicon 통합 메모리

MLX와 llama.cpp의 근본적인 차이는 추상 레이어의 위치에 있습니다: llama.cpp의 Metal은 "플러그인 백엔드"이지만, MLX의 전체 연산 그래프는 설계 초기부터 Metal의 시맨틱 위에 존재합니다.

Lazy Evaluation + 연산 그래프 퓨전

  1. Python 코드가 MLX 연산자를 호출할 때 즉시 실행되지 않고 연산 그래프 노드만 기록
  2. mx.eval()을 호출하면 프레임워크가 전체 그래프를 분석
  3. 인접하고 퓨전 가능한 연산자(matmul + bias + activation 등)가 하나의 Metal 디스패치로 병합
  4. 생성된 Metal compute shader가 런타임에 컴파일 및 캐시되어 이후 재사용

통합 메모리의 심층 활용

  • 모든 텐서가 통합 메모리 풀에 할당되어 CPU와 GPU가 동일한 물리 주소 공간을 공유
  • "VRAM" 개념이 없으며, 모델 가중치 로드 후 GPU가 직접 읽으며 cudaMemcpy에 해당하는 작업이 필요 없음
  • Metal buffer와 MLX 배열이 기저에서 같은 포인터를 공유하여 제로 복사 파라미터 전달

llama.cpp의 Metal 백엔드도 통합 메모리를 활용합니다(Apple Silicon의 하드웨어 특성으로 모든 Metal 프로그램이 자동으로 획득). 하지만 ggml의 메모리 할당자는 이를 위해 설계되지 않아 추가적인 정렬 및 할당 로직이 존재합니다.

GGUF vs MLX 양자화 포맷: 호환되지 않는 두 생태계

MLX는 safetensors + MLX 양자화 메타데이터를 사용하며, GGUF와 완전히 호환되지 않습니다. 동일한 기반 모델도 각각 변환해야 합니다:

  • llama.cpp용: HuggingFace에서 다운로드 → convert.py로 GGUF 변환 및 양자화
  • MLX용: mlx_lm.convert로 변환하거나 mlx-community에서 사전 변환된 버전 다운로드

양자화 비트 폭은 4-bit, 8-bit 및 혼합 정밀도를 지원하며, 연산자 구현이 Metal shader에 직접 깊이 바인딩되어 있습니다—이것이 MLX 양자화 역압축 경로가 GGUF보다 짧은 근본 이유입니다.

MLX vs llama.cpp 성능 차이의 실제 원인: 디스패치 횟수 vs 메모리 대역폭

mlx benchmark에서 가장 오해받기 쉬운 부분입니다. MLX의 속도 이점은 더 좋은 행렬 곱셈 알고리즘에서 오는 것이 아니라, 세 가지 정량화 가능한 엔지니어링 요소에서 옵니다:

1. 디스패치 퓨전: CPU-GPU 동기화 3배 감소

§ 핵심 차이에서 설명한 것처럼, MLX는 토큰당 Metal 디스패치를 약 480회에서 160회로 줄입니다. batch=1, 짧은 시퀀스에서 가장 효과적입니다—GPU compute 시간이 짧을수록 CPU 스케줄링 오버헤드의 비중이 높아집니다.

2. 런타임 커널 특화: 구체적인 텐서 형상에 맞게 최적화

MLX는 특정 형상의 연산을 처음 실행할 때 Metal shader를 컴파일하여 구체적인 행렬 차원에 맞게 tile size와 workgroup 크기를 조정할 수 있습니다. llama.cpp의 사전 컴파일 커널은 보수적인 범용 파라미터를 사용하므로 비표준 시퀀스 길이에 대한 적응성이 떨어집니다.

3. 양자화 역압축 경로가 더 짧음

llama.cpp는 멀티 플랫폼 지원을 위해 양자화 역압축(dequant)이 CPU 폴백 경로를 고려해야 합니다. MLX의 양자화 커널은 Metal을 유일한 대상으로 하므로 역압축 + 행렬 곱셈을 같은 셰이더 내에서 완료하여 글로벌 메모리 읽기/쓰기를 줄입니다.

실측 구간 참고

아래 데이터는 Macstripe Lab 실측 데이터입니다. Llama-3.1-8B / Q4_K_M, batch=1, 2026-06 측정 기준. 추세 참고용이며 구매 또는 기술 선정의 근거로 사용하지 마십시오.

디바이스llama.cpp(Ollama)tok/sMLX tok/s차이
M4 Mac Mini 16GB27–3128–33+3%–7%
M4 Mac Mini 24GB34–3937–43+5%–10%
M4 Pro 48GB72–8080–90+8%–12%

패턴: 메모리가 클수록, 모델이 클수록 MLX 이점이 뚜렷해집니다. 이유는 대형 모델 forward pass의 GPU compute 시간이 더 길어 디스패치 퓨전의 절대적 이익이 더 크기 때문입니다. 16GB에서 7B를 실행할 때는 대역폭이 이미 병목이어서 퓨전 이익이 희석됩니다.

Performance Convergence Model(성능 수렴 차트)

위 표의 추세를 시각화합니다: MLX의 성능 이점이 메모리 용량에 따라 어떻게 증가하고, 대역폭 포화 지점에서 0으로 수렴하는지:

  MLX advantage
  (tok/s delta)

  +12% │                                        ● 48GB (14B)
       │                                   ·
   +8% │                              ·
       │                         ·
   +5% │                    ● 24GB (7B–14B)
       │               ·
   +3% │          ● 16GB (7B)
       
    0% │━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  ← memory bandwidth ceiling
       │   (swap)  (swap)
  -∞% │     ↓ swap 발생 시 둘 다 동시에 붕괴
       
       └────────────────────────────────────────────
              16GB       24GB       48GB       메모리 용량
그림 · MLX vs llama.cpp 성능 차이 수렴 모델 — 메모리 대역폭 상한선 아래에서 MLX가 이점을 가지며, swap 구간에서 둘 다 0으로 수렴

차트의 핵심 의미: 메모리 용량이 커브의 어느 지점에 위치할지를 결정합니다. 16GB → 24GB로 업그레이드하는 이익(프레임워크 변경으로 얻을 수 없는)이 MLX vs llama.cpp의 3%–12% 차이보다 훨씬 큽니다.

대부분의 환경에서 mlx benchmark 차이≈0인 이유: 메모리 대역폭이 진짜 상한선

모든 환경에서 MLX의 이점을 볼 수 있는 것은 아닙니다. 이것이 본문에서 가장 중요한 "역발상 포인트"입니다:

메모리 대역폭 포화: 물리적 한계가 프레임워크 차이를 압도

batch=1 추론의 성능 상한선은 가중치 전송 대역폭이지 GPU 연산 능력이 아닙니다. 토큰 하나를 생성할 때마다 모든 레이어 가중치를 한 번씩 읽어야 합니다(7B Q4 ≈ 4GB 데이터 이동). M4의 메모리 대역폭은 약 120GB/s(16GB 버전)이며, 이 물리적 상한선이 tok/s 상계를 결정합니다. MLX도 llama.cpp도 이를 돌파할 수 없습니다—대역폭 포화 시 둘 다 수렴합니다.

메모리 swap 시 둘 다 동시에 무너짐

통합 메모리가 부족하면 시스템이 가중치를 SSD로 스왑하여 대역폭이 120GB/s에서 3–5GB/s(NVMe 순차 읽기 상한)로 급감합니다. 두 프레임워크 모두 tok/s가 한 자릿수로 떨어지며 프레임워크 차이가 완전히 사라집니다. 해결책은 메모리 용량 업그레이드뿐이며, 프레임워크 변경으로는 해결되지 않습니다.

긴 컨텍스트 prefill: GPU 연산이 병목이 되어 디스패치 오버헤드 비중이 0에 수렴

prefill(긴 프롬프트 처리)은 연산 집중적 작업으로 GPU 이용률이 100%에 가깝습니다. 2048 토큰 프롬프트의 prefill 시간 차이는 일반적으로 <5%입니다.

소형 모델(≤3B): 절대 compute 시간이 너무 짧음

3B Q4 가중치는 약 2GB에 불과하며 한 번의 forward pass GPU 시간이 약 5–10ms입니다. 디스패치 퓨전으로 절약되는 0.3–1 ms의 비중은 높아지지만 절대값이 너무 작아 사용자가 체감하기 어렵습니다.

고정밀 양자화(Q8_0 / fp16): 대역폭이 더 일찍 포화

정밀도가 높을수록 가중치가 커지고 대역폭이 더 빨리 병목이 됩니다. Q8 모델은 16GB 머신에서 거의 반드시 swap이 발생하며, 이 경우 프레임워크 차이를 논하는 것은 의미가 없습니다.

Ollama vs MLX 기술 선정: 에이전트 런타임은 tok/s에 신경 쓰지 않는다

MLX가 하드웨어 레이어에 더 가깝다면, 왜 Claude Code 권장 스택이 Ollama(llama.cpp)인가요? 두 가지는 서로 다른 차원의 문제이기 때문입니다.

HTTP 서버가 핵심 변수

Ollama는 llama.cpp 위에 완전한 추론 서비스 엔지니어링을 제공합니다:

  • 기본 HTTP 추론 서비스:11434, OpenAI 호환 API)—Claude Code 직접 연결, 제로 설정
  • 모델 라이프사이클 관리ollama pull / rm, 미사용 모델 자동 언로드)
  • 멀티 요청 동시 스케줄링(여러 Claude Code 창이 같은 모델 인스턴스를 공유, 중복 로딩 없음)
  • 팀 로컬 네트워크 공유ollama serve --host 0.0.0.0, 전체 팀이 같은 :11434에 연결)

MLX에는 이런 기능이 없습니다. MLX로 Claude Code를 연결하려면: FastAPI 게이트웨이 자체 구축 → 모델 로드/언로드 로직 구현 → 동시 요청 큐 처리 → OpenAI API 호환 레이어 유지 관리. 이것은 명령어 하나로 해결되는 문제가 아니라 완전한 추론 서비스 엔지니어링입니다.

에이전트 tool loop에서 tok/s 차이는 전체의 <5%

에이전트 tool loop에서 Claude Code 한 라운드 호출은 다음을 포함합니다: 프롬프트 조합 → HTTP 요청 → 응답 대기 → 도구 호출 파싱 → 도구 실행 → 다음 라운드. 지연 분포:

요인비중(전형적 에이전트 작업)프레임워크로 최적화 가능?
도구 실행 시간(파일 읽기/쓰기, 셸 명령)50%–70%아니오
HTTP 왕복 + 모델 TTFT20%–35%주로 메모리 용량에 의존
프레임워크 수준 tok/s 차이(MLX vs llama.cpp)<5%예, 하지만 영향 극히 작음

에이전트 경험의 결정적 변수는 메모리 용량과 모델 크기입니다. 프레임워크 차이는 HTTP 레이어와 도구 실행 시간에 완전히 묻힙니다.

Ollama vs MLX의 엔지니어링 경계

각자의 엔지니어링 경계를 명확히 하면 혼동이 없어집니다:

  • Ollama(llama.cpp): HTTP 런타임 레이어, "어떻게 연결할 것인가"의 문제를 해결
  • MLX: 연산 레이어 도구, "Python에서 어떻게 빠르게 실행할 것인가"의 문제를 해결
  • 둘은 상호 배타적이지 않습니다: 같은 Mac에 MLX를 설치하여 벤치마크를 실행하면서 동시에 Ollama로 Claude Code 서비스를 제공할 수 있습니다

→ Ollama vs MLX 기술 선정 전체 로직: Ollama vs MLX: Claude Code 로컬 모델 어떻게 선택하나요?
→ M4 Pro에서 MLX 배포 실전: Apple Silicon M4 Pro 로컬 LLM 실행 가이드: 성능 실측과 MLX 배포

MLX와 llama.cpp 중 무엇을 선택해야 할까?(30초 의사결정 가이드)

실제 사용 목적에 따라 선택하세요. "어느 것이 더 좋다"는 절대적 답은 없습니다:

Apple Silicon LLM 추론 결론 모델: 인용 가능한 세 가지 규칙(mac m4 llm inference speed)

본문의 모든 결론을 재사용 및 인용 가능한 판단 프레임워크로 압축합니다:

판단 모델(직접 인용 가능)

  1. 성능 상한선 = 메모리 대역폭
    Apple Silicon에서 batch=1 추론의 tok/s 상한선은 통합 메모리 대역폭에 의해 결정됩니다(M4 약 120GB/s). 프레임워크는 물리적 한계를 돌파할 수 없습니다.
  2. 프레임워크 차이 = 디스패치 오버헤드
    MLX vs llama.cpp의 성능 차이(3%–12%)는 Metal 디스패치 횟수 차이(480 vs 160)에서 오는 것이며, 연산자 알고리즘이 더 우수해서가 아닙니다.
  3. 시스템 기술 선정 = 런타임 vs 연구
    에이전트 런타임에는 Ollama(llama.cpp)를 선택—HTTP 서버가 결정 변수. 연구 / 벤치마크 / 파인튜닝에는 MLX를 선택—연산 레이어가 하드웨어에 가장 가까움.

프레임워크 최적화는 5%–15%만 개선할 수 있고, 메모리 용량이 85%를 결정합니다.
MLX vs llama.cpp에 관한 모든 논의는 결국 이 한 마디로 귀결됩니다.

관련 질문: Apple Silicon 추론 기술 선정 자주 검색되는 내용

MLX와 llama.cpp 중 로컬 배포에 더 적합한 것은 무엇인가요?

"배포"의 의미에 따라 다릅니다. 추론 서비스를 배포하는 경우(Claude Code / Cursor / 자체 API용)라면 llama.cpp + Ollama가 더 적합합니다—기본 HTTP 서버, 완성된 모델 관리. 연구 환경을 배포하는 경우(새 모델 테스트, 벤치마크, Python 스크립트 작성)라면 MLX가 더 적합합니다—하드웨어에 더 가깝고 Python 인터페이스가 유연합니다.

Apple Silicon에서 LLM 추론에 CUDA를 사용하지 않는 이유는 무엇인가요?

Apple Silicon에는 NVIDIA GPU가 없으므로 CUDA를 지원하지 않습니다. Apple의 GPU는 Metal API를 통해 호출되며, 통합 메모리 아키텍처로 CPU와 GPU가 동일한 물리 메모리 풀을 공유합니다—이것은 NVIDIA의 독립 VRAM 모델과 완전히 다릅니다. MLX와 llama.cpp 모두 Metal을 기반으로 하며 VRAM이 아닌 통합 메모리를 활용합니다.

GGUF와 MLX 양자화 포맷의 차이는 무엇인가요?

두 포맷은 호환되지 않으며 독립된 두 가지 양자화 생태계입니다. GGUF(llama.cpp)는 Q2_K~Q8_0 등 다양한 정밀도를 지원하며 ggml-metal 커널에 전용 구현이 있습니다. MLX는 safetensors + MLX 양자화 메타데이터를 사용하며 양자화 커널이 Metal shader에 직접 바인딩됩니다. 동일한 기반 모델을 두 프레임워크에서 사용하려면 각각 변환해야 합니다.

Mac에서 로컬 LLM 실행에 주로 Ollama를 사용하는 이유는 무엇인가요?

Ollama는 "LLM을 어떻게 실제로 사용할 것인가"의 엔지니어링 문제를 해결합니다: 명령어 하나로 HTTP 서버 시작, OpenAI 호환 API, Claude Code / Cursor / Open WebUI 등 도구와 바로 연결. 내부는 llama.cpp로 Apple Silicon에서 Metal 가속을 통해 충분한 성능을 제공하며, Python 환경이나 자체 서비스 구축이 필요 없습니다.

FAQ

MLX vs llama.cpp 중 어느 것이 더 빠른가요? 성능 차이는 얼마나 되나요?

대부분의 벤치마크 환경에서 MLX가 3%–12% 빠릅니다. 주된 이유는 커널 퓨전(디스패치 횟수 약 480 vs 160)과 런타임 Metal 커널 특화입니다. 단, batch=1 대역폭 포화, 메모리 swap, 또는 긴 prefill 시에는 두 프레임워크의 차이가 거의 사라집니다. 메모리가 클수록(48GB 노드), 모델이 클수록(14B+)MLX 이점이 더 뚜렷해집니다. 16GB에서 7B를 실행할 때 차이는 3%–7%에 불과합니다.

llama.cpp의 Metal 백엔드와 MLX의 근본적인 차이는 무엇인가요?

llama.cpp는 ggml을 통해 멀티 플랫폼을 추상화하며 Metal은 여러 백엔드 중 하나입니다. 커널이 사전 컴파일되어 있고 연산자별로 독립 디스패치됩니다. MLX는 처음부터 Apple Silicon만을 대상으로 설계되어 lazy evaluation이 런타임에 연산자를 퓨전하고, 디스패치 횟수가 3배 적으며, 양자화 경로가 더 짧고, 통합 메모리 정렬이 더 깊습니다.

GGUF와 MLX 양자화 포맷을 상호 변환할 수 있나요?

직접 변환은 불가능하며 두 포맷은 완전히 독립적입니다. GGUF는 llama.cpp의 convert.py를 사용하여 원본 가중치에서 생성하고, MLX 포맷은 mlx_lm.convert로 변환하거나 mlx-community에서 직접 다운로드합니다. 동일한 기반 모델도 각각 변환해야 합니다.

Claude Code가 MLX 대신 Ollama를 선택하는 이유는 무엇인가요?

Ollama는 기본 HTTP 서비스(:11434, OpenAI 호환)를 제공하여 별도 게이트웨이가 필요 없습니다. 에이전트 tool loop에서 프레임워크 수준의 tok/s 차이는 전체 지연의 <5%에 불과하며, 도구 실행 시간과 HTTP 레이어가 실제 병목입니다. MLX에는 내장 HTTP 서버가 없어 Claude Code 연결을 위해 완전한 추론 서비스 스택을 자체 구축해야 하며, 엔지니어링 비용이 모든 속도 이점을 상쇄합니다.

swap 발생 시 어느 프레임워크가 더 견고한가요?

두 프레임워크 모두 심각하게 성능이 저하되며 차이가 사라집니다. 메모리 대역폭이 120GB/s에서 3–5GB/s(NVMe 상한)로 떨어지면 어떤 프레임워크도 SSD 병목을 최적화할 수 없습니다. 메모리 업그레이드(24GB 또는 48GB 노드)가 유일한 해결책입니다.

MLX와 Ollama를 동시에 설치할 수 있나요?

가능합니다, 완전히 충돌하지 않습니다. 권장 구성: Ollama를 백그라운드 서비스로 상시 실행하여 Claude Code를 서빙하고, MLX는 필요할 때 Python 환경에서 벤치마크나 파인튜닝 스크립트를 실행합니다. 두 프레임워크가 같은 통합 메모리를 공유하지만 모델 포맷이 달라 각각 관리해야 합니다.

관련 글