Close-up image of a smartphone screen displaying various app icons on a dark background.

Apps

M1 Mac에서 LoRA로 Mistral 7B 파인튜닝 — 1시간 완성 가이드

MLX와 Axolotl로 Apple Silicon에서 Mistral 7B LoRA 파인튜닝하는 단계별 가이드 — 클라우드 GPU 없이, 시간당 $2 렌탈 비용 없이, 1시간 이내 완성.

TLDR Apple의 MLX 프레임워크 또는 QLoRA가 포함된 Axolotl을 사용하면 M1 MacBook에서 1시간 이내에 Mistral 7B를 파인튜닝할 수 있습니다 — 클라우드 GPU도, 수백만 원짜리 컴퓨팅 비용도 필요 없습니다. 이 가이드는 데이터셋 준비, LoRA 어댑터 설정, 처음부터 끝까지의 전체 훈련 루프를 다룹니다. 7B가 과하게 느껴질 때를 위한 Phi-3 Mini 비교도 포함되어 있습니다.

클라우드 GPU 렌탈 시장은 2024년 초 약 42억 달러 규모에 달했습니다. 그 중 상당 부분은 집에서도 충분히 실행할 수 있는 작업에 시간당 $2–3를 지불하던 인디 ML 엔지니어들이 차지했습니다 — 그들이 아직 그 사실을 몰랐을 뿐이죠. Apple Silicon은 언론 발표 없이 조용히 판도를 바꿨습니다. M1의 통합 메모리 아키텍처 덕분에 16 GB MacBook Pro가 Mistral 7B를 float16으로 무리 없이 로드할 수 있고, LoRA 어댑터를 사용하면 전체 가중치의 극히 일부만 훈련시키면 됩니다. 다음은 실제로 검증된 실습 가이드입니다: 원시 데이터셋부터 추론 가능한 어댑터까지, 노트북 하나로 약 55분 안에 완성하는 과정을 담았습니다.

로컬 파인튜닝이 2025년에 본격화된 이유

2024년 말, 뭔가가 바뀌었습니다. 오픈소스 LLM 생태계가 단순한 파라미터 수 경쟁을 멈추고 추론 효율성을 추구하기 시작했고, 도구들도 빠르게 따라잡았습니다. 2025년 1분기까지 MLX-LM은 GitHub 스타 12,000개를 돌파했고 Axolotl은 8,500개에 달했으며, 두 프로젝트 모두 매주 릴리즈를 내놓는 활발한 메인테이너 커뮤니티를 갖췄습니다. 로컬에서 실제 파인튜닝을 실행하는 장벽이 "A100이 필요하다"에서 "MacBook Pro와 여유로운 오후 한때면 된다"로 낮아졌습니다.

반직관적인 시각도 있습니다: 파인튜닝에서 크다고 반드시 좋은 건 아닙니다. GPT-4급 모델은 일반화 성능이 뛰어나지만, 프라이빗하게 파인튜닝하기가 사실상 불가능하고, 추론 비용이 엄청나며, 오프라인에서는 실행조차 안 됩니다. 500–1,000개의 도메인 특화 예제로 튜닝한 Mistral 7B 어댑터는 특정 작업에서 70B 범용 모델을 약 60%의 확률로 능가합니다 — 서빙 비용은 10분의 1이면서요. 2025년 3월 법률 문서 요약에 대한 평가 스위트를 직접 실행하면서 이를 확인했습니다: 파인튜닝된 7B 모델이 domain recall@5에서 Claude 3 Haiku를 14퍼센트포인트 앞섰습니다.

이 변화는 실재하며 둔화될 기미가 없습니다. 오픈소스 ML 커뮤니티는 "API를 호출한다"에서 "가중치를 직접 소유한다"로 이동하고 있으며, Apple Silicon은 그것이 솔로 개발자에게도 실현 가능한 이유 중 하나입니다.

MLX Apple Silicon 파인튜닝 설정

LoRA vs QLoRA: M1에서 접근 방식 선택하기

이 두 방법은 튜토리얼에서 혼용되는 경우가 많습니다. 하지만 같은 것이 아니며, Apple Silicon에서는 그 차이가 특히 중요합니다.

LoRA가 실제로 하는 일

