Ce partage analysera systématiquement les principaux goulots d'étranglement des performances dans le processus de formation des modèles d'IA, ainsi que les principales solutions d'accélération et principes techniques actuels pour ces goulots d'étranglement, et présentera quelques résultats pratiques de Baidu Intelligent Cloud à cet égard.
Le partage d'aujourd'hui comprend principalement trois parties :
Premièrement, nous présenterons pourquoi nous devons accélérer la formation en IA, c'est-à-dire quel est le contexte général et le point de départ ;
Dans la deuxième partie, nous analyserons systématiquement les possibilités ; le processus de formation réel Les problèmes de goulot d'étranglement des performances qui seront rencontrés, puis présenteront les principales solutions d'accélération actuelles pour résoudre ces problèmes
La troisième partie présente l'effet pratique de la suite d'accélération de la formation IA de la plateforme Baidu Baige, AIAK-Training, pour accélérer certains modèles ; entraînement.
Dans un système d'IA, le processus d'un modèle de la production à l'application comprend généralement deux étapes : la formation hors ligne et le déploiement d'inférence.
La phase de formation hors ligne est le processus de génération d'un modèle. Les utilisateurs doivent préparer les ensembles de données et les algorithmes de réseau neuronal nécessaires à la formation du modèle en fonction de leurs propres scénarios de tâches.
L'algorithme peut être compris comme une fonction mathématique non convexe très complexe, qui comprend de nombreuses variables et paramètres. Le processus de formation du modèle consiste en fait à apprendre les paramètres du modèle de réseau neuronal.
Après le début de la formation du modèle, les données seront lues, puis envoyées au modèle pour un calcul direct, et l'erreur avec la valeur réelle sera calculée. Effectuez ensuite le calcul inverse pour obtenir le gradient des paramètres, et enfin mettez à jour les paramètres. La formation implique plusieurs séries d’itérations de données.
Une fois la formation terminée, nous enregistrerons le modèle formé, puis déploierons le modèle en ligne, accepterons la saisie réelle de l'utilisateur et compléterons l'inférence par le calcul avancé.
Par conséquent, qu'il s'agisse de formation ou d'inférence, le cœur est le calcul des données. Afin d'accélérer l'efficacité informatique, la formation et l'inférence sont généralement effectuées via des puces d'accélération hétérogènes telles que les GPU.
De plus, à en juger par l'historique de développement des modèles d'apprentissage profond, afin de continuer à dépasser la limite supérieure de précision du modèle, le nombre de paramètres du modèle augmente en fait rapidement. Cependant, un plus grand nombre de paramètres entraînera une plus grande complexité de calcul.
Le côté gauche de la figure ci-dessous est tiré d'un document public. De ce résumé, on voit qu'avant 2010, le montant de calcul du modèle a doublé en 20 mois environ. De 2010 à 2015, les calculs des modèles conventionnels ont doublé tous les 5 à 6 mois. Après 2015, la tendance à la formation de grands modèles est apparue et la quantité de calcul a augmenté de 10 à 100 fois.
La formation de modèles nécessite de plus en plus de puissance de calcul et d'infrastructure. La formation nécessite plus de puissance de calcul et prend plus de temps, ce qui entraîne également des coûts de ressources plus élevés. Nous répertorions ici les données sur les coûts divulguées dans certains articles ou études, ce qui montre que le coût de la formation des modèles est très élevé.
Par conséquent, comment mener une formation de modèle de manière stable et comment réduire continuellement les coûts et augmenter l'efficacité sont en réalité cruciaux.
Dans ce contexte, Baidu Intelligent Cloud a lancé Baidu Baige · Plateforme informatique hétérogène d'IA, dans le but de fournir des solutions logicielles et matérielles intégrées pour les scénarios d'IA. Grâce à la pile technologique à quatre couches comprenant l'informatique IA, le stockage IA, l'accélération IA et les conteneurs IA, il répond aux besoins des scénarios commerciaux de niveau supérieur.
Lorsque nous pensons à l'accélération des performances, la première chose qui nous vient peut-être à l'esprit est d'utiliser un meilleur matériel.
Cela apportera une certaine amélioration des performances, mais dans la plupart des cas, la puissance de calcul du matériel peut ne pas être pleinement utilisée. La raison principale est que l'efficacité d'exécution du code de formation n'a pas été ajustée à un état optimal ou meilleur.
Par conséquent, lorsque nous décidons d'utiliser un certain algorithme de modèle, afin d'obtenir une meilleure efficacité des ressources et de la formation, nous devons l'optimiser consciemment. Cependant, il existe également de nombreux défis techniques :
Ces défis ont grandement affecté le réglage des performances de formation des modèles, nous avons donc lancé la suite d'accélération AIAK-Training, dans l'espoir de réduire les coûts d'optimisation grâce à des interfaces abstraites et faciles à utiliser, et d'utiliser pleinement les méthodes d'optimisation collaborative logicielle et matérielle. Accélérez les performances de formation des modèles des clients sur Baidu Smart Cloud.
Avant de présenter les effets spécifiques de l'AIAK-Training, nous présentons d'abord les idées techniques clés et les principes de solution sous le thème de l'accélération de la formation.
Étant donné que l'optimisation de la formation des modèles elle-même est un travail complet de logiciel et de matériel et que la pile technologique est relativement complexe, le contenu d'aujourd'hui ne sera certainement pas en mesure de couvrir tous les détails. Nous ferons de notre mieux pour couvrir les idées clés.
Tout d’abord, jetons un coup d’œil à la solution actuelle de formation de modèles. Au cours de la phase de développement précédente, il y a eu deux changements clés dans les solutions de formation de modèles. L'un est le passage de la formation à carte unique à la formation distribuée, et l'autre est le passage de la formation parallèle de données à la formation parallèle hybride multidimensionnelle. Les principaux points déterminants ici sont la quantité de données d’entraînement et la quantité de paramètres du modèle.
Le plus largement utilisé ici est le parallélisme des données. Dans le schéma de données parallèles, l'ensemble de données est divisé de manière égale en plusieurs parties, puis le modèle complet est enregistré sur chaque carte et les sous-ensembles de données divisés sont traités indépendamment et en parallèle.
Lorsque le nombre de paramètres du modèle est suffisamment grand, par exemple, le nombre de paramètres atteint des dizaines ou des centaines de milliards, et une seule carte ne peut pas s'adapter au modèle complet. Là encore, le parallélisme de modèle ou les solutions parallèles hybrides qui utilisent. le parallélisme des données et le parallélisme des modèles apparaissent.
Le parallélisme du modèle divisera le modèle en différentes cartes et placera une partie du modèle sur chaque carte. Ici, le Tensor est subdivisé selon les différentes méthodes de division, telles que la division intra-couche ou la division inter-couche. approches parallèles aux pipelines.
Étant donné que dans la formation générale des modèles, le parallélisme des données est davantage utilisé, nous nous concentrerons sur le parallélisme des données comme exemple pour présenter les idées d'optimisation des performances.
Nous comprenons d'abord la surcharge de performances existant dans le processus de formation à carte unique du point de vue global des logiciels et du matériel.
Le côté gauche de l'image ci-dessous représente notre processus de formation d'un point de vue logiciel. Le processus de formation sur une seule carte comprend principalement la lecture des données, le prétraitement des données, la sortie du calcul direct et le calcul des pertes, le calcul inverse selon la fonction de perte pour obtenir le gradient de chaque paramètre de couche, et enfin la mise à jour des paramètres du modèle en fonction du gradient. Continuez ce processus jusqu'à ce que la formation converge.
Le côté droit de l'image ci-dessous est un diagramme simplifié de la topologie matérielle des nœuds. Le sommet est le stockage des données, qui peut être un stockage local ou un stockage réseau. Ensuite, il y a le CPU et la mémoire. Il y a 8 cartes GPU connectées au CPU via plusieurs commutateurs PCIe, numérotés de 0 à 7, et les 8 cartes sont interconnectées via NVSwitch. Différentes instances informatiques ont des topologies matérielles différentes.
Par conséquent, du point de vue d'une seule carte, il y a principalement des frais généraux en termes d'E/S, de prétraitement CPU, de copie de données entre CPU et GPU, de calcul GPU, etc.
Ensuite, regardons le processus de parallélisme des données.
Le côté gauche de l'image ci-dessous est toujours le processus principal de formation, et le côté droit montre la topologie matérielle d'un cluster de formation à 3 machines et 24 cartes. Les 3 machines sont interconnectées via le réseau.
Nous avons également introduit dans la partie précédente que dans le parallélisme des données, chaque appareil effectue les processus de calcul avant et arrière en parallèle et indépendamment. Par conséquent, chaque processus de formation rencontrera également le problème de surcharge de performances dans la formation à carte unique mentionné précédemment.
Afin de garantir que le parallélisme des données est mathématiquement équivalent à la formation sur une seule carte, il est nécessaire de s'assurer que les paramètres du modèle de chaque carte sont toujours cohérents pendant le processus d'itération. D'une part, il est nécessaire de rendre cohérent l'état d'initialisation des paramètres du modèle de chaque carte GPU. Cela se fait généralement en diffusant l'état des paramètres de la première carte aux autres cartes avant le début de l'entraînement.
Pendant l'entraînement, en raison des différentes données traitées par chaque appareil, la valeur de perte du modèle obtenue par calcul direct est également différente. Par conséquent, il est également nécessaire de faire la moyenne du gradient après que le gradient ait été calculé en arrière par chaque appareil pour faire la moyenne du modèle. les paramètres sont mis à jour avec la valeur de gradient finale pour garantir que les paramètres du modèle de chaque carte restent cohérents pendant le processus d'itération.
La moyenne des gradients implique le processus de communication, y compris la communication entre les cartes au sein des nœuds, ainsi que la surcharge de communication réseau entre les nœuds. La communication comprend ici la communication synchrone et la communication asynchrone. Cependant, afin d'assurer la convergence de la formation du modèle, la solution de communication synchrone est généralement utilisée et des travaux d'optimisation ultérieurs sont également effectués sur la base de la communication synchrone.
Il ressort de ce qui précède que par rapport à la formation sur une seule carte, le parallélisme des données ajoute principalement une surcharge de communication supplémentaire.
Grâce à l'analyse ci-dessus, nous savons que l'accélération de la formation à l'IA n'est pas seulement un certain aspect du travail, mais nécessite une prise en compte approfondie des dimensions du système telles que le chargement des données, le calcul du modèle et la communication distribuée. Le chargement des données mentionné ici inclut les E/S de données, le prétraitement, la copie de la mémoire et d'autres processus.
Dans une pratique d'optimisation spécifique, étant donné un modèle à optimiser, accélérer la formation du modèle signifie améliorer continuellement le débit global de la formation (le nombre d'échantillons pouvant être formés par seconde). Dans ce processus, nous pouvons généralement d'abord analyser le débit de formation d'une seule carte. Lorsque le débit de formation d'une seule carte s'améliore, nous pouvons ensuite envisager de passer d'une seule carte à plusieurs cartes pour voir comment améliorer le taux d'accélération de la formation. plusieurs cartes.
Tout d'abord, l'optimisation de la formation sur une seule carte, l'objectif ultime de l'optimisation est de consacrer tout son temps au calcul GPU, et le taux d'utilisation de l'accélérateur est de 100 %. Bien entendu, il est difficile d’atteindre complètement cet état dans la pratique, mais nous pouvons utiliser cet indicateur pour guider ou mesurer notre travail.
La clé de l'optimisation des performances d'une seule carte comprend deux parties :
Puis passez d'une seule carte à plusieurs cartes, l'objectif est de savoir comment atteindre un rapport d'accélération linéaire. L'indicateur du taux d'accélération linéaire signifie simplement si les performances d'entraînement sont deux fois supérieures à celles d'une seule carte lorsque l'entraînement est étendu de 1 carte à 2 cartes.
L'essentiel ici est d'optimiser l'efficacité de la communication distribuée. D'une part, il s'agit de l'optimisation du niveau matériel. D'autre part, dans la communication réelle, il est nécessaire de réfléchir à la manière de faire bon usage de la bande passante. ressources du réseau, ou si le processus de communication peut être caché, etc.
Ci-dessous, nous développerons ces aspects en détail.
Le premier est l'optimisation du chargement des données.
Après avoir instancié un dataloader, nous continuerons à itérer le dataloader pour lire un lot de données pour la formation du modèle.
Si aucune optimisation n'est effectuée ici, comme le montre la partie supérieure de la figure ci-dessous, le processus de chargement des données de chaque lot et le processus de formation du modèle de chaque lot sont en fait effectués en série. Du point de vue du GPU, il y aura des écarts de calcul causés par le chargement des données, et il y aura une perte de temps en ressources informatiques.
En plus d'utiliser un meilleur matériel pour améliorer directement l'efficacité de la lecture des données, comme mentionné précédemment, comment pouvons-nous l'optimiser autrement ?
En fait, pendant le processus de formation de l'IA, il existe deux caractéristiques clés dans l'accès aux données :
Tout d'abord, nous devons faire bon usage des solutions d'optimisation existantes dans dataloader. Tout d'abord, définir raisonnablement les hyperparamètres num_workers et lire les données via plusieurs processus. Cette étape peut réaliser la prélecture des données du système de stockage vers. la mémoire hôte. La seconde consiste à copier de la mémoire hôte vers la mémoire GPU, ce qui peut être accéléré grâce au mécanisme de mémoire épinglée.
Présentons brièvement le principe principal de l'accélération de la mémoire épinglée : il existe deux types de données en mémoire : la mémoire paginable et la mémoire épinglée. Les données de la mémoire paginable peuvent être transférées sur le disque. Dans ce cas, lors de l'exécution de H2D, il peut être nécessaire de lire d'abord du disque vers la mémoire, puis de copier de la mémoire vers la mémoire vidéo. De plus, lors de la copie de données de mémoire paginable vers la mémoire GPU, vous devez d'abord créer une mémoire tampon temporaire épinglée, copier les données de la mémoire paginable vers la mémoire épinglée, puis les transférer vers le GPU, ce qui nécessite également des opérations de transfert de données supplémentaires.
Cependant, lorsque nous avons activé la solution ci-dessus, nous avons uniquement implémenté la prélecture du système de stockage vers la mémoire hôte, accélérant ainsi la vitesse de copie des données de l'hôte vers l'appareil. Cependant, la copie de la mémoire de l'hôte vers l'appareil et le noyau de calcul réel sont toujours exécutés en série sur le GPU, c'est-à-dire qu'il existe encore un petit intervalle de temps sur le GPU.
AIAK a apporté d'autres optimisations pour résoudre ce problème, ce qui permet de réaliser le chevauchement du H2D et du calcul direct.
Dans un scénario de données parallèles, il faut prêter attention à la répartition égale des données.
Si les données allouées à chaque processus de formation sont déséquilibrées, la quantité de calcul sera différente, ce qui entraînera que le temps d'achèvement du calcul avant et du calcul inverse de chaque processus soit différent. Ensuite, le processus qui termine le calcul en premier sera différent. différent dans le processus inverse. Il entrera d'abord dans le lien de communication dégradé, mais comme la communication Allreduce est une opération de communication synchrone, tous les processus doivent démarrer et se terminer en même temps. Par conséquent, le processus qui démarre la communication en premier attendra tous les autres. processus pour lancer également AllReduce avant de pouvoir terminer l’opération de communication ensemble. Il y aura des problèmes d'inactivité des ressources causés par différentes vitesses.
Afin de résoudre ce problème, chaque processus doit utiliser la même taille de lot pour lire les données, et la quantité de données dans chaque lot doit être équilibrée. Les données d'image sont généralement d'une taille fixe pour la formation, tandis que les modèles NLP doivent traiter des instructions de longueur variable, ce qui peut nécessiter un traitement spécial. Par exemple, les données peuvent être complétées à la même longueur, ou distribuées uniformément en triant les longueurs d'échantillon, etc. .
Ce qui suit présente l'optimisation de l'efficacité informatique.
Le calcul inclut les mises à jour avant, arrière et des paramètres. L'objectif de l'optimisation des calculs est d'utiliser pleinement la puissance de calcul d'un matériel hétérogène. La situation idéale est de permettre aux performances de calcul réelles de la puce GPU d'atteindre le sommet théorique.
Analysons-le d'abord du point de vue d'un seul opérateur. Lorsque nous nous préparons à effectuer une opération de calcul sur le GPU, le processus simplifié comporte quatre étapes.
Lors du passage d'un opérateur à une formation complète de modèle, étant donné que de nombreux noyaux de calcul doivent être exécutés en continu, il y aura de nombreux problèmes d'écart de calcul entre les calculs du noyau causés par le lancement du noyau et la lecture et l'écriture des résultats intermédiaires.
Il ressort de ce qui précède que l'optimisation de l'efficacité du calcul du modèle nécessite une prise en compte approfondie de l'optimisation de l'accès à la mémoire, de l'optimisation des calculs et d'autres optimisations des frais généraux.
L'optimisation de l'accès à la mémoire considère principalement comment réduire le temps de transfert de données entre la mémoire vidéo et l'unité de calcul. Du point de vue de la mise en œuvre par l'opérateur, il est nécessaire de faire bon usage de l'architecture hiérarchique de stockage GPU, comme déplacer les données vers un stockage plus rapide tel que la mémoire partagée, réduire l'accès à la mémoire globale, économisant ainsi le temps d'accès à la mémoire. Ou faites un bon chevauchement entre les instructions de calcul et les instructions d'accès à la mémoire pour améliorer le taux d'accès à la mémoire de calcul. Lors de l'extension d'un seul opérateur à plusieurs opérateurs, vous devez également réfléchir à la manière de réduire la lecture et l'écriture des résultats intermédiaires. Ce problème peut généralement être optimisé grâce à la fusion d'opérateurs.Le premier est la fusion des opérateurs. Lorsqu'un opérateur est exécuté sur le GPU sous-jacent, un ou plusieurs lancements de noyau seront lancés, et les données interactives entre les noyaux doivent également passer par la mémoire vidéo. La fusion de l'opérateur consiste à fusionner plusieurs noyaux GPU en un seul grand noyau pour une initiation et une exécution unifiées. exécution.
Le nombre d'opérateurs à exécuter étant réduit, la surcharge de planification et d'initiation du noyau peut être réduite.Comment implémenter spécifiquement la fusion d'opérateurs ?
Un moyen d'analyser les opérations inefficaces dans le modèle, à l'aide d'opérateurs de fusion manuscrits basés sur l'expérience d'experts. Concernant le GPU, il s'agit principalement de recherche et développement des opérateurs CUDA, et il y a ici un certain seuil. AIAK-Training fournira une mise en œuvre efficace et optimisée des opérateurs en fonction des structures de modèles typiques ou des besoins des clients.
Une autre façon consiste à compiler et à optimiser la solution. L'optimisation informatique est effectuée par compilation et le code est généré automatiquement, réduisant ainsi le coût de l'optimisation manuelle sur différents matériels. Cependant, de nombreuses solutions de compilation actuelles sont davantage optimisées pour l’inférence, et les solutions de formation sont encore en train d’évoluer rapidement. Cependant, du point de vue de la performance ultime, le travail des opérateurs de fusion d'écriture manuscrite sera toujours indissociable à l'avenir.
Ce qui suit présente quelques cas pratiques de fusion d'opérateurs. Le premier est l’optimisation des structures de réseau modèles typiques.
La figure ci-dessous montre notre optimisation de fusion de calculs pour le module principal WindowAttention dans le modèle SwinTransformer.
Structure WindowAttention, la formule de fonctionnement de base est présentée dans la figure ci-dessous. Pendant le processus de calcul, 7 noyaux de calcul doivent être exécutés en séquence. Couplé à quelques opérations de remodelage et d'autres conversions, un total de 10 noyaux doivent être lancés. Grâce à l'analyse des performances, il a été constaté que la surcharge de redondance d'intervalle du lancement du noyau représente plus de 80 % du temps de bout en bout pendant le processus d'exécution réel, ce qui entraîne un grand espace d'optimisation pour ce module.
En fusionnant ces noyaux en un seul, le temps d'exécution de l'ensemble du module est réduit de 392 microsecondes à 13 microsecondes, et un seul opérateur est accéléré de 30 fois. L'efficacité de la formation de l'ensemble du modèle a été accélérée de plus de 20 % de bout en bout.
L'idée centrale decette optimisation comporte principalement trois points :
L'image ci-dessous est un exemple d'opérations de fusion de données, qui est une optimisation des opérations de compression de coordonnées dans le modèle FCOS3D.
Grâce à l'analyse des performances, nous avons constaté qu'il existe un grand nombre de lacunes du GPU lors de cette opération et que l'utilisation du GPU est faible. La fonction principale de cette opération est de compresser le Tensor 3D en Tensor 2D en fonction de l'index. Dans l'implémentation native, l'index est d'abord généré du côté hôte, puis la copie H2D est effectuée et enfin la compression Tensor est terminée, ce qui entraînera une copie supplémentaire et une surcharge d'attente.
À cette fin, nous avons réimplémenté cette partie de l'opération. L'idée principale est de migrer toutes les opérations vers le GPU, de terminer la génération d'index et la compression de Tensor directement sur le GPU, de réduire la participation du CPU et d'éviter les CPU inutiles. -Copie de mémoire GPU entre.
Le temps d'exécution d'un seul opérateur est réduit de 9,69 millisecondes à 32 microsecondes, soit une accélération de 300 fois, et la formation de bout en bout de l'ensemble du modèle est améliorée de plus de 10 %.
Nous introduisons ensuite une autre idée d'optimisation du calcul, qui consiste à améliorer le parallélisme du calcul et à exploiter pleinement les avantages du calcul parallèle GPU. Nous la présenterons également à l'aide de quelques cas pratiques. .
Nous avons constaté que dans certains modèles, certaines opérations sont effectuées en série. Par exemple, dans certains modèles de détection de cible, pendant le processus de calcul des pertes, certaines opérations ne sont pas effectuées en fonction d'un lot, mais en boucle for pour chaque image ou échantillon. Dans ce cas, lorsque nous augmentons la taille du lot, car la sérialisation ici peut ne pas être effectuée. atteindre la performance souhaitée.
Prenons l'exemple de l'opération SimOTA dans YOLOv7. Dans l'implémentation native, chaque image d'un lot est parcourue via une boucle for, puis l'attribution d'étiquette SimOTA est effectuée pour la gtbox de l'image. Cette implémentation en série entraîne une utilisation très inefficace du GPU pour cette partie de l'opération.
Il n'y a aucune dépendance entre les données lors du traitement de chaque image. Par conséquent, l'une des tâches que nous avons accomplies est de transformer le calcul série en calcul parallèle par lots et d'accélérer l'efficacité de cette partie du calcul en parallélisant l'attribution d'étiquettes pour un lot de données.
Au final, le temps de fonctionnement de SimOTA est passé de 384 millisecondes à 69 millisecondes, l'efficacité de calcul a augmenté de 5,5 fois et l'efficacité de formation de bout en bout de l'ensemble du modèle a augmenté de plus de 18 %.
Il existe d'autres scénarios similaires pendant le processus de formation du modèle, tels que la mise à jour des paramètres. Lorsque les paramètres sont mis à jour, chaque paramètre est parcouru dans une boucle par défaut, puis chaque paramètre démarrera un noyau Cuda pour la mise à jour des paramètres, puis l'exécutera dans l'ordre.
Compte tenu de cette situation, AIAK a également ajouté l'optimisation de FusedOptimizer En fusionnant l'opérateur de mise à jour des paramètres, il peut mettre à jour les paramètres par lots et réduire considérablement le nombre de lancements de noyau.
Ce qui suit présente une autre méthode d'optimisation CUDA Graph, principalement pour réduire la surcharge du CPU Launch Kernel.
CUDA Graph est une fonctionnalité introduite dans la version CUDA 10. Il peut encapsuler une série de noyaux CUDA dans une seule unité. Plusieurs noyaux GPU peuvent être lancés via une seule opération de lancement du processeur, réduisant ainsi la surcharge du noyau de lancement du processeur.
Comme le montre la figure ci-dessous, par défaut, le processeur doit lancer plusieurs noyaux en séquence. Si le temps de calcul du noyau est relativement court, l'écart de lancement entre les noyaux peut devenir un goulot d'étranglement en termes de performances. Avec CUDA Graph, vous n'avez besoin que de consacrer un peu de temps supplémentaire à la création du graphique, et l'émission ultérieure du graphique peut réduire considérablement l'écart entre les noyaux lors de l'exécution réelle.
Maintenant, de nombreux frameworks ont également ajouté la prise en charge de CUDA Graph, permettant à K d'activer cette fonction en insérant du code. Cependant, il existe certaines restrictions d'utilisation, telles que la non-prise en charge de la forme dynamique, la non-prise en charge du flux de contrôle dynamique, l'impossibilité de capturer les opérations du processeur pendant le processus, etc. Vous pouvez essayer d'utiliser cette capacité d'optimisation en fonction de la situation du modèle.
Ce qui suit est la dernière méthode d'optimisation de calcul pour utiliser pleinement l'unité de calcul Tensor Core.
Un GPU contient généralement plusieurs SM, et chaque SM comprend des cœurs de calcul de différents types de données, ainsi que diverses ressources de stockage. Sur le côté gauche de la figure ci-dessous se trouve un diagramme schématique d'un NVIDIA A100 SM. Un SM contient 64 cœurs FP32 CUDA et 4 cœurs Tensor.
Pendant la formation du modèle, les calculs FP32 CUDA Core sont principalement utilisés par défaut, et Tensor Core est une unité d'exécution matérielle spéciale introduite à partir de la série de GPU Volta. Elle est principalement utilisée pour accélérer l'efficacité des opérations matricielles ou de convolution.
Par rapport au FP32 CUDA Core, qui ne peut effectuer des calculs que sur deux scalaires à la fois, Tensor Core peut effectuer des calculs sur deux matrices à la fois, de sorte que le débit de calcul de Tensor Core est bien supérieur à celui du FP32 CUDA Core.
Dans A100, Tensor Core prend en charge une variété de types de données à virgule flottante Pour la formation en deep learning, cela peut impliquer les modes FP16, BF16 et TF32.
TF32 est principalement utilisé dans des scénarios de formation en simple précision. Par rapport à la formation FP32, tout en conservant les mêmes exigences de bande passante d'accès à la mémoire, le débit de calcul théorique est multiplié par 8.
FP16/BF16 est principalement utilisé dans des scénarios d'entraînement de précision mixtes. Par rapport à l'entraînement FP32, les besoins d'accès à la mémoire sont réduits de moitié et le débit de calcul théorique est augmenté de 16 fois.
En utilisant Tensor Core, vous pouvez utiliser l'interface cublas ou cuda sous-jacente pour la programmation. Pour les développeurs d'algorithmes, il est plus simple d'utiliser la solution de formation TF32 ou de formation de précision mixte fournie dans le framework.
Le premier est le mode d'entraînement TF32, TF32 a été introduit par Ampère.
TF32 a 8 bits d'exposant, 10 bits de mantisse et 1 bit de signe dans l'expression des nombres à virgule flottante. Le bit d'exposant est le même que celui du FP32, c'est-à-dire que la plage de représentation des données est la même, mais le bit de la mantisse est inférieur au FP32 et identique au FP16.
Il convient de noter que TF32 n'est pas un type numérique ouvert, mais un mode de calcul de Tensor Core, c'est-à-dire que les utilisateurs ne peuvent pas créer directement un nombre à virgule flottante de type TF32.
Lorsque TF32 est activé, Tensor Core convertira automatiquement FP32 en TF32 lors du calcul de matrices ou d'opérations de convolution. Une fois le calcul terminé, le type de données de sortie est toujours le type FP32.
La formation TF32 est activée par défaut dans certaines versions du framework, il peut être nécessaire de l'activer manuellement via des variables d'environnement ou la configuration des paramètres. Pour plus de détails, veuillez vous référer au manuel d'utilisation du framework.
Cependant, étant donné que la plage de précision du TF32 est réduite par rapport au FP32, vous devez faire attention à l'impact sur la précision de convergence du modèle lors de l'entraînement réel.
L'entraînement de précision mixte fait référence à l'entraînement utilisant la précision mixte FP32 et FP16 tout en minimisant la perte de précision du modèle.
Les principaux avantages de l'entraînement de précision mixte sont les suivants : par rapport à l'entraînement FP32, les besoins en mémoire sont réduits et des réseaux plus grands peuvent être entraînés ou des lots plus grands peuvent être utilisés. Utiliser moins de bande passante mémoire peut accélérer la transmission des données, et les calculs de demi-précision peuvent également rendre les opérations mathématiques plus rapides.
Cependant, comme la plage des bits d'exposant et des bits de mantisse du FP16 est plus petite que celle du FP32, la plage de représentation numérique et la précision sera réduite. En utilisation réelle, des problèmes de dépassement numérique peuvent survenir en raison de la plage de représentation étroite, ou des erreurs d'arrondi peuvent survenir en raison d'une précision insuffisante.
Afin d'optimiser des problèmes similaires, il y a plusieurs tâches techniques clés dans la solution d'entraînement de précision mixte :
Actuellement, tous les frameworks prennent en charge la précision mixte. Le composant AIAK-Training introduit en outre le mode de précision mixte AMP O2 dans NVIDIA Apex, qui transférera de manière plus agressive davantage de calculs vers FP16 pour accélérer la formation. Par rapport au mode O1 par défaut, la vitesse sera encore améliorée, mais la précision peut être affectée et doit être vérifiée avec des modèles spécifiques.
AIAK-Training fournit une méthode d'utilisation compatible avec l'utilisation native de l'ampli torche, ce qui facilite l'activation du mode O2.
Introduisons l’optimisation de la communication C’est aussi un très gros sujet et implique beaucoup de contenu.
Comme mentionné précédemment, la communication est principalement introduite dans la formation distribuée, car le passage d'une seule carte à plusieurs cartes nécessite une certaine synchronisation des données entre plusieurs cartes. Ces opérations de synchronisation sont mises en œuvre via la communication.
La figure suivante répertorie une architecture globale pour l'optimisation de la communication :
Examinons d'abord les idées d'optimisation au niveau de la stratégie de communication. La première est l'optimisation cachée de la communication.
Dans le parallélisme des données, la communication de synchronisation du gradient est effectuée pendant le processus inverse de l'entraînement. Une fois le gradient calculé dans le sens inverse, la moyenne du gradient global peut être effectuée.
Si aucune optimisation du mécanisme n'est effectuée, le calcul inverse et la communication seront effectués en série, et il y aura un intervalle de temps dans le calcul.
Comme il n'y a aucune dépendance de données entre la communication du gradient précédent et le calcul du gradient suivant pendant le processus inverse, la communication du gradient précédent et le calcul du gradient suivant peuvent être parallélisés pour réduire la consommation de temps des deux. . Se chevauchent pour masquer une partie du temps de communication.
Au niveau de la mise en œuvre, les opérateurs de communication et de calcul sont généralement implémentés en les planifiant sur différents flux cuda. Les opérateurs de communication sont planifiés sur le flux de communication, et les opérateurs de calcul sont planifiés sur le flux de calcul. . exécution, obtenant ainsi un chevauchement parallèle de la communication du gradient et du calcul dans le sens inverse.
Actuellement, cette capacité d'optimisation est activée par défaut dans le framework.
Deuxièmement, l'optimisation de l'intégration de la communication.
Par défaut, chaque dégradé du modèle doit initier une opération de communication. Si la taille d'un seul gradient est relativement petite, alors lorsque de petits paquets de données sont réellement communiqués, l'utilisation de la bande passante du réseau sera très faible et les performances de communication seront médiocres.
La fusion de communication consiste à fusionner plusieurs gradients pour une seule communication. D'après l'analyse du modèle de surcharge de communication, elle peut non seulement améliorer l'utilisation de la bande passante, mais également réduire le délai d'initialisation de la communication.
De nos jours, de nombreux frameworks de formation distribués prennent également en charge la stratégie de fusion de gradient par défaut. Certaines implémentations nécessitent d'abord une négociation de gradient pour déterminer la séquence de communication, tandis que d'autres utilisent directement le bucketing de communication statique.
Bien que le framework prenne en charge la fusion de communication par défaut, la taille de la fusion par gradient peut généralement être configurée via des paramètres. Les utilisateurs peuvent ajuster le seuil de fusion approprié en fonction des besoins de l'environnement physique et du modèle, et devraient pouvoir obtenir de meilleurs avantages.
Si vous êtes dans un scénario de formation avec une faible bande passante réseau, comme un environnement TCP à faible bande passante, le retard dans la synchronisation du gradient peut devenir le principal goulot d'étranglement des performances de la formation.
Pour optimiser la réduction de la fréquence de communication, l'idée la plus simple est d'augmenter la taille du lot, afin que plus de données soient utilisées à chaque itération, ce qui réduit le nombre d'itérations, ce qui signifie que le volume de communication est réduit.
Cependant, plus la taille du lot est grande, mieux c'est. Une taille de lot plus grande peut entraîner une diminution de la précision de la convergence du modèle ou un ralentissement de la vitesse de convergence. En réponse à des problèmes similaires, l'industrie a également proposé des algorithmes d'optimisation tels que LARS et LAMB, qui peuvent atténuer des problèmes similaires en ajustant de manière adaptative le taux d'apprentissage à travers les couches. AIAK-Training a également ajouté une prise en charge.
Afin d'augmenter la taille du lot, si la mémoire vidéo est suffisante, vous pouvez ajuster directement le super paramètre batchsize. Si la mémoire vidéo est limitée, vous pouvez également ignorer plusieurs communications de gradient grâce à l'accumulation de gradient, ce qui équivaut en fait à augmenter la taille du lot.
Ce qui suit présente une solution d'optimisation pour la topologie de communication - la communication par topologie hiérarchique, qui vise également la situation où la bande passante du réseau inter-machines est relativement faible.
Grâce à la communication hiérarchique, la bande passante d'interconnexion élevée au sein de la machine peut être pleinement utilisée, tandis que l'impact de la faible bande passante du réseau entre les machines peut être atténué.
Cette solution de communication a également été implémentée dans AIAK. Dans un environnement TCP 25 Gbps, 4 machines et 32 cartes ont été testées pour la formation SwinTransformer Grâce à allreduce en couches, les performances peuvent être accélérées de 85 %.
Enfin, nous introduisons une optimisation au niveau de la bibliothèque de communication sous-jacente, la technologie de communication GPU Direct RDMA. Cette technologie nécessite l'environnement matériel pour prendre en charge le réseau RDMA.
La communication RDMA permet aux applications locales de lire et d'écrire directement la mémoire virtuelle en mode utilisateur des applications distantes. L'ensemble du processus de communication, à l'exception de l'étape initiale de soumission d'une demande d'envoi, qui nécessite la participation du CPU, est complété par le matériel de carte réseau et n'est pas requis. Copie de mémoire, interruption du système et traitement logiciel, ce qui permet d'obtenir une latence extrêmement faible et une bande passante élevée.
Dans le scénario GPU, la technologie GPU Direct RDMA ajoute en outre la prise en charge de RDMA pour accéder directement à la mémoire vidéo du GPU, évitant ainsi la copie des données entre la mémoire vidéo du GPU et la mémoire hôte pendant la communication, réduisant ainsi davantage les délais de communication entre machines.
Cependant, dans des cas réels, nous avons constaté que certains utilisateurs achetaient un environnement RDMA, mais n'utilisaient pas réellement la technologie GDR, ce qui entraînait une faible efficacité de communication. Plusieurs éléments de configuration clés sont répertoriés ici. Si vous rencontrez des problèmes similaires, vous pouvez les dépanner et les définir dans l'ordre.
Nous avons présenté certaines des principales idées et solutions actuelles d'optimisation des performances. Dans l'ensemble, indépendamment de l'optimisation des E/S, de l'optimisation informatique et de l'optimisation des communications, les idées d'optimisation les plus simples sont principalement de savoir comment optimiser l'opération elle-même, ou si elle est effectuée. peut réduire le nombre de fois où l'opération se produit, ou si l'opération peut être parallélisée avec d'autres processus pour masquer la surcharge, etc.
De nombreux travaux d'optimisation ont été introduits auparavant. Pour l'activer correctement, chaque utilisateur doit avoir une compréhension claire des principes de mise en œuvre technique du framework. Afin de simplifier le coût de l'optimisation de la formation, nous avons créé le package d'accélération AIAK-Training.
AIAK-Training créera des capacités d'optimisation de lien complet autour du chargement des données, du calcul du modèle, de la communication, etc. Dans le même temps, nous encapsulerons cette capacité d'optimisation dans une interface simple et facile à utiliser. lignes de code à comparer Utilisation intégrée pratique. Dans le même temps, nous construisons également un mécanisme d'optimisation automatisée des combinaisons de stratégies pour aider automatiquement les utilisateurs à choisir des stratégies d'optimisation efficaces.
Dans une utilisation spécifique, les composants de la bibliothèque d'accélération peuvent être installés et déployés indépendamment, ou vous pouvez utiliser directement l'image du conteneur que nous fournissons.
Voici quelques cas d'application spécifiques.
Comme le montre l'image ci-dessous, il s'agit principalement de l'optimisation du dataloader. Dans ce scénario, le modèle est relativement petit, la taille de l'ensemble de données est également relativement petite et la vitesse de calcul pure est en fait plus rapide. Cependant, le temps de chargement des données dans EPOCH est relativement long, ce qui fait que les E/S deviennent fastidieuses. principal goulot d’étranglement.
En utilisant la réutilisation des processus et le mécanisme de prélecture complet fournis dans AIAK, l'ensemble de la formation du modèle est accéléré de 166 %.
L'image ci-dessous est un cas d'optimisation du calcul du modèle.
Scénario de formation sur le modèle de classe Transformer, pendant la formation réelle, l'évolutivité de la communication est proche de la linéaire, le rapport de consommation de temps d'E/S est également très faible et l'informatique est le principal goulot d'étranglement des performances.
Pour ce modèle, AIAK-Training a effectué une série d'optimisations au niveau du calcul, notamment la fusion opérateur des structures principales, la précision mixte, le réglage de gros lots, etc., et l'efficacité de la formation de l'ensemble du modèle a augmenté de 169 % .
Le cas de la figure ci-dessous s'applique principalement à l'optimisation au niveau de la communication, permettant des stratégies d'optimisation pour les réseaux à faible bande passante dans l'environnement cloud TCP. Sur certains modèles classiques tels que resnet50, bert et vgg16, il peut être accéléré par. 26 % ~ 78 %.
Dans les scénarios de conduite autonome, nous avons également réalisé une série d'optimisations des performances de formation de modèles pour les modèles typiques de vision 2D, de vision 3D, de lidar et de pré-fusion, et les performances de formation ont été accélérées de 49 % à 391 % .
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!