Best Practices für das TensorFlow 1.x-Beschleunigungstraining für Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.

Best Practices für TensorFlow 1.x-Beschleunigungstraining auf Amazon SageMaker

Heutzutage verwenden viele Kunden TensorFlow, um Deep-Learning-Modelle für ihre Klickrate in Werbung und Personalisierungsempfehlungen im E-Commerce zu trainieren. Wenn sich das Verhalten ihrer Kunden ändert, können sie jeden Tag große Mengen neuer Daten ansammeln. Die Iteration von Modellen gehört zu den täglichen Aufgaben eines Datenwissenschaftlers, aber er steht vor dem Problem, dass das Training mit großen Datensätzen zu lange dauert.

Amazon Sage Maker ist eine vollständig verwaltete Plattform für maschinelles Lernen (ML), die Data Scientists helfen könnte, sich auf Modelle statt auf Infrastruktur zu konzentrieren, mit nativer Unterstützung für Bring-your-own-Algorithmen und Frameworks wie TensorFlow und PyTorch. SageMaker bietet flexible verteilte Schulungsoptionen, die sich an Ihre spezifischen Arbeitsabläufe anpassen. Da vielen Datenwissenschaftlern möglicherweise die Erfahrung im Beschleunigungstrainingsprozess fehlt, zeigen wir Ihnen in diesem Beitrag die Faktoren, die für schnelles Deep-Learning-Modelltraining wichtig sind, und die Best Practices des Beschleunigungstrainings für TensorFlow 1.x auf SageMaker. Wir haben auch einen Beispielcode von DeepFM verteiltes Training zu SageMaker auf der GitHub Repo.

Es gibt viele Faktoren, die Sie berücksichtigen sollten, um die CPU-/GPU-Auslastung zu maximieren, wenn Sie Ihr TensorFlow-Skript auf SageMaker ausführen, wie z. B. Infrastruktur, Beschleunigertyp, verteilte Trainingsmethode, Datenlademethode, gemischtes Präzisionstraining und mehr.

Wir diskutieren Best Practices in den folgenden Bereichen:

  • Beschleunigen Sie das Training auf einer einzigen Instanz
  • Beschleunigen Sie das Training auf mehreren Instanzen
  • Datenpipelines
  • Automatisches gemischtes Präzisionstraining

Beschleunigen Sie das Training auf einer einzigen Instanz

Wenn Sie Ihr TensorFlow-Skript auf einer einzelnen Instanz ausführen, können Sie eine computeroptimierte Serie wie die auswählen Amazon Elastic Compute-Cloud (Amazon EC2) C5-Serie oder eine Accelerated-Computing-Serie mit mehreren GPUs in einer einzigen Instanz wie p3.8xlarge, p3.16xlarge, p3dn.24xlarge und p4d.24xlarge.

In diesem Abschnitt diskutieren wir Strategien für mehrere CPUs auf einer einzelnen Instanz und verteiltes Training mit mehreren GPUs auf einer einzelnen Instanz.

Mehrere CPUs auf einer einzigen Instanz

In diesem Abschnitt erörtern wir die manuelle Einstellung der Parallelität von Operatoren auf CPU-Geräten, die Tower-Methode, TensorFlow MirroredStrategy und Horovod.

Manuelles Einstellen der Parallelität der Operatoren auf CPU-Geräten

TensorFlow wählt automatisch die geeignete Anzahl von Threads aus, um die Operationsberechnung im Trainingsprozess zu parallelisieren. Allerdings könnte man das einstellen intra_op Thread-Pool und inter_op Parallelitätseinstellungen, die von TensorFlow bereitgestellt werden, und Umgebungsvariablen von MKL-DNN verwenden, um die Bindung für den Betriebssystem-Thread festzulegen. Siehe folgenden Code:

# 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'

Die Umgebungsvariable KMP_AFFINITY von MKL-DNN eingestellt ist granularity=fine,compact,1,0 standardmäßig. Nachdem Sie sowohl intra als auch inter von TensorFlow auf die maximale Anzahl von vCPUs der aktuellen Instanz festgelegt haben, ist die Obergrenze der CPU-Auslastung fast identisch mit der Anzahl der physischen Kerne der Trainingsinstanz.

