gpu-hot : un tableau de bord NVML en Python pour les serveurs GPU NVIDIA
🔥 Real-time NVIDIA GPU dashboard
En bref
- De quoi s’agit-il ?
- gpu-hot expose les métriques NVML d'une ou plusieurs machines NVIDIA dans une interface web auto-hébergée, avec un mode hub pour agréger plusieurs nœuds. Le projet est jeune, le mode hub est la partie la plus fragile, et la licence MIT laisse une grande liberté d'intégration.
- À qui s’adresse-t-il ?
- gpu-hot convient aux équipes qui exploitent un ou quelques serveurs NVIDIA et veulent une page web locale sans agent propriétaire : une commande docker run --gpus all -p 1312:1312 suffit, et le mode hub peut agréger plusieurs nœuds. Il ne convient pas si vous avez besoin de rétention longue, d'alerting ou de traçabilité par utilisateur, car rien de tout cela n'apparaît dans le matériel fourni.
- Puis-je l’utiliser commercialement ?
- Oui. MIT est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 22 jours.
- En quel langage est-il écrit ?
- Principalement JavaScript, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème concret : rendre NVML lisible sans agent lourd
Sur une machine équipée de GPU NVIDIA, nvidia-smi affiche un instantané puis rend la main. Pour suivre une charge d'entraînement ou d'inférence, il faut relancer la commande, ou surveiller un terminal avec watch. gpu-hot prend le problème par l'autre bout : un processus Python interroge NVML en continu et pousse le résultat vers une page web servie par le même conteneur. La cible est l'ingénieur qui administre un serveur GPU, pas l'équipe qui exploite un parc de plusieurs milliers de cartes. Le README annonce une échelle de 1 à 100+ GPU, mais cette phrase est une intention, pas une mesure : aucun chiffre de charge, de latence ou de consommation mémoire n'accompagne cette affirmation dans le matériel disponible.
Le positionnement est celui d'un outil d'observation locale. Pas d'agent à installer sur chaque machine, pas de base de données, pas de compte à créer. Le conteneur expose un port, le navigateur affiche les courbes. Cette simplicité a un prix : ce que vous voyez à l'écran n'est pas conservé une fois l'onglet fermé, du moins d'après la description des composants côté client.
De NVML au navigateur : le trajet d'une mesure
L'arborescence du dépôt décrit la chaîne. core/monitor.py interroge NVML, core/metrics/collector.py assemble les relevés et core/metrics/utils.py normalise les valeurs. Les relevés partent ensuite par WebSocket, via core/handlers.py côté serveur et static/js/socket-handlers.js côté client, avec un rendu par lots. Le serveur lui-même est une application FastAPI déclarée dans app.py, qui sert aussi les routes HTTP et le dossier static.
Deux mécanismes méritent l'attention. Le premier est le repli : si les métriques n'apparaissent pas, le README indique d'ajouter -e NVIDIA_SMI=true, ce qui bascule la collecte sur core/nvidia_smi_fallback.py, c'est-à-dire sur l'analyse de la sortie de nvidia-smi plutôt que sur les appels NVML. Le second est la mise en pause de l'interrogation quand aucun client n'est connecté, ce qui maintient la consommation CPU au repos proche de zéro selon le README. Ce comportement est cohérent avec un outil pensé pour un poste de travail ou un serveur d'équipe, pas pour une collecte permanente.
La fréquence est réglable par deux variables distinctes : UPDATE_INTERVAL, à 0.5 seconde par défaut, pour NVML, et NVIDIA_SMI_INTERVAL, à 2.0 secondes, pour le repli. Le README parle de métriques « sub-second », ce qui correspond à la valeur par défaut de UPDATE_INTERVAL mais pas au mode nvidia-smi, dont la cadence est quatre fois plus lente. Cette distinction est facile à manquer et change l'allure des courbes.
Le mode hub et son coût de configuration
Le même conteneur sert pour une machine seule et pour une agrégation. En mode hub, chaque serveur GPU lance l'image avec -e NODE_NAME=$(hostname), et une machine sans GPU lance la même image avec -e GPU_HOT_MODE=hub et -e NODE_URLS=http://server1:1312,http://server2:1312. Le hub interroge ces URL et fusionne les résultats. Le code correspondant se trouve dans core/hub.py et core/hub_handlers.py.
C'est la partie la plus contrainte du projet. NODE_URLS est une liste d'URL séparées par des virgules, ce qui suppose que le hub peut joindre chaque nœud directement sur le port 1312. Le README consacre d'ailleurs une section de dépannage à ce point précis : tester avec curl http://node-ip:1312/api/gpu-data, puis vérifier le pare-feu avec sudo ufw allow 1312/tcp. Autrement dit, le modèle de déploiement suppose un réseau plat ou des règles ouvertes, et il n'existe aucune mention d'authentification, de TLS ou de jeton partagé entre le hub et ses nœuds. Exposer ce port sur un réseau non maîtrisé revient à publier l'inventaire matériel de vos machines et la liste de vos processus GPU.
Autre limite du mode hub : la configuration est statique. Ajouter un nœud signifie relancer le conteneur hub avec une nouvelle valeur de NODE_URLS. Il n'y a pas de découverte automatique mentionnée dans le matériel fourni.
Installation : trois commandes et un prérequis non négociable
Le prérequis est le NVIDIA Container Toolkit, cité explicitement dans le README. Sans lui, l'option --gpus all ne transmet aucun périphérique au conteneur et le tableau de bord démarre sans GPU. Pour une machine unique, la commande est :
docker run -d --gpus all -p 1312:1312 ghcr.io/psalias2006/gpu-hot:latest
Pour voir les noms de processus plutôt que de simples PID, il faut ajouter --init --pid=host. Le README précise que cette option donne au conteneur accès aux informations de processus de l'hôte : c'est un élargissement du périmètre de sécurité, à réserver aux machines dont vous contrôlez déjà l'accès. Le port 1312 est défini dans core/config.py, où le README montre une constante PORT = 1312. Le modifier implique de reconstruire l'image, pas simplement de changer une variable d'environnement, puisque cette valeur est du code.
Depuis les sources, la séquence est git clone, cd gpu-hot, puis docker-compose up --build. Les variables utiles en production sont NVIDIA_VISIBLE_DEVICES pour restreindre la collecte à certaines cartes, et UPDATE_INTERVAL pour alléger la charge si le serveur est déjà saturé. Le README recommande d'ailleurs d'augmenter UPDATE_INTERVAL en cas de problème de performance, ce qui est la seule réponse documentée à ce cas.
Ce que l'outil ne fera pas
Il n'y a pas de stockage des métriques. Les graphiques décrits dans static/js/chart-manager.js vivent dans la page ; fermer l'onglet efface l'historique affiché. Aucune base de données, aucun export, aucune rétention ne figurent dans l'arborescence. Si votre besoin est de comparer la consommation d'un job d'entraînement d'hier avec celle d'aujourd'hui, gpu-hot n'est pas l'outil : il faudra un collecteur qui écrit dans Prometheus ou un équivalent, et gpu-hot ne fournit pas d'endpoint au format Prometheus. Les routes HTTP listées sont GET /, GET /api/gpu-data et GET /api/version, rien de plus.
Il n'y a pas non plus d'alerting ni de gestion multi-utilisateurs. Pas de seuil de température, pas de notification, pas de rôle. Le tableau de bord est en lecture seule et anonyme pour quiconque atteint le port. Enfin, la compatibilité se limite au matériel NVIDIA : les topics du dépôt mentionnent cuda et nvidia, l'implémentation repose sur NVML et nvidia-smi, et rien n'indique une prise en charge d'AMD ou d'Intel. Sur un parc mixte, l'outil ne couvrira qu'une partie des machines.
Face à un stack Prometheus et DCGM Exporter
L'alternative la plus directe est la combinaison de NVIDIA DCGM Exporter et Prometheus avec Grafana. La différence n'est pas cosmétique, elle porte sur le modèle de données. DCGM Exporter expose des métriques au format Prometheus, ce qui suppose un serveur Prometheus qui scrape et conserve les séries dans le temps, puis Grafana pour la restitution. gpu-hot fait l'inverse : il pousse les valeurs vers le navigateur en WebSocket et ne conserve rien. Vous obtenez un résultat immédiat sans infrastructure, au prix de la rétention et de l'alerting.
Cette différence a une conséquence pratique sur le coût d'exploitation. Un stack Prometheus ajoute au moins deux services à maintenir, mais il sait répondre à la question « quelle était la température moyenne de cette carte la semaine dernière ». gpu-hot répond à « que se passe-t-il maintenant », et le README le formule ainsi : « Real-time NVIDIA GPU monitoring dashboard. Lightweight, web-based, and self-hosted. » Le mot lightweight résume le compromis. Si vous avez déjà Prometheus en place, ajouter DCGM Exporter est probablement plus cohérent que de déployer un second système d'observation à côté ; si vous n'avez rien, gpu-hot démarre en une commande.
Maintenance, licence et coût de suivi
Le projet est sous licence MIT, ce qui autorise la modification, la redistribution et l'usage commercial, à condition de conserver l'avis de copyright et le texte de la licence. Aucune clause de type copyleft ne contraint votre code : vous pouvez embarquer gpu-hot dans une image interne sans publier vos modifications. Ce paragraphe décrit la licence telle qu'elle est identifiée dans le dépôt, il ne constitue pas un avis juridique.
Le dépôt n'est pas archivé et les versions récentes s'enchaînent : v1.9.0 en mai 2026, puis v1.9.1 et v1.9.2 le même jour en juillet 2026. Deux publications à quelques minutes d'intervalle suggèrent des correctifs rapides après une mise en production, ce qui est un signe de réactivité mais aussi d'un rythme de publication irrégulier. Les journaux de version ne sont pas fournis dans le matériel, donc l'ampleur réelle de ces correctifs ne peut pas être évaluée ici.
Le coût de mise à jour est faible : l'image est publiée sur ghcr.io, et un redémarrage du conteneur suffit pour changer de version. En mode hub, la mise à jour doit être coordonnée entre le hub et les nœuds si le format des messages WebSocket évolue, car rien n'indique une négociation de version entre les deux. Le endpoint GET /api/version existe et le README mentionne une vérification de version au démarrage dans static/js/app.js, mais le comportement en cas d'écart entre hub et nœuds n'est pas documenté. C'est le point à tester en premier si vous exploitez plusieurs machines.
Conclusion éditoriale
gpu-hot convient aux équipes qui exploitent un ou quelques serveurs NVIDIA et veulent une page web locale sans agent propriétaire : une commande docker run --gpus all -p 1312:1312 suffit, et le mode hub peut agréger plusieurs nœuds. Il ne convient pas si vous avez besoin de rétention longue, d'alerting ou de traçabilité par utilisateur, car rien de tout cela n'apparaît dans le matériel fourni. Avant d'adopter, vérifiez deux choses concrètement : que nvidia-smi répond dans un conteneur CUDA de test, puis que curl http://node-ip:1312/api/gpu-data renvoie bien le JSON attendu depuis la machine hub.
Notes de la communauté