Bonnes pratiques pour la formation à l'accélération TensorFlow 1.x sur Amazon SageMaker PlatoBlockchain Data Intelligence. Recherche verticale. Aï.

Meilleures pratiques pour la formation à l'accélération TensorFlow 1.x sur Amazon SageMaker

Aujourd'hui, de nombreux clients utilisent TensorFlow pour former des modèles d'apprentissage en profondeur pour leur taux de clics dans les recommandations de publicité et de personnalisation dans le commerce électronique. À mesure que le comportement de leurs clients change, ils peuvent accumuler chaque jour de grandes quantités de nouvelles données. L'itération de modèle est l'une des tâches quotidiennes d'un scientifique des données, mais il est confronté au problème de prendre trop de temps pour s'entraîner sur de grands ensembles de données.

Amazon Sage Maker est une plate-forme d'apprentissage automatique (ML) entièrement gérée qui pourrait aider les data scientists à se concentrer sur les modèles plutôt que sur l'infrastructure, avec une prise en charge native des algorithmes et des frameworks personnalisés tels que TensorFlow et PyTorch. SageMaker offre des options de formation distribuée flexibles qui s'adaptent à vos flux de travail spécifiques. Étant donné que de nombreux spécialistes des données peuvent manquer d'expérience dans le processus de formation accélérée, dans cet article, nous vous montrons les facteurs importants pour la formation rapide de modèles d'apprentissage en profondeur et les meilleures pratiques de formation accélérée pour TensorFlow 1.x sur SageMaker. Nous avons également un exemple de code de Deep FM formation distribuée sur SageMaker sur le GitHub repo.

Vous devez prendre en compte de nombreux facteurs pour optimiser l'utilisation du CPU/GPU lorsque vous exécutez votre script TensorFlow sur SageMaker, tels que l'infrastructure, le type d'accélérateur, la méthode de formation distribuée, la méthode de chargement des données, la formation de précision mixte, etc.

Nous discutons des meilleures pratiques dans les domaines suivants :

  • Accélérez la formation sur une seule instance
  • Accélérer la formation sur plusieurs instances
  • Canalisations de données
  • Entraînement de précision mixte automatique

Accélérez la formation sur une seule instance

Lors de l'exécution de votre script TensorFlow sur une seule instance, vous pouvez choisir une série optimisée pour l'ordinateur telle que Cloud de calcul élastique Amazon (Amazon EC2) Série C5 ou série de calcul accéléré avec plusieurs GPU dans une seule instance, comme p3.8xlarge, p3.16xlarge, p3dn.24xlarge et p4d.24xlarge.

Dans cette section, nous discutons des stratégies pour plusieurs CPU sur une seule instance et de la formation distribuée avec plusieurs GPU sur une seule instance.

Plusieurs processeurs sur une seule instance

Dans cette section, nous abordons la configuration manuelle du parallélisme des opérateurs sur les périphériques CPU, la méthode tour, TensorFlow MirroredStrategy et Horovod.

Réglage manuel du parallélisme des opérateurs sur les périphériques CPU

TensorFlow sélectionne automatiquement le nombre approprié de threads pour paralléliser le calcul de l'opération dans le processus de formation. Cependant, vous pouvez définir le intra_op pool de threads et inter_op paramètres de parallélisme fournis par TensorFlow et utilisez les variables d'environnement de MKL-DNN pour définir la liaison pour le thread du système d'exploitation. Voir le code suivant :

# Set parallelism of intra_op and inter_op
num_cpus = int(os.environ['SM_NUM_CPUS'])
config = tf.ConfigProto(allow_soft_placement=True, device_count={'CPU': num_cpus}, intra_op_parallelism_threads=num_cpus, inter_op_parallelism_threads=num_cpus)
run_config = tf.estimator.RunConfig().replace(session_config = config)