Wenn Sie einstellen os.environ["KMP_AFFINITY"]= "verbose,disabled", ist der Betriebssystemthread nicht an den Hardware-Hyperthread gebunden und die CPU-Auslastung könnte die Anzahl der physischen Kerne überschreiten.

In Bezug auf die Einstellungen von TensorFlow Intra-Parallelität, TensorFlow Inter-Parallelität und der Anzahl der MKL-DNN-Threads führen unterschiedliche Kombinationen dieser drei Parameter zu unterschiedlichen Trainingsgeschwindigkeiten. Daher müssen Sie jeden Fall testen, um die beste Kombination zu finden. Eine häufige Situation ist die Einstellung der drei Parameter (intra_op_parallelism_threads und inter_op_parallelism_threads für TensorFlow, os.environ['OMP_NUM_THREADS'] für MKL-DNN) auf die Hälfte der vCPUs (physischer Kern) oder die Gesamtzahl der vCPUs.

Tower-Methode

Um ein Modell über GPUs zu replizieren, erhält jede GPU ihre eigene Instanz des Forward Pass. Die Instanz des Vorwärtsdurchgangs wird als a bezeichnet Turm. Die Tower-Methode wird fast immer für GPU-Geräte verwendet. Um die Trainingsgeschwindigkeit mit anderen Methoden zu vergleichen, verwenden wir auch hier die Tower-Methode für unser CPU-Gerät.

Wenn Sie das CPU-Gerät nicht manuell festlegen, verwendet TensorFlow nicht die Tower-Methode, um die Gradienten zu mitteln, sodass Sie die Stapelgröße in solchen Fällen nicht skalieren müssen.

  1. Stellen Sie das CPU-Gerät manuell ein:
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. Verwenden Sie die replicate_model_fn einpacken 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. Verwenden Sie die TowerOptimizer einpacken optimizer:
optimizer = tf.contrib.estimator.TowerOptimizer(optimizer)

  1. Wickeln Sie Ihre model_fn:
with tf.variable_scope(‘deepfm_model’, reuse=tf.AUTO_REUSE)

  1. Batchgröße skalieren auf (NUM_CPU – 1).

Schauen wir uns den Unterschied der CPU-Auslastung bei aktiviertem Tower-Modus an. Die folgende Abbildung zeigt die CPU-Auslastung der ml.c5.18xlarge-Instance mit der folgenden Konfiguration:

Kein Tower + LibSVM-Daten + Pipe-Modus + MKL-DNN-Bindung deaktivieren + TensorFlow-Intra-/Inter-Op-Parallelitätseinstellung auf maximale Anzahl vCPUs der Instanz

Kein Turm

Die folgende Abbildung zeigt die CPU-Auslastung der ml.c5.18xlarge-Instance mit der folgenden Konfiguration:

Tower mit festgelegtem CPU-Gerät + LibSVM-Daten + Pipe-Modus + MKL-DNN-Bindung deaktivieren + TensorFlow-Intra-/Inter-Op-Parallelitätseinstellung auf maximale Anzahl von vCPUs der Instanz

Die CPU-Auslastung ist bei der Tower-Methode höher und übersteigt die Anzahl der physischen Kerne.

TensorFlow MirroredStrategy

TensorFlow MirroredStrategy bedeutet synchrones Training über mehrere Replikate auf einem Computer. Diese Strategie wird normalerweise für das Training auf einem Computer mit mehreren GPUs verwendet. Um die Trainingsgeschwindigkeit mit einer anderen Methode zu vergleichen, verwenden wir MirroredStrategy für unser CPU-Gerät.

Wenn Sie bei Verwendung von TensorFlow MirroredStrategy das CPU-Gerät nicht festlegen, verwendet TensorFlow nur eine CPU als einzelnen Worker, was eine Ressourcenverschwendung darstellt. Wir empfehlen, das CPU-Gerät manuell einzustellen, da es eine Reduzierungsoperation durchführt /CPU:0, So dass die /CPU:0 Das Gerät wird hier nicht als Replik verwendet. Siehe folgenden Code:

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)

