🔥 oMLX 파헤치기 — 멀티 모델, Claude Code 연동, DFlash까지

#oMLX#Apple Silicon#Claude Code#DFlash#로컬 추론
1206자
14분

oMLX Integrations
출처: oMLX GitHub

지난 편에서 oMLX의 설치, Tiered KV Cache, Continuous Batching을 다뤘다. 이번엔 실제로 이 서버를 써먹는 이야기다. 여러 모델을 동시에 올리고, Claude Code에 붙이고, Tool Calling을 쓰고, v0.3.5에서 새로 들어온 DFlash로 속도를 끌어올리는 것까지.

멀티 모델 서빙

대부분의 로컬 추론 서버는 모델 하나를 올리면 끝이다. 다른 모델을 쓰려면 현재 모델을 내리고, 새 모델을 올려야 한다. 코딩할 때는 Qwen3-Coder를, 문서 요약에는 Llama를, 임베딩에는 BGE-M3를 쓰고 싶다면? 매번 모델을 바꿔 끼워야 한다.

oMLX는 하나의 서버에서 LLM, VLM, OCR, 임베딩, 리랭커를 전부 동시에 서빙한다. 모델 관리는 자동과 수동이 섞여 있다.

자동 관리

  • LRU 퇴거(eviction): 메모리가 부족하면 가장 오래 안 쓴 모델부터 자동으로 내린다.
  • 프로세스 메모리 제한: 전체 메모리 사용량을 시스템 RAM - 8GB로 제한한다(기본값). OOM을 원천 차단한다.

수동 제어

  • 모델 핀닝(pinning): 자주 쓰는 모델을 메모리에 고정한다. LRU에서 제외되니까, 다른 모델이 들어와도 내려가지 않는다.
  • 수동 로드/언로드: 관리자 대시보드에서 뱃지 클릭 한 번으로 모델을 올리거나 내릴 수 있다.
  • 모델별 TTL: 모델마다 유휴 시간 제한을 걸어둔다. 30분 동안 안 쓰이면 자동 언로드 같은 식이다.
  • 모델 별칭(alias): API에서 보이는 이름을 커스터마이즈할 수 있다. /v1/models가 별칭을 반환하고, 요청할 때 별칭과 디렉토리명 모두 쓸 수 있다.
  • 모델 타입 오버라이드: 자동 감지가 틀렸을 때, LLM인지 VLM인지 수동으로 지정할 수 있다.

이걸 다 관리자 대시보드에서 클릭 몇 번으로 한다. 서버 재시작 없이 즉시 적용된다. 사소하지만, 이런 디테일이 "매일 쓰는 도구"와 "한 번 써보고 마는 도구"를 나눈다.

지원하는 모델 타입은 이렇다:

타입지원 모델
LLMmlx-lm이 지원하는 모든 모델
VLMQwen3.5 Series, GLM-4V, Pixtral 등 mlx-vlm 모델
OCRDeepSeek-OCR, DOTS-OCR, GLM-OCR
임베딩BERT, BGE-M3, ModernBERT
리랭커ModernBERT, XLM-RoBERTa

v0.3.0부터는 오디오 모델도 지원한다. mlx-audio를 통해 STT(음성→텍스트), TTS(텍스트→음성), STS(음성→음성) 엔진이 추가됐다.

Claude Code 최적화

이 부분이 개인적으로 가장 끌렸다. Claude CodeOpenCode처럼 긴 컨텍스트를 쓰는 코딩 에이전트를 로컬 모델에 붙일 때, 두 가지 문제가 있다.

문제 1: 컨텍스트 크기 불일치. Claude Code는 200K 토큰 컨텍스트를 전제로 설계됐다. 로컬 모델은 대부분 8K~32K다. Claude Code의 auto-compact가 200K 기준으로 동작하면, 로컬 모델이 이미 한계를 넘긴 뒤에야 컴팩트가 시작된다.

문제 2: 프리필 타임아웃. 긴 프롬프트를 프리필하는 데 시간이 오래 걸리면, SSE(Server-Sent Events) 스트림에 데이터가 안 오고, 클라이언트가 타임아웃을 건다.