# Use Intel MKL-DNN Setting to accelerate training speed
os.environ["KMP_AFFINITY"]= "verbose,disabled"
os.environ['OMP_NUM_THREADS'] = str(num_cpus)
os.environ['KMP_SETTINGS'] = '1'

La variable d'environnement KMP_AFFINITY de MKL-DNN est réglé sur granularity=fine,compact,1,0 par défaut. Après avoir défini à la fois intra et inter de TensorFlow sur le nombre maximal de vCPU de l'instance actuelle, la limite supérieure d'utilisation du processeur est presque identique au nombre de cœurs physiques de l'instance d'entraînement.

Si vous définissez os.environ["KMP_AFFINITY"]= "verbose,disabled", le thread du système d'exploitation n'est pas lié à l'hyper thread matériel et l'utilisation du processeur peut dépasser le nombre de cœurs physiques.

En ce qui concerne les paramètres du parallélisme intra TensorFlow, du parallélisme inter TensorFlow et du nombre de threads MKL-DNN, différentes combinaisons de ces trois paramètres entraînent des vitesses d'entraînement différentes. Par conséquent, vous devez tester chaque cas pour trouver la meilleure combinaison. Une situation courante consiste à définir les trois paramètres (intra_op_parallelism_threads ainsi que inter_op_parallelism_threads pour TensorFlow, os.environ['OMP_NUM_THREADS'] pour MKL-DNN) à la moitié du nombre de vCPU (noyau physique) ou du nombre total de vCPU.

Méthode tour

Pour répliquer un modèle sur des GPU, chaque GPU obtient sa propre instance de la passe avant. L'instance de la passe avant est appelée un tour. La méthode de la tour est presque toujours utilisée pour les appareils GPU. Pour comparer la vitesse d'entraînement avec d'autres méthodes, nous utilisons également ici la méthode de la tour pour notre appareil CPU.

Si vous ne définissez pas le périphérique CPU manuellement, TensorFlow n'utilise pas la méthode de la tour pour faire la moyenne des gradients, vous n'avez donc pas besoin de mettre à l'échelle la taille du lot dans de tels cas.

  1. Définissez manuellement le périphérique CPU :
device_list = []
if manual_CPU_device_set:
		cpu_prefix=’/cpu:’
		for I in range(1, num_cpus):
			devices_list.append(cpu_prefix + str(i))

  1. Utilisez replicate_model_fn Envelopper model_fn:
DeepFM = tf.estimator.Estimator(model_fn=tf.contrib.estimator.replicate_model_fn(model_fn, devices=device_list), model_dir=FLAGS.model_dir, params=model_params, config=config)

  1. Utilisez TowerOptimizer Envelopper optimizer:
optimizer = tf.contrib.estimator.TowerOptimizer(optimizer)

  1. Enveloppez votre model_fn:
with tf.variable_scope(‘deepfm_model’, reuse=tf.AUTO_REUSE)

  1. Mettre à l'échelle la taille du lot à (NUM_CPU - 1).

Regardons la différence d'utilisation du processeur avec le mode tour activé. La figure suivante montre l'utilisation du processeur de l'instance ml.c5.18xlarge avec la configuration suivante :

Pas de tour + données LibSVM + mode canal + liaison désactivée MKL-DNN + paramètre de parallélisme intra/inter op TensorFlow sur le nombre maximal de vCPU de l'instance

Pas de tour

La figure suivante montre l'utilisation du processeur de l'instance ml.c5.18xlarge avec la configuration suivante :

Tour avec périphérique CPU défini + données LibSVM + mode canal + liaison désactivée MKL-DNN + paramètre de parallélisme intra/inter op TensorFlow sur le nombre maximal de vCPU de l'instance

L'utilisation du processeur est plus élevée lors de l'utilisation de la méthode de la tour et dépasse le nombre de cœurs physiques.

TensorFlow MirroredStratégie

