


Exemple de code complet de formation parallèle PyTorch DistributedDataParallel
Le problème de la formation de grands réseaux de neurones profonds (DNN) à l'aide de grands ensembles de données constitue un défi majeur dans le domaine de l'apprentissage profond. À mesure que la taille des DNN et des ensembles de données augmente, les besoins en calcul et en mémoire pour la formation de ces modèles augmentent également. Cela rend difficile, voire impossible, la formation de ces modèles sur une seule machine avec des ressources informatiques limitées. Certains des défis majeurs liés à la formation de grands DNN à l'aide de grands ensembles de données incluent :
- Longue durée de formation : le processus de formation peut prendre des semaines, voire des mois, en fonction de la complexité du modèle et de la taille de l'ensemble de données.
- Limites de mémoire : les grands DNN peuvent nécessiter de grandes quantités de mémoire pour stocker tous les paramètres du modèle, les gradients et les activations intermédiaires pendant l'entraînement. Cela peut entraîner des erreurs de mémoire insuffisante et limiter la taille du modèle pouvant être entraîné sur une seule machine.
Pour relever ces défis, diverses techniques ont été développées pour étendre la formation de grands DNN avec de grands ensembles de données, notamment le parallélisme des modèles, le parallélisme des données et le parallélisme hybride, ainsi que l'optimisation du matériel, des logiciels et des algorithmes.
Dans cet article, nous démontrerons le parallélisme des données et le parallélisme des modèles à l'aide de PyTorch.
Ce que nous appelons le parallélisme fait généralement référence à la formation de réseaux de neurones profonds (dnn) sur plusieurs GPU ou plusieurs machines, pour réduire le temps de formation. L'idée de base derrière le parallélisme des données est de diviser les données d'entraînement en morceaux plus petits et de laisser chaque GPU ou machine traiter un morceau de données distinct. Les résultats de chaque nœud sont ensuite combinés et utilisés pour mettre à jour les paramètres du modèle. Dans le parallélisme des données, l'architecture du modèle est la même sur chaque nœud, mais les paramètres du modèle sont répartis entre les nœuds. Chaque nœud entraîne son propre modèle local à l'aide de blocs de données alloués, et à la fin de chaque itération de formation, les paramètres du modèle sont synchronisés sur tous les nœuds. Ce processus est répété jusqu'à ce que le modèle converge vers un résultat satisfaisant.
Ci-dessous, nous utilisons les ensembles de données ResNet50 et CIFAR10 pour un exemple de code complet :
Dans le parallélisme des données, l'architecture du modèle reste la même sur chaque nœud, mais les paramètres du modèle sont partitionnés entre les nœuds, et chaque nœud utilise Allouer des morceaux de données pour formez votre propre modèle local.
La bibliothèque DistributedDataParallel de PyTorch peut communiquer et synchroniser efficacement les gradients et les paramètres du modèle entre les nœuds pour réaliser une formation distribuée. Cet article fournit des exemples sur la façon d'implémenter le parallélisme des données avec PyTorch à l'aide des ensembles de données ResNet50 et CIFAR10, où le code est exécuté sur plusieurs GPU ou machines, chaque machine traitant un sous-ensemble des données d'entraînement. Le processus de formation est parallélisé à l'aide de la bibliothèque DistributedDataParallel de PyTorch.
Importez les bibliothèques nécessaires
import os from datetime import datetime from time import time import argparse import torchvision import torchvision.transforms as transforms import torch import torch.nn as nn import torch.distributed as dist from torch.nn.parallel import DistributedDataParallel
Ensuite, nous vérifierons le GPU.
import subprocess result = subprocess.run(['nvidia-smi'], stdout=subprocess.PIPE) print(result.stdout.decode())
Parce que nous devons exécuter sur plusieurs serveurs, il n'est pas pratique de les exécuter un par un manuellement, un planificateur est donc nécessaire. Ici, nous utilisons des fichiers SLURM pour exécuter le code (slurmplanificateur de tâches gratuit et open source pour les noyaux Linux et Unix),
def main(): # get distributed configuration from Slurm environment parser = argparse.ArgumentParser() parser.add_argument('-b', '--batch-size', default=128, type =int, help='batch size. it will be divided in mini-batch for each worker') parser.add_argument('-e','--epochs', default=2, type=int, metavar='N', help='number of total epochs to run') parser.add_argument('-c','--checkpoint', default=None, type=str, help='path to checkpoint to load') args = parser.parse_args() rank = int(os.environ['SLURM_PROCID']) local_rank = int(os.environ['SLURM_LOCALID']) size = int(os.environ['SLURM_NTASKS']) master_addr = os.environ["SLURM_SRUN_COMM_HOST"] port = "29500" node_id = os.environ['SLURM_NODEID'] ddp_arg = [rank, local_rank, size, master_addr, port, node_id] train(args, ddp_arg)
Ensuite, nous utilisons la bibliothèque DistributedDataParallel pour effectuer une formation distribuée.
def train(args, ddp_arg): rank, local_rank, size, MASTER_ADDR, port, NODE_ID = ddp_arg # display info if rank == 0: #print(">>> Training on ", len(hostnames), " nodes and ", size, " processes, master node is ", MASTER_ADDR) print(">>> Training on ", size, " GPUs, master node is ", MASTER_ADDR) #print("- Process {} corresponds to GPU {} of node {}".format(rank, local_rank, NODE_ID)) print("- Process {} corresponds to GPU {} of node {}".format(rank, local_rank, NODE_ID)) # configure distribution method: define address and port of the master node and initialise communication backend (NCCL) #dist.init_process_group(backend='nccl', init_method='env://', world_size=size, rank=rank) dist.init_process_group( backend='nccl', init_method='tcp://{}:{}'.format(MASTER_ADDR, port), world_size=size, rank=rank ) # distribute model torch.cuda.set_device(local_rank) gpu = torch.device("cuda") #model = ResNet18(classes=10).to(gpu) model = torchvision.models.resnet50(pretrained=False).to(gpu) ddp_model = DistributedDataParallel(model, device_ids=[local_rank]) if args.checkpoint is not None: map_location = {'cuda:%d' % 0: 'cuda:%d' % local_rank} ddp_model.load_state_dict(torch.load(args.checkpoint, map_location=map_location)) # distribute batch size (mini-batch) batch_size = args.batch_size batch_size_per_gpu = batch_size // size # define loss function (criterion) and optimizer criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(ddp_model.parameters(), 1e-4) transform_train = transforms.Compose([ transforms.RandomCrop(32, padding=4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) # load data with distributed sampler #train_dataset = torchvision.datasets.CIFAR10(root='./data', # train=True, # transform=transform_train, # download=False) # load data with distributed sampler train_dataset = torchvision.datasets.CIFAR10(root='./data', train=True, transform=transform_train, download=False) train_sampler = torch.utils.data.distributed.DistributedSampler(train_dataset, num_replicas=size, rank=rank) train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=batch_size_per_gpu, shuffle=False, num_workers=0, pin_memory=True, sampler=train_sampler) # training (timers and display handled by process 0) if rank == 0: start = datetime.now() total_step = len(train_loader) for epoch in range(args.epochs): if rank == 0: start_dataload = time() for i, (images, labels) in enumerate(train_loader): # distribution of images and labels to all GPUs images = images.to(gpu, non_blocking=True) labels = labels.to(gpu, non_blocking=True) if rank == 0: stop_dataload = time() if rank == 0: start_training = time() # forward pass outputs = ddp_model(images) loss = criterion(outputs, labels) # backward and optimize optimizer.zero_grad() loss.backward() optimizer.step() if rank == 0: stop_training = time() if (i + 1) % 10 == 0 and rank == 0: print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}, Time data load: {:.3f}ms, Time training: {:.3f}ms'.format(epoch + 1, args.epochs, i + 1, total_step, loss.item(), (stop_dataload - start_dataload)*1000, (stop_training - start_training)*1000)) if rank == 0: start_dataload = time() #Save checkpoint at every end of epoch if rank == 0: torch.save(ddp_model.state_dict(), './checkpoint/{}GPU_{}epoch.checkpoint'.format(size, epoch+1)) if rank == 0: print(">>> Training complete in: " + str(datetime.now() - start)) if __name__ == '__main__': main()
Le code divise les données et le modèle sur plusieurs GPU et met à jour le modèle de manière distribuée. Voici quelques explications du code :
train(args, ddp_arg) a deux paramètres, args et ddp_arg, où args est le paramètre de ligne de commande transmis au script, et ddp_arg contient les paramètres distribués liés à la formation.
rank, local_rank, size, MASTER_ADDR, port, NODE_ID = ddp_arg : décompressez les paramètres liés à la formation distribuée dans ddp_arg.
Si le rang est 0, imprimez le nombre de GPU actuellement utilisés et les informations sur l'adresse IP du nœud maître.
dist.init_process_group(backend='nccl', init_method='tcp://{}:{}'.format(MASTER_ADDR, port), world_size=size,rank=rank) : Initialisez le processus distribué à l'aide du groupe backend NCCL.
torch.cuda.set_device(local_rank) : sélectionnez le GPU spécifié pour ce processus.
model = torchvision.models. ResNet50 (pretrained=False).to(gpu) : chargez le modèle ResNet50 à partir du modèle torchvision et déplacez-le vers le GPU spécifié.
ddp_model = DistributedDataParallel(model, device_ids=[local_rank]) : Enveloppez le modèle dans le module DistributedDataParallel, ce qui signifie que nous pouvons effectuer une formation distribuée
Chargez l'ensemble de données CIFAR-10 et appliquez la transformation d'amélioration des données.
train_sampler=torch.utils.data.distributed.DistributedSampler(train_dataset,num_replicas=size,rank=rank) : créez un objet DistributedSampler pour diviser l'ensemble de données sur plusieurs GPU.
train_loader =torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size_per_gpu,shuffle=False,num_workers=0,pin_memory=True,sampler=train_sampler) : créez un objet DataLoader et les données seront chargées dans le modèle par lots. Ceci est cohérent avec nos étapes de formation habituelles, sauf qu'un échantillonnage de données distribué DistributedSampler est ajouté.
Entraînez le modèle pour le nombre d'époques spécifié et mettez à jour les poids à l'aide d'optimizer.step() de manière distribuée.
rank0 enregistre un point de contrôle à la fin de chaque tour.
rank0 affiche la perte et le temps d'entraînement tous les 10 lots.
A la fin de la formation, le temps total passé à imprimer le modèle de formation est également au rang0.
Le test de code
a été formé en utilisant 1 nœud avec 1/2/3/4 GPU, 2 nœuds avec 6/8 GPU et chaque nœud avec 3/4 GPU. Le test de Resnet50 sur Cifar10 est comme indiqué ci-dessous. , la taille du lot reste la même pour chaque test. Le temps nécessaire pour terminer chaque test a été enregistré en secondes. À mesure que le nombre de GPU utilisés augmente, le temps nécessaire pour terminer le test diminue. Lors de l'utilisation de 8 GPU, cela a pris 320 secondes, ce qui est le temps le plus rapide enregistré. C'est sûr, mais nous pouvons voir que la vitesse d'entraînement n'augmente pas linéairement avec l'augmentation du nombre de GPU. Cela peut être dû au fait que Resnet50 est un modèle relativement petit et ne nécessite pas d'entraînement parallèle.
L'utilisation du parallélisme des données sur plusieurs GPU peut réduire considérablement le temps nécessaire à la formation d'un réseau neuronal profond (DNN) sur un ensemble de données donné. À mesure que le nombre de GPU augmente, le temps nécessaire pour terminer le processus de formation diminue, ce qui indique que les DNN peuvent être formés plus efficacement en parallèle.
Cette approche est particulièrement utile lorsqu'il s'agit de grands ensembles de données ou d'architectures DNN complexes. En exploitant plusieurs GPU, le processus de formation peut être accéléré, permettant une itération et une expérimentation plus rapides du modèle. Cependant, il convient de noter que les améliorations de performances obtenues grâce au parallélisme des données peuvent être limitées par des facteurs tels que la surcharge de communication et les limitations de la mémoire GPU, et nécessitent un réglage minutieux pour obtenir les meilleurs résultats.
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

