Spark Memory & Thermal Ops
Le chip GB10 de DGX Spark dispose d'un seul pool de mémoire unifiée 128GB (UMA) partagé par le CPU et le GPU, et un plafond de puissance soutenu bien en dessous de sa valeur nominale. Les deux contredisent les hypothèses des GPU discrets : la marge disponible n'est pas ce que rapporte nvidia-smi, et une exécution qui démarre vite ralentira à mi-parcours sans rien de mal configuré. Cette skill couvre la planification de la marge mémoire, la gestion d'une OOM réelle, et la surveillance thermique sur une longue exécution. Pour les modes de défaillance au lancement (incompatibilités ABI, flash-attn, breakage du playbook), voir spark-training-gotchas — cette skill suppose que la tâche a démarré.
Problèmes courants — Référence rapide
| Situation | À faire |
|---|---|
| Planifier la marge avant le lancement | Budget basé sur free -g, pas nvidia-smi — voir UMA Memory Model |
| La tâche OOM sur la mémoire unifiée | Suivre l'OOM Ladder dans l'ordre : flush, puis batch/pack, puis downgrade de méthode |
| Le débit chute en cours d'exécution | Vérifier le log de puissance/température avant de supposer un bug de config — voir Thermal Monitoring |
| Trainer + serveur d'inférence voulus | Exécuter l'un à la fois — voir Concurrent Workloads |
Quand utiliser cette Skill
- Dimensionner une exécution d'entraînement contre le pool 128GB avant le lancement — ce modèle, cette méthode et cette combinaison batch/pack vont-ils tenir.
- Une exécution OOM en cours de chargement ou en cours de step et l'ordre de remédiation compte — que réessayer en premier, deuxième, troisième.
- Surveiller la température et la puissance pendant une tâche multi-heures, décider si un ralentissement est une limitation thermique ou autre chose.
- Planifier d'exécuter un trainer aux côtés d'un serveur d'inférence (vLLM, Ollama) sur la même machine.
UMA Memory Model
Spark n'a pas de VRAM GPU séparé — le GPU et le CPU partagent un seul pool 128GB. Deux conséquences :
-
nvidia-smietcudaMemGetInfosous-rapportent la pression — ou ne rapportent rien du tout. Les deux rapportent la mémoire visible par l'allocateur CUDA, pas l'état réel du pool — une machine peut afficher une marge dansnvidia-smiet OOM quand même, parce que le page-cache et les pages mmap'd que l'allocateur ne voit pas consomment le même pool. Sur certains driver/configurations, la requête mémoire retourne[N/A], [N/A]purement et simplement au lieu d'un nombre — un script grep'd pour une valeur numérique là n'obtient rien, pas un sous-comptage trompeur (voirspark-training-gotchasgotcha G3). -
Le chargement du modèle est un pic transitoire, pas l'état stable. Charger les poids safetensors mmap le fichier, puis copie dans les tenseurs CUDA — pendant une fenêtre lors du chargement, les pages mmap'd et la copie CUDA comptent contre le pool à la fois. Un modèle qui rentre en entraînement peut OOM au chargement si la marge a été dimensionnée pour l'empreinte post-charge au lieu de ce transitoire doublé.
Planifier et diagnostiquer avec free -g, pas nvidia-smi :
free -g | awk 'NR==2 {print "free:", $4, "GB"}'
Règle de pouce : prendre le chiffre libre, soustraire quelques GB pour la surcharge OS/driver, et budgéter contre le résultat — pas le chiffre spec 128GB. La feuille de calcul dans references/uma-accounting.md accepte le nombre de paramètres, le dtype et la méthode en entrée, et retourne une estimation mémoire à comparer contre des anchors connus.
Séquence de Planification
Avant lancement, travailler ces étapes dans l'ordre :
- Lire
free -g; soustraire la surcharge OS/driver pour le budget. - Estimer poids + optimiseur + gradients + activations depuis
references/uma-accounting.md. - Comparer contre l'anchor le plus proche (70B QLoRA, 27B LoRA, 9B full FT), pas l'estimation seule.
- Si l'estimation est proche du budget, démarrer avec un packing plus court ou un batch plus petit — moins cher que de frapper l'OOM Ladder en cours d'exécution.
Exemple : Dimensionner une exécution 70B QLoRA
Un contrôle de santé de la formule de la feuille de calcul contre l'anchor ≈40GB :
params = 70e9
weights_gb = params * 0.5 / 1e9 # NF4, step 1
adapter_gb = 0.5 # step 5, negligible
total_gb = weights_gb + adapter_gb # + activations
print(f"{total_gb:.0f}GB before activations")
Les poids seuls atterrissent près de l'anchor ≈40GB — un plan estimant bien au-dessus de cela pour la même classe de modèle est un signal pour revérifier dtype et méthode.
The OOM Ladder
Quand une tâche OOM sur la mémoire unifiée, suivre cette ladder dans l'ordre. Chaque étape est plus disruptive que la dernière — ne pas sauter : réduire la batch size n'est jamais l'étape 1.
-
Flush le buffer cache. Le page cache d'une exécution précédente ou une lecture de dataset large comptent souvent pour GB de la marge "manquante". Cela ne coûte rien qu'une réexécution et ne touche pas la configuration de la tâche :
sync; echo 3 > /proc/sys/vm/drop_cachesBesoin de root ; un reset entre-exécution, pas une étape en cours d'entraînement. Voir
spark-training-gotchas(gotcha G3) pour le diagnostic complet derrière cette étape. -
Réduire batch size ou packing length. Seulement après un flush ne libérant pas assez de marge, couper batch size ou packing length — la première étape qui change ce que la tâche fait. Préférer d'abord packing length ; elle pilote l'empreinte activation plus directement à contexte long.
-
Downgrade de méthode : bf16 LoRA avant QLoRA. Si flush et shrink batch/pack OOM toujours, baisser la méthode d'un cran — bf16 LoRA est ensuite, pas l'inverse. Les buffers de dequantization bitsandbytes de QLoRA sont des allocations CUDA-side transitoires qui peuvent OOM avant qu'une exécution bf16 LoRA équivalente le ferait, même si l'empreinte état-stable de QLoRA est plus petite. Une QLoRA OOM n'est pas la preuve que le modèle ne rentre pas.
Fallback plus loin (modèle plus petit, multi-Spark) seulement après les trois étapes et la tâche ne rentre toujours pas.
Thermal Monitoring
Les exécutions multi-heures appuient contre le plafond de puissance soutenu de Spark, bien en dessous de la figure nominale — comportement plateforme attendu, pas un symptôme à expliquer :
-
Sampler la température et la puissance aux côtés des logs d'entraînement, pas après un ralentissement remarqué — chaque 30-60 secondes corrèle une chute de débit avec un événement thermique. Garder le format de sortie CSV que
assets/thermal-sample.shécrit, pour que les timestamps s'alignent contre le log :bash assets/thermal-sample.sh 30 thermal.log -
Un tirage de puissance soutenu ~100W est le plafond plateforme, pas un bug de configuration. Ne pas re-tuner batch size ou précision pour "fixer" un plateau qui est la machine se comportant normalement sous charge. Si la température grimpe tandis que la puissance reste plate sous la figure nominale 240W, c'est la signature à reconnaître.
-
Logger les événements throttle explicitement plutôt que de laisser une exécution ralentir silencieusement non enregistrée. Une exécution dont le per-step time double deux heures in devrait montrer cela dans le log, corrélé contre l'échantillon thermique à ce timestamp. Diagnostiques de throttling complet :
spark-training-gotchas(gotcha G4).
Concurrent Workloads
Parce que le pool 128GB est global, l'éviction se passe sans que les logs de chaque process montrent une OOM :
-
La règle one-heavy-job s'applique aux charges de travail uncapped ou near-capacity — un trainer uncapped et serveur d'inférence (vLLM, Ollama) concourent pour le même pool. Une petite charge de travail capped ne le fait pas : un fine-tune LoRA <4GB coexiste bien aux côtés de vLLM cappé à
gpu-memory-utilization<=0.5— vérifier le cap de l'autre process, pas juste sa présence, avant de l'arrêter. -
Les serveurs d'inférence évincent les pages trainer silencieusement sous contention uncapped/near-capacity, et vice versa — ni ne log une erreur, donc une exécution lente ou KV cache perdu est un symptôme de contention à vérifier. Arrêter les serveurs uncapped non liés avant une exécution longue ou full-pool.
Vérifier les processus GPU-resident en premier :
ps aux | grep -E 'vllm|ollama|trl|axolotl' | grep -v grep
Cette procédure complète spark-training-gotchas (gotchas G3, G4, G6) — cette skill couvre les défaillances au lancement ; celle-ci, la tâche en cours d'exécution.
Feuilles de calcul de math mémoire :
references/uma-accounting.md.