Entraîner des modèles Keras avec TensorFlow Cloud

Voir sur TensorFlow.org Exécuter dans Google Colab Voir la source sur GitHub Télécharger le cahier

introduction

Tensorflow - Cloud est un package Python qui fournit des API pour une transition transparente de débogage local à la formation distribuée dans Google Cloud. Il simplifie le processus de formation des modèles TensorFlow sur le cloud en un seul appel de fonction simple, nécessitant une configuration minimale et aucune modification de votre modèle. TensorFlow Cloud gère automatiquement les tâches spécifiques au cloud, telles que la création d'instances de VM et de stratégies de distribution pour vos modèles. Ce guide montrera comment s'interfacer avec Google Cloud via TensorFlow Cloud, ainsi que la large gamme de fonctionnalités fournies dans TensorFlow Cloud. Nous allons commencer par le cas d'utilisation le plus simple.

Installer

Nous allons commencer par installer TensorFlow Cloud et importer les packages dont nous aurons besoin dans ce guide.

pip install -q tensorflow_cloud
import tensorflow as tf
import tensorflow_cloud as tfc

from tensorflow import keras
from tensorflow.keras import layers
2021-07-27 22:07:16.348453: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0

Présentation de l'API : un premier exemple de bout en bout

Commençons par un script d'entraînement de modèle Keras, tel que le CNN suivant :

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

model = keras.Sequential(
    [
        keras.Input(shape=(28, 28)),
        # Use a Rescaling layer to make sure input values are in the [0, 1] range.
        layers.experimental.preprocessing.Rescaling(1.0 / 255),
        # The original images have shape (28, 28), so we reshape them to (28, 28, 1)
        layers.Reshape(target_shape=(28, 28, 1)),
        # Follow-up with a classic small convnet
        layers.Conv2D(32, 3, activation="relu"),
        layers.MaxPooling2D(2),
        layers.Conv2D(32, 3, activation="relu"),
        layers.MaxPooling2D(2),
        layers.Conv2D(32, 3, activation="relu"),
        layers.Flatten(),
        layers.Dense(128, activation="relu"),
        layers.Dense(10),
    ]
)

model.compile(
    optimizer=keras.optimizers.Adam(),
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
    metrics=keras.metrics.SparseCategoricalAccuracy(),
)

model.fit(x_train, y_train, epochs=20, batch_size=128, validation_split=0.1)

Pour former ce modèle sur Google Cloud nous avons juste besoin d'ajouter un appel à run() au début du script, avant que les importations:

tfc.run()

Vous n'avez pas à vous soucier des tâches spécifiques au cloud telles que la création d'instances de VM et de stratégies de distribution lorsque vous utilisez TensorFlow Cloud. L'API inclut des valeurs par défaut intelligentes pour tous les paramètres - tout est configurable, mais de nombreux modèles peuvent s'appuyer sur ces valeurs par défaut.

Lors de l' appel run() , tensorflow Cloud:

  • Préparez votre script Python ou votre notebook pour la distribution.
  • Convertissez-le en une image Docker avec les dépendances requises.
  • Exécutez la tâche d'entraînement sur une VM GCP alimentée par GPU.
  • Diffusez les journaux et les informations de travail pertinents.

La configuration de VM par défaut est 1 chef et 0 travailleurs avec 8 cœurs de processeur et 1 GPU Tesla T4.

Configuration de Google Cloud

Afin de faciliter les parcours appropriés pour la formation Cloud, vous devrez effectuer une première configuration. Si vous êtes un nouvel utilisateur de Google Cloud, vous devrez suivre quelques étapes préliminaires :

  1. Créer un projet GCP ;
  2. Activer les services AI Platform ;
  3. Créer un compte de service ;
  4. Télécharger une clé d'autorisation ;
  5. Créez un bucket Cloud Storage.

Instructions d'installation pour la première fois détaillées peuvent être trouvées dans le tensorflow Nuage README , et un exemple de configuration supplémentaire est affiché sur le Blog tensorflow .

Workflows communs et stockage Cloud

Dans la plupart des cas, vous souhaiterez récupérer votre modèle après l'entraînement sur Google Cloud. Pour cela, il est crucial de rediriger l'enregistrement et le chargement vers Cloud Storage lors de l'entraînement à distance. Nous pouvons diriger TensorFlow Cloud vers notre bucket Cloud Storage pour diverses tâches. Le compartiment de stockage peut être utilisé pour enregistrer et charger de grands ensembles de données d'entraînement, stocker des journaux de rappel ou des pondérations de modèle et enregistrer des fichiers de modèle entraînés. Pour commencer, nous allons configurer en fit() pour enregistrer le modèle à un stockage Cloud et ensemble le suivi des TensorBoard pour suivre les progrès de la formation.

