Conseils et pièges relatifs à la configuration pour la bibliothèque de modèles parallèles distribués SageMaker - Amazon SageMaker

Conseils et pièges relatifs à la configuration pour la bibliothèque de modèles parallèles distribués SageMaker

Consultez les conseils et les pièges suivants avant d'utiliser la bibliothèque de modèles parallèles distribués d'Amazon SageMaker. Cette liste contient des conseils qui s'appliquent à tous les cadres. Pour obtenir des conseils spécifiques à TensorFlow et PyTorch, consultez Modifier un script d'entraînement TensorFlow et Modifier un script d'entraînement PyTorch, respectivement.

Taille de lot et nombre de micro-lots

  • La bibliothèque est la plus efficace lorsque la taille du lot est augmentée. Dans les cas d'utilisation où le modèle tient dans un seul périphérique, mais ne peut être entraîné qu'avec un lot de petite taille, la taille du lot peut et doit être augmentée après l'intégration de la bibliothèque. Le parallélisme des modèles permet d'économiser de la mémoire pour les grands modèles, ce qui permet un entraînement avec des tailles de lots qui ne tenaient pas dans la mémoire auparavant.

  • Choisir un nombre de micro-lots trop petit ou trop grand peut nuire aux performances. La bibliothèque exécute chaque micro-lot séquentiellement dans chaque périphérique, de sorte que la taille du micro-lot (taille du lot divisée par le nombre de micro-lots) doit être suffisamment grande pour utiliser pleinement chaque GPU. Dans le même temps, comme l'efficacité du pipeline augmente avec le nombre de micro-lots, il est important de trouver le bon équilibre. Normalement, un bon point de départ consiste à essayer 2 ou 4 micro-lots, en augmentant la taille du lot jusqu'à la limite de mémoire, puis à expérimenter avec des tailles de lot et un nombre de micro-lots supérieurs. L'augmentation du nombre de micro-lots permet d'envisager des tailles de lots supérieures, si un pipeline entrelacé est utilisé.

  • La taille de votre lot doit toujours être divisible par le nombre de micro-lots. Veuillez noter que, selon la taille du jeu de données, la taille du dernier lot de chaque époque peut parfois être inférieure au reste, mais ce petit lot doit également être divisible par le nombre de micro-lots. Si ce n'est pas le cas, vous pouvez définir drop_remainder=True dans l'appel tf.Dataset.batch() (TensorFlow) ou drop_last=True dans DataLoader (PyTorch), de sorte que ce dernier petit lot ne soit pas utilisé. Si vous utilisez une API différente pour le pipeline de données, vous devrez peut-être ignorer manuellement le dernier lot chaque fois qu'il n'est pas divisible par le nombre de micro-lots.

Partitionnement manuel

  • Si vous utilisez le partitionnement manuel, pensez toujours aux paramètres qui sont utilisés par plusieurs opérations et modules de votre modèle, tels que la table d'incorporation dans les architectures de transformateur. À des fins d'exactitude, les modules qui partagent le même paramètre doivent être placés dans le même périphérique. Lorsque vous utilisez le partitionnement automatique, la bibliothèque applique automatiquement cette contrainte.

Préparation des données

  • Si le modèle utilise plusieurs entrées, veillez à répartir les opérations aléatoires dans votre pipeline de données (remaniement, par exemple) avec smp.dp_rank(). Si le jeu de données est partitionné de manière déterministe entre des périphériques parallèles de données, assurez-vous que la partition est indexée par smp.dp_rank(). Ceci permet de garantir la cohérence de l'ordre des données affichées sur tous les rangs qui forment une partition de modèle.

Renvoyer les tenseurs à partir de smp.DistributedModel

  • Tout tenseur renvoyé à partir de smp.DistributedModel.call (TensorFlow) ou smp.DistributedModel.forward (PyTorch) est envoyé à tous les autres rangs, à partir du rang qui a calculé ce tenseur particulier. Par conséquent, tout tenseur qui n'est pas nécessaire en dehors des méthodes d'appel et de transmission (activations intermédiaires, par exemple) ne doit pas être renvoyé, car cela provoque un surdébit inutile de communication et de mémoire et nuit aux performances.

Le décorateur @smp.step

  • Si l'argument tenseur d'une fonction décorée smp.step n'a pas de dimension de lot, le nom de l'argument doit être fourni dans la liste non_split_inputs lors de l'appel smp.step. Cela empêche la bibliothèque d'essayer de diviser le tenseur en micro-lots. Pour de plus amples informations, consultez smp.step dans la documentation sur l'API.