oMLX는 두 가지를 동시에 해결했다:

  • 컨텍스트 스케일링: 보고하는 토큰 수를 스케일링해서, Claude Code의 auto-compact가 로컬 모델의 실제 컨텍스트 한계에 맞게 작동하도록 한다.
  • SSE Keep-alive: 프리필이 오래 걸릴 때, 빈 SSE 이벤트를 보내서 읽기 타임아웃을 방지한다.

관리자 대시보드의 Integrations 탭에서 Claude Code, OpenCode, Codex, Pi 연동을 클릭 한 번으로 설정할 수 있다. 수동 설정 파일 편집이 필요 없다.

API 호환성

oMLX는 OpenAI APIAnthropic Messages API 둘 다 지원한다. 드롭인 교체가 가능하다는 뜻이다.

엔드포인트설명
POST /v1/chat/completions채팅 완성 (스트리밍)
POST /v1/completions텍스트 완성 (스트리밍)
POST /v1/messagesAnthropic Messages API
POST /v1/embeddings텍스트 임베딩
POST /v1/rerank문서 리랭킹
GET /v1/models사용 가능한 모델 목록

v0.3.0부터 오디오 엔드포인트도 추가됐다:

엔드포인트설명
POST /v1/audio/transcriptions음성→텍스트
POST /v1/audio/speech텍스트→음성
POST /v1/audio/process음성→음성 (oMLX 전용)

스트리밍 사용량 통계(stream_options.include_usage), Anthropic의 adaptive thinking, 비전 입력(base64, URL) 전부 지원한다.

Tool Calling과 Structured Output

mlx-lm이 지원하는 모든 function calling 형식을 그대로 쓸 수 있다. JSON 스키마 검증과 MCP 도구 통합도 가능하다.

자동 감지되는 모델별 Tool Calling 형식은 이렇다:

모델형식
Llama, Qwen, DeepSeekJSON <tool_call>
Qwen3.5 SeriesXML <function=...>
Gemma<start_function_call>
GLM (4.7, 5)<arg_key>/<arg_value> XML
MiniMaxNamespaced <minimax:tool_call>
Mistral[TOOL_CALLS]
Kimi K2<|tool_calls_section_begin|>

목록에 없는 모델도, 챗 템플릿이 tools 파라미터를 받고 출력이 <tool_call> XML 형식이면 동작한다. 스트리밍 중에는 어시스턴트 텍스트가 점진적으로 나오고, tool call 마크업은 파싱이 끝난 뒤에 전달된다.

v0.3.0에서 추가된 xgrammar 기반 structured output도 눈에 띈다. logit 레벨에서 문법 제약을 걸어서, 모델 forward pass와 병렬로 비트마스크를 적용한다. JSON 스키마를 강제하고 싶을 때 유용하다.

DFlash-MLX: Speculative Decoding의 새 도구

v0.3.5에서 실험적으로 통합된 기능이다. DFlash는 block diffusion 기반의 speculative decoding 프레임워크다.

기존 autoregressive 생성은 토큰을 하나씩 만든다. DFlash는 작은 draft 모델이 여러 토큰을 한 번에 제안하고, 타깃 모델이 한 번의 forward pass로 전체를 검증한다. 맞는 프리픽스까지 수용하고 나머지는 버린다. 출력은 정확히 동일하지만 forward pass 횟수가 줄어든다.

dflash-mlx는 이걸 Apple Silicon의 MLX에서 네이티브로 구현한 것이다. 벤치마크에 따르면 M5 Max에서 Qwen3.5-9B가 85 tok/s를 달성했는데, 이건 기존 autoregressive 대비 3.3배 빠른 수치다. 4배 속도 향상을 보고한 사례도 있다.

기술적으로 흥미로운 점은, DFlash의 drafter가 타깃 모델의 중간 레이어 activation을 조건으로 받는다는 거다. 단순히 최종 logit만 보는 게 아니라, 특정 레이어의 hidden state를 표면화해서 다음 드래프트 블록에 넘긴다. 이게 높은 acceptance rate의 비결이라고 한다.

아직 실험적 기능이라 모든 모델에서 바로 쓸 수 있는 건 아니다. 하지만 로컬 추론에서 속도가 관건인 상황이라면, 앞으로 주목할 방향이다.