Sie müssen die Batchgröße skalieren, wenn Sie MirroredStrategy verwenden; Skalieren Sie beispielsweise die Stapelgröße auf ein Vielfaches der Anzahl der GPU-Geräte.

Für die Unterstrategie, wenn Sie das CPU-Gerät festlegen, wenn Sie das nicht festlegen cross_device_ops Parameter in tf.distribute.MirroredStrategy(), verwendet TensorFlow die ReductionToOneDevice Unterstrategie standardmäßig. Allerdings, wenn Sie festlegen HierarchicalCopyAllReduce Als Unterstrategie erledigt TensorFlow nur die Reduzierungsarbeit /CPU:0. Wenn Sie die TensorFlow-Dataset-API und die Verteilungsstrategie zusammen verwenden, sollte das Dataset-Objekt anstelle von Features und Bezeichnungen in Funktion zurückgegeben werden input_fn.

Normalerweise ist TensorFlow MirroredStrategy beim CPU-Training langsamer als die Tower-Methode, daher empfehlen wir nicht, MirroredStrategy auf einem einzelnen Host mit mehreren CPUs zu verwenden.

Horowod

Horowod ist ein verteiltes Deep-Learning-Trainingsframework für TensorFlow, Keras, PyTorch und Apache MXNet. Das Ziel von Horovod ist es, verteiltes Deep Learning schnell und einfach nutzbar zu machen.

Es gibt einen Parameter von distribution in der SageMaker Python SDK Estimator API, die Sie verwenden könnten, um das verteilte Horovod-Training anzugeben. SageMaker stellt die Infrastruktur bereit und führt Ihr Skript mit MPI aus. Siehe folgenden Code:

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' 
} 
}

Wenn Sie eine GPU-Instanz wie ml.p3.8xlarge auswählen, müssen Sie jede GPU für jeden Worker anheften:

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

Um die Modellkonvergenz zu beschleunigen, skalieren Sie die Lernrate nach der Anzahl der Arbeiter gemäß der offiziellen Dokumentation von Horovod. In realen Projekten sollten Sie die Lernrate jedoch bis zu einem gewissen Grad skalieren, jedoch nicht anhand der Anzahl der Arbeiter, was zu einer schlechten Modellleistung führt. Wenn die ursprüngliche Lernrate beispielsweise 0.001 beträgt, skalieren wir die Lernrate auf 0.0015, selbst wenn die Anzahl der Arbeiter vier oder mehr beträgt.

Im Allgemeinen speichert nur der primäre (Horovod-Rang 0) den Prüfpunkt und das Modell sowie die Bewertungsoperation. Sie müssen die Stapelgröße nicht skalieren, wenn Sie Horovod verwenden. SageMaker-Angebote Rohrmodus um Daten zu streamen Amazon Simple Storage-Service (Amazon S3) in Trainingsinstanzen. Beachten Sie beim Aktivieren des Pipe-Modus, dass verschiedene Worker auf demselben Host unterschiedliche Kanäle verwenden müssen, um Fehler zu vermeiden. Dies liegt daran, dass der erste Worker-Prozess die FIFO-/Kanaldaten liest und andere Worker-Prozesse auf derselben Instanz hängen bleiben, weil sie keine Daten aus demselben FIFO/Kanal lesen können, sodass Horovod nicht ordnungsgemäß funktioniert. Um dieses Problem zu vermeiden, legen Sie die Kanäle entsprechend der Anzahl der Worker pro Instanz fest. Stellen Sie zumindest sicher, dass verschiedene Worker auf demselben Host unterschiedliche Kanäle nutzen; derselbe Kanal kann von Arbeitern auf einem anderen Host genutzt werden.

Bei der Verwendung von Horovod kann der folgende Fehler auftreten:

“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.”