BERT est un modèle de langage d'apprentissage profond pré-entraîné proposé par Google en 2018. Le nom complet est BidirectionnelEncoderRepresentationsfromTransformers, qui est basé sur l'architecture Transformer et présente les caractéristiques d'un codage bidirectionnel. Par rapport aux modèles de codage unidirectionnels traditionnels, BERT peut prendre en compte les informations contextuelles en même temps lors du traitement du texte, de sorte qu'il fonctionne bien dans les tâches de traitement du langage naturel. Sa bidirectionnalité permet à BERT de mieux comprendre les relations sémantiques dans les phrases, améliorant ainsi la capacité expressive du modèle. Grâce à des méthodes de pré-formation et de réglage fin, BERT peut être utilisé pour diverses tâches de traitement du langage naturel, telles que l'analyse des sentiments, la dénomination

Les fonctions d'activation jouent un rôle crucial dans l'apprentissage profond. Elles peuvent introduire des caractéristiques non linéaires dans les réseaux neuronaux, permettant ainsi au réseau de mieux apprendre et simuler des relations entrées-sorties complexes. La sélection et l'utilisation correctes des fonctions d'activation ont un impact important sur les performances et les résultats de formation des réseaux de neurones. Cet article présentera quatre fonctions d'activation couramment utilisées : Sigmoid, Tanh, ReLU et Softmax, à partir de l'introduction, des scénarios d'utilisation, des avantages, Les inconvénients et les solutions d'optimisation sont abordés pour vous fournir une compréhension complète des fonctions d'activation. 1. Fonction sigmoïde Introduction à la formule de la fonction SIgmoïde : La fonction sigmoïde est une fonction non linéaire couramment utilisée qui peut mapper n'importe quel nombre réel entre 0 et 1. Il est généralement utilisé pour unifier le

