Ingénierie Thermique : Optimisation Mac mini M4 (Serveur 24/7 & LLM)

Ce document présente l’étude technique, les benchmarks comparatifs et les solutions d’automatisation mises en œuvre pour la gestion thermique et acoustique du Mac mini M4 hébergeant Mirza en continu (24h/24, 7j/7).

Contexte & Problématique Initiale

  • Machine hôte : Apple Mac mini M4 (Identifiant matériel Mac16,10), 24 Go de mémoire unifiée UMA, macOS Sequoia (Darwin arm64e).

  • Charge de travail : Serveur domestique autonome 24h/24, 7j/7 avec inférence LLM continue (MTPLX local 9B Q6G64 avec décodage spéculatif MTP, context window 16k, endpoint OpenAI-compatible sur port 8766).

  • Problématique identifiée : Lors des phases d’inférence continue, le système montait à des températures élevées (70°C à plus de 90°C), sans que le ventilateur d’origine ne module sa vitesse. Le besoin était d’abaisser le seuil thermique de déclenchement de la ventilation pour pérenniser le silicium et les soudures sans générer d’usure mécanique prématurée sur le roulement du ventilateur.

Comportement Thermique d’Origine (Apple SMC)

Sur les puces Apple Silicon (M1 à M4), la dissipation thermique est régie par le micro-logiciel du SMC (System Management Controller) :

  1. Biais acoustique prioritaire : La courbe constructeur d’Apple privilégie systématiquement le silence absolu au détriment des températures puces.

  2. Plage de fonctionnement standard : Le ventilateur unique (plage constructeur : 1 000 RPM à 4 900 RPM) reste bloqué à son plancher minimal de 1 000 RPM tant que les puces ne franchissent pas des seuils critiques (> 85–90°C) de façon prolongée.

  3. Comportement sous charge LLM : Le GPU (principale unité de calcul pour l’inférence locale) montait à 95.0°C, provoquant un phénomène de thermal cycling (fortes amplitudes thermiques répétées) néfaste pour la fatigue des soudures BGA de la puce unifiée (Coffin-Manson model).

Étude Comparative & Choix des Outils

Analyse comparative des solutions de contrôle thermique

Outil analysé

Licence & Type

Comportement sous Apple Silicon M4

Décision / Statut

macmon / osx-cpu-temp

Open Source (CLI)

Télémétrie en lecture seule (CPU/GPU temp, Watts, RAM). Ne pilote pas le ventilateur.

Conservé pour monitoring passif.

Macs Fan Control

Gratuit / Propriétaire

Perte fréquente de contrôle : le démon système de macOS écrase les cibles manuelles sur M3/M4.

Écarté et désinstallé.

TG Pro

Payant (~10–15 €)

Supporte le M4 mais payant, en contradiction avec la contrainte 100 % open source et gratuite.

Écarté (critère coût).

ThermalForge

Open Source (Swift)

Démon root privilégié (com.thermalforge.daemon) avec socket local sécurisé (/var/run/thermalforge.sock), sécurité matérielle (force 100% à 95°C) et hystérésis fluide.

Retenu et déployé.

Benchmarks & Données Comparatives

Les mesures ont été relevées sous charge réelle d’inférence LLM continue (requêtes concurrentes saturant le GPU Metal à 95–100 %) :

Comparatif des profils thermiques sous charge LLM

Profil

Vitesse Ventilateur

Température GPU Max

Acoustique

Verdict

Stock Apple (Origine)

1 000 RPM (bloqué)

95.0°C

Inaudible (0 dB)

Surchauffe inutile du silicium

Performance

4 169 RPM (85 % max)

66.5°C

Très bruyant

Efficace mais agressif pour du 24/7

Balanced (Retenu)

2 939 RPM (60 % max)

70.0°C

Souffle discret

Compromis idéal (température sûre & usure minimale)

Évolution Temporelle sous Profil Balanced

Relevé détaillé sur une charge d’inférence de 45 secondes sous profil Balanced :

Chronologie de montée en charge (Profil Balanced)

Temps

Vitesse Ventilateur

Mode

Température GPU

Température Max

00s

1 000 RPM

auto

39.2°C

51.5°C

05s

1 000 RPM

manual

57.9°C

63.2°C

15s

1 641 RPM

manual

64.4°C

70.4°C

25s

2 765 RPM

manual

67.8°C

71.3°C

35s

2 939 RPM

manual

69.4°C

71.3°C

40s

2 939 RPM

manual

70.0°C

72.5°C

Analyse Mécanique & Usure du Ventilateur

Le ventilateur du Mac mini M4 est équipé d’un moteur sans balai (brushless DC) doté d’un roulement hydrodynamique (FDB - Fluid Dynamic Bearing).

Facteurs d’usure mécanique

  • Ce qui n’use PAS le ventilateur : Tourner en continu à vitesse modérée (1 500 à 3 000 RPM). Dans cette plage, le film lubrifiant fluide est hydrodynamiquement stable et le moteur brushless est conçu pour opérer sans contact solide pendant 50 000 à 70 000 heures (soit 6 à 8 ans non-stop).

  • Ce qui use le ventilateur : 1. Tourner à plein régime continu (> 4 200 – 4 900 RPM), ce qui surchauffe les roulements et fragilise le lubrifiant. 2. Les variations d’accélération brutales et les cycles d’arrêt/démarrage répétés (start-stop cycles), qui créent des micro-contacts avant que le film hydrodynamique ne se forme.

Pourquoi le profil Balanced préserve la mécanique

  1. Vitesse plafonnée : Plafonnement automatique à ~2 900 RPM (environ 60 % de la vitesse maximale de 4 900 RPM), garantissant un régime stable à faible frottement.

  2. Transition progressive : Utilisation d’une courbe en ease-in (\(pos^2\)) et d’une hystérésis (coupure sous 50°C), évitant tout choc mécanique ou à-coup brutal sur les roulements.

  3. Température stabilisée : Le GPU reste ancré à 70°C, soit 30°C en dessous du seuil de bridage thermique d’Apple (100°C).

Pérennisation 24/7 & Service LaunchDaemon

Pour garantir que le profil Balanced reste actif en permanence sans intervention manuelle et survive aux redémarrages de macOS, un service LaunchDaemon a été configuré :

Création du service système

sudo bash -c 'cat << "EOF" > /Library/LaunchDaemons/com.thermalforge.watch.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.thermalforge.watch</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/thermalforge</string>
        <string>watch</string>
        <string>--profile</string>
        <string>balanced</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
</dict>
</plist>
EOF
chmod 644 /Library/LaunchDaemons/com.thermalforge.watch.plist
launchctl load -w /Library/LaunchDaemons/com.thermalforge.watch.plist'

Propriétés clés du démon

  • RunAtLoad = true : Démarre automatiquement dès l’initialisation du système sans session graphique utilisateur.

  • KeepAlive = true : En cas d’anomalie ou de terminaison inattendue, le gestionnaire launchd de macOS relance immédiatement le processus.

  • Exécution en arrière-plan avec privilèges système appropriés.

Commandes Utiles d’Administration

Vérifier l’état en temps réel (RPM et températures des sondes SMC) :

thermalforge status

Vérifier que les services d’arrière-plan tournent :

sudo launchctl list | grep thermalforge
# com.thermalforge.daemon et com.thermalforge.watch doivent apparaître avec le code retour 0

Désactiver le service en cas de besoin :

sudo launchctl unload -w /Library/LaunchDaemons/com.thermalforge.watch.plist
sudo rm /Library/LaunchDaemons/com.thermalforge.watch.plist