Maison  >  Article  >  Périphériques technologiques  >  Du bare metal au grand modèle avec 70 milliards de paramètres, voici un tutoriel et des scripts prêts à l'emploi

Du bare metal au grand modèle avec 70 milliards de paramètres, voici un tutoriel et des scripts prêts à l'emploi

王林
王林original
2024-07-24 20:13:31456parcourir

Nous savons que le LLM est formé sur des clusters informatiques à grande échelle utilisant des données massives. Ce site a présenté de nombreuses méthodes et technologies utilisées pour assister et améliorer le processus de formation LLM. Aujourd'hui, ce que nous souhaitons partager est un article qui approfondit la technologie sous-jacente et présente comment transformer un ensemble de « bare metals » sans même un système d'exploitation en un cluster informatique pour la formation LLM. Cet article provient d'Imbue, une startup d'IA qui s'efforce d'atteindre une intelligence générale en comprenant comment les machines pensent. Bien sûr, transformer un tas de « bare metal » sans système d'exploitation en un cluster informatique pour la formation LLM n'est pas un processus facile, plein d'exploration et d'essais et d'erreurs, mais Imbue a finalement réussi à former un LLM avec 70 milliards de paramètres et accumulés. de nombreuses expériences utiles dans le processus. Cet article fournira un aperçu approfondi du processus suivi par l'équipe pour créer sa propre infrastructure de formation LLM et partagera les nombreux outils et scripts qu'ils ont écrits pour faciliter la surveillance, l'inspection et le débogage. Si vous souhaitez créer votre propre infrastructure de formation LLM ou si vous êtes curieux de savoir comment est créé le LLM, cet article mérite d'être lu et collecté. Ce qui suit est l'article original de l'équipe Imbue. Introduction Notre petite équipe de chercheurs et d'ingénieurs a passé plusieurs mois à former un modèle de 70 milliards de paramètres à partir de zéro sur notre propre infrastructure, et le modèle a surpassé l'échantillon zéro sur les tâches liées à l'inférence. Aujourd'hui, nous partageons le processus de mise en place de l'infrastructure requise : depuis la constitution du cluster initial et l'installation du système d'exploitation jusqu'à la configuration de la récupération automatique lorsque des erreurs sont rencontrées lors de la formation. Nous détaillons les défis rencontrés et les solutions à chaque étape. En plus de ces apprentissages, nous publierons également de nombreux scripts que nous avons développés au fil du temps pour permettre aux autres équipes de créer plus facilement une infrastructure stable pour leur propre formation de modèles. Tout au long du processus, notre équipe d'ingénieurs a travaillé avec Voltage Park pour préparer les clusters d'ordinateurs et jeter les bases des applications de production. L'ensemble de ce processus comprend : 1. La configuration de chaque machine 2. La configuration d'InfiniBand 3. S'assurer que les machines sont entièrement saines 4. Diagnostiquer les problèmes de formation courants 5. Améliorer les outils d'infrastructure Chaque étape est décrite en détail ci-dessous. Contexte : comment cela fonctionne Notre objectif en effectuant des calculs est de garantir que nous pouvons expérimenter rapidement avec de grands modèles de langage. Pour ce faire, nous avons besoin d’un grand nombre de GPU haute vitesse capables de communiquer entre eux à grande vitesse. Cet article se concentrera sur un cluster avec 4088 GPU H100 répartis sur 511 machines, soit 8 GPU par machine. La raison pour laquelle il existe 511 ordinateurs équipés de GPU est que certaines connexions doivent être réservées au nœud Unified Fabric Manager, dont le rôle est de gérer le réseau InfiniBand. Sur les hôtes 511 équipés de GPU, chaque GPU est directement connecté à une carte réseau ConnectX-7, qui peut transférer des données à 400 Gbps vers n'importe quel GPU du réseau InfiniBand. Notre topologie réseau InfiniBand est « totalement non bloquante », ce qui permet théoriquement aux GPU de communiquer entre eux à une vitesse maximale. Pour ce faire, nous utilisons une architecture réseau InfiniBand à trois couches : des commutateurs InfiniBand à trois couches. Avec les bonnes connexions, ce niveau élevé de débit peut être atteint sur l’ensemble du réseau. L'image ci-dessous montre un aperçu de ce réseau InfiniBand :

Du bare metal au grand modèle avec 70 milliards de paramètres, voici un tutoriel et des scripts prêts à lemploi


