🔥 oMLX — 맥에서 LLM 추론 서버 제대로 돌리기
강의 목차

출처: oMLX GitHub
로컬에서 LLM을 돌리겠다고 Ollama를 설치한 게 작년이었다. 그때만 해도 "이 정도면 쓸만하네" 싶었는데, 코딩 에이전트를 붙이기 시작하면서 문제가 터졌다. 컨텍스트가 길어질수록 첫 토큰이 나올 때까지 30초, 60초씩 걸렸다. 대화를 이어갈 때마다 이전 KV 캐시가 통째로 날아가서 매번 처음부터 다시 계산했다. Mac의 통합 메모리가 아무리 넉넉해도 이건 답이 아니었다.
oMLX를 발견한 건 그런 불만이 쌓이던 중이었다. "KV 캐시를 SSD에 저장한다고?" 처음엔 반신반의했다. SSD 읽기가 GPU 재계산보다 빠를 리 없잖아. 그런데 실제로는 프리필(prefill) 연산 비용이 워낙 크기 때문에, 디스크에서 복원하는 게 압도적으로 빠르다. 이 단순한 아이디어 하나가 로컬 LLM 추론의 실용성을 완전히 바꿔놓았다.
oMLX가 뭔가
oMLX는 Apple Silicon에 최적화된 LLM 추론 서버다. Apple의 MLX 프레임워크 위에서 동작하고, mlx-lm과 mlx-vlm을 백엔드로 쓴다. 2026년 2월에 첫 커밋이 올라갔고, 4월 현재 v0.3.5까지 왔다. 스타 10,300개, 기여자 48명. 두 달 만에 63번의 릴리스를 찍었다는 건, 이 프로젝트가 얼마나 빠르게 움직이는지를 보여준다.
만든 사람은 jundot이라는 개발자인데, README에 이런 말을 남겨놨다.
내가 써본 모든 LLM 서버는 편의성과 제어 사이에서 하나를 포기하게 만들었다. 자주 쓰는 모델은 메모리에 고정하고, 무거운 모델은 요청 시 자동 교체하고, 컨텍스트 제한도 설정하고 — 이걸 전부 메뉴바에서 관리하고 싶었다.
솔직히 이 한 문장이 oMLX의 존재 이유를 다 설명한다.
핵심 기능을 정리하면 이렇다:
- Tiered KV Cache: RAM(Hot) + SSD(Cold) 이중 캐시 구조
- Continuous Batching: 동시 요청 처리 (mlx-lm의 BatchGenerator 기반)
- 멀티 모델 서빙: LLM, VLM, OCR, 임베딩, 리랭커를 하나의 서버에서
- OpenAI + Anthropic API 호환: 드롭인 교체 가능
- macOS 메뉴바 앱: Electron이 아니라 네이티브 PyObjC
- 관리자 대시보드: 웹 UI에서 모델 관리, 채팅, 벤치마크, 설정 전부
시스템 요구사항은 macOS 15.0+(Sequoia), Python 3.10+, Apple Silicon(M1/M2/M3/M4)이다.
설치하기
설치 방법은 세 가지다. macOS 앱, Homebrew, 소스 빌드.
macOS 앱
가장 간단하다. Releases 페이지에서 .dmg를 받아서 Applications에 끌어다 놓으면 끝이다. 인앱 자동 업데이트를 지원해서 다음 업그레이드는 클릭 한 번이면 된다. 다만 macOS 앱은 omlx CLI를 설치하지 않는다. 터미널에서 쓰려면 Homebrew로 설치해야 한다.
Homebrew
터미널 작업을 선호한다면 이쪽이 맞다.
brew tap jundot/omlx https://github.com/jundot/omlx
brew install omlxbrew tap jundot/omlx https://github.com/jundot/omlx
brew install omlx업그레이드:
brew update && brew upgrade omlxbrew update && brew upgrade omlx백그라운드 서비스로 돌리면 크래시 시 자동 재시작된다:
brew services start omlxbrew services start omlxMCP(Model Context Protocol) 지원이 필요하면:
/opt/homebrew/opt/omlx/libexec/bin/pip install mcp/opt/homebrew/opt/omlx/libexec/bin/pip install mcp소스에서 설치
직접 빌드하고 싶다면:
git clone https://github.com/jundot/omlx.git
cd omlx
pip install -e . # 기본 설치
pip install -e ".[mcp]" # MCP 지원 포함git clone https://github.com/jundot/omlx.git
cd omlx
pip install -e . # 기본 설치
pip install -e ".[mcp]" # MCP 지원 포함첫 서버 띄우기
설치했으면 바로 서버를 올려보자.
CLI로 시작
omlx serve --model-dir ~/modelsomlx serve --model-dir ~/models이게 전부다. ~/models 디렉토리 아래의 하위 폴더를 자동으로 탐색해서 LLM, VLM, 임베딩 모델, 리랭커를 전부 인식한다. 모델 디렉토리 구조는 이런 식이면 된다:
~/models/
├── Step-3.5-Flash-8bit/
├── Qwen3-Coder-Next-8bit/
├── gpt-oss-120b-MXFP4-Q8/
├── Qwen3.5-122B-A10B-4bit/
└── bge-m3/~/models/
├── Step-3.5-Flash-8bit/
├── Qwen3-Coder-Next-8bit/
├── gpt-oss-120b-MXFP4-Q8/
├── Qwen3.5-122B-A10B-4bit/
└── bge-m3/2단계 폴더 구조(mlx-community/model-name/)도 지원한다. HuggingFace에서 받은 모델을 그대로 넣으면 된다는 뜻이다.
서버가 올라오면 http://localhost:8000/v1으로 OpenAI 호환 API에 접근할 수 있다. 내장 채팅 UI는 http://localhost:8000/admin/chat에서 쓸 수 있다.
macOS 앱으로 시작
앱을 실행하면 Welcome 화면이 뜨면서 세 단계를 안내한다: 모델 디렉토리 설정, 서버 시작, 첫 모델 다운로드. 관리자 대시보드에서 HuggingFace의 MLX 모델을 직접 검색하고 다운로드할 수도 있다.
Homebrew 서비스
Homebrew로 설치했다면 백그라운드 서비스로 관리할 수 있다:
brew services start omlx # 시작 (크래시 시 자동 재시작)
brew services stop omlx # 중지
brew services restart omlx # 재시작
brew services info omlx # 상태 확인brew services start omlx # 시작 (크래시 시 자동 재시작)
brew services stop omlx # 중지
brew services restart omlx # 재시작
brew services info omlx # 상태 확인서비스는 기본 설정(~/.omlx/models, 포트 8000)으로 동작한다. 커스터마이즈하려면 환경 변수(OMLX_MODEL_DIR, OMLX_PORT)를 설정하거나, omlx serve --model-dir /your/path를 한 번 실행하면 ~/.omlx/settings.json에 설정이 저장된다.
로그는 두 곳에 기록된다:
- 서비스 로그:
$(brew --prefix)/var/log/omlx.log - 서버 로그:
~/.omlx/logs/server.log
핵심: Tiered KV Cache
oMLX를 다른 로컬 추론 서버와 구분 짓는 가장 큰 특징이다. 이해하려면 먼저 KV 캐시가 뭔지부터 짚어야 한다.