Écrit précédemment, nous discutons aujourd'hui de la manière dont la technologie d'apprentissage profond peut améliorer les performances du SLAM (localisation et cartographie simultanées) basé sur la vision dans des environnements complexes. En combinant des méthodes d'extraction de caractéristiques approfondies et de correspondance de profondeur, nous introduisons ici un système SLAM visuel hybride polyvalent conçu pour améliorer l'adaptation dans des scénarios difficiles tels que des conditions de faible luminosité, un éclairage dynamique, des zones faiblement texturées et une gigue importante. Notre système prend en charge plusieurs modes, notamment les configurations étendues monoculaire, stéréo, monoculaire-inertielle et stéréo-inertielle. En outre, il analyse également comment combiner le SLAM visuel avec des méthodes d’apprentissage profond pour inspirer d’autres recherches. Grâce à des expériences approfondies sur des ensembles de données publiques et des données auto-échantillonnées, nous démontrons la supériorité du SL-SLAM en termes de précision de positionnement et de robustesse du suivi.

L'intégration d'espace latent (LatentSpaceEmbedding) est le processus de mappage de données de grande dimension vers un espace de faible dimension. Dans le domaine de l'apprentissage automatique et de l'apprentissage profond, l'intégration d'espace latent est généralement un modèle de réseau neuronal qui mappe les données d'entrée de grande dimension dans un ensemble de représentations vectorielles de basse dimension. Cet ensemble de vecteurs est souvent appelé « vecteurs latents » ou « latents ». encodages". Le but de l’intégration de l’espace latent est de capturer les caractéristiques importantes des données et de les représenter sous une forme plus concise et compréhensible. Grâce à l'intégration de l'espace latent, nous pouvons effectuer des opérations telles que la visualisation, la classification et le regroupement de données dans un espace de faible dimension pour mieux comprendre et utiliser les données. L'intégration d'espace latent a de nombreuses applications dans de nombreux domaines, tels que la génération d'images, l'extraction de caractéristiques, la réduction de dimensionnalité, etc. L'intégration de l'espace latent est le principal

