← 모든 글

MLX와 Apple Silicon: Apple의 모델이 아니라 내 모델이 필요할 때

Apple의 Foundation Models 프레임워크는 모델을 단 하나 건네줍니다. 시스템의 모델이며, 봉인되어 있고, 무료이고, Apple의 일정에 맞춰 업데이트됩니다. 대부분의 온디바이스 언어 작업에서는 이것이 올바른 도구이며, 그 너머로 손을 뻗는 것은 실수입니다. 하지만 어떤 작업은 내가 직접 고른 모델을 필요로 합니다. 특정한 오픈 웨이트 LLM, 내가 버전을 고정한 모델, 내 데이터로 학습시킨 파인튜닝, 또는 시스템 모델이 갖지 못한 능력 말입니다. 내 모델을 온디바이스에서 돌려야 할 때, Foundation Models 아래에 놓인 계층이 바로 MLX입니다1.

MLX는 Apple Silicon에서 머신러닝을 수행하기 위한 Apple의 배열 프레임워크로, 앱에 직접 내장하는 Swift API(MLX Swift)를 갖추고 있습니다2. 호출해서 쓰는 시스템 프레임워크가 아니라, 모델 가중치와 함께 배포하는 라이브러리입니다. 바로 그 차이가 거래의 전부이며, 이 차이를 이해하는 것이야말로 한 계층 아래로 내려갈지 아니면 Apple이 정해 둔 자리에 머무를지를 판단하는 방법입니다.

핵심 요약

  • MLX는 Apple Silicon을 위해 만들어진 NumPy 스타일의 배열 프레임워크로, 지연 평가, 합성 가능한 함수 변환, 그리고 Metal 백엔드를 갖추고 있습니다2.
  • 통합 메모리 모델이 바로 이것을 휴대폰에서 동작하게 만드는 이유입니다. 배열은 CPU와 GPU가 공유하는 하나의 메모리 풀에 존재하므로, MLX는 동일한 버퍼 위에서 양쪽 모두를 넘나들며 동작하며 호스트-디바이스 간 복사 비용이 들지 않습니다3.
  • LLMModelFactory로 오픈 웨이트 LLM을 온디바이스에서 실행하세요. mlx-community/Llama-3.2-3B-Instruct-4bit 같은 양자화 모델을 가리킨 다음, ChatSession을 통해 생성하면 됩니다4.
  • LoRA 어댑터로 파인튜닝하세요. 작은 어댑터를 학습시키고, adapters.safetensors를 배포한 다음, load(into:)가 런타임에 베이스 모델의 Linear 레이어를 LoRALinear로 교체합니다5.
  • 내 모델을 갖는 데에는 대가가 따릅니다. 앱 용량(가중치가 큽니다), 메모리 압박, 시스템 통합의 부재, 그리고 모든 업데이트를 직접 책임져야 한다는 점입니다. Foundation Models에는 이런 비용이 전혀 없는데, Apple이 대신 치러 주기 때문입니다.

MLX란 무엇이며, 왜 Apple Silicon이 그것을 가능하게 하는가

MLX는 NumPy처럼 보이는 배열과 연산을 제공하고, 여기에 머신러닝이 필요로 하는 변환들을 더합니다. 자동 미분, 벡터화, 그리고 계산 그래프를 만들어 두었다가 결과를 읽을 때 비로소 실행하는 지연 평가입니다2. 이것만 놓고 보면 수십 개의 프레임워크에도 해당하는 설명입니다. MLX가 주머니 속 기기에서 수십억 파라미터 규모의 모델을 돌릴 수 있게 만드는 것은 바로 메모리 모델입니다.

