
nvidia-smi : le réflexe simple pour surveiller ses GPU pendant l’entraînement distribué d’un LLM
Quand on entraîne un modèle LLM, les GPU deviennent rapidement le cœur du système. Ce sont eux qui portent la majorité des calculs, la mémoire du modèle, les gradients et une grande partie de la charge d’entraînement.
Sur un petit modèle, on peut parfois se contenter de lancer son script et attendre. Mais avec un LLM, surtout en entraînement distribué sur plusieurs GPU, cette approche devient risquée. Il faut savoir ce qui se passe réellement sur la machine.
Est-ce que tous les GPU travaillent ?
Est-ce que la mémoire est bien répartie ?
Est-ce qu’un GPU est saturé pendant que les autres dorment ?
Est-ce que le problème vient du code, du DataLoader, de Docker, de CUDA ou de la configuration distribuée ?
Pour répondre rapidement à ces questions, il existe un outil très simple mais extrêmement utile : nvidia-smi.
C’est quoi nvidia-smi ?
nvidia-smi signifie NVIDIA System Management Interface.
C’est une commande fournie avec les drivers NVIDIA. Elle permet de voir l’état des cartes graphiques installées sur une machine.
La commande de base est très simple :
nvidia-smiElle affiche plusieurs informations importantes :
GPU name
Driver version
CUDA version
Memory usage
GPU utilization
Temperature
Power usage
Running processesDans un projet d’entraînement LLM, ces informations sont précieuses. Elles permettent de savoir si les GPU sont bien reconnus, s’ils sont utilisés, et si l’entraînement se déroule normalement.
Pourquoi cet outil est important pour les LLM ?
Un LLM peut être trop lourd pour tenir sur un seul GPU. Pour cette raison, on utilise souvent plusieurs GPU avec des techniques comme :
Data Parallelism
Tensor Parallelism
Pipeline Parallelism
FSDP
DeepSpeed ZeROLe but est de répartir le travail entre plusieurs cartes.
Mais il y a un problème : le fait d’avoir plusieurs GPU ne veut pas forcément dire qu’ils sont tous utilisés.
On peut penser avoir lancé un entraînement sur 4 GPU, alors qu’en réalité seul le GPU 0 travaille. Les autres restent presque vides. C’est une erreur assez fréquente quand la configuration de torchrun, accelerate, DeepSpeed ou Docker n’est pas correcte.
Avec nvidia-smi, on peut voir ce problème immédiatement.
Le premier réflexe : vérifier si les GPU sont visibles
Avant même de lancer l’entraînement, il faut vérifier que la machine voit bien les GPU.
nvidia-smiSi tout est correct, on doit voir la liste des cartes NVIDIA disponibles.
Par exemple :
GPU 0 NVIDIA A100
GPU 1 NVIDIA A100
GPU 2 NVIDIA A100
GPU 3 NVIDIA A100Si aucune carte n’apparaît, il y a probablement un problème avec :
le driver NVIDIA
CUDA
Docker
NVIDIA Container Toolkit
la configuration de la machineDans ce cas, inutile de lancer l’entraînement. Le framework ne pourra pas utiliser les GPU correctement.
Surveiller la mémoire GPU
La mémoire GPU est souvent le premier mur qu’on rencontre avec les LLM.
Dans nvidia-smi, il faut regarder la colonne :
Memory-UsageExemple :
38500 MiB / 40960 MiBCela veut dire que le GPU utilise environ 38,5 Go sur 40 Go disponibles.
Pendant un entraînement distribué, on veut voir si la mémoire est utilisée de manière cohérente sur tous les GPU.
Un bon signe ressemble à ceci :
GPU 0 : 38900 MiB / 40960 MiB
GPU 1 : 38850 MiB / 40960 MiB
GPU 2 : 39010 MiB / 40960 MiB
GPU 3 : 38790 MiB / 40960 MiBIci, les quatre GPU travaillent. La mémoire est assez équilibrée.
Par contre, si on voit ceci :
GPU 0 : 39000 MiB / 40960 MiB
GPU 1 : 500 MiB / 40960 MiB
GPU 2 : 400 MiB / 40960 MiB
GPU 3 : 450 MiB / 40960 MiBcela veut souvent dire que seul le GPU 0 est réellement utilisé.
Dans ce cas, il faut vérifier la commande de lancement. Par exemple, si on utilise PyTorch, il ne suffit pas toujours de faire :
python train.pyPour utiliser plusieurs GPU, on lance souvent avec :
torchrun --nproc_per_node=4 train.pySurveiller l’utilisation réelle des GPU
La mémoire pleine ne veut pas toujours dire que le GPU travaille bien.
C’est pour cela qu’il faut aussi regarder :
GPU-UtilCette valeur montre le pourcentage d’utilisation du GPU.
Pendant un bon entraînement, on peut souvent voir :
80% à 100%C’est généralement bon signe.
Mais si la mémoire est pleine et que l’utilisation reste très basse, par exemple :
Memory-Usage : 39000 MiB / 40960 MiB
GPU-Util : 5%alors quelque chose bloque.
Les causes possibles sont nombreuses :
DataLoader trop lent
CPU saturé
données chargées depuis un disque lent
batch size trop petit
mauvaise synchronisation entre GPU
communication réseau lente entre serveurs
pipeline d’entraînement mal équilibréDans un entraînement distribué, ce genre de problème est très courant. Les GPU peuvent attendre les données, attendre les autres processus, ou rester bloqués à cause d’une mauvaise configuration.
Vérifier les processus actifs
En bas de la sortie nvidia-smi, on trouve une section très utile :
ProcessesElle montre quels programmes utilisent les GPU.
Exemple :
GPU PID Process name GPU Memory
0 12345 python 38500 MiB
1 12346 python 38600 MiB
2 12347 python 38400 MiB
3 12348 python 38700 MiBPour un entraînement distribué avec 4 GPU, il est normal de voir plusieurs processus Python, souvent un processus par GPU.
Si on ne voit qu’un seul processus, alors que l’on pensait utiliser 4 GPU, il y a probablement un problème dans le lancement.
Par exemple :
torchrun --standalone --nproc_per_node=4 train.pydevrait normalement lancer 4 processus.
La commande la plus pratique pendant l’entraînement
Pendant l’entraînement, on ne veut pas relancer manuellement nvidia-smi toutes les deux secondes.
La commande la plus pratique est :
watch -n 1 nvidia-smiElle met à jour l’affichage toutes les secondes.
C’est très utile au démarrage d’un entraînement. En quelques secondes, on voit si :
les GPU prennent de la mémoire
les processus Python apparaissent
l’utilisation GPU monte
la charge est répartie
un GPU reste videOn peut aussi utiliser :
nvidia-smi -l 1qui affiche les informations toutes les secondes.
Obtenir une sortie plus propre
La sortie par défaut de nvidia-smi est utile, mais parfois trop chargée.
Pour suivre seulement les métriques importantes, on peut utiliser :
nvidia-smi --query-gpu=index,name,memory.used,memory.total,utilization.gpu,temperature.gpu,power.draw --format=csvExemple :
index, name, memory.used, memory.total, utilization.gpu, temperature.gpu, power.draw
0, NVIDIA A100, 38900 MiB, 40960 MiB, 96 %, 68 C, 250 W
1, NVIDIA A100, 38850 MiB, 40960 MiB, 94 %, 67 C, 248 W
2, NVIDIA A100, 39010 MiB, 40960 MiB, 95 %, 69 C, 251 W
3, NVIDIA A100, 38790 MiB, 40960 MiB, 93 %, 66 C, 247 WCette commande est très utile pour logger l’état des GPU pendant un entraînement long.
On peut aussi suivre les métriques toutes les 5 secondes :
nvidia-smi --query-gpu=timestamp,index,memory.used,utilization.gpu,power.draw,temperature.gpu --format=csv -l 5Cas fréquent : Docker voit-il vraiment les GPU ?
Beaucoup d’entraînements LLM sont lancés dans Docker.
Dans ce cas, il ne suffit pas que la machine hôte voie les GPU. Il faut aussi que le container y ait accès.
On peut lancer un container avec :
docker run --gpus all -it mon-image-llm bashPuis, à l’intérieur du container :
nvidia-smiSi nvidia-smi fonctionne sur la machine hôte mais pas dans le container, le problème vient souvent de la configuration Docker ou de NVIDIA Container Toolkit.
C’est un point important. Si le container ne voit pas les GPU, PyTorch, TensorFlow, DeepSpeed ou Accelerate ne pourront pas les utiliser.
Exemple avec PyTorch Distributed
Avec PyTorch, un lancement distribué simple peut ressembler à ceci :
torchrun --standalone --nproc_per_node=4 train.pyIci, on demande à PyTorch de lancer 4 processus sur la machine.
Pendant l’exécution, nvidia-smi devrait afficher des processus sur plusieurs GPU :
GPU 0 : python 39000 MiB
GPU 1 : python 38900 MiB
GPU 2 : python 39100 MiB
GPU 3 : python 39050 MiBSi seul le GPU 0 travaille, il faut vérifier plusieurs choses :
CUDA_VISIBLE_DEVICESPar exemple :
CUDA_VISIBLE_DEVICES=0,1,2,3 torchrun --nproc_per_node=4 train.pyCette variable indique quels GPU sont visibles pour le programme.
Si elle est définie comme ceci :
CUDA_VISIBLE_DEVICES=0alors seul le GPU 0 sera visible, même si la machine possède 4 GPU.
Exemple avec DeepSpeed
DeepSpeed est souvent utilisé pour entraîner ou fine-tuner des LLM plus grands.
Un lancement peut ressembler à ceci :
deepspeed --num_gpus=4 train.py --deepspeed ds_config.jsonAvec nvidia-smi, on peut vérifier si DeepSpeed utilise bien les 4 GPU.
Quand on utilise ZeRO Stage 2 ou ZeRO Stage 3, la mémoire peut être répartie de manière plus intelligente. Cela permet d’entraîner des modèles plus grands, car les poids, gradients et états de l’optimiseur ne sont pas tous dupliqués sur chaque GPU.
Mais si un GPU consomme beaucoup plus de mémoire que les autres, il peut y avoir un souci :
configuration DeepSpeed incorrecte
modèle mal réparti
pipeline déséquilibré
batch size mal choisi
checkpoint ou optimizer states trop lourds sur un GPUnvidia-smi ne donne pas toute l’explication, mais il permet de repérer rapidement qu’il y a un déséquilibre.
Exemple avec Hugging Face Accelerate
Avec Hugging Face Accelerate, on configure d’abord l’environnement :
accelerate configPuis on lance l’entraînement :
accelerate launch train.pyLà encore, nvidia-smi permet de vérifier si la configuration est correcte.
Si Accelerate est configuré pour un seul GPU, l’entraînement n’utilisera qu’un GPU. Même si la machine en possède plusieurs.
Dans ce cas, il faut refaire :
accelerate configet choisir la bonne configuration distribuée.
Les problèmes que nvidia-smi aide à repérer rapidement
1. Un seul GPU est utilisé
Symptôme :
GPU 0 : beaucoup de mémoire utilisée
GPU 1 : presque rien
GPU 2 : presque rien
GPU 3 : presque rienCauses possibles :
script lancé avec python train.py au lieu de torchrun
mauvaise configuration Accelerate
CUDA_VISIBLE_DEVICES mal défini
DeepSpeed mal configuré
code non adapté au distributed training2. Les GPU ont beaucoup de mémoire utilisée, mais travaillent peu
Symptôme :
Memory-Usage : très élevé
GPU-Util : très faibleCauses possibles :
chargement des données trop lent
CPU saturé
disque trop lent
batch size trop petit
DataLoader mal configuré
synchronisation lente entre GPU
communication réseau lente entre machines3. La température est trop élevée
Symptôme :
Temp : 85 C ou plusDans un entraînement long, la température doit être surveillée.
Si elle monte trop haut, le GPU peut réduire ses performances pour se protéger. On appelle cela le thermal throttling.
Les causes peuvent être :
mauvaise ventilation
serveur trop chaud
poussière
charge trop longue
limite de puissance trop élevée4. CUDA out of memory
Symptôme côté script :
CUDA out of memoryDans nvidia-smi, on voit généralement que la mémoire GPU est presque pleine.
Quelques solutions possibles :
réduire le batch size
utiliser gradient accumulation
activer fp16 ou bf16
utiliser gradient checkpointing
réduire la longueur de séquence
utiliser DeepSpeed ZeRO
utiliser FSDP
faire du fine-tuning plus léger avec LoRA ou QLoRAUne commande souvent oubliée : la topologie GPU
Pour l’entraînement distribué, il ne suffit pas de savoir combien de GPU sont disponibles. Il faut aussi comprendre comment ils sont connectés entre eux.
La commande suivante est très utile :
nvidia-smi topo -mElle montre la topologie entre les GPU.
On peut voir si les cartes communiquent via :
PCIe
NVLink
NVSwitchC’est important, car l’entraînement distribué demande beaucoup de communication entre GPU.
Pour certains modèles et certaines stratégies de parallélisme, une machine avec NVLink ou NVSwitch peut être beaucoup plus performante qu’une machine où les GPU communiquent uniquement via PCIe.
Les limites de nvidia-smi
nvidia-smi est excellent pour voir l’état des GPU, mais ce n’est pas un profiler complet.
Il ne dira pas précisément :
quelle couche du modèle consomme le plus
quelle opération ralentit l’entraînement
combien de temps prend la synchronisation des gradients
si le DataLoader est vraiment optimal
si le réseau entre les machines est le vrai goulot d’étranglementPour aller plus loin, on peut utiliser :
torch.profiler
TensorBoard
Weights & Biases
NVIDIA Nsight Systems
DeepSpeed logs
Accelerate logsMais dans la pratique, nvidia-smi reste souvent le premier outil à ouvrir quand quelque chose ne va pas.
Conclusion
Dans l’entraînement distribué d’un LLM, nvidia-smi est un outil simple, mais indispensable.
Il permet de répondre rapidement à des questions très concrètes :
Est-ce que mes GPU sont visibles ?
Est-ce que tous les GPU sont utilisés ?
Est-ce que la mémoire est équilibrée ?
Est-ce qu’un processus Python tourne sur chaque GPU ?
Est-ce que les GPU travaillent vraiment ?
Est-ce qu’un GPU chauffe trop ?Pour un ingénieur IA, savoir lire nvidia-smi est un vrai avantage. Beaucoup de problèmes peuvent être détectés en quelques secondes simplement en observant la mémoire, l’utilisation GPU et les processus actifs.
Le bon réflexe au démarrage d’un entraînement distribué est donc :
watch -n 1 nvidia-smiSi tous les GPU montent en mémoire, que l’utilisation est élevée, que les processus sont bien répartis et que les températures restent correctes, c’est généralement bon signe.
Si un GPU reste vide, si l’utilisation est faible ou si la mémoire est très déséquilibrée, il faut revenir à la configuration distribuée : torchrun, DeepSpeed, Accelerate, Docker, CUDA_VISIBLE_DEVICES, DataLoader ou réseau.
nvidia-smi ne remplace pas les outils avancés de profiling, mais il reste le premier réflexe pour comprendre ce qui se passe vraiment sur les GPU pendant l’entraînement d’un LLM.
