MLX LM으로 Apple Silicon에서 로컬 AI 실행하기

Apple Silicon의 통합 메모리를 활용해 MLX LM 모델을 설치하고 터미널 생성과 로컬 HTTP API로 연결하는 절차, 보안 경계와 복구 방법을 안내합니다.

MLX LM으로 Apple Silicon에서 로컬 AI 실행하기

Apple Silicon Mac에서 언어 모델을 로컬로 돌리고 싶다면 MLX LM은 비교적 짧은 설치 과정으로 생성 명령과 HTTP API를 함께 시험할 수 있는 도구다. 다만 모든 모델이 같은 메모리에서 편안하게 작동하는 것은 아니며, 내장 서버는 기본적인 보안만 제공하므로 개인 실험과 내부 개발용이라는 경계를 먼저 세워야 한다.

무엇을 준비할까

MLX는 Apple이 Apple Silicon의 통합 메모리 구조를 활용하도록 만든 배열 프레임워크이고, MLX LM은 그 위에서 텍스트 생성·변환·양자화·미세조정을 돕는다. 이 글의 명령은 공식 문서 기준이며 macOS의 Apple Silicon 환경을 전제로 한다. Python 가상환경과 모델을 받을 저장 공간도 필요하다.

먼저 전용 가상환경을 만든다. 시스템 Python에 바로 설치하면 다른 프로젝트와 의존성이 섞일 수 있다.

python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install mlx-lm
mlx_lm.generate --help

마지막 도움말이 표시되면 CLI 설치가 정상이다. command not found라면 가상환경이 활성화됐는지, python -m pip show mlx-lm이 패키지를 찾는지부터 확인한다.

첫 생성을 실행하기

공식 예제처럼 MLX 형식으로 변환된 Hugging Face 모델 저장소를 지정할 수 있다. 최초 실행 때는 모델이 내려받아지므로 시간과 디스크 사용량이 늘어난다. 아래 모델 이름은 예시이며, 실제 사용 전 모델 카드의 라이선스와 메모리 요구량을 확인한다.

mlx_lm.generate \
  --model mlx-community/Mistral-7B-Instruct-v0.3-4bit \
  --prompt "세 문장으로 로컬 추론의 장점을 설명해줘" \
  --max-tokens 180

응답 텍스트와 함께 생성 속도·메모리 정보가 출력되면 성공이다. 메모리 압박이 심하거나 운영체제가 스왑을 과도하게 쓰면 더 작은 모델이나 더 강하게 양자화된 모델을 선택한다. 모델 이름만 보고 필요한 메모리를 단정하지 말고 실제 모델 카드와 실행 시 사용량을 함께 본다.

모델 저장소가 MLX LM을 거쳐 터미널과 로컬 API로 나뉘는 흐름
모델 저장소가 MLX LM을 거쳐 터미널과 로컬 API로 나뉘는 흐름

로컬 API 열기

MLX LM에는 OpenAI 채팅 API와 비슷한 형태의 개발용 서버가 있다. 공식 문서는 이 서버가 기본적인 보안 검사만 구현하므로 프로덕션에 권장하지 않는다고 명시한다. 기본값인 로컬 호스트에서 먼저 사용하고, 인터넷에 직접 노출하지 않는다.

mlx_lm.server \
  --model mlx-community/Mistral-7B-Instruct-v0.3-4bit \
  --port 8080

다른 터미널에서 모델 목록과 채팅 요청을 확인한다.

curl http://127.0.0.1:8080/v1/models \
  -H 'Content-Type: application/json'

curl http://127.0.0.1:8080/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "messages": [
      {"role": "user", "content": "JSON 테스트라고 짧게 답해줘"}
    ],
    "temperature": 0.2,
    "max_tokens": 80
  }'

첫 명령에서 모델 ID가, 두 번째에서 choices와 usage를 포함한 JSON이 오면 연결이 된 것이다. 앱에서는 기본 URL을 http://127.0.0.1:8080/v1로 두고, 요청마다 필요한 대화 기록만 전달한다.

옵션을 조정하기

max_tokens는 답변 길이의 상한이고 temperature는 출력의 변동성을 조절한다. 반복 가능한 분류·추출 작업은 낮게, 아이디어 생성은 조금 높게 시작하되 결과 품질을 샘플로 비교한다. 긴 입력은 컨텍스트와 메모리를 더 사용한다. 모델 크기, KV 캐시, 입력 길이를 한꺼번에 키우지 말고 하나씩 조정한다.

서버의 stream을 켜면 토큰을 순차적으로 받을 수 있다. 대화형 UI에는 유용하지만, 클라이언트가 중간 연결 종료와 부분 응답을 처리해야 한다. 자동화에서는 완성된 JSON을 받는 비스트리밍 요청이 먼저 구현하기 쉽다.

데이터 경계

로컬 실행은 프롬프트가 외부 모델 API로 자동 전송되지 않는다는 장점이 있다. 그렇다고 입력 데이터가 무조건 안전해지는 것은 아니다. 모델 파일을 받는 저장소, 앱 로그, 셸 히스토리, 백업, 같은 Mac의 다른 사용자 권한까지 포함해 경계를 본다.

  • 민감한 프롬프트를 명령줄 인자로 직접 넣으면 셸 기록이나 프로세스 목록에 남을 수 있다.
  • 내려받는 모델의 라이선스와 사용 제한은 모델마다 다르다.
  • 개발 서버를 0.0.0.0에 바인딩하면 네트워크의 다른 장치가 접근할 수 있다.
  • 로컬 모델의 답변도 환각과 오류가 있으므로 중요한 판단은 원자료로 검증한다.

오류를 진단하기

모델을 불러오다 종료되면 먼저 더 작은 양자화 모델로 재현한다. 새 모델에서 가중치나 아키텍처 불일치가 나면 MLX LM을 업데이트하고 릴리스 노트를 확인한다.

source .venv/bin/activate
python -m pip install --upgrade mlx-lm
python -m pip show mlx-lm

API가 연결되지 않으면 서버 터미널에 오류가 없는지, 8080 포트를 다른 프로세스가 쓰는지 확인한다. 요청 형식 오류는 Content-Type: application/json, messages 배열, JSON 따옴표를 차례로 점검한다. 품질이 이상하면 채팅 템플릿을 지원하는 instruct 모델인지 모델 카드를 확인한다.

중지와 제거

서버는 실행한 터미널에서 Ctrl+C로 중지한다. 프로젝트 실험을 끝냈다면 가상환경과 필요 없는 모델 캐시를 구분해 정리한다. 캐시 전체 삭제는 다른 MLX 프로젝트의 모델까지 지울 수 있으므로 먼저 사용량을 확인한다.

deactivate 2>/dev/null || true
rm -rf .venv

가상환경 삭제는 이 프로젝트의 Python 패키지만 제거한다. 모델 캐시는 별도이므로 무작정 함께 지우지 않는 편이 안전하다.

출처