TensorFlow MirroredStrategy signifie une formation synchrone sur plusieurs répliques sur une seule machine. Cette stratégie est généralement utilisée pour la formation sur une machine avec plusieurs GPU. Pour comparer la vitesse d'entraînement avec une autre méthode, nous utilisons MirroredStrategy pour notre appareil CPU.

Lorsque vous utilisez TensorFlow MirroredStrategy, si vous ne définissez pas le périphérique CPU, TensorFlow n'utilise qu'un seul processeur en tant que travailleur unique, ce qui représente un gaspillage de ressources. Nous vous recommandons de configurer manuellement le périphérique CPU, car il effectuera une opération de réduction sur /CPU:0, alors le /CPU:0 l'appareil n'est pas utilisé comme réplique ici. Voir le code suivant :

device_list = []
if manual_CPU_device_set:
		cpu_prefix=’/cpu:’
		for I in range(1, num_cpus):
			devices_list.append(cpu_prefix + str(i))
mirrored_strategy = tf.distribute.MirroredStrategy(devices=devices_list)
	else:
mirrored_strategy = tf.distribute.MirroredStrategy()

# Set strategy to config:
config = tf.estimator.RunConfig(train_distribute=mirrored_strategy,
eval_distribute=mirrored_strategy,
session_config = config)

Vous devez mettre à l'échelle la taille du lot lorsque vous utilisez MirroredStrategy ; par exemple, adaptez la taille du lot à un multiple du nombre de périphériques GPU.

Pour la sous-stratégie lorsque vous définissez le périphérique CPU, si vous ne définissez pas le cross_device_ops paramètre dans tf.distribute.MirroredStrategy(), TensorFlow utilise le ReductionToOneDevice sous-stratégie par défaut. Cependant, si vous définissez HierarchicalCopyAllReduce en tant que sous-stratégie, TensorFlow ne fait que réduire le travail sur /CPU:0. Lorsque vous utilisez l'API d'ensemble de données TensorFlow et distribuez la stratégie ensemble, l'objet d'ensemble de données doit être renvoyé à la place des fonctionnalités et des étiquettes dans la fonction input_fn.

Habituellement, TensorFlow MirroredStrategy est plus lent que la méthode de la tour sur la formation du processeur, nous ne recommandons donc pas d'utiliser MirroredStrategy sur un hôte unique multi-CPU.

Horovod

Horovod est un cadre de formation d'apprentissage en profondeur distribué pour TensorFlow, Keras, PyTorch et Apache MXNet. L'objectif d'Horovod est de rendre l'apprentissage en profondeur distribué rapide et facile à utiliser.

Il existe un paramètre de distribution dans l'API SageMaker Python SDK Estimator, que vous pouvez utiliser pour indiquer la formation distribuée Horovod. SageMaker provisionne l'infrastructure et exécute votre script avec MPI. Voir le code suivant :

hvd_processes_per_host = 4
distribution = {'mpi': { 
'enabled': True, 
'processes_per_host': hvd_processes_per_host,
'custom_mpi_options': '-verbose --NCCL_DEBUG=INFO -x OMPI_MCA_btl_vader_single_copy_mechanism=none' 
} 
}

Lorsque vous choisissez une instance GPU telle que ml.p3.8xlarge, vous devez épingler chaque GPU pour chaque nœud de calcul :

config = tf.ConfigProto()
config.gpu_options.visible_device_list = str(hvd.local_rank())

Pour accélérer la convergence du modèle, mettez à l'échelle le taux d'apprentissage en fonction du nombre de travailleurs conformément à la documentation officielle d'Horovod. Cependant, dans les projets réels, vous devez ajuster le taux d'apprentissage dans une certaine mesure, mais pas en fonction du nombre de travailleurs, ce qui entraîne de mauvaises performances du modèle. Par exemple, si le taux d'apprentissage d'origine est de 0.001, nous adaptons le taux d'apprentissage à 0.0015, même si le nombre de travailleurs est de quatre ou plus.

