Parallélisme des données partitionnées - Amazon SageMaker

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Parallélisme des données partitionnées

Le parallélisme de données partitionné est une technique d'entraînement distribuée économisant de la mémoire qui divise l'état d'un modèle (paramètres du modèle, gradients et états de l'optimiseur) au sein d'un groupe de données parallèles. GPUs

Note

Le parallélisme des données partitionnées est disponible PyTorch dans la bibliothèque de parallélisme des SageMaker modèles v1.11.0 et versions ultérieures.

Lorsque vous étendez votre tâche de formation à un grand GPU cluster, vous pouvez réduire l'empreinte GPU mémoire du modèle en répartissant l'état d'apprentissage du modèle sur plusieursGPUs. Cela présente deux avantages : vous pouvez adapter des modèles plus grands, qui manqueraient sinon de mémoire avec le parallélisme de données standard, ou vous pouvez augmenter la taille du lot en utilisant la mémoire libéréeGPU.

La technique standard de parallélisme des données reproduit les états d'apprentissage dans le groupe GPUs in the data parallel et effectue une agrégation de gradient en fonction de l'opération. AllReduce Le parallélisme des données partitionnées modifie la procédure d'entraînement distribué à données parallèles standard pour tenir compte de la nature partitionnée des états de l'optimiseur. Un groupe de rangs sur lequel les états du modèle et de l'optimiseur sont partitionnés est appelé groupe de partitionnement. La technique de parallélisme des données fragmentées partage les paramètres pouvant être entraînés d'un modèle ainsi que les dégradés correspondants et les états de l'optimiseur dans le groupe de partitionnement. GPUs

SageMaker parvient à un parallélisme des données fragmenté grâce à la mise en œuvre de MIC, dont il est question dans le billet de AWS blog Near linear scaling of gigantic-model training on. AWS Dans cette implémentation, vous pouvez définir le degré de partitionnement en tant que paramètre configurable, qui doit être inférieur au degré de parallélisme des données. À chaque passage en avant et en arrière, le MICS recombine temporairement les paramètres du modèle tout au GPUs long de l'AllGatheropération. Après le passage en avant ou en arrière de chaque couche, le MICS partage à nouveau les paramètres pour économiser GPU de la mémoire. Pendant le passage en arrière, les MICS réduisent les dégradés et les répartissent simultanément tout au long GPUs de l'opération. ReduceScatter Enfin, la méthode MiCS applique les gradients partitionnés et réduits locaux à leurs partitions de paramètres locales correspondantes, en utilisant les partitions locales des états de l'optimiseur. Pour réduire la surcharge de communication, la bibliothèque de parallélisme du SageMaker modèle préextrait les couches à venir lors de la passe avant ou arrière, et superpose les communications réseau aux calculs.

L'état d'entraînement du modèle est répliqué dans l'ensemble des groupes de partitionnement. Cela signifie qu'avant d'appliquer les gradients aux paramètres, l'opération AllReduce doit avoir lieu dans tous les groupes de partitionnement, en plus de l'opération ReduceScatter qui a lieu au sein du groupe de partitionnement.

En effet, le parallélisme des données fragmentées introduit un compromis entre la surcharge de communication et l'efficacité de la mémoire. GPU L'utilisation du parallélisme de données fragmenté augmente le coût de communication, mais l'empreinte mémoire GPU (à l'exclusion de l'utilisation de mémoire due aux activations) est divisée par le degré de parallélisme des données fragmentées, ce qui permet d'intégrer des modèles plus grands dans le cluster. GPU

Sélection du degré de parallélisme de données partitionnées

Lorsque vous sélectionnez une valeur pour le degré de parallélisme de données partitionnées, cette valeur doit diviser le degré de parallélisme de données de manière égale. Par exemple, pour une tâche de parallélisme des données à 8 voies, choisissez 2, 4 ou 8 comme degré de parallélisme des données partitionnées. Lorsque vous choisissez le degré de parallélisme des données partitionnées, nous vous recommandons de commencer par un petit nombre, puis de l'augmenter progressivement jusqu'à ce que le modèle tienne dans la mémoire avec la taille de lot souhaitée.

Sélection de la taille du lot

Après avoir configuré le parallélisme des données partitionnées, assurez-vous de trouver la configuration d'entraînement la plus optimale qui puisse s'exécuter avec succès sur le cluster. GPU Pour entraîner de grands modèles linguistiques (LLM), commencez par la taille du lot 1, puis augmentez-la progressivement jusqu'à ce que vous atteigniez le point de réception de l'erreur out-of-memory (OOM). Si l'OOMerreur se produit même avec la plus petite taille de lot, appliquez un degré plus élevé de parallélisme de données fragmenté ou une combinaison de parallélisme de données fragmenté et de parallélisme de tenseurs.