Dans la vague actuelle de changements technologiques rapides, l'intelligence artificielle (IA), l'apprentissage automatique (ML) et l'apprentissage profond (DL) sont comme des étoiles brillantes, à la tête de la nouvelle vague des technologies de l'information. Ces trois mots apparaissent fréquemment dans diverses discussions de pointe et applications pratiques, mais pour de nombreux explorateurs novices dans ce domaine, leurs significations spécifiques et leurs connexions internes peuvent encore être entourées de mystère. Alors regardons d'abord cette photo. On constate qu’il existe une corrélation étroite et une relation progressive entre l’apprentissage profond, l’apprentissage automatique et l’intelligence artificielle. Le deep learning est un domaine spécifique du machine learning, et le machine learning

Près de 20 ans se sont écoulés depuis que le concept d'apprentissage profond a été proposé en 2006. L'apprentissage profond, en tant que révolution dans le domaine de l'intelligence artificielle, a donné naissance à de nombreux algorithmes influents. Alors, selon vous, quels sont les 10 meilleurs algorithmes pour l’apprentissage profond ? Voici les meilleurs algorithmes d’apprentissage profond, à mon avis. Ils occupent tous une position importante en termes d’innovation, de valeur d’application et d’influence. 1. Contexte du réseau neuronal profond (DNN) : Le réseau neuronal profond (DNN), également appelé perceptron multicouche, est l'algorithme d'apprentissage profond le plus courant lorsqu'il a été inventé pour la première fois, jusqu'à récemment en raison du goulot d'étranglement de la puissance de calcul. années, puissance de calcul, La percée est venue avec l'explosion des données. DNN est un modèle de réseau neuronal qui contient plusieurs couches cachées. Dans ce modèle, chaque couche transmet l'entrée à la couche suivante et