Généralement, seul le primaire (Horovod rang 0) enregistre le point de contrôle et le modèle ainsi que l'opération d'évaluation. Vous n'avez pas besoin de mettre à l'échelle la taille du lot lorsque vous utilisez Horovod. Offres SageMaker Mode tuyau diffuser des données à partir de Service de stockage simple Amazon (Amazon S3) dans les instances de formation. Lorsque vous activez le mode Pipe, sachez que différents agents sur le même hôte doivent utiliser différents canaux pour éviter les erreurs. En effet, le premier processus de travail lit les données FIFO/canal et les autres processus de travail sur la même instance se bloquent car ils ne peuvent pas lire les données du même FIFO/canal, donc Horovod ne fonctionne pas correctement. Pour éviter ce problème, définissez les canaux en fonction du nombre de nœuds de calcul par instance. Assurez-vous au moins que différents travailleurs sur le même hôte utilisent différents canaux ; le même canal peut être consommé par les travailleurs sur un hôte différent.

Lorsque vous utilisez Horovod, vous pouvez rencontrer l'erreur suivante :

“One or more tensors were submitted to be reduced, gathered or broadcasted by subset of ranks and are waiting for remainder of ranks for more than 60 seconds. This may indicate that different ranks are trying to submit different tensors or that only subset of ranks is submitting tensors, which will cause deadlock.”

La cause possible de ce problème est qu'un certain rang (tel que le rang 0) fonctionne plus lentement ou effectue plus de tâches que les autres rangs, ce qui fait que les autres rangs attendent longtemps. Bien que le rang 0 doive parfois faire plus de travail que les autres rangs, il convient de noter que le rang 0 ne devrait pas faire grand-chose pendant longtemps. Par exemple, pour l'évaluation du modèle sur le jeu de validation et la sauvegarde des points de contrôle lors de la formation, s'il est inévitable que ces opérations prennent beaucoup de temps, ce qui pourrait entraîner des erreurs, une solution de contournement consiste à laisser tous les travailleurs faire le même travail que le rang 0 (points de contrôle sauvegarde, évaluation, etc.).

Le partage de données est l'un des éléments les plus importants à prendre en compte lors de l'utilisation de la formation distribuée. Vous pouvez utiliser TensorFlow dataset.shard() dans votre scénario. SageMaker propose également une fonctionnalité de partition de jeu de données dans le canal d'entrées en mettant distribution=S3shardbykey dans le canal de l'ensemble de données. Voir le code suivant :

dataset = PipeModeDataset(channel, record_format='TFRecord')

number_host = len(FLAGS.hosts)

if FLAGS.enable_data_multi_path : # If there are multi channels mapping with different S3 path
    if FLAGS.enable_s3_shard == False :
        if number_host > 1:
            index = hvd.rank() // FLAGS.worker_per_host
            dataset = dataset.shard(number_host, index)
else :
    if FLAGS.enable_s3_shard :
        dataset = dataset.shard(FLAGS.worker_per_host, hvd.local_rank())
    else :
        dataset = dataset.shard(hvd.size(), hvd.rank())

La figure suivante montre le résultat lors de l'utilisation de Horovod (ml.c5.18xlarge, Horovod + LibSVM + paramètres intra op et inter op par défaut), que vous pouvez comparer à la méthode de la tour.

Horovod

Entraînement distribué avec plusieurs GPU sur une seule instance

Il est normal de commencer une formation distribuée avec plusieurs GPU sur une seule instance, car les scientifiques des données n'ont besoin de gérer qu'une seule instance et de tirer parti de l'interconnexion à haut débit entre les GPU. Les tâches de formation SageMaker prennent en charge plusieurs types d'instance qui ont plusieurs GPU sur une seule instance, tels que ml.p3.8xlarge, ml.p3.16xlarge, ml.p3dn.24xlarge et ml.p4d.24xlarge. La méthode est la même que plusieurs processeurs dans une seule instance, mais avec quelques modifications dans le script.