Die mögliche Ursache für dieses Problem ist, dass ein bestimmter Rang (z. B. Rang 0) langsamer arbeitet oder mehr Jobs erledigt als andere Ränge, und dies dazu führt, dass andere Ränge lange warten. Obwohl Rang 0 manchmal mehr Arbeit leisten muss als andere Ränge, sollte beachtet werden, dass Rang 0 lange Zeit nicht viel leisten sollte. Wenn beispielsweise für die Modellbewertung des Validierungssatzes und das Speichern von Checkpoints während des Trainings unvermeidlich ist, dass diese Vorgänge lange dauern, was zu Fehlern führen kann, besteht eine Problemumgehung darin, alle Worker die gleiche Arbeit wie Rang 0 (Checkpoints Speichern, Auswerten usw.).

Data Sharding ist eines der wichtigsten Dinge, die bei der Verwendung von verteiltem Training zu berücksichtigen sind. Sie können TensorFlow verwenden dataset.shard() in deinem Skript. SageMaker bietet auch eine Dataset-Shard-Funktion in der Eingangskanal indem man es einstellt distribution=S3shardbykey im Datensatzkanal. Siehe folgenden Code:

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())

Die folgende Abbildung zeigt das Ergebnis bei Verwendung von Horovod (ml.c5.18xlarge, Horovod + LibSVM + default intra op and inter op setting), das Sie mit der Tower-Methode vergleichen können.

Horowod

Verteiltes Training mit mehreren GPUs auf einer einzigen Instanz

Es ist normal, das verteilte Training mit mehreren GPUs auf einer einzigen Instanz zu starten, da Data Scientists nur eine Instanz verwalten und die Vorteile der Hochgeschwindigkeitsverbindung zwischen GPUs nutzen müssen. SageMaker-Trainingsjobs unterstützen mehrere Instance-Typen, die mehrere GPUs auf einer einzelnen Instance haben, z. B. ml.p3.8xlarge, ml.p3.16xlarge, ml.p3dn.24xlarge und ml.p4d.24xlarge. Die Methode ist die gleiche wie bei mehreren CPUs in einer einzelnen Instanz, jedoch mit einigen Änderungen im Skript.

Tower-Methode

Die Tower-Methode ist hier fast die gleiche wie beim Multi-CPU-Training. Sie müssen die Stapelgröße entsprechend der Anzahl der verwendeten GPUs skalieren.

TensorFlow MirroredStrategy

Die Standard-Unterstrategie von MirroredStrategy is NcclAllReduce. Sie müssen die Stapelgröße entsprechend der Anzahl der verwendeten GPUs skalieren. Siehe folgenden Code:

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

Beschleunigen Sie das Training auf mehreren Instanzen

Scaling Out ist immer eine Option, um die Trainingsgeschwindigkeit zu verbessern. Immer mehr Datenwissenschaftler wählen dies als Standardoption in Bezug auf verteiltes Training. In diesem Abschnitt diskutieren wir Strategien für verteiltes Training mit mehreren Hosts.

Mehrere CPUs mit mehreren Instanzen

Es gibt vier Hauptmethoden für die Verwendung mehrerer CPUs mit mehreren Instanzen beim Aktivieren des verteilten Trainings:

    • Parameterserver ohne manuelles Einstellen der Parallelität der Operatoren auf CPU-Geräten
    • Parameterserver mit manueller Einstellung der Operatorparallelität auf CPU-Geräten
    • Parameterserver mit Turm (CPU-Geräte manuell einstellen und einstellen allow_soft_placement=True in tf.ConfigProto)
    • Horowod

Bei Verwendung eines Parameterservers in der tf.estimator API muss der Pfad des Prüfpunkts ein gemeinsam nutzbarer Pfad wie Amazon S3 oder der lokale Pfad von sein Amazon Elastic File Service (Amazon EFS)-Zuordnung zum Container. Für einen Parameterserver in tf.keras, kann der Checkpoint-Pfad auf den lokalen Pfad gesetzt werden. Für Horovod kann der Prüfpunktpfad auf einen lokalen Pfad der Trainingsinstanz festgelegt werden.