데스크톱 GPU에서는 데이터가 시스템 RAM에 있고, 계산하려면 버스를 통해 GPU의 별도 메모리로 복사한 다음 결과를 다시 복사해 와야 합니다. 그 복사가 바로 비용이며, 큰 모델에서는 그 비용이 가혹합니다. Apple Silicon에는 통합 메모리가 있습니다. CPU, GPU, Neural Engine이 모두 직접 주소를 지정하는 하나의 풀입니다. MLX는 바로 이 사실을 중심으로 설계되었습니다3. 배열은 “CPU에 있는” 것도 “GPU에 있는” 것도 아닙니다. 메모리에 있을 뿐이고, 어떤 프로세서든 그 자리에서 곧바로 연산합니다. 복사도 없고, 버스 비용도 없습니다. 4비트로 양자화된 30억 파라미터 모델은 몇 기가바이트에 들어맞으며, 비슷한 메모리를 가진 분리형 GPU 머신에서라면 같은 작업을 비현실적으로 만들어 버릴 왕복 복사 없이 실행됩니다. Apple이 몇 년 전에 내린 하드웨어 결정이야말로 실제 모델의 온디바이스 추론이 애초에 성립할 수 있는 이유이며, 타일 기반의 통합 메모리 아키텍처는 MLX가 딛고 선 토대입니다.

온디바이스에서 LLM 실행하기

“특정 모델을 원한다”에서 화면에 텍스트가 뜨기까지의 경로는 짧습니다. MLX Swift의 LLM 계층은 Hugging Face Hub에서 양자화 모델을 불러와 실행합니다4.

let container = try await LLMModelFactory.shared.loadContainer(
    from: HubClient.default,
    using: TokenizersLoader(),
    configuration: .init(id: "mlx-community/Llama-3.2-3B-Instruct-4bit")
)

let session = ChatSession(container)
let response = try await session.respond(to: "Summarize this in one line: \(text)")

토큰 단위로 갱신되는 UI를 원한다면, 대신 스트림을 생성해 도착하는 대로 청크를 렌더링하세요4.

let input = try await container.prepare(input: UserInput(prompt: prompt))
let stream = try await container.generate(input: input, parameters: GenerateParameters())
for await event in stream {
    if case let .chunk(text) = event { /* append to UI */ }
}

실무적 무게의 대부분은 두 가지 세부 사항이 짊어집니다. 첫째, 모델 ID에 붙은 4bit은 있어도 그만인 장식이 아닙니다. 양자화야말로 모델이 메모리에 들어맞고 기기에서 쓸 만한 속도로 돌아가게 만드는 요소입니다. 전체 정밀도가 아니라 4비트(또는 그 이하) 가중치를 배포하는 것입니다. 둘째, 가중치는 양자화하더라도 여전히 큽니다. 그래서 이를 앱에 묶어 넣을지(즉시 사용 가능하지만 다운로드가 무겁습니다) 아니면 최초 실행 시 내려받을지(바이너리는 가볍지만 대기 시간과 실패 처리 경로가 생깁니다)를 신중하게 결정해야 합니다. Foundation Models는 모델이 이미 기기에 있기 때문에 이런 질문을 던질 일이 결코 없습니다. MLX에서는 가중치가 당신의 몫입니다.

파인튜닝: 새 모델이 아니라 LoRA 어댑터

내 모델을 가져오는 이유는 베이스 모델 자체인 경우가 드뭅니다. 그것을 내 도메인에 맞게 가르치는 것이 이유입니다. 수십억 파라미터 모델을 온디바이스에서 전체 파인튜닝하는 것은 선택지가 아닙니다. LoRA(저랭크 적응)가 선택지입니다. 베이스 모델의 동작을 조정하는 작은 어댑터 가중치 묶음을 학습시키고, 베이스는 손대지 않은 채로 둡니다. 어댑터는 기가바이트가 아니라 메가바이트 단위입니다5.

MLX Swift는 adapter_config.jsonadapters.safetensors가 담긴 디렉터리에서 학습된 어댑터를 불러온 다음, 이미 컨테이너에 적재된 모델에 적용합니다5.

let adapter = try LoRAContainer.from(directory: adapterURL)
await container.update { context in
    try? adapter.load(into: context.model)   // swaps Linear layers for LoRALinear
}