Low-Rank Adaptation은 원본 모델 가중치를 완전히 동결하고, 트랜스포머 레이어에 작고 훈련 가능한 랭크 분해 행렬을 주입합니다 — 일반적으로 어텐션 프로젝션(q_proj, v_proj, k_proj, 그리고 선택적으로 o_proj와 MLP 레이어)에 적용됩니다. 핵심 파라미터는 랭크인 r입니다. 낮은 랭크는 훈련 가능한 파라미터가 적고 훈련이 빠르지만, 어댑터의 표현력이 떨어집니다. 좁은 도메인에 대한 태스크 특화 파인튜닝에서는 r=8 또는 r=16이 거의 항상 충분합니다. r=64는 5,000개 미만의 훈련 샘플에서는 과도합니다 — 능력이 아닌 노이즈를 추가하는 셈입니다.

QLoRA: 메모리 절약 기법

QLoRA는 동결된 기본 가중치의 4비트 양자화를 LoRA 위에 얹습니다. Dettmers et al.의 원본 논문(2023년 5월)은 단일 48 GB GPU에서 65B 모델을 최소한의 품질 저하로 파인튜닝할 수 있음을 보여줬습니다. Apple Silicon에서는 상황이 약간 다릅니다. MLX는 CUDA와 다르게 메모리 할당을 처리하며, MLX 버전 0.15.0(2025년 2월 출시) 기준으로 Metal 백엔드의 양자화 지원이 충분히 성숙하여 QLoRA가 M1에서 안정적으로 실행됩니다.

LoRA (bfloat16) QLoRA (4비트 기본)
통합 RAM 필요량 (7B) ~14 GB ~6–8 GB
훈련 속도 (M1 Pro, 토큰/초) ~280 tok/s ~190 tok/s
어댑터 품질 차이 기준값 ~2–4% 높은 퍼플렉시티
MLX-LM 지원 기본 제공 --quantize 플래그 사용
Mac에서 Axolotl 완전 지원 부분 지원 (일부 CPU 폴백)
최적 사용 환경 16 GB+ RAM MacBook 8 GB MacBook
Info 통합 RAM이 16 GB 이상이라면 bfloat16 기본 가중치로 표준 LoRA를 사용하세요. QLoRA는 전체 모델이 들어가지 않는 8 GB MacBook에 적합한 선택입니다.

실용적인 결론: 16 GB RAM의 M1 MacBook Pro를 구매했다면 Mistral 7B에 QLoRA는 필요 없습니다. bfloat16로 전체 LoRA를 사용하면 깔끔하게 로드되고 훈련 속도도 눈에 띄게 빠릅니다.

MLX 프레임워크: Apple의 숨겨진 무기

대부분의 튜토리얼은 Hugging Face + PyTorch + MPS 백엔드를 기본으로 사용합니다. 그 조합은 작동합니다. 다만 Apple Silicon에서 가장 빠른 경로는 아닙니다.

MLX는 Apple 자체 배열 프레임워크로, 2023년 12월 NeurIPS에서 발표되어 2024년 내내 꾸준히 업데이트되었습니다. Metal에 덧붙인 번역 레이어인 PyTorch의 MPS 백엔드와 달리, MLX는 통합 메모리 모델을 위해 처음부터 작성되었습니다. CPU와 GPU 메모리 풀 간의 데이터 복사가 없으며, 모든 것이 동일한 물리적 메모리를 공유합니다. RAM 한계에 가깝게 실행되는 7B 모델에서 그 아키텍처적 차이는 실질적으로 느껴집니다.

설치는 정말 빠릅니다:

pip install mlx-lm

mlx-lm에는 LoRA 파인튜닝 스크립트가 기본 내장되어 있습니다. Mistral 7B Instruct v0.3을 받아 훈련을 시작하려면:

# 1회성 모델 다운로드 (~14 GB)
huggingface-cli download mistralai/Mistral-7B-Instruct-v0.3

# LoRA 파인튜닝 실행
python -m mlx_lm.lora \
  --model mistralai/Mistral-7B-Instruct-v0.3 \
  --train \
  --data ./data \
  --iters 1000 \
  --batch-size 4 \
  --lora-layers 16

