← 모든 글

Apple Silicon에서의 MLX: 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의 무료이고 유지보수되며 통합된 모델을, 이제 여러분이 소유하게 된 더 무겁고 유지보수되지 않는 사본과 맞바꾼 셈입니다. 판단력이 곧 일의 전부입니다.



  1. Foundation Models 프레임워크에 대한 MLX의 위치 설정: 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 문서, unified memory. 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 adapters reference. 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 연구 루프로, 검증 bits-per-byte를 최소화하기 위해 아키텍처와 하이퍼파라미터를 자율적으로 수정하며 개선된 것만 남깁니다. 여기서 설명한 통합 메모리와 양자화 동작은 그 실험에서 비롯된 것입니다. 

관련 게시물

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

Apple의 Foundation Models 프레임워크 정리: LanguageModelSession, @Generable 기반 guided generation, 도구 호출, 가용성, 그리고 온디바이스 모델을 벗어나야…

8 분 소요

Core ML 온디바이스 추론: 실제로 출시되는 패턴들

Core ML은 모델을 Neural Engine, GPU 또는 CPU에서 실행합니다. 출시에 통하는 패턴은 모델 변환, 디스패치 힌팅, 지연 시간 예산, 양자화입니다.

9 분 소요

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

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

7 분 소요