load(into:)는 모델의 표준 Linear 레이어를 어댑터의 저랭크 델타를 접어 넣은 LoRALinear 레이어로 교체하므로, 이제 추론은 당신의 파인튜닝을 반영합니다. 모델이 컨테이너 안에 존재하기 때문에 어댑터는 container.update를 통해 적용하며, 런타임에 어댑터를 즉시 교체(하나를 unload(from:)하고 다른 하나를 load(into:))하여 단일 베이스 모델에 기능별로 다른 동작을 부여할 수 있습니다. 이 패턴은 Apple이 Foundation Models 커스텀 어댑터를 통해 시스템 모델에 제공하는 것과 닮아 있습니다. 다른 점은, 여기서는 볼 수도 없는 모델을 적응시키는 대신 베이스 모델과 학습 파이프라인과 그 결과를 당신이 소유한다는 것입니다.

판단: Foundation Models, MLX, 아니면 클라우드

세 개의 계층이 있고, 잘못 고르면 능력을 잃거나 피할 수 있었던 작업 더미를 떠안게 됩니다.

  • Foundation Models — 시스템 모델이 그 작업을 해낼 수 있을 때. 무료이고, 프라이버시가 보장되며, 배포할 가중치가 없고, 관리할 메모리가 없으며, 시스템 통합을 공짜로 얻습니다. 기본값은 여기입니다. Apple이 이를 위해 만든 온디바이스 언어 작업(요약, 분류, 추출, 재작성, 구조화 출력)은 두말할 것 없이 여기에 속합니다.
  • MLX — 시스템이 주지 않는 모델이 필요할 때. 특정한 오픈 웨이트 LLM, OS 업데이트로 바뀌지 않도록 고정한 버전, 도메인 파인튜닝, 또는 Foundation Models의 범위를 벗어난 아키텍처(비전-언어 모델, 비텍스트 모델) 같은 것입니다. 앱 용량과 메모리와 소유 책임으로 비용을 치르고, 그 대가로 통제권을 삽니다.
  • 클라우드 — 모델이 정말로 커야만 할 때. 최전선 추론, 긴 컨텍스트 분석, 가장 큰 모델만 해낼 수 있는 일로서 수십억 파라미터짜리 온디바이스 모델로는 감당이 안 되는 것들입니다. 온디바이스는 최전선 모델의 대체재가 아닙니다. 곡선 위의 다른 한 점일 뿐입니다.

솔직하게 읽자면, MLX는 더 나은 기본값이 아니라 특정한 이유를 위해 의도적으로 한 단계 내려서는 선택입니다. 당신의 기능에서 Foundation Models가 부족하게 하는 능력이 무엇인지 짚어낼 수 없다면, MLX는 필요하지 않습니다. 그것을 배포한다는 것은 안 가져도 됐을 수 기가바이트의 가중치와 메모리 예산을 떠안는다는 뜻입니다.

MLX에 손을 뻗지 말아야 할 때

  • 시스템 모델이 이미 그 일을 해낸다. Foundation Models의 작업 목록을 다시 읽어 보세요. 당신의 작업이 그 목록에 있다면, 여기서 멈추세요.
  • 가중치를 감당할 수 없다. 양자화된 작은 모델도 여전히 큰 자산입니다. 앱 용량이나 최초 실행 다운로드가 사용자에게 실질적인 제약이라면, 그 제약 하나만으로 답이 정해질 수도 있습니다.
  • 고정된 모델에 대해 Neural Engine의 최저 전력 경로가 필요하다. 바뀌지 않는, 이미 배포된 알려진 모델이라면 Core ML과 그 변환기가 가장 빠듯한 전력과 지연으로 Neural Engine을 겨냥합니다. MLX는 유연성과 연구 수준의 반복에서 빛나고, Core ML은 잠가 둔 프로덕션 모델에서 빛납니다. 둘은 서로 다른 도구이며, “온디바이스 ML”은 단 하나의 결정이 아닙니다.
  • 유지보수하지 않을 것이다. 내 모델을 갖는다는 것은 그 모델의 업데이트, 보안, 드리프트를 내가 소유한다는 뜻입니다. 시스템 모델은 Apple이 대신 업데이트해 줍니다. 모델을 소유할 인력이 갖춰져 있지 않다면, 모델을 들이지 마세요.