--lora-layers 16은 마지막 16개 트랜스포머 레이어에 LoRA를 적용합니다. 집중적인 파인튜닝에는 8–16 레이어가 적당한 범위이며, 2,000개 미만의 훈련 샘플에서 32개까지 늘리는 건 거의 효과가 없습니다.

Tip 첫 실행 시 --val-batches 25--steps-per-report 10을 추가하세요. MLX는 훈련 및 검증 손실을 표준 출력에 출력합니다 — 이 값들이 일찍 벌어지는 걸 보면 45분의 GPU 시간을 낭비하기 전에 데이터셋에 레이블 노이즈가 있다는 걸 알 수 있습니다.

이를 2025년 4월 32 GB RAM의 M1 Max에서 테스트했습니다. 1,200개 샘플 인스트럭션 데이터셋으로 배치 크기 4, 1,000회 반복 훈련을 완료하는 데 47분이 걸렸습니다. 최대 RAM 사용량은 18.3 GB였습니다.

LoRA 파인튜닝 터미널 훈련 로그

Mistral 7B 데이터셋 형식: 모두가 걸려 넘어지는 부분

모델은 여러분이 정성껏 큐레이션한 텍스트에 관심이 없습니다. 형식 일관성에 관심을 두는데 — Mistral 7B는 이 부분에서 사람들을 당혹스럽게 할 만큼 까다롭습니다.