Méthode tour

La méthode de la tour ici est presque la même que dans la formation multi-CPU. Vous devez mettre à l'échelle la taille du lot en fonction du nombre de GPU utilisés.

TensorFlow MirroredStratégie

La sous-stratégie par défaut de MirroredStrategy is NcclAllReduce. Vous devez mettre à l'échelle la taille du lot en fonction du nombre de GPU utilisés. Voir le code suivant :

mirrored_strategy = tf.distribute.MirroredStrategy()
config = tf.estimator.RunConfig(train_distribute=mirrored_strategy,
				eval_distribute=mirrored_strategy)

Accélérer la formation sur plusieurs instances

La mise à l'échelle est toujours une option pour améliorer la vitesse d'entraînement. De plus en plus de scientifiques des données choisissent cette option par défaut en ce qui concerne la formation distribuée. Dans cette section, nous discutons des stratégies de formation distribuée avec plusieurs hôtes.

Plusieurs processeurs avec plusieurs instances

Il existe quatre méthodes principales pour utiliser plusieurs processeurs avec plusieurs instances lors de l'activation de la formation distribuée :

    • Serveur de paramètres sans réglage manuel du parallélisme des opérateurs sur les appareils CPU
    • Serveur de paramètres avec réglage manuel du parallélisme des opérateurs sur les appareils CPU
    • Serveur de paramètres avec tour (configuration manuelle des périphériques CPU et configuration allow_soft_placement=True in tf.ConfigProto)
    • Horovod

Lors de l'utilisation d'un serveur de paramètres dans le tf.estimator API, le chemin du point de contrôle doit être un chemin partageable tel qu'Amazon S3 ou le chemin local de Service de fichiers élastique Amazon (Amazon EFS) mappage vers le conteneur. Pour un serveur de paramètres dans tf.keras, le chemin du point de contrôle peut être défini sur le chemin local. Pour Horovod, le chemin du point de contrôle peut être défini sur un chemin local de l'instance de formation.

Lors de l'utilisation d'un serveur de paramètres et du tf.estimator API avec le chemin du point de contrôle vers Amazon S3, si le modèle est assez volumineux, vous pouvez rencontrer une erreur du principal bloqué lors de l'enregistrement du point de contrôle sur S3. Vous pouvez utiliser le conteneur intégré SageMaker TensorFlow 1.15 ou TensorFlow 1.15.2 ou utiliser Amazon EFS comme chemin de point de contrôle du partage.

Lors de l'utilisation d'un serveur de paramètres pour plusieurs hôtes, la charge des paramètres sur chaque processus de serveur de paramètres peut être déséquilibrée (en particulier lorsqu'il existe des variables de table d'intégration relativement volumineuses), ce qui peut entraîner des erreurs. Vous pouvez vérifier la taille de fichier de chaque point de contrôle de la partition dans Amazon S3 pour déterminer si les paramètres sur le serveur de paramètres sont équilibrés, car chaque serveur de paramètres correspond à une partition du fichier de point de contrôle. Pour éviter de tels problèmes, vous pouvez utiliser la fonction de partitionnement pour essayer de répartir uniformément les paramètres de chaque serveur de paramètres :

with tf.variable_scope('deepfm_model', reuse=tf.AUTO_REUSE, partitioner = tf.fixed_size_partitioner(num_shards=len(FLAGS.hosts))):

GPU unique avec plusieurs instances

Les tâches de formation SageMaker prennent en charge les instances qui n'ont qu'un seul GPU, comme les séries ml.p3.xlarge, ml.g4dn et ml.g5. Deux méthodes principales sont utilisées dans ce scénario : les serveurs de paramètres et Horovod.