MLX가 보상하는 기량은 언제 그것을 쓸지에 대한 절제입니다. 이 프레임워크는 진실로 놀랍습니다. 도메인에 맞게 파인튜닝된 진짜 언어 모델이 서버도 없고 토큰당 비용도 없이 기기 위에서 통째로 돌아가는데, 그것도 바로 이런 일을 위해 메모리 아키텍처가 만들어진 하드웨어에서 돌아갑니다. 그 능력은 이유를 짚어낸 다음이라면 손을 뻗을 만한 가치가 있습니다. 이유 없이 손을 뻗으면, Apple의 무료이고 유지보수되며 통합된 모델을, 이제는 당신이 소유하는 더 무겁고 유지보수되지 않는 사본과 맞바꾼 셈입니다. 판단, 그것이 일의 전부입니다.

FAQ

Apple의 MLX 프레임워크란 무엇인가요?

MLX는 Apple Silicon에서 머신러닝을 수행하기 위한 배열 프레임워크로, NumPy 스타일의 API, 합성 가능한 함수 변환(자동 미분, 벡터화), 지연 계산, 그리고 Metal 백엔드를 갖추고 있습니다2. MLX Swift는 이를 앱에 내장하기 위한 Swift API이며, 이를 통해 내 모델을 온디바이스에서 실행하고 파인튜닝할 수 있습니다.

MLX는 Apple Silicon의 통합 메모리를 어떻게 활용하나요?

MLX 배열은 공유 메모리에 존재하므로, 별도의 메모리 풀 사이에서 데이터를 복사하지 않고도 CPU나 GPU에서 연산이 실행됩니다3. 바로 이 무전송 특성이 Apple Silicon의 통합 메모리 아키텍처를 온디바이스 모델 실행에 효율적이게 만드는 요소입니다.

MLX로 오픈 웨이트 LLM을 온디바이스에서 실행할 수 있나요?

네. LLMModelFactory.shared.loadContainer(from:using:configuration:)는 Hugging Face Hub에서 mlx-community/Llama-3.2-3B-Instruct-4bit 같은 양자화 모델을 불러옵니다. ChatSession은 단일 호출용 respond(to:)를 제공하고, container.generate(input:parameters:)는 점진적 출력을 위해 .chunk(text) 이벤트를 스트리밍합니다4.

MLX로 모델을 어떻게 파인튜닝하나요?

새 모델이 아니라 LoRA 어댑터로 합니다. LoRAContainer.from(directory:)adapter_config.jsonadapters.safetensors가 담긴 디렉터리에서 어댑터를 불러옵니다. container.update를 통해 적용하면 모델의 Linear 레이어를 LoRALinear 레이어로 교체하며, 런타임에 어댑터를 즉시 교체할 수 있습니다5.

MLX vs Foundation Models vs Core ML, 무엇을 써야 하나요?

Apple의 시스템 모델이 그 작업을 해낼 수 있을 때는 Foundation Models를 기본값으로 삼으세요(무료, 프라이버시 보장, 배포할 가중치 없음)1. MLX는 시스템이 주지 않는 모델이 필요할 때만 손을 뻗으세요. 특정한 오픈 웨이트 LLM, 고정된 버전, 도메인 파인튜닝, 또는 Foundation Models의 범위를 벗어난 아키텍처 말입니다. Neural Engine의 최저 전력 경로가 필요한 잠가 둔 프로덕션 모델에는 Core ML을, 그리고 모델이 정말로 최전선 규모여야만 할 때는 클라우드를 사용하세요.

언제 MLX에 손을 뻗지 말아야 하나요?