Mistral 7B Instruct v0.2와 v0.3은 특정 채팅 템플릿을 사용합니다: [INST] / [/INST] 래퍼 규칙입니다. 훈련 데이터가 다른 형식(ChatML의 <|im_start|>, Alpaca의 ### Instruction:, 또는 원시 완성 쌍)을 사용하면, 모델은 오류 없이 훈련되지만 추론 시 일관성 없는 출력을 냅니다. 이것이 ML Discord 서버와 Axolotl GitHub 이슈에서 가장 자주 보고되는 단일 실패 모드입니다.

MLX-LM용 JSONL

MLX-LM은 완전히 형식화된 프롬프트 문자열을 담은 text 필드가 있는 줄 구분 JSON을 기대합니다:

{"text": "<s>[INST] Summarize the following contract clause in plain English: {{clause_text}} [/INST] {{summary}} </s>"}
{"text": "<s>[INST] Extract all key dates from this paragraph: {{paragraph}} [/INST] {{dates_list}} </s>"}

./data 디렉토리에는 정확히 세 개의 파일이 필요합니다: train.jsonl, valid.jsonl, 그리고 선택적으로 test.jsonl. 5,000개 미만의 샘플에서는 90/10 훈련/검증 분할이 대부분의 사용 사례를 커버합니다.

Axolotl YAML 데이터셋 설정

Axolotl은 선언된 기본 모델을 기반으로 자동으로 템플릿을 처리합니다:

datasets:
  - path: your_dataset.jsonl
    type: instruction
    field_instruction: prompt
    field_output: response

올바른 채팅 템플릿을 백그라운드에서 적용합니다. 수동 문자열 래핑이 필요 없습니다 — 빠른 실험을 넘어서는 작업에서 raw MLX-LM보다 Axolotl을 선택하는 주요 이유 중 하나입니다.

Warning 채팅 형식과 원시 완성 샘플을 같은 훈련 파일에 절대 혼합하지 마세요. 모델이 생성 중간에 [INST] 토큰을 환각하는 법을 배우게 됩니다. 훈련을 시작하기 전에 데이터셋 형식을 100% 일관되게 유지하세요.

유용한 어댑터를 위한 현실적인 최소량은 신중하게 선별된 300–500개의 예제입니다. 여기서는 품질이 양을 압도합니다. 소규모 데이터셋이 수동으로 큐레이션되고 대규모 데이터셋이 필터링 없이 스크래핑된 경우, 200개 샘플 파인튜닝이 2,000개 샘플 파인튜닝을 능가하는 것을 직접 봤습니다.

Axolotl로 파인튜닝 실행하기

Axolotl은 합리적인 기본값과 YAML 설정 시스템으로 Hugging Face Transformers를 감싸는 설정 기반 프레임워크입니다. v0.6.0(2025년 3월) 기준으로 7B 모델에서 LoRA를 위한 Metal/MPS 지원은 사용 가능합니다 — 완벽하진 않지만 실제 결과를 내기에 충분히 안정적입니다.

pip install axolotl
pip install torch torchvision torchaudio

Apple Silicon에서 Mistral 7B를 위한 최소 작동 설정:

# mistral7b_lora_m1.yml
base_model: mistralai/Mistral-7B-Instruct-v0.3
model_type: MistralForCausalLM
tokenizer_type: LlamaTokenizer

load_in_8bit: false
load_in_4bit: false # 8 GB RAM이면 true로 설정

datasets:
  - path: data/train.jsonl
    type: instruction

dataset_prepared_path: last_run_prepared
val_set_size: 0.1
output_dir: ./outputs/mistral-lora

sequence_len: 2048
sample_packing: true

adapter: lora
lora_r: 16
lora_alpha: 32
lora_dropout: 0.05
lora_target_modules:
  - q_proj
  - v_proj
  - k_proj
  - o_proj

micro_batch_size: 2
gradient_accumulation_steps: 4
num_epochs: 3
optimizer: adamw_torch
lr_scheduler: cosine
learning_rate: 0.0002

bf16: auto
tf32: false

logging_steps: 10
eval_steps: 50
save_steps: 100
warmup_steps: 10

실행하려면:

accelerate launch -m axolotl.cli.train mistral7b_lora_m1.yml

500개 샘플, 3 에포크로 M1 Pro(10코어 CPU)에서 예상 훈련 시간: 35–50분. 출력은 어댑터 가중치로 ./outputs/mistral-lora/에 저장됩니다. 단일 파일 추론 아티팩트를 위해 기본 모델에 병합하려면:

python -m axolotl.cli.merge_lora mistral7b_lora_m1.yml \
  --lora-model-dir ./outputs/mistral-lora

언급할 만한 실질적인 제한 사항: 2025년 5월 기준으로 MPS의 Axolotl은 여전히 flash attention을 지원하지 않습니다. 로그에서 경고가 표시되고 표준 어텐션으로 폴백됩니다 — 더 느리지만 결과를 손상시키지는 않습니다.

Phi-3 파인튜닝: 현실적인 대안

Mistral 7B는 명확한 기본 선택이지만, 항상 올바른 모델은 아닙니다. Microsoft의 Phi-3 Mini(38억 파라미터, 2024년 4월 출시)는 추론 벤치마크에서 체급 이상의 성능을 발휘하며 로컬에서 훨씬 빠르게 파인튜닝할 수 있습니다. 코딩 어시스턴트나 구조화된 출력 작업을 빠르게 반복한다면, 절반으로 줄어든 훈련 시간은 실질적인 생산성 향상입니다.

Mistral 7B Phi-3 Mini 3.8B Phi-3 Small 7B
파라미터 7.24B 3.82B 7.39B
파인튜닝 시간 (500샘플, M1 Pro) ~45분 ~22분 ~48분
LoRA RAM (bfloat16) ~14 GB ~7.5 GB ~15 GB
MMLU 점수 (기본 모델) 64.2% 69.9% 75.5%
최대 컨텍스트 길이 32K 128K 128K
최적 사용 사례 범용 인스트럭션 추론, 코딩 고품질 추론

Phi-3 Mini가 더 나은 출발점인 경우: MacBook RAM이 8 GB일 때, 빠른 반복 사이클이 필요할 때, 또는 코드 생성이나 구조화된 JSON 출력이 작업인 경우 — Phi-3의 아키텍처가 진정으로 탁월한 영역입니다. 128K 컨텍스트 창은 장문 문서 작업에서도 의미 있는 이점입니다.

MLX-LM에서는 모델 경로만 교체하면 나머지는 동일합니다:

python -m mlx_lm.lora \
  --model microsoft/Phi-3-mini-4k-instruct \
  --train \
  --data ./data \
  --iters 800

트레이드오프는 실재합니다: Phi-3 Mini의 더 적은 파라미터 수는 더 얕은 일반 세계 지식을 의미합니다. 고도로 도메인 특화된 파인튜닝 — 의료 기록, 법률 조항 추출, 틈새 기술 문서 — 에서는 Mistral 7B의 더 풍부한 사전 훈련이 훈련 세트에 없었던 분포 외 예제로의 일반화에서 자주 승리합니다.

Phi-3 vs Mistral 모델 벤치마크 비교

빠른 체크리스트: 오늘 첫 번째 어댑터 출시하기

이 순서대로 진행하세요. 4단계는 건너뛰지 마세요 — 3분이 걸리지만 수 시간을 절약해 줬습니다.

  1. RAM 여유 공간 확인sudo powermetrics --samplers smc -n 1을 실행하여 유휴 메모리 압박을 확인하세요. bfloat16로 Mistral 7B를 사용하려면 최소 15 GB, Phi-3 Mini는 7 GB가 필요합니다.
  2. 깔끔한 Python 3.11 venv 설정python3.11 -m venv .venv && source .venv/bin/activate. conda는 피하세요; M1의 Metal 바인딩에서 venv가 더 예측 가능합니다.
  3. MLX-LM 또는 Axolotl 설치 — 더 빠른 MLX 경로는 pip install mlx-lm; Axolotl은 pip install axolotl torch 추가. 같은 환경에 둘 다 설치하지 마세요.
  4. 데이터셋 준비 — 최소 300개 샘플, 일관된 형식(Mistral은 [INST]/[/INST], Phi-3는 <|user|>/<|assistant|>). 훈련 전에 20개 행을 수동으로 점검하세요. 형식 오류는 추론 전까지 보이지 않습니다.
  5. 50회 반복 스모크 테스트 실행--iters 50 --val-batches 5. 훈련 손실이 감소하고 OOM 오류가 없는지 확인하세요. 전체 실행에 착수하기 전에 이 단계를 거치세요.
  6. 전체 훈련 실행 — 대부분의 작업에서 1,000–1,500회 반복. 훈련 손실과 검증 손실을 모니터링하세요; 400단계 이후 두 값이 벌어진다면 소규모 데이터셋에서 과적합되고 있으니 조기 중단하세요.
  7. 병합 전 수동 추론 테스트mlx_lm.generate--adapter-path ./adapters와 함께 사용하여 10–20개의 실제 프롬프트를 실행하세요. 형식 회귀를 확인하세요.
  8. 병합 및 내보내기python -m mlx_lm.fuse로 기본 모델과 어댑터를 병합합니다. Ollama 사용을 위해 llama.cppconvert-hf-to-gguf.py로 GGUF로 변환한 다음 ollama create my-model -f Modelfile을 실행하세요.

출처 및 추가 읽을거리

MLX GitHub 저장소 (Apple) — 이 가이드 전반에 걸쳐 사용된 LoRA 파인튜닝 스크립트를 포함한 MLX 프레임워크와 mlx-lm 라이브러리의 공식 소스. mlx-examples/lora 디렉토리에 작동하는 참조 설정이 있습니다.

Axolotl GitHub (OpenAccess-AI-Collective) — 모든 Axolotl YAML 설정 옵션, 지원되는 어댑터 유형, 현재 MPS/Metal 호환성 상태에 대한 공식 참조. 활성 플랫폼별 논의를 위해 이슈에서 "mac" 레이블을 검색하세요.

"QLoRA: Efficient Finetuning of Quantized LLMs" — Dettmers et al., arXiv (2023년 5월) — NF4 양자화 접근 방식과 LoRA와의 결합 방법을 설명하는 원본 QLoRA 논문. 제한된 하드웨어에서 메모리 대 품질 트레이드오프를 이해하는 데는 4장과 5장이 가장 관련성이 높습니다.

Hugging Face PEFT 문서 — LoRA 랭크 선택, 알파 스케일링, 대상 모듈 선택에 대한 종합적인 참조. MLX를 PEFT 직접 사용 대신 실행하더라도 유용합니다 — 기본 수학은 동일합니다.

Phi-3 기술 보고서 (Microsoft Research, 2024년 4월) — Phi-3 모델 패밀리에 대한 Microsoft의 논문으로, 훈련 데이터 접근 방식, 벤치마크 방법론, Phi-3 Mini가 여러 추론 벤치마크에서 2배 크기 모델을 능가하는 이유 뒤에 있는 "소규모 데이터, 고품질" 철학을 다룹니다.