def create_model():
    model = keras.Sequential(
        [
            keras.Input(shape=(28, 28)),
            layers.experimental.preprocessing.Rescaling(1.0 / 255),
            layers.Reshape(target_shape=(28, 28, 1)),
            layers.Conv2D(32, 3, activation="relu"),
            layers.MaxPooling2D(2),
            layers.Conv2D(32, 3, activation="relu"),
            layers.MaxPooling2D(2),
            layers.Conv2D(32, 3, activation="relu"),
            layers.Flatten(),
            layers.Dense(128, activation="relu"),
            layers.Dense(10),
        ]
    )

    model.compile(
        optimizer=keras.optimizers.Adam(),
        loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
        metrics=keras.metrics.SparseCategoricalAccuracy(),
    )
    return model

Enregistrons les journaux TensorBoard et les points de contrôle de modèle générés pendant la formation dans notre bucket de stockage cloud.

import datetime
import os

# Note: Please change the gcp_bucket to your bucket name.
gcp_bucket = "keras-examples"

checkpoint_path = os.path.join("gs://", gcp_bucket, "mnist_example", "save_at_{epoch}")

tensorboard_path = os.path.join(  # Timestamp included to enable timeseries graphs
    "gs://", gcp_bucket, "logs", datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
)

callbacks = [
    # TensorBoard will store logs for each epoch and graph performance for us.
    keras.callbacks.TensorBoard(log_dir=tensorboard_path, histogram_freq=1),
    # ModelCheckpoint will save models after each epoch for retrieval later.
    keras.callbacks.ModelCheckpoint(checkpoint_path),
    # EarlyStopping will terminate training when val_loss ceases to improve.
    keras.callbacks.EarlyStopping(monitor="val_loss", patience=3),
]

model = create_model()
2021-07-27 22:07:18.825259: I tensorflow/core/profiler/lib/profiler_session.cc:126] Profiler session initializing.
2021-07-27 22:07:18.825306: I tensorflow/core/profiler/lib/profiler_session.cc:141] Profiler session started.
2021-07-27 22:07:18.826514: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcuda.so.1
2021-07-27 22:07:19.524654: I tensorflow/core/profiler/internal/gpu/cupti_tracer.cc:1611] Profiler found 1 GPUs
2021-07-27 22:07:19.569799: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcupti.so.11.2
2021-07-27 22:07:19.574795: I tensorflow/core/profiler/lib/profiler_session.cc:159] Profiler session tear down.
2021-07-27 22:07:19.574958: I tensorflow/core/profiler/internal/gpu/cupti_tracer.cc:1743] CUPTI activity buffer flushed
2021-07-27 22:07:19.590994: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.592061: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-07-27 22:07:19.592100: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-07-27 22:07:19.595897: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublas.so.11
2021-07-27 22:07:19.595991: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublasLt.so.11
2021-07-27 22:07:19.597230: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcufft.so.10
2021-07-27 22:07:19.597581: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcurand.so.10
2021-07-27 22:07:19.598756: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusolver.so.11
2021-07-27 22:07:19.599746: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcusparse.so.11
2021-07-27 22:07:19.599930: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudnn.so.8
2021-07-27 22:07:19.600043: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.601088: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.602037: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-07-27 22:07:19.602416: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2021-07-27 22:07:19.603033: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.604024: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties: 
pciBusID: 0000:00:05.0 name: Tesla V100-SXM2-16GB computeCapability: 7.0
coreClock: 1.53GHz coreCount: 80 deviceMemorySize: 15.78GiB deviceMemoryBandwidth: 836.37GiB/s
2021-07-27 22:07:19.604096: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.605089: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:19.606005: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1871] Adding visible gpu devices: 0
2021-07-27 22:07:19.606052: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
2021-07-27 22:07:20.242028: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1258] Device interconnect StreamExecutor with strength 1 edge matrix:
2021-07-27 22:07:20.242067: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1264]      0 
2021-07-27 22:07:20.242076: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1277] 0:   N 
2021-07-27 22:07:20.242317: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:20.243478: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:20.244412: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2021-07-27 22:07:20.245277: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1418] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 14646 MB memory) -> physical GPU (device: 0, name: Tesla V100-SXM2-16GB, pci bus id: 0000:00:05.0, compute capability: 7.0)
WARNING:tensorflow:Please add `keras.layers.InputLayer` instead of `keras.Input` to Sequential model. `keras.Input` is intended to be used by Functional model.
WARNING:tensorflow:Please add `keras.layers.InputLayer` instead of `keras.Input` to Sequential model. `keras.Input` is intended to be used by Functional model.