Bei Verwendung eines Parameterservers und der tf.estimator API mit dem Checkpoint-Pfad zu Amazon S3, wenn das Modell ziemlich groß ist, tritt möglicherweise ein Fehler auf, dass der primäre beim Speichern des Checkpoints in S3 hängen bleibt. Sie können den in SageMaker integrierten Container TensorFlow 1.15 oder TensorFlow 1.15.2 oder Amazon EFS als Prüfpunktpfad der Freigabe verwenden.

Wenn Sie einen Parameterserver für mehrere Hosts verwenden, kann die Parameterlast auf jedem Parameterserverprozess unausgeglichen sein (insbesondere wenn relativ große Einbettungstabellenvariablen vorhanden sind), was zu Fehlern führen kann. Sie können die Dateigröße jedes Prüfpunkts des Shards in Amazon S3 überprüfen, um festzustellen, ob die Parameter auf dem Parameterserver ausgeglichen sind, da jeder Parameterserver einem Shard der Prüfpunktdatei entspricht. Um solche Probleme zu vermeiden, können Sie die Partitionierungsfunktion verwenden, um zu versuchen, die Parameter jedes Parameterservers gleichmäßig zu verteilen:

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

Einzelne GPU mit mehreren Instanzen

SageMaker-Trainingsjobs unterstützen Instanzen mit nur einer GPU, wie die Serien ml.p3.xlarge, ml.g4dn und ml.g5. In diesem Szenario werden zwei Hauptmethoden verwendet: Parameterserver und Horovod.

Die eingebaute verteilte Trainingsmethode des Parameterservers von SageMaker besteht darin, einen Parameterserverprozess und einen Arbeitsprozess für jede Trainingsinstanz zu starten (jeder Parameterserver ist nur für einen Teil der Modellparameter verantwortlich), daher ist die Standardeinstellung Multi-Computer Single- GPU-Training. Das in SageMaker integrierte verteilte Training für den Parameterserver ist eine asynchrone Gradientenaktualisierungsmethode. Um die Auswirkungen asynchroner Aktualisierungen auf die Trainingskonvergenz zu reduzieren, wird empfohlen, die Lernrate zu reduzieren. Wenn Sie alle GPUs auf der Instanz verwenden möchten, müssen Sie eine Kombination aus Parameterservern und der Tower-Methode verwenden.

Für Horovod einfach einstellen processes_per_host=1 im Verteilungsparameter der SageMaker Python Estimator API.

Mehrere GPUs mit mehreren Instanzen

Bei Parameterservern und der Tower-Methode sind die Codeänderungen im Grunde die gleichen wie bei der Tower-Methode für eine einzelne Instanz mit mehreren GPUs, und es ist nicht erforderlich, die GPU-Geräte manuell festzulegen.

Legen Sie für Horovod „processes_per_host“ im Verteilungsparameter auf die Anzahl der GPUs jeder Trainingsinstanz fest. Wenn Sie den Pipe-Modus verwenden, muss die Anzahl der Worker pro Instanz mit der Anzahl der Kanäle übereinstimmen.

Datenpipelines

Neben der besprochenen Infrastruktur gibt es noch eine weitere wichtige Sache zu beachten: die Datenpipeline. Eine Datenpipeline bezieht sich darauf, wie Sie Daten laden und transformieren, bevor sie in neuronale Netze eingespeist werden. Die CPU wird verwendet, um Daten vorzubereiten, während die GPU verwendet wird, um die Daten von der CPU zu berechnen. Da GPU eine teure Ressource ist, ist mehr GPU-Leerlaufzeit ineffizient; Eine gute Datenpipeline in Ihrem Trainingsjob könnte die GPU- und CPU-Auslastung verbessern.

Wenn Sie versuchen, Ihre TensorFlow-Dateneingabepipeline zu optimieren, sollten Sie die in verwendete API-Reihenfolge berücksichtigen TensorFlow-Datensätze, die Größe der Trainingsdaten (viele kleine Dateien oder mehrere große Dateien), die Stapelgröße und so weiter.

Schauen wir uns das Zusammenspiel zwischen GPU und CPU während des Trainings an. Die folgenden Abbildungen vergleichen Interaktionen mit und ohne Pipeline.

Pipeline