Comment appliquer le parallélisme de données partitionnées à votre tâche d'entraînement

Pour commencer à utiliser le parallélisme des données partitionnées, appliquez les modifications requises à votre script d'apprentissage et configurez l' SageMaker PyTorch estimateur avec les paramètres. sharded-data-parallelism-specific Pensez également à prendre des valeurs de référence et des exemples de blocs-notes comme point de départ.

Adaptez votre script PyTorch d'entraînement

Suivez les instructions de l'étape 1 : Modifiez un script d' PyTorch entraînement pour encapsuler les objets du modèle et de l'optimiseur avec les smdistributed.modelparallel.torch enveloppes des modules torch.nn.parallel ettorch.distributed.

(Facultatif) Modification supplémentaire pour enregistrer les paramètres externes du modèle

Si votre modèle est construit avec torch.nn.Module et utilise des paramètres qui ne sont pas définis dans la classe de module, vous devez les enregistrer manuellement dans le module SMP afin de recueillir les paramètres complets pendant. Pour enregistrer les paramètres d'un module, utilisez smp.register_parameter(module, parameter).

class Module(torch.nn.Module): def __init__(self, *args): super().__init__(self, *args) self.layer1 = Layer1() self.layer2 = Layer2() smp.register_parameter(self, self.layer1.weight) def forward(self, input): x = self.layer1(input) # self.layer1.weight is required by self.layer2.forward y = self.layer2(x, self.layer1.weight) return y

Configuration de l' SageMaker PyTorch estimateur

Lorsque vous configurez un SageMaker PyTorch estimateur dansÉtape 2 : Lancer un job de formation à l'aide du SDK SageMaker Python, ajoutez les paramètres du parallélisme des données fragmentées.

Pour activer le parallélisme des données partitionnées, ajoutez le sharded_data_parallel_degree paramètre à l'estimateur. SageMaker PyTorch Ce paramètre indique le nombre de points GPUs sur lesquels l'état d'apprentissage est fragmenté. La valeur pour sharded_data_parallel_degree doit être un entier compris entre 1 et le degré de parallélisme des données, et elle doit diviser de manière égale le degré de parallélisme des données. Notez que la bibliothèque détecte automatiquement le nombre de GPUs donc le degré de parallélisme des données. Les paramètres supplémentaires suivants sont disponibles pour configurer le parallélisme des données partitionnées.

  • "sdp_reduce_bucket_size"(int, default : 5e8) — Spécifie la taille des compartiments de PyTorch DDP dégradé en nombre d'éléments du dtype par défaut.

  • "sdp_param_persistence_threshold"(int, par défaut : 1e6) — Spécifie la taille d'un tenseur de paramètres en nombre d'éléments qui peuvent persister sur chacun d'eux. GPU Le parallélisme de données fractionné divise chaque tenseur de paramètres au sein d'GPUsun groupe de données parallèles. Si le nombre d'éléments dans le tenseur de paramètres est inférieur à ce seuil, le tenseur de paramètres n'est pas divisé ; cela permet de réduire la surcharge de communication car le tenseur de paramètres est répliqué entre données parallèles. GPUs

  • "sdp_max_live_parameters" (entier, par défaut : 1e9) : spécifie le nombre maximal de paramètres pouvant être simultanément dans un état d'entraînement recombiné pendant la transmission vers l'avant ou vers l'arrière. La récupération de paramètres avec l'opération AllGather s'interrompt lorsque le nombre de paramètres actifs atteint le seuil donné. Notez que l'augmentation de ce paramètre augmente l'empreinte mémoire.

  • "sdp_hierarchical_allgather" (booléen, par défaut : True) : si ce paramètre a pour valeur True, l'opération AllGather s'exécute de manière hiérarchique : elle s'exécute d'abord dans chaque nœud, puis sur tous les nœuds. Pour les tâches d'entraînement distribué à plusieurs nœuds, l'opération AllGather hiérarchique est automatiquement activée.

  • "sdp_gradient_clipping" (valeur à virgule flottante, par défaut : 1,0) : spécifie un seuil pour l'écrêtage de gradient de la norme L2 des gradients avant leur propagation vers l'arrière via les paramètres du modèle. Lorsque le parallélisme des données partitionnées est activé, l'écrêtage de gradient est également activé. Le seuil par défaut est 1.0. Réglez ce paramètre si vous rencontrez le problème d'explosion de gradient.

Le code suivant montre un exemple de configuration du parallélisme des données partitionnées.