Ici, nous allons charger nos données directement depuis Keras. En général, il est recommandé de stocker votre ensemble de données dans votre bucket Cloud Storage, mais TensorFlow Cloud peut également accueillir des ensembles de données stockés localement. Cela est couvert dans la section Multi-fichiers de ce guide.

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

Le tensorflow - remote() Cloud API fournit la remote() fonction pour déterminer si le code est en cours d' exécution localement ou sur le nuage. Cela permet la désignation distincte en fit() paramètres pour l' exécution locale et à distance, et fournit des moyens pour le débogage facile sans surcharger votre machine locale.

if tfc.remote():
    epochs = 100
    callbacks = callbacks
    batch_size = 128
else:
    epochs = 5
    batch_size = 64
    callbacks = None

model.fit(x_train, y_train, epochs=epochs, callbacks=callbacks, batch_size=batch_size)
2021-07-27 22:07:21.458608: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:176] None of the MLIR Optimization Passes are enabled (registered 2)
2021-07-27 22:07:21.459072: I tensorflow/core/platform/profile_utils/cpu_utils.cc:114] CPU Frequency: 2000170000 Hz
Epoch 1/5
2021-07-27 22:07:21.885085: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudnn.so.8
2021-07-27 22:07:23.986122: I tensorflow/stream_executor/cuda/cuda_dnn.cc:359] Loaded cuDNN version 8100
2021-07-27 22:07:29.307903: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublas.so.11
2021-07-27 22:07:29.684317: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcublasLt.so.11
938/938 [==============================] - 12s 3ms/step - loss: 0.2065 - sparse_categorical_accuracy: 0.9374
Epoch 2/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0577 - sparse_categorical_accuracy: 0.9822
Epoch 3/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0415 - sparse_categorical_accuracy: 0.9868
Epoch 4/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0332 - sparse_categorical_accuracy: 0.9893
Epoch 5/5
938/938 [==============================] - 3s 3ms/step - loss: 0.0275 - sparse_categorical_accuracy: 0.9915
<tensorflow.python.keras.callbacks.History at 0x7f7b0c66a390>

Enregistrons le modèle dans GCS une fois la formation terminée.

save_path = os.path.join("gs://", gcp_bucket, "mnist_example")

if tfc.remote():
    model.save(save_path)

Nous pouvons également utiliser ce bucket de stockage pour la création d'images Docker, au lieu de votre instance Docker locale. Pour cela, il suffit d' ajouter votre seau au docker_image_bucket_name paramètre.

tfc.run(docker_image_bucket_name=gcp_bucket)

Après avoir entraîné le modèle, nous pouvons charger le modèle enregistré et afficher nos journaux TensorBoard pour surveiller les performances.

model = keras.models.load_model(save_path)
!tensorboard dev upload --logdir "gs://keras-examples-jonah/logs/fit" --name "Guide MNIST"

Des projets à grande échelle

Dans de nombreux cas, votre projet contenant un modèle Keras peut englober plusieurs scripts Python, ou peut impliquer des données externes ou des dépendances spécifiques. TensorFlow Cloud est entièrement flexible pour un déploiement à grande échelle et fournit un certain nombre de fonctionnalités intelligentes pour vous aider dans vos projets.

Points d'entrée : prise en charge des scripts Python et des blocs-notes Jupyter

Votre appel à l' run() API ne sera pas toujours contenu dans le même script Python comme votre code de formation de modèle. A cet effet, nous fournissons un entry_point paramètre. Le entry_point paramètre peut être utilisé pour spécifier le script Python ou un ordinateur portable dans lequel votre vie de code de formation du modèle. Lors de l' appel run() à partir du même script que votre modèle, utilisez le entry_point par défaut None .

pip dépendances

Si vos appels de projet sur d' autres pip dépendances, il est possible de spécifier les bibliothèques supplémentaires requises en incluant un requirements.txt fichier. Dans ce fichier, placez simplement une liste de toutes les dépendances requises et TensorFlow Cloud s'occupera de les intégrer dans votre build cloud.

Cahiers Python

TensorFlow Cloud peut également être exécuté à partir de blocs-notes Python. En outre, votre spécifié entry_point peut être un ordinateur portable en cas de besoin. Il y a deux différences clés à garder à l'esprit entre TensorFlow Cloud sur les notebooks et les scripts :

  • Lors de l' appel run() à partir d'un ordinateur portable, un seau Cloud Storage doit être spécifié pour la construction et le stockage de votre image Docker.
  • L'authentification GCloud se fait entièrement via votre clé d'authentification, sans spécification de projet. Un exemple de workflow utilisant TensorFlow Cloud à partir d'un ordinateur portable est fourni dans la section « Rassembler le tout » de ce guide.