출처: oMLX GitHub
KV 캐시란
트랜스포머 모델이 토큰을 생성할 때, 이전 토큰들의 Key-Value 쌍을 저장해둔다. 다음 토큰을 만들 때 이전 토큰을 다시 계산하지 않기 위해서다. 대화가 길어질수록 이 캐시가 커지고, 메모리를 많이 잡아먹는다.
문제는 대부분의 로컬 추론 서버가 이 캐시를 RAM에만 보관한다는 거다. 모델을 교체하거나 서버를 재시작하면? 전부 날아간다. 새 대화를 시작하면? 이전 컨텍스트를 처음부터 다시 프리필해야 한다. 이게 바로 긴 대기 시간이 발생하는 원인이다.
Hot + Cold 이중 캐시
oMLX는 vLLM에서 영감을 받은 블록 기반 KV 캐시 관리를 구현했다. Prefix Sharing과 Copy-on-Write를 지원하는데, 여기에 두 계층 구조를 더했다.
Hot 계층 (RAM): 자주 접근하는 블록을 메모리에 보관한다. 빠르다.
Cold 계층 (SSD): Hot 캐시가 가득 차면 블록을 SSD로 내보낸다. safetensors 포맷으로 저장된다. 다음에 같은 프리픽스를 가진 요청이 들어오면, 처음부터 재계산하는 대신 디스크에서 복원한다.
이게 왜 빠른 걸까? 수학이 단순하다. 32K 토큰 컨텍스트를 프리필하는 데 드는 연산 비용 대비, SSD에서 수백 MB를 읽는 비용이 훨씬 적다. Apple Silicon의 NVMe SSD는 초당 수 GB를 읽을 수 있고, 이건 GPU가 수십억 개의 행렬 곱셈을 다시 하는 것보다 빠르다.
더 좋은 건, 서버를 재시작해도 Cold 캐시가 살아 있다는 점이다. SSD에 저장되니까. 맥을 껐다 켜도 이전 대화의 컨텍스트가 남아있다.
SSD 캐시를 활성화하려면:
omlx serve --model-dir ~/models --paged-ssd-cache-dir ~/.omlx/cacheomlx serve --model-dir ~/models --paged-ssd-cache-dir ~/.omlx/cacheHot 캐시 크기도 조절할 수 있다:
omlx serve --model-dir ~/models --hot-cache-max-size 20%omlx serve --model-dir ~/models --hot-cache-max-size 20%vLLM이 GPU HBM → CPU DRAM → NVMe SSD의 3단 계층을 쓰는 반면, oMLX는 Apple Silicon의 통합 메모리 구조에 맞게 RAM → SSD 2단 계층으로 단순화했다. GPU와 CPU가 메모리를 공유하는 환경에서는 이게 더 합리적이다.
Continuous Batching이 왜 중요한가
전통적인 추론 서버는 요청을 하나씩 처리한다. A가 500토큰짜리 응답을 생성하는 동안, B는 기다려야 한다. GPU가 놀고 있어도.
Continuous Batching은 다르다. 반복(iteration) 수준에서 스케줄링한다. A의 토큰 하나를 생성하고, 같은 스텝에서 B의 토큰도 생성한다. A가 끝나면 그 슬롯에 즉시 C를 넣는다. GPU가 쉴 틈이 없다.
MLX 기반 프레임워크에서 측정한 결과, Continuous Batching은 llama.cpp 대비 21%에서 87%까지 높은 처리량을 달성했고, 16개의 동시 요청 시 집계 처리량이 4.3배까지 스케일링되었다. 다만 이 이점은 14B 이하 모델에서 두드러지고, 27B 이상에서는 메모리 대역폭이 병목이 되면서 격차가 줄어든다.
oMLX는 mlx-lm의 BatchGenerator를 기반으로 이를 구현했고, 최대 동시 요청 수를 CLI나 관리자 패널에서 설정할 수 있다:
omlx serve --model-dir ~/models --max-concurrent-requests 16omlx serve --model-dir ~/models --max-concurrent-requests 16기본값은 8이다.
CLI 설정 총정리
서버를 세밀하게 튜닝하고 싶다면 알아둘 옵션들이다:
# 모델 메모리 제한
omlx serve --model-dir ~/models --max-model-memory 32GB
# 프로세스 메모리 제한 (기본값: 시스템 RAM - 8GB)
omlx serve --model-dir ~/models --max-process-memory 80%
# API 키 인증
omlx serve --model-dir ~/models --api-key your-secret-key
# HuggingFace 미러 (제한 지역용)
omlx serve --model-dir ~/models --hf-endpoint https://hf-mirror.com
# MCP 도구 지원
omlx serve --model-dir ~/models --mcp-config mcp.json# 모델 메모리 제한
omlx serve --model-dir ~/models --max-model-memory 32GB
# 프로세스 메모리 제한 (기본값: 시스템 RAM - 8GB)
omlx serve --model-dir ~/models --max-process-memory 80%
# API 키 인증
omlx serve --model-dir ~/models --api-key your-secret-key
# HuggingFace 미러 (제한 지역용)
omlx serve --model-dir ~/models --hf-endpoint https://hf-mirror.com
# MCP 도구 지원
omlx serve --model-dir ~/models --mcp-config mcp.json모든 설정은 웹 관리자 패널(/admin)에서도 변경할 수 있고, ~/.omlx/settings.json에 저장된다. CLI 플래그가 우선한다.
다음 편 예고
이번 글에서는 oMLX의 설치와 핵심 아키텍처를 다뤘다. Tiered KV Cache와 Continuous Batching이 왜 로컬 추론의 실용성을 바꿔놓는지 이해했을 거다.
하지만 oMLX의 진짜 매력은 여기서부터다. 다음 편에서는 멀티 모델 서빙의 세부 전략(LRU 퇴거, 핀닝, TTL), Claude Code와의 연동, Tool Calling, 그리고 v0.3.5에서 통합된 DFlash-MLX(speculative decoding으로 3.3배 속도 향상)까지 파고들 예정이다. Ollama, LM Studio와의 차이점도 정리한다.
이 프로젝트를 파면 팔수록, 만든 사람이 실제로 로컬 LLM을 매일 쓰는 개발자라는 게 느껴진다. "이론상 좋은 기능"이 아니라 "내가 실제로 필요해서 만든 기능"이 가득하다.
시리즈: oMLX — 맥에서 LLM을 제대로 굴려보자
참고 자료
- oMLX GitHub 레포지토리 — 소스 코드, README, 릴리스 노트
- oMLX 공식 사이트 — 벤치마크, 문서, 다운로드
- MLX 프레임워크 — Apple의 머신러닝 프레임워크
- mlx-lm — MLX 기반 LLM 추론 라이브러리
- Continuous Batching 원리 — HuggingFace의 Continuous Batching 설명
- vLLM KV Cache Offloading — vLLM의 KV 캐시 오프로딩 아키텍처