Ollama, LM Studio와 뭐가 다른가

2026년 4월 기준, Mac에서 로컬 LLM을 돌리는 선택지는 크게 세 가지다. 각각 지향하는 바가 다르다.

Ollama: CLI 중심의 모델 서버. 가장 넓은 모델 호환성을 가지고 있다. 2026년 3월에 MLX 백엔드를 프리뷰로 추가했고, v0.14부터는 네이티브 Anthropic API 호환도 된다. "brew install처럼 모델을 설치하고, 항상 켜두는 서버"를 지향한다.

LM Studio: GUI 중심의 데스크톱 앱. MLX를 기본 백엔드로 쓰기 때문에 Mac에서 성능이 좋다. M3 Ultra 기준으로 Gemma 3 1B에서 237 tok/s가 나온다는 벤치마크가 있다. 모델 발견과 실험이 편하다.

oMLX: 서버 중심, Apple Silicon 전용. 위 둘과 결정적으로 다른 점이 세 가지다.

  1. Tiered KV Cache. 이건 oMLX만 가지고 있다. Ollama와 LM Studio는 RAM 캐시만 쓴다. 서버를 재시작하면 캐시가 전부 날아간다.
  2. 멀티 모델 동시 서빙. Ollama도 여러 모델을 올릴 수 있지만, LRU 퇴거, 핀닝, 모델별 TTL 같은 세밀한 제어는 oMLX가 더 앞선다.
  3. 코딩 에이전트 최적화. 컨텍스트 스케일링, SSE keep-alive, 원클릭 연동 설정 같은 기능은 oMLX에만 있다.

반면 oMLX의 약점도 분명하다. Apple Silicon 전용이라 Linux나 Windows에서는 못 쓴다. GGUF 포맷을 지원하지 않아서 MLX 변환 모델만 쓸 수 있다. Ollama의 방대한 모델 라이브러리와 비교하면 접근성이 떨어진다.

선택 기준을 정리하면:

  • 다양한 환경, 넓은 모델 호환성 → Ollama
  • GUI 중심, 모델 탐색과 실험 → LM Studio
  • Apple Silicon에서 코딩 에이전트와 함께 실용적으로 → oMLX

정리하면서

두 편에 걸쳐 oMLX를 뜯어봤다. 처음에는 "또 하나의 로컬 추론 서버"인 줄 알았는데, Tiered KV Cache 하나만 봐도 접근 방식이 확실히 다르다. "서버를 껐다 켜도 캐시가 남는다"는 건, 로컬 LLM이 일회성 장난감에서 일상 도구로 넘어가는 지점이다.

두 달 만에 63번 릴리스를 찍는 속도가 무섭다. 아직 v0.3.x라서 안정성에 대한 의문은 남아있고, Apple Silicon 전용이라는 제약도 크다. 하지만 M시리즈 맥을 쓰면서 로컬 LLM을 진지하게 활용하고 싶다면, 지금 당장 시도해 볼 가치는 충분하다.

이번 주말에 내 M4 Pro에 직접 올려서, 평소 쓰는 코딩 에이전트 파이프라인에 붙여볼 생각이다. SSD 캐시 효과가 체감상 얼마나 나는지, DFlash가 실제로 빠른지. 써보고 나면 그 결과도 정리해 둘 예정이다.


시리즈: oMLX — 맥에서 LLM을 제대로 굴려보자

참고 자료

YouTube 영상

채널 보기
AI는 왜 수백 차원의 벡터를 사용할까? 고차원 공간과 행렬 | 선형대수학
AI 추천 시스템의 원리, 벡터 사이의 각도와 코사인 유사도 | 선형대수학
트라이(Trie)에서 단어를 삭제하는 방법 | Trie 자료구조 이야기
행렬의 가장 중요한 연산 - 행렬 곱셈 | 선형대수학
직교성과 벡터 투영 | 선형대수학
마지막편, 트라이 노드를 50% 이상 줄이는 방법? 압축 트라이 성능 분석 | Trie 자료구조 이야기
내적의 기하학적 의미와 코사인 유사도 원리 | 선형대수학
숫자 하나가 AI 모델의 운명을 바꾼다? | 선형대수학