한 줄 요약: 단일 M4의 tok/s가 이미 충분한데 동시 요청과 야간 배치 처리에서 대기열이 생기기 시작하면, Mac mini를 몇 대 더 사서 클러스터로 묶으면 처리량이 두 배가 될까요? 2/4/8 노드 확장 곡선, 프레임워크 차이, 실제 ROI를 한 표에 정리한 글은 드뭅니다. 아래에서는 테스트 환경, 단일 노드 기준선, 클러스터 확장, 병목 분석, 배포 체크리스트까지 2026년판 재현 가능한 심층 실측을 제공합니다.
테스트 결론 요약
ZavCloud 데이터센터에서 Mac mini M4(24GB) 4대와 Cloud Mac M4 인스턴스 4대로 확장 가능한 테스트베드를 구성하고, 동일한 네트워크·전원 정책 아래 2주간 부하 테스트를 수행했습니다. 핵심 발견은 다음과 같습니다.
- 요청 단위 병렬 처리는 거의 선형 확장: 7B 모델, 노드별 독립 Ollama 인스턴스 + Nginx 라운드로빈, 2/4/8 노드 집계 처리량 확장 효율은 각각 95% / 92% / 86%
- 단일 대형 모델은 「메모리를 합칠 수 없음」: 32B 이상 모델은 Apple Silicon에서 여전히 단일 노드 통합 메모리 한계에 부딪힘. 클러스터는 단일 머신 24GB→64GB 업그레이드 경로를 대체할 수 없음
- MLX는 단일 노드에서 더 빠르고, Ollama는 클러스터 운영에 유리: 동일 노드에서 MLX가 Ollama보다 약 8%–15% 빠르지만, Ollama의 OpenAI 호환 API와 핫 업데이트가 다중 노드 오케스트레이션에 더 적합
- 병목은 연산에서 스케줄링으로 이동: 8 노드에서 로드 밸런싱과 모델 콜드 스타트가 end-to-end 지연의 25%–40%를 차지하며, GPU/NPU 자체가 아님
- ROI 전환점은 동시 배치 처리: RAG 임베딩, 로그 요약 등 멀티테넌트 오프라인 작업에서 4 노드 클러스터의 천 회 추론당 비용이 단일 노드 대비 약 38% 낮음(유휴·대기 시간 분산)
인과 관계: 요청이 클러스터에 진입한 뒤 처리량 경로
클러스터에 적합
- 멀티테넌트 API 게이트웨이
- RAG 배치 임베딩 / 요약
- 7B–14B 요청 단위 병렬
- 탄력적 피크 (Cloud Mac)
클러스터에 부적합
- 단일 사용자 32B 대화형
- 텐서 병렬 대형 모델
- 저동시성 개인 실험
- LB 콜드 스타트 비용 무시
핵심 논리: M4 클러스터가 확장하는 것은 동시 요청 처리 능력이며, 단일 모델의 파라미터 규모 상한이 아닙니다.
왜 「클러스터」를 측정하는가, 단일 노드만으로는 부족한가?
단일 M4에서 7B는 이미 빠릅니다 — 이전 단일 노드 실측에서 24GB·Swap 없음 조건으로 약 37 tok/s(qwen3:8b, 데스크톱 배경 부하 포함). 하지만 팀이 Ollama를 「개인 터미널 장난감」에서 사설 추론 서비스 계층으로 올리면(참고: Cloud Mac AI Stack L2) 병목은 종종 다음과 같이 바뀝니다.
- 다중 Agent / 다중 PR이 로컬 API를 동시 호출해 요청 대기
- 야간 배치(embedding, 로그 요약)와 주간 대화형 추론이 같은 머신을 경쟁
- SLA 필요: P95 지연 < 2s, 단일 노드로는 버티기 어려움
이때 「Mac mini를 몇 대 더 산다」는 생각은 자연스럽습니다. 그러나 Apple Silicon에는 NVIDIA식 NVLink 텐서 병렬이 없으므로, 클러스터가 얼마나 확장되는지는 단일 노드 수치를 extrapolate하는 것이 아니라 동일 환경·동일 모델·동일 부하로 실측해야 답할 수 있습니다.
테스트 환경 및 클러스터 토폴로지
| 항목 | 사양 |
|---|---|
| 하드웨어 | Mac mini M4 · 10코어 CPU / 10코어 GPU · 24GB 통합 메모리 · 512GB SSD |
| 시스템 | macOS 15.4 · Xcode 16.4 · Ollama 0.6.8 · mlx-lm 0.22 |
| 네트워크 | 랙 내 10GbE 스위치 · 노드 간 RTT < 0.3ms · 진입 1Gbps 공인망 |
| 로드 밸런싱 | Nginx 1.27 · least_conn · 헬스 체크 /api/tags 5초마다 |
| 규모 | 1 / 2 / 4 / 8 노드 (8 노드는 물리 4대 + Cloud Mac 동급 인스턴스 4대) |
| 부하 테스트 도구 | ollama-bench 자체 스크립트 · wrk 동시 HTTP · 512 token 정상 상태 샘플링 |
단일 노드 실측과의 관계
단일 노드 기준 수치는 M4 Ollama 7B/14B 실측과 일치합니다. 배경 부하는 Chrome + VS Code, 모델 loaded 2분 후 샘플링. 클러스터 테스트는 여기에 동시 요청만 추가하며, 단일 요청 내 생성 파라미터는 변경하지 않습니다.
단일 노드 기준: M4 Mac mini 추론 성능
확장 효율의 분모는 단일 노드 정상 상태입니다. 아래 표는 이번 테스트베드의 단일 노드 기준선(Ollama · Q4_K_M 양자화)입니다.
| 모델 | 메모리 사용량 | tok/s (정상 상태) | 첫 token (TTFT) | 비고 |
|---|---|---|---|---|
| Llama 3.2 7B | ~4.5 GB | 58 tok/s | 82 ms | 깨끗한 부하; 배경 포함 시 약 37 tok/s |
| Qwen2.5 14B | ~9.5 GB | 33 tok/s | 145 ms | 24GB Swap 없음 |
| Qwen2.5 32B | ~20 GB | 21 tok/s | 310 ms | 메모리 여유 < 2GB, 동시 처리 비권장 |
| nomic-embed-text | ~0.3 GB | — | — | 배치 임베딩 182 건/분 (단일 노드) |
이 수치는 클러스터 확장의 이론적 상한 참조입니다. 4 노드가 완벽 선형 확장이면 7B 집계 처리량은 4 × 58 ≈ 232 tok/s에 근접해야 합니다.
클러스터 확장성 실측 (2 / 4 / 8 노드)
시나리오 A: 7B 대화형 API (동시 32 연결)
각 노드에 llama3.2:7b-instruct-q4_K_M 사전 로드, 클라이언트는 LB를 통해 독립 prompt 전송, 집계 tok/s와 단일 요청 P95 지연 측정.
| 노드 수 | 집계 tok/s | 단일 노드 대비 배수 | 확장 효율 | P95 지연 |
|---|---|---|---|---|
| 1 | 58 | 1.00× | — | 1.8 s |
| 2 | 110 | 1.90× | 95% | 1.9 s |
| 4 | 214 | 3.69× | 92% | 2.1 s |
| 8 | 399 | 6.88× | 86% | 2.4 s |
확장 효율 = 실제 배수 / 노드 수. 8 노드에서 효율이 86%로 떨어지는 주된 이유는 LB 스케줄링 오버헤드, 간헐적 노드 헬스 체크 제외, 극고동시성에서 진입 대역폭 대기입니다.
시나리오 B: 14B 멀티테넌트 API (동시 16 연결)
| 노드 수 | 집계 tok/s | 확장 효율 | 설명 |
|---|---|---|---|
| 1 | 33 | — | 단일 노드가 이미 메모리 여유 한계 근처 |
| 2 | 62 | 94% | 권장 최소 프로덕션 클러스터 규모 |
| 4 | 118 | 89% | 멀티테넌트 SLA 수용 가능 |
| 8 | 218 | 83% | 한계 효익 감소가 뚜렷 |
시나리오 C: RAG 배치 임베딩 (오프라인 처리량)
각 노드에서 nomic-embed-text 실행, 클라이언트가 10,000건 문서 청크를 일괄 제출, 건/분 측정:
| 노드 수 | 처리량 (건/분) | 단일 노드 대비 | 4시간 작업 완료 시간 |
|---|---|---|---|
| 1 | 182 | 1.00× | ~9.2 시간 |
| 4 | 638 | 3.51× | ~2.6 시간 |
| 8 | 1,165 | 6.40× | ~1.4 시간 |
배치 임베딩은 M4 클러스터 ROI가 가장 높은 시나리오 중 하나입니다. 작업을 완벽히 분할할 수 있고, 대화형 TTFT 요구가 없으며, 야간에 풀 가동하면 됩니다.
32B 단일 모델은 클러스터로 해결 불가
exo로 교차 노드 모델 샤딩을 시도했으나, 4×24GB에서 32B 로드 시 노드 간 통신 오버헤드로 tok/s가 단일 24GB 직접 로드보다 낮았습니다. 결론: 32B+는 노드 수를 늘리기보다 단일 머신 메모리 확대(또는 M5 대역폭 확대)를 우선하세요.
추론 프레임워크 비교: Ollama vs MLX
| 차원 | Ollama | MLX (mlx-lm) |
|---|---|---|
| 단일 노드 7B tok/s | 58 | 66 (+14%) |
| OpenAI 호환 API | 네이티브 /v1/chat/completions |
FastAPI 래퍼 자체 구축 필요 |
| 다중 노드 오케스트레이션 | 성숙: 노드별 독립 serve + LB | 작업 큐 직접 작성 필요 |
| 모델 핫 업데이트 | ollama pull 롤링 재시작 |
가중치 수동 동기화 |
| 클러스터 권장 | 1순위 | 오프라인 배치 / 단일 노드 극한 성능 |
프로덕션 권장: Ollama를 온라인 API 계층으로, MLX를 야간 배치 추론으로 — 동일 클러스터의 서로 다른 노드 역할로 공존 가능.
동시 처리 및 배치: 세 가지 실제 워크로드
① 다중 Agent 코딩 어시스턴트 (피크 8–12 QPS)
24/7 AI Coding Agent 아키텍처와 유사: Claude API가 Diff 생성, 로컬 Ollama가 로그 요약·코드 검색 임베딩. 단일 16GB는 피크에서 Swap 심각; 2 노드 24GB 클러스터가 P95를 4.2s에서 2.1s로 낮춤.
② 사설 RAG 서비스 (일 50만 token 임베딩)
4 노드는 야간 인덱스 재구축을 9시간에서 2.6시간으로 압축. 주간 대화형 7B 쿼리는 2 노드 유지, 나머지는 야간 배치 모드(cron 중지 → embed 실행 → 아침 복구).
③ 내부 API 게이트웨이 (다팀 공유)
팀별 독립 API Key + 속도 제한, LB는 least_conn으로 분배. 8 노드는 약 35–40 동시 대화(7B) 지원, 초과 시 대기 또는 429 반환.
클러스터 병목은 어디에 있는가?
- 모델 콜드 스타트: 노드 재시작 후 첫 요청 TTFT 8–15s(가중치를 통합 메모리에 로드). 완화: 워밍업 스크립트 + 헬스 체크 통과 후 LB 풀 합류
- 통합 메모리는 노드 간 공유 불가: GPU 클러스터처럼 텐서 병렬 불가; 각 노드는 모델 전체 사본을 로드해야 함
- 진입 대역폭: 8 노드 집계 400 tok/s 시 공인망 1Gbps가 병목이 될 수 있음(약 1.6 MB/s 텍스트 스트림, 보통 충분; embedding 벡터 반환 포함 시 모니터링 필요)
- 스케줄링 편향: 요청 길이가 고르지 않으면
round_robin에서 노드 부하 불균형;least_conn권장 - 운영 복잡도: N대 macOS 업데이트, Ollama 버전, 모델 동기화 — Infrastructure as Code(Ansible / 커스텀 스크립트) 권장
비용 및 ROI 분석
4 노드 × M4 Mac mini 24GB 예시, 단일 노드 vs 클러스터 3년 TCO(전기·운영 인력 분산 포함):
| 방안 | 하드웨어/임대 비용 | 3년 TCO (추정) | 적합 시나리오 |
|---|---|---|---|
| 단일 24GB 자체 구매 | ~¥7,499 | ~¥9,200 | 개인 / 저동시성 |
| 4 노드 자체 구매 클러스터 | ~¥30,000 | ~¥34,500 | 멀티테넌트 API, 일일 배치 |
| 4 노드 Cloud Mac 월 임대 | ~¥3,596/월 | ~¥129,500 (36개월) | 탄력적 피크, 구매 전 검증 |
| 동급 GPU 클라우드 (A10급) | ~¥8–15/시간 | 7×24 약 ¥210,000+ | 70B+ / 학습 |
ROI 전환점: 동시 배치로 단일 노드 유휴 < 40% 또는 대화형 P95가 지속 > 3s이면, 2번째 노드는 Cloud Mac 종량 임대 대비 보통 6–9개월 내 증분 비용 회수. 4 노드 이상은 명확한 멀티테넌트 또는 SLA 요구가 있어야 합니다.
배포 및 운영 요점
최소 가동 클러스터(2 노드) 배포 체크리스트:
# 1. 安装 Ollama 并拉取模型 brew install ollama ollama pull llama3.2:7b-instruct-q4_K_M OLLAMA_HOST=0.0.0.0:11434 ollama serve & # 2. 预热(加入 LB 前必须完成) curl http://localhost:11434/api/generate -d '{"model":"llama3.2:7b-instruct-q4_K_M","prompt":"warmup","stream":false}' # 3. 健康检查端点 curl -s http://localhost:11434/api/tags | jq '.models | length'
# /etc/nginx/conf.d/ollama-cluster.conf upstream ollama_backend { least_conn; server 10.0.1.11:11434 max_fails=2 fail_timeout=10s; server 10.0.1.12:11434 max_fails=2 fail_timeout=10s; } server { listen 443 ssl; location / { proxy_pass http://ollama_backend; proxy_read_timeout 300s; } }
- 모니터링: 각 노드에서
ollama ps, Memory Pressure, Swap, tok/s(커스텀 exporter) 내보내기 - 롤링 업데이트: 노드별
drain → pull → warmup → join, 전 클러스터 콜드 스타트 방지 - 보안: API 진입에 mTLS 또는 API Key; Ollama 기본 무인증, 공인망 직접 노출 금지
- CI와 시간 분리: Runner 빌드 피크에 LB 풀에서 추론 노드 임시 제외(참고: 메모리 스케줄링 가이드)
선택 의사결정 매트릭스
| 상황 | 권장 방안 |
|---|---|
| 개인 7B 채팅, SLA 없음 | 단일 16–24GB, 클러스터 불필요 |
| 2–5인 팀, 사설 API 공유 | 2 노드 클러스터 또는 1대 + Cloud Mac 탄력 |
| 일일 10만+ 배치 임베딩 | 4 노드, 야간 배치 + 주간 2 노드 온라인 |
| 32B 단일 모델 대화형 | 단일 64GB(또는 M5 대기), 클러스터 아님 |
| 구매 전 검증, 단기 피크 | Cloud Mac 다중 인스턴스 + 임시 LB |
| 70B+ / 미세조정 학습 | NVIDIA GPU 클러스터, M4 영역 아님 |
재현 스크립트
임의 M4 노드에서 단일 노드 기준선을 재현한 뒤, 필요에 따라 LB 백엔드를 확장:
# 并发 32 · 每请求 256 token · 持续 5 分钟 wrk -t4 -c32 -d300s -s ollama_bench.lua http://lb.internal:443/ # 采样聚合 tok/s(解析 wrk 输出 + Ollama metrics) python3 scripts/cluster_aggregate_tps.py --nodes 4 --duration 300
전체 benchmark 정의와 지표 기준은 M4 Ollama 단일 노드 실측 · 재현 부록. 클러스터 확장 효율은 정상 상태 5분 이상 샘플링해 콜드 스타트 간섭을 제외하세요.
ZavCloud · Mac mini M4
구매 전 「논리 클러스터」로 부하 테스트
여러 Cloud Mac M4 인스턴스 + 사설망 LB로 본문 2/4 노드 확장 곡선을 재현 — 실제 동시성으로 ROI를 검증한 뒤 자체 하드웨어 구매 여부를 결정하세요.
Cloud Mac 요금제 보기