La méthode de formation distribuée du serveur de paramètres intégré de SageMaker consiste à démarrer un processus de serveur de paramètres et un processus de travail pour chaque instance de formation (chaque serveur de paramètres n'est responsable que d'une partie des paramètres du modèle), de sorte que la valeur par défaut est multi-machine. Formation GPU. La formation distribuée du serveur de paramètres intégré SageMaker est une méthode de mise à jour de gradient asynchrone. Pour réduire l'impact des mises à jour asynchrones sur la convergence de la formation, il est recommandé de réduire le taux d'apprentissage. Si vous souhaitez utiliser tous les GPU sur l'instance, vous devez utiliser une combinaison de serveurs de paramètres et de la méthode tour.

Pour Horovod, il suffit de régler processes_per_host=1 dans le paramètre de distribution de l'API SageMaker Python Estimator.

Plusieurs GPU avec plusieurs instances

Pour les serveurs de paramètres et la méthode tour, les modifications de code sont fondamentalement les mêmes que pour la méthode tour pour une seule instance avec plusieurs GPU, et il n'est pas nécessaire de définir manuellement les périphériques GPU.

Pour Horovod, définissez process_per_host dans le paramètre de distribution sur le nombre de GPU de chaque instance d'entraînement. Si vous utilisez le mode Pipe, le nombre de nœuds de calcul par instance doit correspondre au nombre de canaux.

Canalisations de données

En plus de l'infrastructure dont nous avons parlé, il y a une autre chose importante à considérer : le pipeline de données. Un pipeline de données fait référence à la façon dont vous chargez et transformez les données avant qu'elles n'alimentent les réseaux de neurones. Le CPU est utilisé pour préparer les données, tandis que le GPU est utilisé pour calculer les données du CPU. Étant donné que le GPU est une ressource coûteuse, plus de temps d'inactivité du GPU est inefficace ; un bon pipeline de données dans votre travail de formation pourrait améliorer l'utilisation du GPU et du CPU.

Lorsque vous essayez d'optimiser votre pipeline d'entrée de données TensorFlow, tenez compte de l'ordre des API utilisé dans Ensembles de données TensorFlow, la taille des données d'entraînement (beaucoup de petits fichiers ou plusieurs fichiers volumineux), la taille du lot, etc.

Regardons l'interaction entre le GPU et le CPU pendant l'entraînement. Les figures suivantes comparent les interactions avec et sans pipeline.

pipeline

Un meilleur pipeline pourrait réduire le temps d'inactivité du GPU. Tenez compte des conseils suivants :

  • Utiliser une logique de fonction simple pour extraire les caractéristiques et les étiquettes
  • Prélecture d'échantillons en mémoire
  • Réduisez les E/S disque inutiles et les E/S réseau
  • Mettre en cache les caractéristiques et les étiquettes traitées en mémoire
  • Réduire le nombre de temps de réplication entre CPU et GPU
  • Demandez à différents travailleurs de traiter différentes parties de l'ensemble de données de formation
  • Réduisez les temps d'appel de l'API d'ensemble de données TensorFlow