Veuillez noter que la communication lors de la formation du réseau s'effectue via InfiniBand et non via Ethernet. Bien que ces machines soient également connectées à Ethernet, le rôle de ce réseau est de transporter des données telles que des jeux de données et des points de contrôle. Si vous utilisez Ethernet pour envoyer des données, cela sera beaucoup plus lent car les données sont transférées du GPU vers le CPU puis via la carte Ethernet à des vitesses de 100 Gbit/s. Bien qu'il soit possible de s'entraîner sur Ethernet à l'aide d'une technologie appelée RDMA sur Ethernet Convergé (RoCE), cela nécessite beaucoup de travail supplémentaire tant du côté matériel que logiciel et est généralement moins fiable qu'InfiniBand. Les détails peuvent être trouvés dans ce document : https://arxiv.org/pdf/2402.15627
Il existe également un Ethernet secondaire utilisé uniquement pour la configuration et la gestion, permettant l'accès au BIOS (Basic Input Output System), à l'alimentation et à d'autres faibles machines de niveau L'interface de contrôle de l'interface. Sans ce réseau de gestion, nous devrions configurer manuellement chaque nœud via un pilote USB, un clavier et un moniteur. Pour les situations comportant des centaines de machines, cette approche n’est pas durable.
Pour réaliser une formation haute performance sur ce cluster, chaque composant (InfiniBand, Ethernet, GPU et les nœuds eux-mêmes) doit fonctionner presque parfaitement. Si l’une de ces 12 000+ connexions est un peu instable, cela peut ralentir l’ensemble de l’entraînement.
Le prochain contenu de cet article est de présenter comment faire en sorte que tout fonctionne parfaitement et de manière stable.
Procédure : Comment transformer le bare metal en un cluster entièrement opérationnel
Configuration de chaque machine
Après avoir établi la connexion Ethernet initiale au cluster via le réseau de gestion, l'accès au contrôleur de gestion de la carte mère (BMC/contrôleur de gestion de la carte mère) est obtenu avec un certificat. Un BMC est un processeur de service dédié qui surveille à distance les systèmes hôtes et est généralement connecté à un réseau distinct. Il nous permet de faire fonctionner la machine comme si nous étions physiquement présents et fournit en outre des API pour l'état du matériel, les paramètres du BIOS et la gestion de l'alimentation.
Après avoir équipé ces composants, nous pouvons retrousser nos manches et commencer la mise en place du cluster.
Étape 0 : configurer d'abord une machine
Nous avons commencé par installer Ubuntu 22.04 sur un serveur utilisant iDRAC (le contrôleur de gestion de la carte mère de Dell), puis avons configuré tout le reste en fonction de ce système d'exploitation. L'une des fonctionnalités d'iDRAC est de permettre l'installation et le démarrage d'images ISO à partir de l'ordinateur local et de fournir une console virtuelle via le navigateur. Idéalement, il s’agit de la seule étape d’installation manuelle du processus.
Étape 1 : Installez le système d'exploitation sur chaque machine
Après avoir configuré la première machine, procédez à l'installation du logiciel Metal-as-a-Service (MAAS) d'Ubuntu pour vous aider à configurer les serveurs restants. Utilisez l'outil iDRAC de démarrage et d'automatisation du protocole PXE (Preboot Execution Environment Protocol) pour demander à chaque machine de démarrer à partir du réseau et de configurer MAAS pour répondre aux demandes de démarrage PXE. Lors d'un démarrage réseau initial, le serveur obtient une adresse IP et un noyau initial de MAAS via le protocole d'allocation IP dynamique DHCP sans avoir à installer quoi que ce soit sur le disque local. Il s'agit de l'environnement de base pour automatiser les installations reproductibles du système d'exploitation. Théoriquement, il suffit d'attendre le premier démarrage et tout sera réglé. Mais en pratique, l'intégration de MAAS avec BMC n'est pas fiable, nous utilisons donc l'API iDRAC pour collecter au préalable l'adresse MAC de chaque machine (un identifiant matériel physique unique).
Pendant tout ce processus d'entraînement, le MAAS est généralement le composant le plus fiable de la pile vertébrale. Cependant, nous avons rencontré au début certains problèmes propres à notre configuration. Par exemple, lors de la configuration des premières machines, je n'ai pas pu installer quoi que ce soit via apt en raison de problèmes de vérification du certificat HTTPS car les horloges étaient très éloignées les unes des autres. De même, puisque le serveur MAAS doit être responsable de beaucoup de choses (serveur DHCP, serveur DNS pour résoudre les noms d'hôte en IP, proxy HTTP entre l'hôte et le serveur de packages Ubuntu officiel, serveur NTP, gestion de la configuration cloud-init, un terrain base de données de vérité utilisée pour connecter l'adresse MAC à l'IP, au nom d'hôte et aux métadonnées personnalisées), il nous est donc difficile de résoudre ces problèmes à la racine. De plus, il y a le problème de la courbe d'apprentissage du cycle de vie de la configuration MAAS, car l'objectif de conception est de gérer la complexité de la gestion des déploiements inédits et de la migration progressive des nœuds et de divers états intermédiaires de débogage/malsains.
Étape 2 : Diagnostiquer les machines en panne
Nous avons constaté qu'environ 10 % des machines n'ont pas pu démarrer, principalement en raison de problèmes physiques avec le serveur. Il s'agit d'un scénario courant pour la configuration de grands clusters GPU. Les situations que nous avons rencontrées incluent : des câbles réseau manquants ou incorrects, des problèmes matériels dans l'iDRAC, des blocs d'alimentation endommagés, des pilotes NVME (mémoire non volatile rapide) endommagés, un câblage interne manquant, des cartes réseau ou des GPU qui ne s'affichent pas. Nous avons automatiquement vérifié ces problèmes, renvoyé certaines machines à Dell pour les tester à nouveau et soumis les bons de travail appropriés au personnel du centre de données. Un avantage de configurer nous-mêmes le cluster est que nous pouvons immédiatement utiliser des machines saines en attendant la maintenance sur certaines machines.
Étape 3 : Machine minimale observable viable
Nous procédons à la configuration des éléments suivants sur chaque serveur :
1.Docker (pour faciliter l'exécution des services et des tâches de formation)
  1. Pilote GPU du centre de données
    3. Outil d'exportation de nœud Prometheus (utilisé pour exporter le flux de données d'indicateur de matériel/système d'exploitation stable)
    4. Outil d'exportation DCGM (utilisé pour exporter des données d'indicateur supplémentaires du GPU NVIDIA, telles que l'état du GPU, l'horloge, utilisation)
  2. Tous les pools RAIDZ ZFS non pilotés par le système d'exploitation, qui permettent aux machines de continuer à fonctionner même en cas de panne d'un pilote, tout en fournissant également une compression transparente gratuite (en particulier pour les ensembles de données en texte brut et les journaux répétitifs) Utile - l'utilisation de cet outil augmente généralement l'espace utilisable par un facteur de 10 par rapport à la non-utilisation de l'outil)
    Nous effectuons ensuite des diagnostics de base du GPU pour déterminer si le GPU fonctionne généralement - sinon, cela se produit généralement en quelques secondes. Des problèmes matériels surviennent en quelques heures.
    Pendant cette période, nous avons rencontré des goulots d'étranglement de bande passante lors de la tentative d'installation simultanée de packages sur les 400 nœuds. C'est la première fois que nous recevons des alertes de surchauffe à haute température sur plusieurs composants déployés dans notre centre de données. Ces premiers problèmes de chauffage ont été en grande partie résolus grâce aux mises à jour du micrologiciel.
    Étape 4 : Formation GPU à nœud unique
    L'étape suivante consiste à s'assurer que chaque machine peut gérer seule de véritables charges de travail GPU. De nombreuses machines sont incapables de le faire. Les problèmes incluent :
    Erreurs liées au GPU Ces problèmes peuvent être résolus en réinsérant la carte GPU dans l'emplacement pour carte : faites glisser le serveur de 200 livres hors du rack et retirez-le. le couvercle du boîtier et le GPU, puis retirez le GPU, réinstallez le GPU, puis rebranchez les câbles et repoussez le serveur dans le rack.
    Selon les journaux du serveur Ubuntu, de nombreux câbles entre le GPU et le bus PCIe ou la carte réseau ont généré cette erreur : "largeur limitée : x4 Il existe également divers problèmes affectant plusieurs hôtes. Dell nous a aidé à résoudre quelques problèmes grâce à une mise à niveau du micrologiciel :
    Le disque NVMe ne présentait aucun problème, mais bloquait l'intégralité de la machine lorsqu'on le touchait.
    Les disques durs apparaissent dans un ordre aléatoire sous Linux, ce qui provoque une confusion pour MAAS et entraîne l'installation du système d'exploitation sur le mauvais disque.
    Mauvaise lecture de la température, ce qui fait que le ventilateur tourne tout le temps à pleine vitesse. La raison peut être un problème avec le pilote NVIDIA, qui est résolu en rétrogradant la version du pilote.
    La mise à l'échelle dynamique du processeur est incontrôlable, limitant les cœurs de travail à 2 GHz.
    La communication directe GPU-GPU (GDR ou GPUDirect RDMA Peer Memory Client) ne peut pas être appliquée avec succès.
    Configurer InfiniBand
    Étape 0 : Installer UFM
    L'un des avantages d'InfiniBand est sa conception centralisée, de sorte que l'ensemble du réseau ait un seul cerveau. Par conséquent, nous n’avons à gérer qu’une seule instance des 320 commutateurs réseau dans l’ensemble de la structure réseau. Notre première tâche consistait à déterminer quel commutateur connectait quelles machines, puis à l'associer au schéma de câblage et à les renommer en fonction de l'emplacement physique du commutateur.
    Étape 1 : recâblage
    Au départ, UFM était incapable de détecter ces 320 commutateurs, sans parler des hôtes qui étaient censés être présents dans la structure. Après avoir consulté nos partenaires de centres de données, nous avons confirmé que les commutateurs étaient sous tension et câblés, mais que nous ne parvenions toujours pas à les détecter. Après avoir examiné la liste du câblage réseau, nous avons remarqué que la conception de haut niveau de la structure du réseau était incorrecte : au lieu d'être unifiée, la structure était divisée en huit réseaux déconnectés sans chemin de routage commun. Après le recâblage, nous avons ajouté une étape de vérification pour vérifier que toutes les connexions physiques sont cohérentes avec la nouvelle conception.
    Étape 2 : Dix mille alarmes de température (alerte)
    Après avoir résolu le problème de câblage physique, InfiniBand a réussi à établir des connexions avec tous les commutateurs InfiniBand de la structure du réseau. Cependant, presque tous les ports de commutation ont commencé à signaler des températures excessives, dépassant parfois 70°C, même s'ils ne transmettaient pas de données. Nous avons constaté que le problème provenait de l'espace ouvert entre les commutateurs d'un même rack, ce qui provoquait un retour d'air chaud vers l'avant. Notre partenaire de centre de données nous a aidé à diagnostiquer rapidement le problème et à développer une solution appropriée.
    Étape 3 : 1 800 alarmes
    De nombreux ports ont également des taux d'erreur élevés, ou fluctuent entre des états normaux et endommagés, ce que l'on appelle « battement ». Ces problèmes ne surviennent que lorsque les ports sont réellement utilisés. Ils sont donc difficiles à détecter à l'avance car l'ensemble de notre structure est constitué de 10 000 liens hautement redondants. Notre partenaire du centre de données a aidé à nettoyer et à réinstaller les ports d'alarme, et nous avons désactivé les émetteurs-récepteurs d'alarme restants en attendant leur remplacement.
    Bien qu'InfiniBand soit résilient aux pannes matérielles, une fois qu'environ 10 % de la structure commence à tomber en panne, des fonctionnalités telles que le routage adaptatif ne fonctionnent pas de manière fiable pour tenir compte de la perte occasionnelle de lien.
    Pendant cette période, nous avons mené avec succès une formation multi-nœuds en utilisant 100 à 200 machines. Notre processus est quelque peu improvisé : nous faisons parfois tourner un ensemble aléatoire de nœuds, observons leurs performances, puis essayons d'en faire fonctionner autant que possible.Cette méthode permet de trouver un sous-ensemble fiable de la structure du réseau InfiniBand, mais elle est très difficile car à chaque fois il faut changer l'ensemble des nœuds utilisés pour l'entraînement, et donc les liens InfiniBand par défaut.
    Étape 4 : Gravure d'InfiniBand
    Pour diagnostiquer plus efficacement les problèmes d'InfiniBand, nous avons conçu une charge de travail pour l'ensemble du cluster qui transmettait simultanément autant de données que possible via chaque port de l'ensemble de la structure. Ceci est différent de l'exécution d'une charge de travail importante et réduite sur l'ensemble du cluster, qui nécessite l'utilisation de NCCL pour optimiser la communication entre les nœuds individuels en utilisant NVLink pour la communication GPU via les emplacements du module serveur PCIe (SXM).
    Au lieu de cela, nous avons opté pour une approche par force brute et avons réussi avec facilité. UFM commencera à émettre des alertes lorsque le volume de transfert de données sur la plupart des ports dépassera 97 % de la capacité théorique, et certains commutateurs tomberont temporairement en panne. Chaque port que nous pensions avoir atteint à la fin de la journée était suffisamment robuste, et le reste a été désactivé ou supprimé en attendant des réparations.
    Étape 5 : GPUDirect RDMA
    Pour permettre la communication GPU sans encourir de surcharge de calcul du CPU, nous activons une fonctionnalité appelée GPUDirect RDMA, qui permet une communication directe entre les cartes réseau InfiniBand. Cela implique deux étapes clés :
  3. Démarrez un module de base supplémentaire
  4. Assurez-vous que le service de contrôle d'accès PCIe (ACS) est désactivé pour éviter des blocages immédiats
    Étape 6 : Amplifiez le serveur « en or »
    À utiliser lors de la création d'un cluster GPU avec Avec le matériel le plus récent, une règle générale est la suivante : environ 3 % des machines auront des problèmes chaque semaine, alors soyez prêt.
    Cependant, il faut l'expliquer : toutes les machines n'ont pas une probabilité uniforme de 3 % de panne, mais un petit nombre de machines non traitées rencontrent divers problèmes à plusieurs reprises jusqu'à ce qu'elles soient correctement réparées. Cela met en évidence les avantages d’avoir un grand nombre de machines dans la même structure de réseau. Ainsi, au lieu de simplement trouver des machines aléatoires sur lesquelles exécuter une formation à grande échelle, comme whack-a-mole pour voir ce qui tombe en panne, notre approche consiste à nous concentrer sur la mise à l'échelle de serveurs réputés fiables, les serveurs « en or ».
    Étape 7 : Maintenance
    La maintenance d'InfiniBand implique principalement de répondre aux alarmes UFM, de remplacer les câbles et les émetteurs-récepteurs défectueux et, occasionnellement, de diagnostiquer des erreurs plus difficiles (telles que des pannes de commutateur). Il existe généralement deux facteurs qui conduisent à une maintenance à grande échelle :
  5. Les mises à jour du micrologiciel, en particulier lorsque seulement la moitié du cluster a terminé la mise à jour, cela peut entraîner une corruption de l'état de l'UFM et nécessiter un redémarrage de l'UFM sur tous les commutateurs InfiniBand.
    2. Redémarrage massif des boîtiers GPU en même temps, ce qui peut inonder l'état UFM d'un grand nombre de mises à jour et nécessiter également le redémarrage du service UFM.
    Assurer que la machine est entièrement saine
    Au cours de ce processus, nous avons découvert de multiples façons dont des machines individuelles pouvaient mal fonctionner ou ralentir l'entraînement. Beaucoup de ces modes de défaillance ne sont pas immédiatement apparents, c'est pourquoi nous avons écrit un certain nombre de scripts de vérification de l'état pour vérifier si l'hôte était suffisamment sain. Nous avons publié le code ici : https://github.com/imbue-ai/cluster-health
    Veuillez noter que bon nombre de ces contrôles de santé sont spécifiques à notre environnement d'exécution et ne sont pas nécessairement liés au matériel sous-jacent. facile à réparer ou à automatiser. C'était intentionnel : pour atteindre l'objectif global de préparer nos machines à la formation, nous souhaitions un point d'entrée unique capable de répondre simplement par oui ou par non et de résumer un certain nombre de détails précis.
    GPU Health Check
    Nous vérifions que le nombre de GPU est correct, que la vérification ECC (Error Correction Code) est activée et qu'il n'y a pas d'erreurs ECC. Nous avons également vérifié que la topologie NVLink (qui connecte les GPU entre eux) est opérationnelle et sans erreur.
    Bilan de santé de l'espace disque
    Nous vérifions si l'utilisation de l'espace disque de l'hôte dépasse 95 %.
    Docker Health Check
    Nous avons vérifié si Docker peut exécuter le conteneur avec le GPU connecté (c'est-à-dire si le NVIDIA Container Runtime fonctionne correctement), et également vérifié si le conteneur Docker lié à la surveillance/analyse a été activé et a obtenu les autorisations d'hôte correctes. .
    Dmesg Health Check
    Nous avons vérifié dmesg pour les erreurs matérielles Xids ou SXid (défauts causés par les GPU NVIDIA ou les commutateurs NVIDIA inter-GPU). Nous lisons également toutes les lignes de journal dmesg pour vérifier qu'elles peuvent toutes être classées dans la liste des « lignes de journal communes/attendues ».
    Bilan de santé iDRAC
    Nous avons vérifié les erreurs iDRAC sur la machine, qui ont ignoré les messages d'erreur non fatals. Il s'agit d'une vérification spécifique aux ordinateurs Dell, elle n'est donc pas incluse dans notre code open source.
    Bilan de santé du disque
    Nous avons vérifié que zpool est installé, que Docker y est correctement connecté et qu'il peut réellement l'atteindre sans bloquer le processeur.
    InfiniBand Health Check
    Nous vérifions si les taux d'erreur InfiniBand augmentent et/ou si le micrologiciel du pilote est obsolète.
    Nvlink Health Check
    Nous vérifions les erreurs NVLink sur la machine. En pratique, cela ne semble pas provoquer d’échecs de formation, mais cela peut ralentir la formation.
    Bilan de santé GDR
    Nous avons vérifié si le GDR est activé sur la machine.
    VBIOS Health Check
    Nous avons vérifié que la version VBIOS du GPU et le firmware de la carte mère H100 sont à jour.
    Flint Health Check
    Nous avons utilisé Flint et hca_self_test pour vérifier que le pilote Mellanox OFED, le micrologiciel de la carte réseau et le micrologiciel de l'émetteur-récepteur sont les versions correctes et qu'ils sont correctement compilés pour le pilote NVIDIA.
    Bilan de santé PSB
    Nous avons interrogé les périphériques PCIe pour vérifier que la vitesse et la largeur de la connexion entre le GPU, le PSB (PCIe Switch Bus) et la carte réseau correspondaient à nos attentes. Nous avons également vérifié que le firmware du switch est à jour. Ce script a été développé par Dell et non par Imbue, nous ne pouvons donc pas le partager pour le moment.
    En plus de ces contrôles de santé rapides, nous effectuons également des contrôles de santé plus complexes, notamment :
    Initialisation des calculs matriciels via PyTorch et mesure de la bande passante NVLink ainsi que de la vitesse de calcul et de la mémoire du GPU. Nous définissons les indicateurs GDR appropriés pour tester InfiniBand et NVLink.
    Utilisez ib_write_bw et –use_cuda pour envoyer des données via des cartes IB et mesurer la bande passante des cartes PCIe et InfiniBand. Ce processus a duré une période prolongée (environ 15 minutes) pour garantir que le lien InfiniBand flottant a été identifié.
    Exécutez une exécution de diagnostic multi-nœuds pour vérifier les capacités d'initialisation de NCCL et si elle se bloque de manière aléatoire. S'il y a des blocages, notre code NCCL fork ajoute une journalisation supplémentaire. Cela prend 12 à 24 heures pour détecter un problème, nous l'exécutons donc généralement uniquement sur les nouveaux nœuds ou si nous soupçonnons un problème.
    Vérifiez l'exportation DCGM pour tout événement de limitation d'horloge GPU (à l'exclusion de gpu_idle et power_cap attendus). Pour vérifier ces événements d'alimentation, le meilleur moyen consiste à exécuter une formation multi-nœuds qui vérifie simultanément tous les GPU, cartes InfiniBand, processeurs et disques.
    Diagnostiquer les problèmes de formation courants
    Une fois que le matériel fonctionne correctement, vous pouvez commencer la formation.
    Cette section partagera quelques étapes de débogage spécifiques et des informations basées sur notre expérience dans l'exécution de formations de modèles de langage à grande échelle sur notre cluster.
    Crash au démarrage
    D'une certaine manière, c'est le meilleur bug que vous puissiez rencontrer car il est (théoriquement) facile à reproduire et à itérer.
    Nous avons d'abord vérifié que notre code s'exécutait sur la bonne version, la configuration et les variables d'environnement. Bien que basique, nous avons trouvé cela essentiel : garantir que le processus de formation des startups est reproductible et facile à vérifier. L’une des principales raisons est que les abstractions intermédiaires telles que la mise en cache des images Docker ou les configurations secrètes opaques peuvent prêter à confusion.
    Une autre vérification de base que nous effectuons consiste à nous assurer que toutes les machines sont en ligne et que les traces de pile ou les journaux émis peuvent être facilement regroupés et inspectés. Nous avons utilisé les piles logicielles Loki, Prometheus et Grafana, mais tout outil SaaS d'agrégation de journaux ou de suivi approprié fera l'affaire. Étant donné que ces exécutions de formation sont de nature synchrone et distribuée, la première erreur entraîne souvent une cascade d’erreurs sans rapport. Ici, les contrôles de santé peuvent également aider à détecter immédiatement des erreurs telles qu’un disque dur corrompu ou un GPU manquant ou invalide.
    Nous avons construit un système qui redémarre automatiquement en cas de panne, ce qui rend l'agrégation des journaux et des erreurs encore plus importante pour éviter toute confusion entre les erreurs liées aux différents redémarrages. Certaines erreurs courantes que nous rencontrons incluent :
    1. "L'ordre de transfert diffère selon les rangs : le rang 0 rassemble 43 paramètres tandis que le rang 1228 rassemble 1 paramètre". Nous avons trouvé qu'il s'agissait d'une fonctionnalité étrange de l'implémentation FSDP (Fully Sharded Data Parallel) de PyTorch, qui a été résolue par un redémarrage.
    2. Erreur GPU Out of Memory (OOM), qui ressemble à ceci : "CUDA out of memory. J'ai essayé d'allouer..." En vérifiant notre configuration et notre code plusieurs fois et en annulant les modifications récentes du code (en raison de spécifications incohérentes du périphérique PyTorch). lors du démarrage, provoquant correctement une utilisation excessive du GPU n°0), nous avons résolu ces problèmes.
    3.Erreurs CPU/RAM hors mémoire (MOO). Ces erreurs ne sont pas faciles à trouver dans les journaux d'erreurs et peuvent généralement être détectées via le journal dmesg de l'hôte en dehors du conteneur Docker. Lorsque OOM Killer est appelé pour arrêter un processus forké ou un homologue réseau, nous pouvons voir qu'ils se manifestent principalement par CalledProcessError ou ConnectionError. Lorsqu’un appel OOM Killer est détecté depuis dmesg, nous préférons simplement abandonner le bilan de santé et redémarrer la box. Nous avons également vérifié nos chemins de code pour un garbage collection manuel adéquat (il y a une section ci-dessous sur la façon de désactiver cela), et avons également vérifié toute tentative inattendue de calcul ou de déplacement de tenseurs sur le processeur.
    Crash pendant la formation
    La première tâche consiste à permettre au système de s'exécuter automatiquement, afin qu'il puisse réexécuter automatiquement toutes les vérifications de l'état, puis redémarrer lorsqu'aucun hôte défectueux n'est trouvé. Nous avons rencontré des erreurs matérielles aléatoires, notamment des erreurs Xid et SXid ; celles-ci pouvaient faire planter l'exécution sans émettre de trace de pile Python significative. Certains problèmes, tels que le remappage des lignes, peuvent être résolus en redémarrant. D'autres, comme les erreurs ECC non corrigibles, nécessitent souvent une maintenance matérielle ou des pièces de rechange.
    De plus, nous avons observé que des données d'entraînement mal formées peuvent également provoquer des plantages. Par exemple, s'il y a un seul document très volumineux dans le corpus, cela peut provoquer une erreur de mémoire insuffisante sur le GPU ou le CPU.Pour éviter ce problème, nous avons implémenté un chargeur de données entièrement déterministe, rendant chaque crash facilement reproductible en étant lié à une époque ou à un numéro d'étape. Nous avons constaté que la désactivation du chargement des données ou le remplacement de fausses données (telles que des données entièrement nulles) permettent de confirmer si la cause première de l'erreur réside dans les données.
    Enfin, il est également utile d’enregistrer les statistiques générales sur l’état du réseau et des nœuds via des méthodes d’agrégation de métriques. Des problèmes tels qu'une brève déconnexion Ethernet ou un espace disque faible peuvent ne pas apparaître comme des messages d'erreur utiles, mais peuvent être facilement corrélés aux données collectées.
    Se bloque sans traces de pile (et éventuellement des délais d'attente plus tard)
    Le débogage de ces types d'erreurs peut être frustrant en raison du manque d'informations utiles et de la difficulté de les reproduire de manière fiable.
    L'un des types d'erreur les plus mémorables est accompagné d'un message d'erreur comme celui-ci :

    Watchdog caught collective operation timeout:WorkNCCL (SeqNum=408951, OpType=_ALLGATHER_BASE, … , Timeout (ms)=600000) ran for 600351 milliseconds before timing out


    et ce message d'erreur est émis par tous les travailleurs du GPU lors de l'entraînement.

Cela signifie qu'un ou plusieurs hôtes n'ont pas réussi à terminer l'opération NCCL ou que les connexions NCCL et InfiniBand se sont écrasées, provoquant le blocage de tous les autres hôtes sur une opération tensorielle en même temps jusqu'à ce que le délai d'expiration NCCL_TIMEOUT soit atteint. Malheureusement, en raison de la nature de la bibliothèque logicielle NCCL, il est difficile de trouver quel hôte est à l'origine du problème.

Nous avons apporté quelques modifications à la journalisation de la bibliothèque logicielle NCCL, voir notre version forkée : https://github.com/boweiliu/nccl. Cela peut mieux révéler les messages ou les opérations en cours lorsqu'un crash se produit, et ainsi déterminer quel hôte ou GPU peut bloquer l'exécution.

Veuillez noter que pour identifier les hôtes qui se comportent mal, nous devons souvent déterminer quels hôtes ne génèrent pas certains messages de journal. L'absence de tels messages indique que le travailleur sur cet hôte a pris du retard ou s'est écrasé.

D'autres situations sans réponse sans message d'erreur disponible sont généralement liées à des problèmes liés au matériel, tels que les erreurs Xid/SXid/ECC mentionnées précédemment qui provoquent le verrouillage du pilote NVIDIA ou du pilote de communication NVIDIA Docker. Pour distinguer les blocages NCCL des blocages de pilotes et des conditions de concurrence ou blocages dans le code Python, nous utilisons des outils tels que Py-Spy et le débogueur de projet GNU (GDB) pour déboguer les processus bloqués rencontrés en temps réel. Un problème spécifique a été découvert en utilisant cette approche : en raison d'une erreur de configuration dans les paramètres du thread Python, nous n'avons pas pu lancer correctement huit processus GPU NCCL multithread sur certains hôtes, qui ont rencontré une condition de concurrence critique lors de l'étape du code d'initialisation avant PyTorch.

  • Ralentissement de l'entraînement (mesuré par MFU)

Le manque d'outils rend ce type de problème encore plus frustrant que le précédent. En plus d'utiliser Py-Spy, l'inspection de trace de pile et GDB, nous avons également utilisé NVIDIA Nsight et des outils de profilage, dont certains sont difficiles à utiliser dans des environnements hautement distribués.

Malheureusement, il existe de nombreuses raisons pour un ralentissement général ou une vitesse plus lente que le modèle d'utilisation en virgule flottante (MFU) démontré précédemment.

Tout d’abord, il s’avère utile de vérifier plusieurs fois les variables de configuration, de code et d’environnement. Les erreurs que nous avons rencontrées incluent l'exécution d'un mauvais modèle, une mauvaise taille de lot, de mauvais paramètres UFM ou NCCL, des erreurs CUDA_DEVICE_MAX_CONNECTIONS. Cela entraînera des performances sous-optimales.

Nous trouvons également utile de mesurer le MFU instantané (c'est-à-dire par lot) (plutôt que les moyennes lissées ou fenêtrées), car les courbes MFU non lissées aident souvent à diagnostiquer les classes problématiques. Les problèmes qui ralentissent l'entraînement sont les suivants :

  • Démarrez immédiatement l'entraînement à partir d'un MFU très faible (moins d'un dixième de la valeur attendue) et restez stable.

Il s'agit très probablement d'un problème matériel lié à la connexion réseau InfiniBand, tel que le Couche T2 ou T3 Le commutateur plante. Des problèmes matériels entre le GPU et la carte réseau peuvent également provoquer cette situation, pour laquelle dmesg signalera une erreur comme celle-ci : Voies PCIe x16 limitées par…

  • Démarrez immédiatement l'entraînement à partir de 30 % du MFU attendu et restez stable

La raison peut être un L'hôte a des paramètres GDR incorrects (mémoire homologue NVIDIA) ou des variables d'environnement GDR incorrectes.

  • Démarrez immédiatement l'entraînement à partir d'environ 60 à 80 % du MFU attendu et restez stable

La raison la plus courante est une mauvaise qualité ou une défaillance de la liaison InfiniBand, en particulier un seul GPU avec une défaillance liée à la carte réseau InfiniBand, entraînant un routage NCCL Try. trafic via NVLink local et en utilisant la carte réseau sur un autre GPU sur le même hôte. La limitation du processeur peut également être à l'origine de ce problème, qui nécessite d'ajuster les paramètres du BIOS sur certains hôtes.

  • Ralentissement soudain et énorme (10x) lors du traitement de certains lots de données, et cela arrive assez souvent

Il s'agit essentiellement de points de contrôle ou d'évaluation - cela peut être déterminé en vérifiant le nombre d'époques ou d'étapes de vérification. Malheureusement, si vous configurez une alarme automatique lorsque le MFU est anormal, de nombreuses fausses alarmes se produiront.

  • Ralentissement soudain et énorme (10x) lors du traitement de certains lots de données

Cela se produit de manière aléatoire et assez rarement (probablement une fois toutes les 15 minutes) et est entièrement rétabli immédiatement après MFU.

La cause la plus courante semble être que d'autres charges de travail gourmandes en CPU sont planifiées sur un hôte en cours d'exécution. Nous avons constaté que plutôt que de créer des outils de profilage pour identifier des hôtes spécifiques, il était plus facile de surveiller grossièrement le processeur par PID. La cause peut être des problèmes occasionnels de connectivité réseau, tels que des goulots d'étranglement du chargeur de données. Nous avons surveillé les données de métriques pour les chargements de données, les points de contrôle et tout code non NCCL et ajouté des journaux de synchronisation du code Python, qui se sont révélés très fiables.

  • MFU ralentit progressivement pendant le fonctionnement, mais revient à 100 % après chaque redémarrage

Théoriquement, la cause pourrait être une accumulation de chaleur sur le commutateur, mais nous n'avons jamais vu cela se produire. Cependant, à l'aide des profileurs Python et NVIDIA, nous avons déterminé que la cause de la dégradation des performances semble être le garbage collection automatique.

Du bare metal au grand modèle avec 70 milliards de paramètres, voici un tutoriel et des scripts prêts à lemploi

Le débit de débogage diminue

Lors du débogage pour résoudre ces ralentissements, nous avons découvert que le débit était presque voué à baisser périodiquement. À mesure que la formation progresse, ce déclin aura un impact croissant sur l’informatique distribuée. Cela nous a amené à spéculer que la cause de cette chute pourrait être liée à la collecte automatique des déchets - une suspicion que nous avons vérifiée grâce à des analyses et des tests. Lorsque nous avons désactivé le garbage collection automatique et défini le garbage collection uniquement à des intervalles spécifiques sur tous les hôtes, cette « baisse » de débit a disparu.

Nous utilisons FSDP, un algorithme d'entraînement distribué synchrone basé sur ZeRO-3. Lors d'une opération de blocage, un seul processus de travail exécutant le garbage collection peut ralentir tous les autres travailleurs. Si vous disposez de centaines de processus de travail, cela peut entraîner des ralentissements importants.

Les performances sont bonnes au début, puis chutent brusquement (jusqu'à 70 % de celles attendues) et continuent à haute fréquence (toutes les 15 secondes).

Nous avons observé que cela est lié à la "raison de limitation d'horloge" du GPU NVIDIA, qui peut être résolu par NVIDIA DCGM résout ce problème avec les paramètres appropriés. Des problèmes thermiques (température élevée du GPU ou panne/efficacité réduite du ventilateur de refroidissement de la console) ou une panne d'alimentation peuvent être à l'origine de ce problème. De plus, lorsque nous maximisons l'utilisation des 8 GPU et de l'utilisation de 8x NIC InfiniBand ainsi que du CPU/RAM/disque, certains de nos hôtes dotés d'un matériel d'alimentation spécifique ont des problèmes de tension, mais ne les utilisent tous que (généralement uniquement sur Cela ne se produit que pendant le entraînement réel).

Corrélation des problèmes de performances

  • Bonnes performances mais plus de bruit que d'habitude (variation du bruit blanc haute fréquence entre 90 % et 100 % du MFU attendu)

Cela est également lié au matériel InfiniBand, mais il y a généralement un certain degré de dégradation des performances ou de gigue due aux liaisons situées dans les couches supérieures du réseau, plutôt qu'aux hôtes les moins redondants vers la couche T2.

Malheureusement, bon nombre de ces problèmes sont difficiles à identifier sur un hôte spécifique, et les problèmes liés à InfiniBand sont particulièrement difficiles à identifier en raison de la nature sensible à la topologie de la technologie de commutation InfiniBand. InfiniBand semble favoriser les hôtes adjacents dans la conception InfiniBand fat-tree, tandis que UFM peut acheminer les paquets à des vitesses de liaison asymétriques.

Liste de contrôle d'exhaustivité pour les problèmes de débit de débogage

Ce qui suit est un simple résumé/organigramme/liste de contrôle d'exhaustivité pour le débogage des problèmes de débit :

  • Ce système a-t-il fonctionné correctement auparavant ?
  • Quelles modifications avez-vous apportées récemment (telles que la fusion du code, la mise à jour des pilotes) ?
  • L'hôte que vous dirigez est-il en bonne santé ? Tous vos services dépendants fonctionnent-ils correctement, y compris les SaaS tiers, tels que Docker Hub, GitHub, etc. ?
  • Êtes-vous sûr que le code, l'environnement, la configuration, la version, la liste d'hôtes, l'ordre de classement et la graine aléatoire exécutée maintenant sont exactement les mêmes que la dernière fois ? (Si une telle vérification peut être mise en œuvre.)
  • Le problème peut-il être reproduit ? Quel est le rapport entre
  • et d’autres choses ? D'autres procédés ? Tâches planifiées crontab quotidiennes ? Hôte ou indicateur DCGM ou UFM ?
  • Votre outil mesure-t-il correctement ces métriques ?
  • Le problème existe-t-il toujours lors de l'exécution d'une version réduite du code (en utilisant un modèle plus petit, de fausses données, pas de sauvegarde ou de chargement de points de contrôle) ?

Outils d'infrastructure améliorés

Après avoir terminé les étapes ci-dessus, vous serez en mesure d'obtenir de bonnes performances lors de l'entraînement de votre modèle... au moins jusqu'à ce que quelque chose se casse.

Cette section présentera quelques outils et systèmes permettant d'assurer une formation cohérente et stable, tout en nécessitant idéalement le moins d'intervention humaine possible. Comme notre équipe est petite, nous n'avons pas assez de main d'œuvre pour effectuer des réparations manuelles, nous souhaitons donc également automatiser ce processus autant que possible.

Presque tous les problèmes que nous avons rencontrés au cours de ce processus peuvent être attribués à une panne de machine ou de composant réseau. Ces types de pannes sont courants dans les grands clusters. Notre approche consiste donc à désactiver automatiquement la machine et les composants réseau défaillants et à envoyer une demande de réparation.

Panne de machine

Nous avons développé un système qui redémarre automatiquement à partir du point de contrôle le plus récent en cas de crash d'une exécution. Dans ce processus de redémarrage, l'état de chaque machine disponible est d'abord vérifié, puis chaque machine est classée en fonction des résultats du contrôle d'état qu'elle réussit, puis une tentative est effectuée pour redémarrer l'entraînement sur la machine la plus saine.

Défaillance des composants réseau

Toutes les pannes de réseau que nous avons observées étaient détectables par UFM et enregistrées dans le journal des événements UFM. La réponse était donc simple : analysez le journal UFM et prenez les mesures appropriées.

Le système d'événements UFM est très complexe et contient des dizaines de types d'événements. En pratique, cependant, nous avons constaté que seuls quelques événements posaient problème, principalement liés à des défaillances de liaison ou à des techniques d'erreur de symboles élevés. Après avoir identifié ces événements, nous pouvons écrire des scripts pour analyser les journaux d'événements UFM, désactiver les liens et les ports associés aux événements récents, demander des ordres de travail de maintenance pour ces composants réseau et réactiver ces composants une fois la maintenance terminée.

Système de fichiers d'images local

Pour ces formations distribuées à grande échelle, on a découvert depuis longtemps que la vitesse d'échange de données entre le cluster et Ethernet est un goulot d'étranglement majeur. La bande passante d'une connexion Ethernet partagée est d'environ 10 Gbit/s ; elle peut rapidement saturer si des centaines de travailleurs téléchargent simultanément des ensembles de données et modélisent des points de contrôle.

À cette fin, nous avons décidé de créer un système de fichiers local au sein de notre cluster comme miroir du stockage cloud, qui est essentiellement un espace de cache pouvant réduire la quantité de fichiers lus à partir de S3. Pour tenir compte du désabonnement du cluster (c'est-à-dire lorsqu'une machine est désactivée ou remplacée pour des raisons de maintenance), nous disposons de trois copies de chaque fichier et utilisons un hachage cohérent pour répartir uniformément la charge afin de maximiser les performances pendant le désabonnement du cluster. Le cluster disposant d'un espace disque limité, nous avons dû développer des outils pour suivre le cycle de vie des fichiers et purger les fichiers qui n'étaient plus utiles.

Registre Docker distribué local

Nous avons utilisé Kraken, un excellent logiciel open source pour le transfert peer-to-peer d'images Docker. Nous n'avons eu pratiquement aucun problème avec le logiciel, ce qui nous a assez surpris compte tenu de la complexité de nos tâches et de leur mise en œuvre. Adresse de l'outil : https://github.com/uber/kraken

Divers outils de surveillance des performances

Nous avons configuré l'analyseur Torch par défaut et les systèmes Nsight de NVIDIA. Ce dernier nous aide à comprendre le temps exact requis pour les passages avant/arrière et la communication NCCL, et nous aide en outre à déterminer si une taille de modèle et un nombre de travailleurs donnés deviendront un goulot d'étranglement. Cependant, Nsight Systems est un peu difficile à utiliser car il nécessite d'exécuter Docker en mode privilégié, ce qui nécessite de désactiver les contrôles de sécurité liés aux événements de surveillance des performances, et la sauvegarde de sa configuration nécessite souvent l'arrêt de l'ensemble du processus de formation.

De plus, nous avons écrit des outils pour détecter les lots de données d'entraînement lents et comprendre leurs causes possibles. Nous avons trouvé cela utile. L'un des outils les plus utiles surveille la durée de chaque lot et supprime la trace de la pile du travailleur si un lot est trop lent, ce qui facilite la recherche d'hôtes présentant des problèmes matériels ou logiciels mineurs.

Divisez les machines en différents groupes pour localiser les hôtes défectueux

Au cours des premiers mois d'utilisation de ce cluster (lorsque les contrôles de santé n'étaient pas aussi approfondis qu'aujourd'hui), nous avons souvent rencontré cette situation : dans un groupe, un dysfonctionnement s'est produit pendant la formation sur la machine, mais il n'était pas clair quelle machine posait le problème. Pour trouver les hôtes défectueux, nous avons développé des outils qui permettent de diviser facilement un ensemble de machines en différents groupes et d'exécuter des formations plus petites sur chaque groupe de machines.

Par exemple, si une formation sur 48 machines échoue, exécutez une formation plus petite sur 6 groupes de 8 machines chacun, puis exécutez une formation plus petite sur 8 groupes de 6 machines chacun. En règle générale, une seule exécution des deux phases échouera, ce qui nous permet de conclure en toute confiance qu'une machine qui échoue dans les deux phases est défectueuse.

Réflexion et leçons apprises

Dans le processus de mise en place et d'entretien de l'infrastructure, nous avons appris quelques leçons utiles :

  • Une pratique utile consiste à échanger la position de la machine. Au moment de l'exécution, il peut être utile d'utiliser 10 à 20 % de machines en plus que nécessaire afin que la formation puisse être facilement redémarrée en cas de panne de la machine. La configuration d'un réseau de clusters afin que chaque machine soit étroitement connectée à toutes les autres machines nous permet d'utiliser n'importe quel sous-ensemble fonctionnel de ces machines.
  • Il est payant d'écrire des tests et des solutions automatisées pour chaque panne matérielle ou logicielle que vous rencontrez, car chaque problème rencontré lors de la formation se reproduira. De même, pour chaque message d'erreur ambigu, cela vaut la peine d'écrire un outil qui explique mieux l'erreur.
  • La reproductibilité est la clé d’une excellente recherche scientifique. L'un des principes que nous avons adoptés d'emblée était : « Ne changez qu'une chose à la fois », même dans les choses les plus simples.
  • Faites confiance, mais vérifiez aussi. Chaque fois que nous faisons appel à des outils externes ou à de nouvelles personnes (que ce soit à l'intérieur ou à l'extérieur de l'entreprise), nous vérifions ce qu'ils prétendent, surtout si les étapes ultérieures dépendent de ces affirmations.

Résumé

La formation de grands modèles de langage nécessite dès le début une infrastructure complexe. Nous choisissons de nous impliquer profondément dans les détails de la mise en place de notre infrastructure parce que nous pensons qu'il est important de bien comprendre les systèmes que nous exploitons et parce que nous pensons qu'il est plus efficace de le faire.

Maintenant, après avoir suivi ce processus, nous sommes heureux d'avoir adopté cette approche : avoir un contrôle total sur notre infrastructure et la capacité de déboguer facilement à chaque niveau d'abstraction s'est avéré être d'une valeur cruciale. Bien que ce processus ait nécessité beaucoup de supervision et d'itérations, il nous a permis d'acquérir une compréhension approfondie du flux de travail sous-jacent, de créer un ensemble d'outils pour garantir la santé de l'hôte, d'apprendre à automatiser le système pour garantir une formation continue et fluide, et finalement de créer un Ensemble d'infrastructures qui nous permettent de former rapidement et de manière itérative des modèles linguistiques de pointe.

Ce processus de construction d'infrastructures reflète notre méthodologie de base pour rechercher et créer des agents d'IA : explorer les détails,

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn