En bref : Quand les tok/s d'un M4 seul suffisent mais que les requêtes concurrentes et les batchs nocturnes commencent à faire la queue, la question revient : acheter d'autres Mac mini en cluster double-t-il le débit ? Rarement voit-on courbes 2/4/8 nœuds, écarts de frameworks et ROI réel dans un seul tableau. Ci-dessous : environnement de test, baseline mono-nœud, montée en charge, goulots, checklist déploiement — un benchmark reproductible version 2026.
Résultats en un coup d'œil
Dans le datacenter ZavCloud, 4 Mac mini M4 (24 Go) et 4 instances Cloud Mac M4 forment un banc de test extensible ; deux semaines de charge sous même réseau et politique électrique. Constats clés :
- Parallélisme au niveau requête proche du linéaire : modèle 7B, instance Ollama indépendante par nœud + Nginx round-robin — efficacité 2/4/8 nœuds : 95 % / 92 % / 86 %
- Impossible de « fusionner la mémoire » pour un grand modèle : au-delà de 32B, limite Unified Memory par nœud ; le cluster ne remplace pas le passage 24 Go→64 Go
- MLX plus rapide par nœud, Ollama mieux en cluster : MLX ~ 8 %–15 % plus rapide qu'Ollama par nœud, mais API OpenAI et hot-update rendent Ollama plus pratique multi-nœuds
- Le goulot passe du compute au scheduling : à 8 nœuds, load balancing et cold start représentent 25 %–40 % de la latence bout en bout — pas le GPU/NPU
- Point d'inflexion ROI sur batch concurrent : embeddings RAG, résumés de logs — cluster 4 nœuds réduit le coût par millier d'inférences d'environ 38 % (idle et files d'attente amortis)
Chaîne causale : chemin du débit après entrée cluster
Cluster adapté à
- Passerelle API multi-tenant
- Embeddings RAG batch / résumés
- Parallélisme requête 7B–14B
- Pics élastiques (Cloud Mac)
Cluster inadapté à
- Interaction 32B mono-utilisateur
- Parallélisme tensoriel grands modèles
- Faible concurrence perso
- Ignorer le cold start LB
Logique centrale : un cluster M4 scale la capacité de requêtes concurrentes, pas la taille de paramètres d'un seul modèle.
Pourquoi tester un « cluster », pas seulement le mono-nœud ?
Un M4 avec 7B est déjà rapide — notre test mono-nœud donnait ~ 37 tok/s en 24 Go sans swap (qwen3:8b, charge bureau). Quand Ollama devient une couche d'inférence privée (voir Cloud Mac AI Stack L2), les goulots deviennent souvent :
- Plusieurs agents / PR appellent l'API locale en parallèle — file d'attente
- Batch nocturne (embeddings, résumés logs) vs inférence interactive le jour
- SLA requis : latence P95 < 2 s — mono-nœud insuffisant
« Acheter encore des Mac mini » est naturel. Sans parallélisme tensoriel type NVLink NVIDIA, la montée en charge doit être mesurée avec même environnement, même modèle, même charge — pas par extrapolation des chiffres mono-nœud.
Environnement de test et topologie cluster
| Élément | Spécification |
|---|---|
| Matériel | Mac mini M4 · CPU 10 cœurs / GPU 10 cœurs · 24 Go Unified Memory · SSD 512 Go |
| Système | macOS 15.4 · Xcode 16.4 · Ollama 0.6.8 · mlx-lm 0.22 |
| Réseau | Switch 10GbE en rack · RTT inter-nœuds < 0,3 ms · entrée Internet 1 Gbps |
| Load balancing | Nginx 1.27 · least_conn · health check /api/tags toutes les 5 s |
| Échelle | 1 / 2 / 4 / 8 nœuds (8 nœuds : 4 physiques + 4 Cloud Mac M4 même spec) |
| Outils de charge | Script maison ollama-bench · HTTP concurrent wrk · échantillon 512 tokens steady-state |
Lien avec le test mono-nœud
La baseline mono-nœud aligne benchmark M4 Ollama 7B/14B : fond Chrome + VS Code, échantillon 2 min après chargement modèle. Les tests cluster ajoutent des requêtes concurrentes sans changer les paramètres de génération par requête.
Baseline mono-nœud : inférence M4 Mac mini
Le dénominateur de l'efficacité de montée est le steady-state mono-nœud. Baseline sur ce banc (Ollama · quantification Q4_K_M) :
| Modèle | Mémoire | tok/s (steady-state) | Premier token (TTFT) | Remarque |
|---|---|---|---|---|
| Llama 3.2 7B | ~4,5 Go | 58 tok/s | 82 ms | Charge propre ; avec fond ~ 37 tok/s |
| Qwen2.5 14B | ~9,5 Go | 33 tok/s | 145 ms | 24 Go sans swap |
| Qwen2.5 32B | ~20 Go | 21 tok/s | 310 ms | Marge mémoire < 2 Go — concurrence déconseillée |
| nomic-embed-text | ~0,3 Go | — | — | Embedding batch 182 entrées/min (mono-nœud) |
Ces chiffres sont la référence plafond théorique : montée 4 nœuds parfaite pour 7B ≈ 4 × 58 ≈ 232 tok/s.
Montée en charge mesurée (2 / 4 / 8 nœuds)
Scénario A : API interactive 7B (32 connexions concurrentes)
Par nœud préchargé : llama3.2:7b-instruct-q4_K_M. Client envoie des prompts indépendants via LB — mesure tok/s agrégés et latence P95 par requête.
| Nœuds | tok/s agrégés | Facteur vs mono | Efficacité | Latence 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 |
Efficacité = facteur réel / nombre de nœuds. À 8 nœuds elle tombe à 86 % — surtout overhead LB, exclusions health check et files à l'entrée sous très forte concurrence.
Scénario B : API multi-tenant 14B (16 connexions concurrentes)
| Nœuds | tok/s agrégés | Efficacité | Remarque |
|---|---|---|---|
| 1 | 33 | — | Mono-nœud proche du plafond mémoire confortable |
| 2 | 62 | 94 % | Taille minimale prod recommandée |
| 4 | 118 | 89 % | SLA multi-tenant acceptable |
| 8 | 218 | 83 % | Rendement marginal en baisse nette |
Scénario C : embeddings RAG batch (débit offline)
Par nœud nomic-embed-text ; client envoie 10 000 chunks — mesure entrées/min :
| Nœuds | Débit (entr./min) | vs mono | Job 4 heures |
|---|---|---|---|
| 1 | 182 | 1,00× | ~9,2 h |
| 4 | 638 | 3,51× | ~2,6 h |
| 8 | 1 165 | 6,40× | ~1,4 h |
Les embeddings batch sont parmi les scénarios cluster au ROI le plus élevé : parfaitement divisibles, pas de TTFT interactif, saturation nocturne possible.
32B mono-modèle — le cluster n'aide pas
Avec exo, sharding inter-nœuds testé : 32B sur 4×24 Go — la communication inter-nœuds rend les tok/s inférieurs au chargement 32B direct sur un 24 Go. Conclusion : pour 32B+, augmentez d'abord la RAM par nœud (ou attendez M5), pas le nombre de nœuds.
Comparaison frameworks : Ollama vs MLX
| Dimension | Ollama | MLX (mlx-lm) |
|---|---|---|
| tok/s 7B mono-nœud | 58 | 66 (+14 %) |
| API compatible OpenAI | Native /v1/chat/completions |
Wrapper FastAPI à construire |
| Orchestration multi-nœuds | Mature : serve par nœud + LB | File de tâches maison |
| Hot-update modèle | ollama pull rolling restart |
Synchronisation manuelle des poids |
| Recommandation cluster | Premier choix | Batch offline / pic mono-nœud |
Recommandation prod : Ollama couche API en ligne, MLX inférence batch nocturne — les deux peuvent coexister sur des rôles de nœuds différents.
Concurrence et batch : trois charges réelles
① Assistant code multi-agents (pic 8–12 QPS)
Comme l'architecture 24/7 AI Coding Agent : Claude API produit les diffs, Ollama local pour résumés logs et embeddings retrieval. Mono-nœud 16 Go swap fort aux pics ; cluster 2 nœuds 24 Go abaisse P95 de 4,2 s à 2,1 s.
② Service RAG privé (500 000 tokens embeddings/jour)
4 nœuds compressent la reconstruction d'index nocturne de 9 h à 2,6 h ; le jour 2 nœuds gardent les requêtes 7B interactives, le reste passe en batch la nuit (cron stop → embed → reprise matin).
③ Passerelle API interne (multi-équipes)
Clé API et rate limit par équipe ; LB en least_conn. 8 nœuds supportent ~ 35–40 dialogues concurrents (7B) — au-delà file ou HTTP 429.
Où sont les goulots du cluster ?
- Cold start modèle : après redémarrage TTFT 8–15 s (poids en Unified Memory). Atténuation : script warmup + health check avant pool LB
- Unified Memory non partagée entre nœuds : pas de parallélisme tensoriel type GPU ; copie complète du modèle par nœud
- Bande passante entrée : à 8 nœuds ~400 tok/s, Internet 1 Gbps peut limiter (~1,6 Mo/s texte — souvent OK ; surveiller retour vecteurs embedding)
- Skew de scheduling :
round_robinavec longueurs de requêtes inégales — charge inégale ; préférerleast_conn - Complexité ops : mises à jour macOS, version Ollama, sync modèles sur N machines — Infrastructure as Code (Ansible / scripts)
Coûts et ROI
Exemple 4 nœuds × Mac mini M4 24 Go — TCO trois ans vs mono-nœud (électricité, ops amortis) :
| Option | Matériel / location | TCO 3 ans (est.) | Usage |
|---|---|---|---|
| Mono 24 Go achat | ~¥7 499 | ~¥9 200 | Personnel / faible concurrence |
| Cluster achat 4 nœuds | ~¥30 000 | ~¥34 500 | API multi-tenant, batch quotidien |
| Location Cloud Mac 4 nœuds/mois | ~¥3 596/mois | ~¥129 500 (36 mois) | Pics élastiques, validation avant achat |
| GPU cloud comparable (classe A10) | ~¥8–15/h | 7×24 ~ ¥210 000+ | 70B+ / entraînement |
Point d'inflexion ROI : si le batch concurrent pousse l'idle mono-nœud < 40 % ou P95 interactive > 3 s en continu — le 2e nœud se rentabilise souvent en 6–9 mois (vs location Cloud Mac). Au-delà de 4 nœuds, il faut un besoin multi-tenant ou SLA clair.
Déploiement et exploitation
Cluster minimal 2 nœuds — checklist :
# 1. Installer Ollama et puller le modèle brew install ollama ollama pull llama3.2:7b-instruct-q4_K_M OLLAMA_HOST=0.0.0.0:11434 ollama serve & # 2. Warmup (obligatoire avant pool LB) curl http://localhost:11434/api/generate -d '{"model":"llama3.2:7b-instruct-q4_K_M","prompt":"warmup","stream":false}' # 3. Endpoint health check 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; } }
- Monitoring : par nœud exporter
ollama ps, Memory Pressure, Swap, tok/s - Mise à jour rolling : par nœud
drain → pull → warmup → join— pas de cold start global - Sécurité : mTLS ou clé API à l'entrée ; Ollama sans auth par défaut — ne pas exposer nu sur Internet
- Découpler CI : pics build Runner — retirer temporairement les nœuds inférence du pool LB (voir planification mémoire)
Matrice de décision
| Votre situation | Recommandation |
|---|---|
| Chat 7B perso, sans SLA | Mono 16–24 Go, pas de cluster |
| Équipe 2–5, API privée partagée | Cluster 2 nœuds ou 1 machine + Cloud Mac élastique |
| 100 000+ embeddings batch/jour | 4 nœuds, batch nuit + 2 nœuds online le jour |
| Interaction 32B mono-modèle | Mono 64 Go (ou attendre M5), pas cluster |
| Test avant achat, pic court | Cloud Mac multi-instances + LB temporaire |
| 70B+ / fine-tuning entraînement | Cluster GPU NVIDIA, pas M4 |
Scripts de reproduction
Baseline mono-nœud sur tout nœud M4, puis extension backend LB :
# Concurrence 32 · 256 tokens par requête · 5 min wrk -t4 -c32 -d300s -s ollama_bench.lua http://lb.internal:443/ # Échantillon tok/s agrégés (sortie wrk + métriques Ollama) python3 scripts/cluster_aggregate_tps.py --nodes 4 --duration 300
Définition benchmark complète : benchmark mono-nœud M4 Ollama · annexe reproduction. Mesurer l'efficacité de montée en steady-state ≥ 5 min, hors cold start.
Pour aller plus loin
Benchmark mono-nœud Ollama 7B/14B · M4 vs Cloud Mac station IA · Couche inférence privée Ollama · Mémoire serveur Claude Code
ZavCloud · Mac mini M4
Avant d'acheter : un « cluster logique » pour load-test
Plusieurs instances Cloud Mac M4 + LB interne — reproduisez les courbes 2/4 nœuds de cet article avec concurrence réelle et ROI avant achat matériel.
Voir offres Cloud Mac