Projets multi-fichiers

Si votre modèle dépend de fichiers supplémentaires, il vous suffit de vous assurer que ces fichiers résident dans le même répertoire (ou sous-répertoire) que le point d'entrée spécifié. Chaque fichier qui est stocké dans le même répertoire que spécifié entry_point sera inclus dans l'image Docker, ainsi que tous les fichiers stockés dans les sous - répertoires adjacents au entry_point . Cela est également vrai pour les dépendances dont vous avez besoin qui ne peuvent être acquises par pip

Pour un exemple d'un point d' entrée personnalisé et projet multi-fichiers avec dépendances PiP, jetez un oeil à cet exemple de plusieurs fichiers sur le tensorflow dépôt Cloud . Par souci de concision, nous allons inclure l'exemple run() appel:

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    entry_point="train_model.py",
    requirements="requirements.txt"
)

Configuration de la machine et formation distribuée

La formation de modèle peut nécessiter un large éventail de ressources différentes, selon la taille du modèle ou de l'ensemble de données. Lors de la comptabilisation des configurations avec plusieurs processeurs graphiques, il devient essentiel de choisir un raccord stratégie de distribution . Ici, nous décrivons quelques configurations possibles :

Distribution multi-travailleurs

Ici, nous pouvons utiliser COMMON_MACHINE_CONFIGS pour désigner 1 CPU en chef et 4 GPUs travailleurs.

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    chief_config=tfc.COMMON_MACHINE_CONFIGS['CPU'],
    worker_count=2,
    worker_config=tfc.COMMON_MACHINE_CONFIGS['T4_4X']
)

Par défaut, tensorflow Nuage choisit la meilleure stratégie de distribution pour la configuration de votre machine avec une formule simple en utilisant la chief_config , worker_config et worker_count paramètres fournis.

Répartition des TPU

Entraînons le même modèle sur TPU, comme indiqué :

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    chief_config=tfc.COMMON_MACHINE_CONFIGS["CPU"],
    worker_count=1,
    worker_config=tfc.COMMON_MACHINE_CONFIGS["TPU"]
)

Stratégie de distribution personnalisée

Pour définir une stratégie de distribution personnalisée, formatez votre code comme vous le feriez normalement selon le guide de formation distribué et ensemble distribution_strategy à None . Ci-dessous, nous spécifierons notre propre stratégie de distribution pour le même modèle MNIST.

(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()

mirrored_strategy = tf.distribute.MirroredStrategy()
with mirrored_strategy.scope():
  model = create_model()

if tfc.remote():
    epochs = 100
    batch_size = 128
else:
    epochs = 10
    batch_size = 64
    callbacks = None

model.fit(
    x_train, y_train, epochs=epochs, callbacks=callbacks, batch_size=batch_size
)

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    chief_config=tfc.COMMON_MACHINE_CONFIGS['CPU'],
    worker_count=2,
    worker_config=tfc.COMMON_MACHINE_CONFIGS['T4_4X'],
    distribution_strategy=None
)

Images Docker personnalisées

Par défaut, tensorflow Nuage utilise une image de base Docker fourni par Google et correspondant à votre version actuelle de tensorflow. Cependant, vous pouvez également spécifier une image Docker personnalisée pour répondre à vos exigences de construction, si nécessaire. Pour cet exemple, nous allons spécifier l'image Docker d'une ancienne version de TensorFlow :

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    base_docker_image="tensorflow/tensorflow:2.1.0-gpu"
)

Métriques supplémentaires

Vous trouverez peut-être utile de baliser vos tâches Cloud avec des étiquettes spécifiques ou de diffuser les journaux de votre modèle pendant l'entraînement Cloud. C'est une bonne pratique de maintenir un étiquetage approprié sur toutes les tâches Cloud, pour la tenue des dossiers. A cet effet, run() accepte un dictionnaire d'étiquettes jusqu'à 64 paires de valeurs de clés, qui sont visibles à partir des journaux de construction Cloud. Journaux tels que la performance d'époque et d' économie de modèle internes sont accessibles en utilisant le lien fourni en exécutant tfc.run ou imprimées sur votre terminal local en utilisant le stream_logs drapeau.

job_labels = {"job": "mnist-example", "team": "keras-io", "user": "jonah"}

tfc.run(
    docker_image_bucket_name=gcp_bucket,
    job_labels=job_labels,
    stream_logs=True
)

Mettre tous ensemble

Pour une Colab en profondeur qui utilise de nombreuses fonctionnalités décrites dans ce guide, suivre cet exemple pour former un modèle état de l'art de reconnaître les races de chiens de photos à l' aide extraction de caractéristiques.