Cet article est reproduit à partir de Lei Feng.com Si vous devez le réimprimer, veuillez vous rendre sur le site officiel de Lei Feng.com pour demander une autorisation.
Les réseaux de neurones à grande échelle sont l'un des sujets brûlants dans le domaine actuel de l'intelligence artificielle. Alors, comment entraîner de grands modèles ?
Récemment, OpenAI, qui a lancé le modèle de pré-entraînement à grande échelle GPT-3, a publié un article de blog présentant quatre méthodes d'entraînement parallèle permettant d'économiser de la mémoire et basées sur le GPU, qui sont :
Légende : Diverses stratégies parallèles sur le modèle à trois couches, chaque couleur représente un calque et des lignes pointillées séparent les différents GPU.
"La formation parallèle aux données" signifie copier les mêmes paramètres sur plusieurs GPU (souvent appelés "workers") et attribuer différents exemples à chaque GPU pour les traiter simultanément.
Le parallélisme des données nécessite à lui seul que le modèle tienne dans une seule mémoire GPU, mais lorsque vous exploitez plusieurs GPU pour le calcul, le coût est le stockage de plusieurs copies des paramètres. Cela étant dit, il existe cependant des stratégies pour augmenter la RAM effective disponible pour le GPU, comme le déchargement temporaire des paramètres vers la mémoire du CPU entre les utilisations.
À mesure que chaque travailleur parallèle de données met à jour sa copie des paramètres, ils doivent se coordonner les uns avec les autres pour garantir que chaque travailleur continue d'avoir des paramètres similaires. La méthode la plus simple consiste à introduire une « communication bloquante » entre les travailleurs :
Étape 1 : Calculer la pente de chaque travailleur indépendamment
Étape 2 : Faire la moyenne des pentes des différents travailleurs ;
Étape 3 : Calculer les mêmes nouveaux paramètres indépendamment sur chaque travailleur.
L'étape 2 est une moyenne bloquante qui nécessite le transfert d'une grande quantité de données (proportionnelle au nombre de travailleurs multiplié par la taille du paramètre), ce qui peut nuire au débit de la formation. Il existe différents schémas de synchronisation asynchrone qui peuvent éliminer cette perte, mais au détriment de l'efficacité de l'apprentissage, dans la pratique, les gens s'en tiennent généralement aux méthodes synchrones.
Diviser un grand modèle en morceaux de couches consécutives est simple, mais comme il existe des dépendances séquentielles entre les entrées et les sorties d'une couche, il est naïf d'attendre que la sortie de la machine précédente soit utilisée comme entrée. L'exécution de peut entraîner un temps d'inactivité important. Ces blocs de temps d'attente sont appelés « bulles » et constituent des calculs inutiles qui pourraient être effectués par des machines inactives.
Légende : Illustration d'une configuration parallèle de pipeline simple où le modèle est divisé verticalement en 4 partitions. Le travailleur 1 héberge les paramètres du modèle de la couche 1 (la plus proche de l'entrée), tandis que le travailleur 4 héberge la couche 4 (la plus proche de la sortie). "F", "B" et "U" représentent respectivement les opérations avant, arrière et de mise à jour. L'indice indique sur quel travailleur l'opération doit être exécutée. En raison des dépendances séquentielles, les données sont traitées par un seul travailleur à la fois, ce qui entraîne d'importantes « bulles » de temps d'inactivité.
Nous pouvons réutiliser l'idée du parallélisme des données pour réduire le coût de création de bulles de temps en faisant en sorte que chaque travailleur ne traite qu'un sous-ensemble d'éléments de données à la fois, ce qui nous permet de superposer intelligemment les nouveaux calculs avec les temps d'attente. L'idée principale est qu'en divisant un lot en plusieurs micro-lots, chaque micro-lot doit être traité proportionnellement plus rapidement et chaque travailleur commence à travailler dès que le micro-lot suivant devient disponible, accélérant ainsi la mise en œuvre du pipeline. Avec suffisamment de microlots, les travailleurs peuvent être utilisés la plupart du temps, avec un minimum de « bulles » au début et à la fin des étapes. Les gradients sont moyennés sur les microlots et les paramètres ne sont mis à jour qu'une fois tous les microlots terminés.
Le nombre de travailleurs répartis dans un modèle est souvent appelé « profondeur du pipeline ».
Lors de la passe avant, un ouvrier envoie uniquement les sorties de ses blocs de couches (appelés "activations") au travailleur suivant ; lors de la passe arrière, il envoie uniquement les gradients de ces activations au personnel ouvrier précédent ; Il existe un vaste espace de conception quant à la manière d’organiser ces canaux et d’agréger les gradients entre micro-lots. Par exemple, la méthode GPipe fait en sorte que chaque processus de travail avance et recule en continu, puis agrège de manière synchrone les gradients de plusieurs micro-lots à la fin, tandis que PipeDream fait en sorte que chaque travailleur traite alternativement les passes avant et arrière.
Légende : Comparaison des schémas de pipeline GPipe et PipeDream, utilisant 4 micro-lots par lot. Les microlots 1 à 8 correspondent à deux lots de données consécutifs. Le « numéro » dans la figure indique sur quel micro-lot est utilisé et l'indice marque l'ID du travailleur. Notez que PipeDream atteint une plus grande efficacité en effectuant certains calculs à l'aide de paramètres obsolètes.
Pour de nombreux modèles modernes (par exemple Transformer), le goulot d'étranglement informatique consiste à multiplier la matrice de lots d'activation par une matrice de poids importante. La multiplication matricielle peut être considérée comme un produit scalaire entre des paires de lignes et de colonnes ; les produits scalaires peuvent être calculés indépendamment sur différents GPU, ou chaque partie du produit scalaire peut être calculée sur différents GPU et les résultats additionnés. Quelle que soit la stratégie, nous pouvons diviser la matrice de pondération en « fragments » de taille égale, héberger chaque fragment sur un GPU différent et utiliser ce fragment pour calculer la partie pertinente du produit matriciel entier avant de la communiquer pour combiner le résultat.
Un exemple est Megatron-LM, qui parallélise la multiplication matricielle au sein des couches d'auto-attention et MLP du Transformateur. PTD-P utilise le parallélisme du tenseur, des données et du pipeline, et sa planification de pipeline alloue plusieurs couches discrètes à chaque appareil pour réduire la perte de bulles au détriment d'une communication réseau accrue.
Parfois, les entrées du réseau peuvent être parallélisées dans plusieurs dimensions, avec un degré élevé de calcul parallèle par rapport à la communication croisée. Le parallélisme de séquence est l'idée selon laquelle une séquence d'entrée est divisée dans le temps en plusieurs sous-exemples, réduisant proportionnellement la consommation maximale de mémoire en permettant au calcul de continuer sur des exemples plus fins.
4Un exemple d'approche consiste à disposer de plusieurs ensembles de poids, et le réseau peut sélectionner l'ensemble de poids à utiliser au moment de l'inférence via un mécanisme de déclenchement, qui permet plus de paramètres sans augmenter le coût de calcul. Chaque ensemble de poids est appelé un « expert », et l’espoir est que le réseau apprendra à attribuer des calculs et des compétences spécialisés à chaque expert. Différents experts peuvent héberger différents GPU, offrant ainsi un moyen clair d'augmenter le nombre de GPU utilisés pour un modèle.
Légende : Le réseau sécurisé ne sélectionne que 2 experts sur n.
GShard étend les paramètres de MoE Transformer à 600 milliards de paramètres, où seule la couche MoE est répartie sur plusieurs appareils TPU et les autres couches sont entièrement répliquées. Switch Transformer adapte la taille du modèle à des milliards de paramètres avec une parcimonie plus élevée en acheminant une entrée vers un seul expert.
Il existe de nombreuses autres stratégies informatiques qui peuvent rendre plus facile la formation de réseaux neuronaux de plus en plus grands. Par exemple :
Pour calculer les dégradés, les activations d'origine doivent être enregistrées, ce qui consomme beaucoup de RAM de l'appareil. Le point de contrôle (également appelé recalcul d'activation) stocke tout sous-ensemble d'activations et, lors d'une passe arrière, recalcule les activations intermédiaires dans le temps, économisant ainsi une mémoire importante au prix de calcul d'au plus une passe avant complète supplémentaire. On peut également continuellement équilibrer les coûts de calcul et de mémoire en activant sélectivement le recalcul, qui vérifie un sous-ensemble d'activations pour lesquelles le coût de stockage est relativement élevé mais le coût de calcul est faible.
L'entraînement de précision mixte utilise des nombres de précision inférieure (le plus souvent FP16) pour entraîner le modèle. Les accélérateurs modernes peuvent atteindre un nombre de FLOP plus élevé en utilisant des nombres de précision inférieure et également économiser la RAM de l'appareil. Avec des soins appropriés, le modèle résultant peut être produit pratiquement sans perte de précision.
Le déchargement consiste à décharger temporairement les données inutilisées sur le processeur ou entre différents appareils, et à les relire si nécessaire. Une implémentation naïve ralentira considérablement la formation, mais une implémentation sophistiquée pré-extraitra les données afin que l'appareil n'ait jamais à attendre. Une implémentation de cette idée est ZeRO, qui partitionne les paramètres, les gradients et l'état de l'optimiseur sur tout le matériel disponible et les réifie selon les besoins.
Des optimiseurs efficaces en mémoire ont été proposés pour réduire l'empreinte mémoire de l'état d'exécution maintenu par l'optimiseur, comme Adafactor.
La compression peut également être utilisée pour stocker des résultats intermédiaires dans le réseau. Par exemple, Gist compresse les activations enregistrées pour les passes arrière ; DALL-E compresse les dégradés avant de les synchroniser.
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!