TensorFlow fournit une API de transformation liée aux formats d'ensemble de données, et l'ordre de l'API de transformation dans TensorFlow affecte beaucoup la vitesse de formation. Le meilleur ordre d'appel de l'API d'ensemble de données TensorFlow doit être testé. Voici quelques principes de base :

  • Utilisez une carte vectorisée. Cela signifie appeler d'abord l'API de lot de l'ensemble de données TensorFlow, puis l'API de carte de l'ensemble de données. La fonction d'analyse personnalisée fournie dans la fonction de carte, telle que decode_tfrecord dans l'exemple de code, analyse un mini lot de données. Au contraire, la carte d'abord, puis le lot est une carte scalaire, et la fonction d'analyseur personnalisé ne traite qu'un seul échantillon.
  • Utilisez l'API de cache d'ensemble de données TensorFlow pour mettre en cache les fonctionnalités et les étiquettes. Placez l'API de cache de l'ensemble de données TensorFlow avant l'API de répétition de l'ensemble de données TensorFlow, sinon l'utilisation de la RAM augmente de manière linéaire d'époque en époque. Si l'ensemble de données est aussi volumineux que la RAM, n'utilisez pas l'API de cache d'ensemble de données TensorFlow. Si vous devez utiliser l'API de cache d'ensemble de données TensorFlow et l'API de lecture aléatoire, envisagez d'utiliser l'ordre suivant : créez un objet d'ensemble de données TensorFlow -> API de cache -> API de lecture aléatoire -> API de traitement par lots -> API de mappage -> API de répétition -> API de prélecture.
  • Utilisez l'option tfrecord format de jeu de données supérieur au format LibSVM.
  • Le mode Fichier ou le mode Pipe dépend du format de votre jeu de données et de la quantité de fichiers. La tfrecorddataset L'API peut définir num_parallel_reads pour lire plusieurs fichiers en parallèle et définir buffer_size pour optimiser la lecture des données, alors que pipemodedataset L'API n'a pas de tels paramètres. Le mode Pipe est plus adapté aux situations où un seul fichier est volumineux et le nombre total de fichiers est petit. Nous vous recommandons d'utiliser une tâche de traitement SageMaker pour effectuer le travail de prétraitement, comme joindre plusieurs fichiers à un fichier plus volumineux en fonction des étiquettes, utiliser une méthode d'échantillonnage pour rendre l'ensemble de données plus équilibré et mélanger l'ensemble de données équilibré.

Consultez l'exemple de code suivant :

def decode_tfrecord(batch_examples):
        # The feature definition here should BE consistent with LibSVM TO TFRecord process.
        features = tf.parse_example(batch_examples,
                                           features={
                                               "label": tf.FixedLenFeature([], tf.float32),
                                               "ids": tf.FixedLenFeature(dtype=tf.int64, shape=[FLAGS.field_size]),
                                               "values": tf.FixedLenFeature(dtype=tf.float32, shape=[FLAGS.field_size]) 
                                           })
        
        batch_label = features["label"]
        batch_ids = features["ids"]
        batch_values = features["values"]
        
        return {"feat_ids": batch_ids, "feat_vals": batch_values}, batch_label


    def decode_libsvm(line):
        columns = tf.string_split([line], ' ')
        labels = tf.string_to_number(columns.values[0], out_type=tf.float32)
        splits = tf.string_split(columns.values[1:], ':')
        id_vals = tf.reshape(splits.values,splits.dense_shape)
        feat_ids, feat_vals = tf.split(id_vals,num_or_size_splits=2,axis=1)
        feat_ids = tf.string_to_number(feat_ids, out_type=tf.int32)
        feat_vals = tf.string_to_number(feat_vals, out_type=tf.float32)
        return {"feat_ids": feat_ids, "feat_vals": feat_vals}, labels

if FLAGS.pipe_mode == 0:
        dataset = tf.data.TFRecordDataset(filenames)
    else :
        # Enter Pipe mode
        dataset = PipeModeDataset(channel, record_format='TFRecord')
        
    if FLAGS.enable_s3_shard == False:
        host_rank = FLAGS.hosts.index(FLAGS.current_host)
        number_host = len(FLAGS.hosts)
        dataset = dataset.shard(number_host, host_rank)
    
    dataset = dataset.batch(batch_size, drop_remainder=True) # Batch size to use
    dataset = dataset.map(decode_tfrecord,
                          num_parallel_calls=tf.data.experimental.AUTOTUNE) 

    if num_epochs > 1:
        dataset = dataset.repeat(num_epochs)
    dataset = dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)

Pour l'entraînement sur les instances de processeur, la définition du parallélisme de intra op, inter op, et la variable d'environnement de MKL-DNN est un bon point de départ.

Entraînement de précision mixte automatique