Eine bessere Pipeline könnte die GPU-Leerlaufzeit reduzieren. Beachten Sie die folgenden Tipps:

  • Verwenden Sie einfache Funktionslogik beim Extrahieren von Merkmalen und Beschriftungen
  • Samples vorab in den Speicher laden
  • Reduzieren Sie unnötige Festplatten-E/A und Netzwerk-E/A
  • Cachen Sie die verarbeiteten Features und Beschriftungen im Arbeitsspeicher
  • Reduzieren Sie die Anzahl der Replikationszeiten zwischen CPU und GPU
  • Lassen Sie unterschiedliche Mitarbeiter mit unterschiedlichen Teilen des Trainingsdatensatzes arbeiten
  • Reduzieren Sie die Aufrufzeiten der TensorFlow-Dataset-API

TensorFlow bietet eine Transformations-API für Datensatzformate, und die Reihenfolge der Transformations-API in TensorFlow wirkt sich stark auf die Trainingsgeschwindigkeit aus. Die beste Reihenfolge zum Aufrufen der TensorFlow-Dataset-API muss getestet werden. Im Folgenden einige Grundprinzipien:

  • Verwenden Sie eine vektorisierte Karte. Rufen Sie also zuerst die TensorFlow-Dataset-Batch-API und dann die Dataset-Map-API auf. Die benutzerdefinierte Parsing-Funktion, die in der Kartenfunktion bereitgestellt wird, wie z decode_tfrecord analysiert im Beispielcode einen Minibatch von Daten. Im Gegensatz dazu ist „map first and then batch“ eine skalare Zuordnung, und die benutzerdefinierte Parserfunktion verarbeitet nur ein Sample.
  • Verwenden Sie die Dataset-Cache-API von TensorFlow, um Features und Labels zwischenzuspeichern. Platzieren Sie die TensorFlow-Datensatz-Cache-API vor der TensorFlow-Datensatz-Wiederholungs-API, andernfalls steigt die RAM-Nutzung von Epoche zu Epoche linear an. Wenn das Dataset so groß wie RAM ist, verwenden Sie nicht die Dataset-Cache-API von TensorFlow. Wenn Sie die TensorFlow-Dataset-Cache-API und die Shuffle-API verwenden müssen, erwägen Sie die Verwendung der folgenden Reihenfolge: TensorFlow-Dataset-Objekt erstellen -> Cache-API -> Shuffle-API -> Batch-API -> Map-API -> Repeat-API -> Prefetch-API.
  • Verwenden Sie das tfrecord Datensatzformat mehr als das LibSVM-Format.
  • Der Dateimodus oder Pipe-Modus hängt von Ihrem Datensatzformat und der Anzahl der Dateien ab. Das tfrecorddataset API kann eingestellt werden num_parallel_reads mehrere Dateien parallel lesen und einstellen buffer_size um das Lesen von Daten zu optimieren, während die pipemodedataset API hat solche Einstellungen nicht. Der Pipe-Modus eignet sich besser für Situationen, in denen eine einzelne Datei groß und die Gesamtzahl der Dateien klein ist. Wir empfehlen die Verwendung eines SageMaker-Verarbeitungsauftrags für die Vorverarbeitung, z. B. das Zusammenfügen mehrerer Dateien zu einer größeren Datei gemäß den Bezeichnungen, das Verwenden einer Stichprobenmethode, um den Datensatz ausgewogener zu machen, und das Mischen des ausgewogenen Datensatzes.

Sehen Sie sich das folgende Codebeispiel an:

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)

Legen Sie für das Training auf CPU-Instanzen die Parallelität von fest intra op, inter op, und die Umgebungsvariable von MKL-DNN ist ein guter Ausgangspunkt.

Automatisches gemischtes Präzisionstraining

Das letzte, was wir besprechen, ist das automatische gemischte Präzisionstraining, das die Geschwindigkeit beschleunigen und zu einer besseren Modellleistung führen kann. Zum jetzigen Zeitpunkt unterstützen Nvidia V100 GPU (P3-Instanz) und A100 (P4dn-Instanz) Tensor Core. Sie können gemischtes Präzisionstraining in TensorFlow aktivieren, wenn Sie diese Arten von Instanzen verwenden. Ab Version 1.14 unterstützt TensorFlow das automatische gemischte Präzisionstraining. Sie können die folgende Anweisung verwenden, um Ihren ursprünglichen Optimierer zu umschließen:

tf.train.experimental.enable_mixed_precision_graph_rewrite(optimizer)

Wenn das Modell klein und die GPU-Auslastung gering ist, bietet das automatische gemischte Präzisionstraining keinen Vorteil. Wenn das Modell groß ist, kann das automatische gemischte Präzisionstraining die Trainingsgeschwindigkeit beschleunigen.

Zusammenfassung

Wenn Sie mit dem Deep-Learning-Modelltraining in SageMaker beginnen, beachten Sie die folgenden Tipps, um eine schnellere Trainingsgeschwindigkeit zu erreichen:

  • Probieren Sie zuerst die Multi-CPU-Einzelinstanz-Methode oder die Single-GPU-Einzelinstanz-Methode aus. Wenn die CPU-/GPU-Auslastung sehr hoch ist (z. B. mehr als 90 %), fahren Sie mit dem nächsten Schritt fort.
  • Probieren Sie mehr CPUs in einem einzelnen Host oder mehr GPUs in einem einzelnen Host aus. Wenn die Auslastung nahe der maximalen Auslastung von CPUs oder GPUs liegt, fahren Sie mit dem nächsten Schritt fort.
  • Probieren Sie mehrere CPUs oder mehrere GPUs mit mehreren Hosts aus.
  • Sie müssen Codes ändern, wenn Sie Parameterserver oder Horovod verwenden. Die Codeänderung ist für die sitzungsbasierte API von TensorFlow nicht dieselbe. tf.estimator API und tf.keras API. Ein Parameterserver oder Horovod kann in verschiedenen Trainingsfällen und Aufgaben unterschiedliche Trainingsgeschwindigkeiten anzeigen, probieren Sie also beide Methoden aus, wenn Sie die Zeit und das Budget haben, um die beste Methode zu ermitteln.

Beachten Sie die folgenden Ratschläge:

  • Überprüfen Sie die Auslastung vor der Skalierung, optimieren Sie Ihre Datenpipeline und lassen Sie CPU und GPU in der Zeitleiste überlappen.
  • Erst hochskalieren, dann rausskalieren.
  • Wenn Sie Ihre GPU-Auslastung nach all den Methoden nicht erhöhen können, versuchen Sie es mit CPU. Es gibt viele Fälle (insbesondere für das Clickthrough-Rate-Ranking-Modell), in denen die Gesamttrainingszeit des CPU-Instance-Trainings kürzer und kostengünstiger ist als das GPU-Instance-Training.

Wir haben auch ein Codebeispiel in der GitHub Repo, wo wir zwei Beispiele für verteiltes DeepFM-Training auf SageMaker zeigen. Einer ist ein TensorFlow-Parameterserver auf CPU-Instanzen, der andere ist Horovod auf GPU-Instanzen.


Über die Autoren

Best Practices für das TensorFlow 1.x-Beschleunigungstraining für Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikale Suche. Ai. Yuhui Liang ist Senior Machine Learning Solutions Architect. Er konzentriert sich auf die Förderung und Anwendung des maschinellen Lernens und ist stark in die maschinellen Lernprojekte vieler Kunden involviert. Er verfügt über umfangreiche Erfahrung in den Bereichen Deep Learning, verteiltes Training, Empfehlungssysteme und Computational Advertising.

Best Practices für das TensorFlow 1.x-Beschleunigungstraining für Amazon SageMaker PlatoBlockchain Data Intelligence. Vertikale Suche. Ai.Shishuai Wang ist Senior Machine Learning Solutions Architect. Er arbeitet mit AWS-Kunden zusammen, um ihnen dabei zu helfen, maschinelles Lernen in großem Umfang einzuführen. Er schaut gerne Filme und reist um die Welt.

Zeitstempel:

Mehr von AWS Maschinelles Lernen