1. Introduction La récupération de vecteurs est devenue un élément essentiel des systèmes modernes de recherche et de recommandation. Il permet une correspondance de requêtes et des recommandations efficaces en convertissant des objets complexes (tels que du texte, des images ou des sons) en vecteurs numériques et en effectuant des recherches de similarité dans des espaces multidimensionnels. Des bases à la pratique, passez en revue l'historique du développement d'Elasticsearch. vector retrieval_elasticsearch En tant que moteur de recherche open source populaire, le développement d'Elasticsearch en matière de récupération de vecteurs a toujours attiré beaucoup d'attention. Cet article passera en revue l'historique du développement de la récupération de vecteurs Elasticsearch, en se concentrant sur les caractéristiques et la progression de chaque étape. En prenant l'historique comme guide, il est pratique pour chacun d'établir une gamme complète de récupération de vecteurs Elasticsearch.

L'ensemble de données ScienceAI Question Answering (QA) joue un rôle essentiel dans la promotion de la recherche sur le traitement du langage naturel (NLP). Des ensembles de données d'assurance qualité de haute qualité peuvent non seulement être utilisés pour affiner les modèles, mais également évaluer efficacement les capacités des grands modèles linguistiques (LLM), en particulier la capacité à comprendre et à raisonner sur les connaissances scientifiques. Bien qu’il existe actuellement de nombreux ensembles de données scientifiques d’assurance qualité couvrant la médecine, la chimie, la biologie et d’autres domaines, ces ensembles de données présentent encore certaines lacunes. Premièrement, le formulaire de données est relativement simple, et la plupart sont des questions à choix multiples. Elles sont faciles à évaluer, mais limitent la plage de sélection des réponses du modèle et ne peuvent pas tester pleinement la capacité du modèle à répondre aux questions scientifiques. En revanche, les questions et réponses ouvertes