La dernière chose dont nous discutons est l'entraînement automatique de précision mixte, qui peut accélérer la vitesse et entraîner des performances du modèle. Au moment d'écrire ces lignes, les GPU Nvidia V100 (instance P3) et A100 (instance P4dn) prennent en charge le noyau Tensor. Vous pouvez activer l'entraînement de précision mixte dans TensorFlow lorsque vous utilisez ces types d'instances. À partir de la version 1.14, TensorFlow prend en charge l'entraînement automatique de précision mixte. Vous pouvez utiliser l'instruction suivante pour encapsuler votre optimiseur d'origine :

tf.train.experimental.enable_mixed_precision_graph_rewrite(optimizer)

Si le modèle est petit et que l'utilisation du GPU est faible, l'entraînement automatique de précision mixte ne présente aucun avantage. Si le modèle est grand, l'entraînement de précision mixte automatique peut accélérer la vitesse d'entraînement.

Conclusion

Lorsque vous démarrez votre formation de modèle d'apprentissage en profondeur dans SageMaker, tenez compte des conseils suivants pour obtenir une vitesse de formation plus rapide :

  • Essayez d'abord la méthode multi-CPU, mono-instance ou mono-GPU, mono-instance. Si l'utilisation CPU/GPU est très élevée (par exemple plus de 90 %), passez à l'étape suivante.
  • Essayez plus de CPU sur un seul hôte ou plus de GPU sur un seul hôte. Si l'utilisation est proche de l'utilisation maximale des CPU ou des GPU, passez à l'étape suivante.
  • Essayez plusieurs CPU ou plusieurs GPU avec plusieurs hôtes.
  • Vous devez modifier les codes lorsque vous utilisez des serveurs de paramètres ou Horovod. La modification du code n'est pas la même pour l'API basée sur les sessions TensorFlow, tf.estimator API, et tf.keras API. Un serveur de paramètres ou Horovod peut afficher différentes vitesses d'entraînement dans différents cas et tâches d'entraînement, alors essayez les deux méthodes si vous avez le temps et le budget pour déterminer la meilleure.

Gardez à l'esprit les conseils suivants :

  • Vérifiez l'utilisation avant la mise à l'échelle, optimisez votre pipeline de données et faites en sorte que le CPU et le GPU se chevauchent dans la chronologie.
  • D'abord scale-up, puis scale-out.
  • Si vous ne pouvez pas augmenter l'utilisation de votre GPU après toutes les méthodes, essayez CPU. Il existe de nombreux cas (en particulier pour le modèle de classement du taux de clics) où le temps de formation total de la formation d'instance CPU est plus court et plus rentable que la formation d'instance GPU.

Nous avons également un exemple de code dans le GitHub repo, où nous montrons deux exemples de formation distribuée DeepFM sur SageMaker. L'un est un serveur de paramètres TensorFlow sur les instances CPU, l'autre est Horovod sur les instances GPU.


À propos des auteurs

Bonnes pratiques pour la formation à l'accélération TensorFlow 1.x sur Amazon SageMaker PlatoBlockchain Data Intelligence. Recherche verticale. Aï. Yu Hui Liang est un architecte principal de solutions d'apprentissage automatique. Il se concentre sur la promotion et l'application de l'apprentissage automatique et est profondément impliqué dans les projets d'apprentissage automatique de nombreux clients. Il possède une riche expérience dans la formation distribuée en apprentissage profond, les systèmes de recommandation et la publicité informatique.

Bonnes pratiques pour la formation à l'accélération TensorFlow 1.x sur Amazon SageMaker PlatoBlockchain Data Intelligence. Recherche verticale. Aï.Shishuai Wang est un architecte senior de solutions d'apprentissage automatique. Il travaille avec les clients d'AWS pour les aider à adopter l'apprentissage automatique à grande échelle. Il aime regarder des films et voyager à travers le monde.

Horodatage:

Plus de Apprentissage automatique AWS