import sagemaker from sagemaker.pytorch import PyTorch smp_options = { "enabled": True, "parameters": { # "pipeline_parallel_degree": 1, # Optional, default is 1 # "tensor_parallel_degree": 1, # Optional, default is 1 "ddp": True, # parameters for sharded data parallelism "sharded_data_parallel_degree": 2, # Add this to activate sharded data parallelism "sdp_reduce_bucket_size": int(5e8), # Optional "sdp_param_persistence_threshold": int(1e6), # Optional "sdp_max_live_parameters": int(1e9), # Optional "sdp_hierarchical_allgather": True, # Optional "sdp_gradient_clipping": 1.0 # Optional } } mpi_options = { "enabled" : True, # Required "processes_per_host" : 8 # Required } smp_estimator = PyTorch( entry_point="your_training_script.py", # Specify your train script role=sagemaker.get_execution_role(), instance_count=1, instance_type='ml.p3.16xlarge', framework_version='1.13.1', py_version='py3', distribution={ "smdistributed": {"modelparallel": smp_options}, "mpi": mpi_options }, base_job_name="sharded-data-parallel-job" ) smp_estimator.fit('s3://my_bucket/my_training_data/')

Référence de configurations

L'équipe de formation SageMaker distribuée fournit les configurations de référence suivantes que vous pouvez utiliser comme point de départ. Vous pouvez extrapoler à partir des configurations suivantes pour expérimenter et estimer l'utilisation de la GPU mémoire pour la configuration de votre modèle.

Parallélisme de données fragmenté avec les collectifs SMDDP

Modèle/le nombre de paramètres Nombre d'instances Type d’instance Durée de la séquence Taille globale du lot Taille du mini-lot Degré de parallélisation des données partitionnées
GPT- NEOX -20 B 2 ml.p4d.24xlarge 2048 64 4 16
GPT- NEOX -20 B 8 ml.p4d.24xlarge 2048 768 12 32

Par exemple, si vous augmentez la longueur de séquence d'un modèle de 20 milliards de paramètres ou si vous augmentez la taille du modèle à 65 milliards de paramètres, vous devez d'abord essayer de réduire la taille du lot. Si le modèle ne correspond toujours pas à la plus petite taille de lot (la taille de lot de 1), essayez d'augmenter le degré de parallélisme du modèle.

Parallélisme de données fragmenté avec parallélisme tensoriel et collectifs NCCL

Modèle/le nombre de paramètres Nombre d'instances Type d’instance Durée de la séquence Taille globale du lot Taille du mini-lot Degré de parallélisation des données partitionnées Degré de parallélisation du tenseur Déchargement de l'activation
GPT- NEOX -65 B 64 ml.p4d.24xlarge 2048 512 8 16 8 Y
GPT- NEOX -65 B 64 ml.p4d.24xlarge 4096 512 2 64 2 Y

L'utilisation combinée du parallélisme des données fragmentées et du parallélisme des tenseurs est utile lorsque vous souhaitez adapter un grand modèle de langage (LLM) à un cluster à grande échelle tout en utilisant des données texte avec une longueur de séquence plus longue, ce qui permet d'utiliser une taille de lot plus petite, et donc de gérer l'utilisation de la GPU mémoire pour vous entraîner sur des séquences de texte plus longues. LLMs Pour en savoir plus, consultez Parallélisme de données partitionnées avec parallélisme de tenseurs.

Pour des études de cas, des benchmarks et d'autres exemples de configuration, consultez le billet de blog New performance improvements in Amazon SageMaker model parallel library.

Parallélisme de données fragmenté avec les collectifs SMDDP

La bibliothèque de parallélisme des SageMaker données propose des primitives de communication collective (SMDDPcollectives) optimisées pour l'infrastructure. AWS Il parvient à l'optimisation en adoptant un modèle de all-to-all-type communication en utilisant Elastic Fabric Adapter (EFA), ce qui permet de créer des collectifs à haut débit et moins sensibles à la latence, de décharger le traitement lié à la communication vers le et de libérer des cycles de calcul. CPU GPU Sur les grands clusters, SMDDP les collectifs peuvent améliorer les performances de formation distribuée jusqu'à 40 % par rapport àNCCL. Pour des études de cas et des résultats de référence, consultez le blog Nouvelles améliorations des performances dans la bibliothèque de parallélisme des SageMaker modèles Amazon.

Note

Le parallélisme de données partitionné avec SMDDP Collectives est disponible dans la bibliothèque de parallélisme de SageMaker modèles v1.13.0 et versions ultérieures, et dans la bibliothèque de parallélisme de données v1.6.0 et versions ultérieures. SageMaker Voir également Supported configurations pour utiliser le parallélisme de données fragmenté avec les collectifs. SMDDP

Dans le cas du parallélisme de données fragmenté, qui est une technique couramment utilisée dans l'apprentissage distribué à grande échelle, le AllGather collectif est utilisé pour reconstituer les paramètres de la couche fragmentée pour les calculs de passes avant et arrière, en parallèle avec le calcul. GPU Pour les modèles de grande taille, l'efficacité de l'AllGatheropération est essentielle pour éviter les problèmes de GPU congestion et le ralentissement de la vitesse d'entraînement. Lorsque le parallélisme des données partitionnées est activé, SMDDP Collectives intègre ces AllGather collectifs essentiels aux performances, améliorant ainsi le débit d'entraînement.

Entraînez-vous avec SMDDP des collectifs

Lorsque votre tâche de formation a activé le parallélisme des données fragmenté et qu'elle répond à cette exigenceSupported configurations, les SMDDP collectifs sont automatiquement activés. En interne, les SMDDP collectifs optimisent le AllGather collectif pour qu'il soit performant sur l' AWS infrastructure et s'en remettent NCCL à tous les autres collectifs. De plus, dans des configurations non prises en charge, tous les collectifs, y comprisAllGather, utilisent automatiquement le NCCL backend.

Depuis la version 1.13.0 de la bibliothèque de parallélisme des SageMaker modèles, le "ddp_dist_backend" paramètre est ajouté aux options. modelparallel La valeur par défaut de ce paramètre de configuration est"auto", qui utilise des SMDDP collectifs dans la mesure du possible, et revient à la valeur NCCL normale. Pour forcer la bibliothèque à toujours être utiliséeNCCL, spécifiez "nccl" le paramètre "ddp_dist_backend" de configuration.

L'exemple de code suivant montre comment configurer un PyTorch estimateur à l'aide du parallélisme de données fragmenté avec le "ddp_dist_backend" paramètre, qui est défini "auto" par défaut et dont l'ajout est donc facultatif.

import sagemaker from sagemaker.pytorch import PyTorch smp_options = { "enabled":True, "parameters": { "partitions": 1, "ddp": True, "sharded_data_parallel_degree": 64 "bf16": True, "ddp_dist_backend": "auto" # Specify "nccl" to force to use NCCL. } } mpi_options = { "enabled" : True, # Required "processes_per_host" : 8 # Required } smd_mp_estimator = PyTorch( entry_point="your_training_script.py", # Specify your train script source_dir="location_to_your_script", role=sagemaker.get_execution_role(), instance_count=8, instance_type='ml.p4d.24xlarge', framework_version='1.13.1', py_version='py3', distribution={ "smdistributed": {"modelparallel": smp_options}, "mpi": mpi_options }, base_job_name="sharded-data-parallel-demo", ) smd_mp_estimator.fit('s3://my_bucket/my_training_data/')

Configurations prises en charge

Le AllGather fonctionnement avec les SMDDP collectifs est activé dans les tâches de formation lorsque toutes les exigences de configuration suivantes sont satisfaites.

  • Le degré de parallélisme des données partitionnées est supérieur à 1

  • Instance_count supérieur à 1

  • Instance_type égal à ml.p4d.24xlarge

  • SageMaker conteneur d'entraînement pour PyTorch v1.12.1 ou version ultérieure

  • La bibliothèque de parallélisme des SageMaker données v1.6.0 ou version ultérieure

  • La bibliothèque de parallélisme des SageMaker modèles v1.13.0 ou version ultérieure

Réglage des performances et de la mémoire

SMDDPLes collectifs utilisent de GPU la mémoire supplémentaire. Deux variables d'environnement permettent de configurer l'utilisation de la GPU mémoire en fonction des différents cas d'utilisation des modèles d'entraînement.

  • SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES— Pendant l'SMDDPAllGatheropération, le tampon AllGather d'entrée est copié dans un tampon temporaire pour la communication entre nœuds. La variable SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES contrôle la taille (en octets) de cette mémoire tampon temporaire. Si la taille de la mémoire tampon temporaire est inférieure à la taille de la mémoire tampon AllGather d'entrée, le AllGather collectif est de nouveau utiliséNCCL.

    • Valeur par défaut : 16 * 1024 * 1024 (16 Mo)

    • Valeurs acceptables : tout multiple de 8 192

  • SMDDP_AG_SORT_BUFFER_SIZE_BYTES : la variable SMDDP_AG_SORT_BUFFER_SIZE_BYTES permet de dimensionner la mémoire tampon temporaire (en octets) pour contenir les données collectées lors de la communication entre nœuds. Si la taille de cette mémoire tampon temporaire est inférieure à1/8 * sharded_data_parallel_degree * AllGather input size, le AllGather collectif recommence à être utiliséNCCL.

    • Valeur par défaut : 128 * 1024 * 1024 (128 Mo)

    • Valeurs acceptables : tout multiple de 8 192

Conseils de réglage sur les variables de taille de la mémoire tampon

Les valeurs par défaut des variables d'environnement devraient fonctionner correctement dans la plupart des cas d'utilisation. Nous recommandons de régler ces variables uniquement si l'entraînement se heurte à l'erreur out-of-memory (OOM).

La liste suivante présente quelques conseils de réglage pour réduire l'empreinte GPU mémoire des SMDDP collectifs tout en préservant les gains de performance qu'ils génèrent.

  • Réglage de SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES

    • La taille de la mémoire tampon d'entrée AllGather est plus petite pour les modèles plus petits. Par conséquent, la taille requise pour SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES peut être plus petite pour les modèles comportant moins de paramètres.

    • La taille de la mémoire tampon AllGather d'entrée diminue au fur et à mesure que l'on sharded_data_parallel_degree augmente, car le modèle est davantage GPUs segmenté. Par conséquent, la taille requise pour SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES peut être plus petite pour les tâches d'entraînement avec des valeurs élevées pour sharded_data_parallel_degree.

  • Réglage de SMDDP_AG_SORT_BUFFER_SIZE_BYTES

    • La quantité de données collectées à partir de la communication entre nœuds est moins importante pour les modèles comportant moins de paramètres. Par conséquent, la taille requise pour SMDDP_AG_SORT_BUFFER_SIZE_BYTES peut être plus petite pour de tels modèles avec moins de paramètres.

Certains collectifs peuvent revenir à l'usage NCCL ; par conséquent, vous risquez de ne pas bénéficier du gain de performance des SMDDP collectifs optimisés. Si de GPU la mémoire supplémentaire est disponible, vous pouvez envisager d'augmenter les valeurs du gain SMDDP_AG_SORT_BUFFER_SIZE_BYTES de performances SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES et d'en tirer parti.

Le code suivant montre comment configurer les variables d'environnement en les ajoutant mpi_options au paramètre de distribution de l' PyTorch estimateur.

import sagemaker from sagemaker.pytorch import PyTorch smp_options = { .... # All modelparallel configuration options go here } mpi_options = { "enabled" : True, # Required "processes_per_host" : 8 # Required } # Use the following two lines to tune values of the environment variables for buffer mpioptions += " -x SMDDP_AG_SCRATCH_BUFFER_SIZE_BYTES=8192" mpioptions += " -x SMDDP_AG_SORT_BUFFER_SIZE_BYTES=8192" smd_mp_estimator = PyTorch( entry_point="your_training_script.py", # Specify your train script source_dir="location_to_your_script", role=sagemaker.get_execution_role(), instance_count=8, instance_type='ml.p4d.24xlarge', framework_version='1.13.1', py_version='py3', distribution={ "smdistributed": {"modelparallel": smp_options}, "mpi": mpi_options }, base_job_name="sharded-data-parallel-demo-with-tuning", ) smd_mp_estimator.fit('s3://my_bucket/my_training_data/')

Entraînement à précision mixte avec parallélisme de données partitionnées

Pour économiser davantage de GPU mémoire grâce à des nombres à virgule flottante à demi-précision et à un parallélisme de données fragmenté, vous pouvez activer le format à virgule flottante 16 bits (FP16) ou le format à virgule flottante Brain (BF16) en ajoutant un paramètre supplémentaire à la configuration d'entraînement distribuée.

Note

Un entraînement de précision mixte avec parallélisme de données fragmenté est disponible dans la bibliothèque de parallélisme de SageMaker modèles v1.11.0 et versions ultérieures.

Pour la FP16 formation avec le parallélisme des données fragmentées

Pour exécuter un FP16 entraînement avec un parallélisme de données fragmenté, ajoutez-le "fp16": True" au dictionnaire de smp_options configuration. Dans votre script d'entraînement, vous pouvez choisir entre les options de mise à l'échelle statique et dynamique des pertes via le module smp.DistributedOptimizer. Pour de plus amples informations, veuillez consulter FP16Entraînement avec le parallélisme des modèles.

smp_options = { "enabled": True, "parameters": { "ddp": True, "sharded_data_parallel_degree": 2, "fp16": True } }

Pour la BF16 formation avec le parallélisme des données fragmentées

La fonction de parallélisme des données fragmentées de SageMaker prend en charge l'apprentissage du type de données. BF16 Le type de BF16 données utilise 8 bits pour représenter l'exposant d'un nombre à virgule flottante, tandis que le type de FP16 données utilise 5 bits. La préservation des 8 bits pour l'exposant permet de conserver la même représentation de l'exposant d'un nombre à virgule flottante à précision unique () FP32 de 32 bits. Cela simplifie la conversion entre FP32 et et BF16 est nettement moins susceptible de provoquer des problèmes de débordement et de sous-débit qui surviennent souvent lors de l'FP16entraînement, en particulier lors de l'entraînement de modèles plus grands. Bien que les deux types de données utilisent 16 bits au total, cette plage de représentation accrue de l'exposant dans le BF16 format se fait au détriment de la précision. Dans le cadre de l'entraînement de grands modèles, cette baisse de précision est souvent considérée comme un compromis acceptable pour la plage et la stabilité de l'entraînement.

Note

Actuellement, la BF16 formation ne fonctionne que lorsque le parallélisme des données partitionnées est activé.

Pour exécuter un BF16 entraînement avec un parallélisme de données fragmenté, ajoutez-le "bf16": True au dictionnaire de smp_options configuration.

smp_options = { "enabled": True, "parameters": { "ddp": True, "sharded_data_parallel_degree": 2, "bf16": True } }

Parallélisme de données partitionnées avec parallélisme de tenseurs

Si vous utilisez le parallélisme de données partitionnées et que vous devez également réduire la taille globale du lot, envisagez d'utiliser le parallélisme de tenseurs avec le parallélisme de données partitionnées. Lorsque vous entraînez un modèle de grande taille avec un parallélisme de données fragmenté sur un très grand cluster de calcul (généralement 128 nœuds ou plus), même une petite taille de lot par unité se GPU traduit par une taille de lot globale très importante. Cela peut entraîner des problèmes de convergence ou de faibles performances de calcul. Il n'est GPU parfois pas possible de réduire la taille des lots par lot en utilisant uniquement le parallélisme des données fragmentées lorsqu'un lot est déjà volumineux et ne peut pas être réduit davantage. Dans de tels cas, l'utilisation du parallélisme de données partitionnées en combinaison avec le parallélisme de tenseurs permet de réduire la taille globale du lot.

Le choix des degrés de parallélisme de données partitionnées et de parallélisme de tenseurs optimaux dépend de l'échelle du modèle, du type d'instance et de la taille de lot globale qui est raisonnable pour que le modèle à converger. Nous vous recommandons de partir d'un faible degré de parallélisme tenseur pour adapter la taille du lot global au cluster de calcul afin de résoudre CUDA out-of-memory les erreurs et d'obtenir les meilleures performances. Consultez les deux exemples de cas suivants pour découvrir comment la combinaison du parallélisme des tenseurs et du parallélisme des données fragmentées vous aide à ajuster la taille globale du lot en le regroupant GPUs pour le parallélisme du modèle, ce qui se traduit par une diminution du nombre de répliques de modèles et une réduction de la taille globale du lot.

Note

Cette fonctionnalité est disponible dans la bibliothèque de parallélisme des SageMaker modèles v1.15 et prend en charge la version 1.13.1. PyTorch

Note

Cette fonctionnalité est disponible pour les modèles pris en charge par la fonctionnalité de parallélisme de tenseurs de la bibliothèque. Pour trouver la liste des modèles pris en charge, consultez Prise en charge des modèles Transformer Hugging Face. Notez également que vous devez transférer tensor_parallelism=True à l'argument smp.model_creation lorsque vous modifiez votre script d'entraînement. Pour en savoir plus, consultez le script de formation train_gpt_simple.pydans le GitHub référentiel SageMaker d'exemples.

Exemple 1

Supposons que nous voulions entraîner un modèle sur un cluster de 1 536 GPUs (192 nœuds de 8 GPUs dans chacun), en réglant le degré de parallélisme des données partitionnées à 32 (sharded_data_parallel_degree=32) et la taille du lot par lot GPU à 1, chaque lot ayant une longueur de séquence de 4 096 jetons. Dans ce cas, il existe 1 536 réplicas de modèles, la taille globale du lot devient 1 536 et chaque lot global contient environ 6 millions de jetons.

(1536 GPUs) * (1 batch per GPU) = (1536 global batches) (1536 batches) * (4096 tokens per batch) = (6,291,456 tokens)

L'ajout d'un parallélisme de tenseurs peut réduire la taille globale du lot. Un exemple de configuration peut consister à régler le degré de parallélisme du tenseur sur 8 et la taille du lot GPU sur 4. Cela forme 192 groupes de tenseurs parallèles ou 192 répliques de modèles, où chaque réplique de modèle est répartie sur 8. GPUs La taille de lot de 4 correspond à la quantité de données d'entraînement par itération et par groupe de parallélisme de tenseurs ; en d'autres termes, chaque réplica de modèle consomme 4 lots par itération. Dans ce cas, la taille globale du lot devient 768 et chaque lot global contient environ 3 millions de jetons. Par conséquent, la taille globale du lot est réduite de moitié par rapport au cas précédent avec un parallélisme de données partitionnées uniquement.

(1536 GPUs) / (8 tensor parallel degree) = (192 tensor parallelism groups) (192 tensor parallelism groups) * (4 batches per tensor parallelism group) = (768 global batches) (768 batches) * (4096 tokens per batch) = (3,145,728 tokens)

Exemple 2

Lorsque le parallélisme de données partitionnées et le parallélisme de tenseurs sont activés, la bibliothèque applique d'abord le parallélisme de tenseur et partitionne le modèle sur cette dimension. Pour chaque rang de parallélisme de tenseurs, le parallélisme de données est appliqué conformément au sharded_data_parallel_degree.

Par exemple, supposons que nous voulions définir 32 GPUs avec un degré de parallélisme du tenseur de 4 (formant des groupes de 4GPUs), un degré de parallélisme des données partitionnées de 4, pour aboutir à un degré de réplication de 2. L'affectation crée huit GPU groupes basés sur le degré de parallélisme du tenseur, comme suit : (0,1,2,3)(4,5,6,7),(8,9,10,11),(12,13,14,15),(16,17,18,19),, (20,21,22,23)(24,25,26,27),(28,29,30,31). C'est-à-dire que quatre GPUs forment un groupe parallèle de tenseurs. Dans ce cas, le groupe de parallèles de données réduit pour le 0e rang GPUs des groupes de tenseurs parallèles serait. (0,4,8,12,16,20,24,28) Le groupe de parallélisme de données réduit est partitionné en fonction du degré de parallélisme de données partitionnées de 4, ce qui donne lieu à deux groupes de réplication pour le parallélisme de données. GPUs(0,4,8,12)formez un groupe de partitionnement, qui détient collectivement une copie complète de tous les paramètres du 0e rang parallèle du tenseur, GPUs (16,20,24,28) et formez un autre groupe de ce type. D'autres rangs de parallélisme de tenseurs possèdent également des groupes de partitionnement et de réplication similaires.

Figure 1 : Groupes de parallélisme tensoriel.

Figure 1 : Groupes de parallélisme tensoriel pour (nœuds, degré de parallélisme des données fragmentées, degré de parallélisme des tenseurs) = (4, 4, 4), où chaque rectangle représente GPU un avec des indices compris entre 0 et 31. Les groupes de parallélisme des tenseurs de la GPUs forme vont de à. TPG 0 TPG 7 Les groupes de réplication sont ({TPG0, TPG4}, {TPG1, TPG5}, {TPG2, TPG6} et {TPG3, TPG7}) ; chaque paire de groupes de réplication partage la même couleur mais remplie différemment.

Figure 2 : Groupes de parallélisme de données fragmentées.

Figure 2 : Groupes de parallélisme de données fragmentées pour (nœuds, degré de parallélisme des données fragmentées, degré de parallélisme des tenseurs) = (4, 4, 4), où chaque rectangle représente GPU un avec des indices compris entre 0 et 31. Le GPUs formulaire a fragmenté les groupes de parallélisme des données de à. SDPG 0 SDPG 7 Les groupes de réplication sont ({SDPG0, SDPG4}, {SDPG1, SDPG5}, {SDPG2, SDPG6} et {SDPG3, SDPG7}) ; chaque paire de groupes de réplication partage la même couleur mais remplie différemment.

Comment activer le parallélisme de données partitionnées avec le parallélisme de tenseurs

Pour utiliser le parallélisme de données fragmenté avec le parallélisme tensoriel, vous devez définir les deux paramètres sharded_data_parallel_degree et, tensor_parallel_degree dans la configuration, distribution lors de la création d'un objet de la classe d'estimateur. SageMaker PyTorch

Vous devez également activer prescaled_batch. Cela signifie qu'au lieu de GPU lire chacun son propre lot de données, chaque groupe tensor parallel lit collectivement un lot combiné de la taille de lot choisie. En fait, au lieu de diviser le jeu de données en parties égales au nombre de GPUs (ou taille parallèle des donnéessmp.dp_size()), il le divise en parties égales au nombre de parties GPUs divisées par tensor_parallel_degree (également appelé taille réduite des données parallèles,smp.rdp_size()). Pour plus de détails sur le traitement par lots prédimensionnés, consultez Prescaled Batch dans la SageMaker documentation Python. SDK Consultez également l'exemple de script d'entraînement train_gpt_simple.pypour GPT -2 dans le GitHub référentiel SageMaker Examples.

L'extrait de code suivant montre un exemple de création d'un objet PyTorch estimateur basé sur le scénario susmentionné dans. Exemple 2

mpi_options = "-verbose --mca orte_base_help_aggregate 0 " smp_parameters = { "ddp": True, "fp16": True, "prescaled_batch": True, "sharded_data_parallel_degree": 4, "tensor_parallel_degree": 4 } pytorch_estimator = PyTorch( entry_point="your_training_script.py", role=role, instance_type="ml.p4d.24xlarge", volume_size=200, instance_count=4, sagemaker_session=sagemaker_session, py_version="py3", framework_version="1.13.1", distribution={ "smdistributed": { "modelparallel": { "enabled": True, "parameters": smp_parameters, } }, "mpi": { "enabled": True, "processes_per_host": 8, "custom_mpi_options": mpi_options, }, }, source_dir="source_directory_of_your_code", output_path=s3_output_location )

Conseils et considérations concernant l'utilisation du parallélisme de données partitionnées

Tenez compte des points suivants lorsque vous utilisez le parallélisme de données fragmenté de la bibliothèque de parallélisme du SageMaker modèle.

  • Le parallélisme des données fragmentées est compatible avec l'entraînement. FP16 Pour organiser un FP16 entraînement, consultez la FP16Entraînement avec le parallélisme des modèles section.

  • Le parallélisme de données partitionnées est compatible avec le parallélisme de tenseurs. Les éléments suivants sont ceux que vous devrez peut-être prendre en compte pour utiliser le parallélisme de données partitionnées avec le parallélisme de tenseurs.

    • Lorsque vous utilisez le parallélisme de données partitionnées avec le parallélisme de tenseur, les couches d'intégration sont également automatiquement réparties dans le groupe de parallélisme de tenseurs. En d'autres termes, le paramètre distribute_embedding est automatiquement défini sur True. Pour plus d'informations sur le parallélisme de tenseurs, consultez Parallélisme de tenseur.

    • Notez que le parallélisme des données fragmentées avec le parallélisme des tenseurs utilise actuellement les NCCL collectifs comme backend de la stratégie d'entraînement distribuée.

    Pour plus d'informations, consultez la section Parallélisme de données partitionnées avec parallélisme de tenseurs.

  • Le parallélisme de données partitionnées n'est actuellement pas compatible avec le parallélisme de pipelines, ni le partitionnement de l'état de l'optimiseur. Pour activer le parallélisme de données partitionnées, désactivez le partitionnement de l'état de l'optimiseur et définissez le degré de parallélisme de pipelines sur 1.

  • Les fonctionnalités des points de contrôle d'activation et du déchargement de l'activation sont compatibles avec le parallélisme des données partitionnées.

  • Pour utiliser le parallélisme des données partitionnées avec cumul de gradient, définissez l'argument backward_passes_per_step sur le nombre d'étapes de cumul lors de l'enveloppement de votre modèle avec le module smdistributed.modelparallel.torch.DistributedModel. Cela garantit que l'opération AllReduce de gradient entre les groupes de réplication du modèle (groupes de partitionnement) a lieu à la limite du cumul de gradient.

  • Vous pouvez vérifier vos modèles entraînés avec le parallélisme de données fragmenté à l'aide du point de contrôle de la bibliothèque, et. APIs smp.save_checkpoint smp.resume_from_checkpoint Pour de plus amples informations, veuillez consulter Vérification d'un PyTorch modèle distribué (pour la bibliothèque de parallélisme des SageMaker modèles v1.10.0 et versions ultérieures).

  • Le comportement du paramètre de configuration delayed_parameter_initialization change dans le cadre du parallélisme des données partitionnées. Lorsque ces deux fonctionnalités sont activées simultanément, les paramètres sont immédiatement initialisés lors de la création du modèle d'une manière partitionnée au lieu de retarder l'initialisation des paramètres, de sorte que chaque rang initialise et stocke sa propre partition de paramètres.

  • Lorsque le parallélisme des données partitionnées est activé, la bibliothèque effectue un écrêtage de gradient en interne lorsque l'appel optimizer.step() s'exécute. Vous n'avez pas besoin d'utiliser un utilitaire APIs pour le découpage en dégradé, tel que torch.nn.utils.clip_grad_norm_(). Pour ajuster la valeur de seuil pour le découpage en dégradé, vous pouvez la définir via le sdp_gradient_clipping paramètre de configuration des paramètres de distribution lorsque vous créez l' SageMaker PyTorch estimateur, comme indiqué dans la section. Comment appliquer le parallélisme de données partitionnées à votre tâche d'entraînement