시스템 모델이 이미 그 일을 해낼 때, 기가바이트의 가중치를 배포할 여유가 없을 때, 고정된 모델이라면 Core ML의 최저 전력 Neural Engine 경로가 더 적합할 때, 또는 모델의 업데이트와 보안과 드리프트를 소유할 인력이 갖춰져 있지 않을 때입니다. MLX는 더 나은 기본값이 아니라, 짚어낸 이유를 위해 의도적으로 한 단계 내려서는 선택입니다.



  1. MLX를 Foundation Models 프레임워크와의 관계 속에서 자리매김하기. Foundation Models는 Apple의 고정된 온디바이스 시스템 모델을 노출하며(참고: Apple Foundation Models: 온디바이스 LLM 프레임워크), MLX는 당신이 직접 고르고 파인튜닝하는 모델을 실행합니다. 둘은 온디바이스 스택의 서로 다른 계층에서 서로 다른 필요를 다룹니다. 

  2. Apple Machine Learning Research, MLXMLX Swift. MLX는 Apple Silicon에서 머신러닝을 수행하기 위한 배열 프레임워크로, NumPy 스타일의 API, 합성 가능한 함수 변환(자동 미분, 벡터화), 지연 계산, 그리고 Metal 백엔드를 갖추고 있습니다. MLX Swift는 이를 앱에 내장하기 위한 Swift API입니다. 

  3. MLX 문서, 통합 메모리. MLX 배열은 공유 메모리에 존재하며, 별도의 메모리 풀 사이에서 데이터를 전송하지 않고도 CPU나 GPU에서 연산이 실행될 수 있습니다. 바로 이 특성이 Apple Silicon의 통합 메모리 아키텍처를 온디바이스 모델 실행에 효율적이게 만듭니다. 하드웨어에 관한 배경: Apple Silicon의 TBDR와 통합 메모리

  4. Apple Machine Learning Research, MLX Swift Examples / MLX Swift LM. LLMModelFactory.shared.loadContainer(from:using:configuration:)는 Hugging Face Hub에서 양자화 모델(예: mlx-community/Llama-3.2-3B-Instruct-4bit)을 불러옵니다. ChatSession은 단일 호출용 respond(to:)를 제공하고, container.generate(input:parameters:)GenerateParametersUserInput을 통해 점진적 출력을 위한 .chunk(text) 이벤트 스트림을 산출합니다. 

  5. Apple Machine Learning Research, MLX Swift LM LoRA 어댑터 레퍼런스. LoRAContainer.from(directory:)adapter_config.jsonadapters.safetensors가 담긴 디렉터리에서 어댑터를 불러옵니다. container.update를 통해 적용하면 adapter.load(into: context.model)이 모델의 Linear 레이어를 LoRALinear 레이어로 교체하며, unload(from:)가 하나를 제거하므로 어댑터를 런타임에 즉시 교체할 수 있습니다. Apple의 시스템 모델 경로는 Foundation Models 커스텀 어댑터와 비교해 보세요. 

  6. 저자의 직접적인 MLX 작업: MLX를 통해 Apple Silicon에서 고정 예산 학습 실험을 돌리는 자율 ML 연구 루프로, 검증 BPB(bits-per-byte)를 최소화하기 위해 아키텍처와 하이퍼파라미터를 자율적으로 수정하며 개선된 결과만 남깁니다. 여기서 설명한 통합 메모리와 양자화 동작은 그 실험에서 비롯되었습니다. 

관련 게시물

Apple Foundation Models: 온디바이스 LLM 프레임워크 완벽 해설

Apple의 Foundation Models 프레임워크: LanguageModelSession, @Generable 가이드 생성, 도구 호출, 가용성, 그리고 온디바이스 모델을 벗어나야 할 시점까지.

9 분 소요

Apple Vision 프레임워크: 대부분의 개발자가 건너뛰는 온디바이스 CV

Apple Vision은 24가지가 넘는 온디바이스 CV 작업을 제공합니다. 대부분의 개발자는 Vision이 밀리초 단위로 무료로 온디바이스에서 처리하는 작업에 OpenAI Vision을 기본값으로 사용합니다.

10 분 소요

AI 시스템 구축: RAG에서 에이전트까지

3,500줄의 에이전트 시스템을 86개의 훅과 합의 검증으로 구축했습니다. RAG, 파인튜닝, 에이전트 오케스트레이션에 대해 배운 것들을 공유합니다.

7 분 소요