1. Présentation
Dans cet atelier, vous allez apprendre à exécuter un job d'entraînement personnalisé sur Vertex AI Training avec la fonctionnalité d'empaquetage automatique. Les jobs d'entraînement personnalisés sur Vertex AI utilisent des conteneurs. Si vous ne souhaitez pas créer votre propre image, vous pouvez utiliser l'empaquetage automatique, qui crée une image Docker personnalisée à partir de votre code, la transfère vers Container Registry et démarre une CustomJob
basée sur l'image.
Objectifs
Vous allez apprendre à effectuer les opérations suivantes :
- Utilisez le mode local pour tester votre code.
- Configurez et lancez un job d'entraînement personnalisé avec l'empaquetage automatique.
Le coût total d'exécution de cet atelier sur Google Cloud est d'environ 2 $.
2. Présentation du cas d'utilisation
À l'aide des bibliothèques de Hugging Face, vous allez affiner un modèle Bert sur l'ensemble de données IMDB. Le modèle prédira si une critique de film est positive ou négative. L'ensemble de données sera téléchargé depuis la bibliothèque d'ensembles de données Hugging Face et le modèle Bert depuis la bibliothèque Hugging Face Transformers.
3. Présentation de Vertex AI
Cet atelier utilise la toute dernière offre de produits d'IA de Google Cloud. Vertex AI simplifie l'expérience de développement en intégrant toutes les offres de ML de Google Cloud. Auparavant, les modèles entraînés avec AutoML et les modèles personnalisés étaient accessibles depuis des services distincts. La nouvelle offre regroupe ces deux types de modèles mais aussi d'autres nouveaux produits en une seule API. Vous pouvez également migrer des projets existants vers Vertex AI. Pour envoyer un commentaire, consultez la page d'assistance.
Vertex AI comprend de nombreux produits différents qui permettent de gérer les workflows de ML de bout en bout. Cet atelier se concentre sur Training et Workbench.
4. Configurer votre environnement
Pour suivre cet atelier de programmation, vous aurez besoin d'un projet Google Cloud Platform dans lequel la facturation est activée. Pour créer un projet, suivez ces instructions.
Étape 1 : Activez l'API Compute Engine
Accédez à Compute Engine et cliquez sur Activer si ce n'est pas déjà fait.
Étape 2: Activez l'API Vertex AI
Accédez à la section Vertex AI de Cloud Console, puis cliquez sur Activer l'API Vertex AI.
Étape 3: Activez l'API Container Registry
Accédez à Container Registry et cliquez sur Activer si ce n'est pas déjà fait. Vous l'utiliserez afin de créer un conteneur pour votre job d'entraînement personnalisé.
Étape 4 : Créez une instance Vertex AI Workbench
Dans la section Vertex AI de Cloud Console, cliquez sur Workbench :
Cliquez ensuite sur NOTEBOOKS GÉRÉS:
Sélectionnez ensuite NOUVEAU NOTEBOOK.
Attribuez un nom à votre notebook, puis cliquez sur Paramètres avancés.
Sous "Paramètres avancés", activez l'arrêt en cas d'inactivité et définissez le nombre de minutes sur 60. Cela entraîne l'arrêt automatique du notebook lorsqu'il n'est pas utilisé. Vous ne payez donc pas de frais inutiles.
Vous pouvez conserver tous les autres paramètres avancés tels quels.
Cliquez ensuite sur Créer.
Une fois l'instance créée, sélectionnez Ouvrir JupyterLab.
La première fois que vous utilisez une nouvelle instance, vous êtes invité à vous authentifier.
5. Rédiger le code d'entraînement
Pour commencer, à partir du menu de lancement, ouvrez une fenêtre de terminal dans votre instance de notebook :
Créez un répertoire appelé autopkg-codelab
et utilisez la commande cd pour y accéder.
mkdir autopkg-codelab
cd autopkg-codelab
Depuis votre terminal, exécutez le code suivant afin de créer un répertoire pour le code d'entraînement et un fichier Python dans lequel vous ajouterez le code :
mkdir trainer
touch trainer/task.py
Votre répertoire autopkg-codelab/
doit maintenant contenir les éléments suivants :
+ trainer/
+ task.py
Ouvrez ensuite le fichier task.py
que vous venez de créer et copiez-y le code ci-dessous.
import argparse
import tensorflow as tf
from datasets import load_dataset
from transformers import AutoTokenizer
from transformers import TFAutoModelForSequenceClassification
CHECKPOINT = "bert-base-cased"
def get_args():
'''Parses args.'''
parser = argparse.ArgumentParser()
parser.add_argument(
'--epochs',
required=False,
default=3,
type=int,
help='number of epochs')
parser.add_argument(
'--job_dir',
required=True,
type=str,
help='bucket to store saved model, include gs://')
args = parser.parse_args()
return args
def create_datasets():
'''Creates a tf.data.Dataset for train and evaluation.'''
raw_datasets = load_dataset('imdb')
tokenizer = AutoTokenizer.from_pretrained(CHECKPOINT)
tokenized_datasets = raw_datasets.map((lambda examples: tokenize_function(examples, tokenizer)), batched=True)
# To speed up training, we use only a portion of the data.
# Use full_train_dataset and full_eval_dataset if you want to train on all the data.
small_train_dataset = tokenized_datasets['train'].shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets['test'].shuffle(seed=42).select(range(1000))
full_train_dataset = tokenized_datasets['train']
full_eval_dataset = tokenized_datasets['test']
tf_train_dataset = small_train_dataset.remove_columns(['text']).with_format("tensorflow")
tf_eval_dataset = small_eval_dataset.remove_columns(['text']).with_format("tensorflow")
train_features = {x: tf_train_dataset[x] for x in tokenizer.model_input_names}
train_tf_dataset = tf.data.Dataset.from_tensor_slices((train_features, tf_train_dataset["label"]))
train_tf_dataset = train_tf_dataset.shuffle(len(tf_train_dataset)).batch(8)
eval_features = {x: tf_eval_dataset[x] for x in tokenizer.model_input_names}
eval_tf_dataset = tf.data.Dataset.from_tensor_slices((eval_features, tf_eval_dataset["label"]))
eval_tf_dataset = eval_tf_dataset.batch(8)
return train_tf_dataset, eval_tf_dataset
def tokenize_function(examples, tokenizer):
'''Tokenizes text examples.'''
return tokenizer(examples['text'], padding='max_length', truncation=True)
def main():
args = get_args()
train_tf_dataset, eval_tf_dataset = create_datasets()
model = TFAutoModelForSequenceClassification.from_pretrained(CHECKPOINT, num_labels=2)
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=tf.metrics.SparseCategoricalAccuracy(),
)
model.fit(train_tf_dataset, validation_data=eval_tf_dataset, epochs=args.epochs)
model.save(f'{args.job_dir}/model_output')
if __name__ == "__main__":
main()
Quelques points à noter concernant le code:
CHECKPOINT
est le modèle que nous souhaitons ajuster. Dans ce cas, nous utilisons Bert.- La méthode
TFAutoModelForSequenceClassification
charge l'architecture du modèle de langage et les poids spécifiés dans TensorFlow, puis ajoute un nœud de classification avec des poids initialisés de manière aléatoire. Dans ce cas, nous avons un problème de classification binaire (positif ou négatif). Nous spécifions doncnum_labels=2
pour ce classificateur.
6. Conteneuriser et exécuter du code d'entraînement en local
Vous pouvez utiliser la commande gcloud ai custom-jobs local-run
pour créer une image de conteneur Docker basée sur votre code d'entraînement, puis exécuter l'image en tant que conteneur sur votre ordinateur local. L'exécution d'un conteneur en local exécute votre code d'entraînement de la même manière que sur Vertex AI Training. Elle peut vous aider à déboguer les problèmes liés à votre code avant d'effectuer un entraînement personnalisé sur Vertex AI.
Dans notre tâche d'entraînement, nous allons exporter notre modèle entraîné vers un bucket Cloud Storage. Depuis votre terminal, exécutez la commande suivante afin de définir une variable d'environnement pour votre projet, en veillant à remplacer your-cloud-project
par l'ID de votre projet :
PROJECT_ID='your-cloud-project'
Créez ensuite un bucket. Si vous disposez déjà d'un bucket, n'hésitez pas à l'utiliser à la place.
BUCKET_NAME="gs://${PROJECT_ID}-bucket"
gsutil mb -l us-central1 $BUCKET_NAME
Lorsque nous exécuterons le job d'entraînement personnalisé sur Vertex AI Training, nous utiliserons un GPU. Toutefois, comme nous n'avons pas spécifié notre instance Workbench avec des GPU, nous allons utiliser une image basée sur le processeur pour les tests en local. Dans cet exemple, nous utilisons un conteneur prédéfini pour l'entraînement Vertex AI.
Exécutez la commande suivante pour définir l'URI d'une image Docker à utiliser comme base du conteneur.
BASE_CPU_IMAGE=us-docker.pkg.dev/vertex-ai/training/tf-cpu.2-7:latest
Définissez ensuite un nom pour l'image Docker créée par la commande d'exécution locale.
OUTPUT_IMAGE=$PROJECT_ID-local-package-cpu:latest
Notre code d'entraînement utilise les ensembles de données et les bibliothèques de transformateurs Hugging Face. Ces bibliothèques ne sont pas incluses dans l'image que nous avons sélectionnée comme image de base. Nous devons donc les indiquer comme exigences. Pour ce faire, nous allons créer un fichier requirements.txt
dans notre répertoire autopkg-codelab
.
Assurez-vous d'être dans le répertoire autopkg-codelab
, puis saisissez ce qui suit dans le terminal.
touch requirements.txt
Votre répertoire autopkg-codelab
doit maintenant contenir les éléments suivants :
+ requirements.txt
+ trainer/
+ task.py
Ouvrez le fichier de spécifications et collez-y le code suivant :
datasets==1.18.2
transformers==4.16.2
Enfin, exécutez la commande gcloud ai custom-jobs local-run
pour lancer l'entraînement sur notre instance gérée par Workbench.
gcloud ai custom-jobs local-run \
--executor-image-uri=$BASE_CPU_IMAGE \
--python-module=trainer.task \
--output-image-uri=$OUTPUT_IMAGE \
-- \
--job_dir=$BUCKET_NAME
L'image Docker devrait être créée. Les dépendances que nous avons ajoutées au fichier requirements.txt
seront installées avec pip. La première fois que vous exécutez cette commande, l'opération peut prendre quelques minutes. Une fois l'image créée, le fichier task.py
commence à s'exécuter et l'entraînement du modèle s'affiche. L'écran qui s'affiche devrait ressembler à ce qui suit :
Comme nous n'utilisons pas de GPU localement, l'entraînement du modèle prendra beaucoup de temps. Vous pouvez appuyer sur Ctrl+C pour annuler l'entraînement local au lieu d'attendre la fin de la tâche.
Notez que si vous souhaitez effectuer d'autres tests, vous pouvez également exécuter directement l'image créée ci-dessus, sans la reconditionner.
gcloud beta ai custom-jobs local-run \
--executor-image-uri=$OUTPUT_IMAGE \
-- \
--job_dir=$BUCKET_NAME \
--epochs=1
7. Créer une tâche personnalisée
Maintenant que nous avons testé le mode local, nous allons utiliser la fonctionnalité de création automatique de package pour lancer notre job d'entraînement personnalisé sur Vertex AI Training. Cette fonctionnalité permet d'effectuer les actions suivantes en une seule commande:
- Créer une image Docker personnalisée basée sur votre code
- Stocker l'image dans Container Registry
- Démarrer une opération
CustomJob
basée sur l'image
Revenez au terminal et montez d'un niveau au-dessus de votre répertoire autopkg-codelab
.
+ autopkg-codelab
+ requirements.txt
+ trainer/
+ task.py
Spécifiez l'image GPU TensorFlow prédéfinie de Vertex AI Training comme image de base pour le job d'entraînement personnalisé.
BASE_GPU_IMAGE=us-docker.pkg.dev/vertex-ai/training/tf-gpu.2-7:latest
Exécutez ensuite la commande gcloud ai custom-jobs create
. Tout d'abord, cette commande crée une image Docker personnalisée basée sur le code d'entraînement. L'image de base est le conteneur prédéfini d'entraînement Vertex AI que nous avons défini sur BASE_GPU_IMAGE
. La fonctionnalité d'autopackaging installe ensuite les ensembles de données et les bibliothèques de transformateurs via pip, comme indiqué dans le fichier requirements.txt
.
gcloud ai custom-jobs create \
--region=us-central1 \
--display-name=fine_tune_bert \
--args=--job_dir=$BUCKET_NAME \
--worker-pool-spec=machine-type=n1-standard-4,replica-count=1,accelerator-type=NVIDIA_TESLA_V100,executor-image-uri=$BASE_GPU_IMAGE,local-package-path=autopkg-codelab,python-module=trainer.task
Examinons l'argument worker-pool-spec
. Il définit la configuration du pool de nœuds de calcul utilisée par la tâche personnalisée. Vous pouvez spécifier plusieurs spécifications de pool de nœuds de calcul afin de créer un job personnalisé avec plusieurs pools de nœuds de calcul pour l'entraînement distribué. Dans cet exemple, nous ne spécifions qu'un seul pool de nœuds de calcul, car notre code d'entraînement n'est pas configuré pour l'entraînement distribué.
Voici quelques-uns des principaux champs de cette spécification:
machine-type
(obligatoire): type de machine. Cliquez ici pour connaître les types acceptés.replica-count
: nombre d'instances dupliquées de nœuds de calcul à utiliser pour ce pool de nœuds de calcul. Par défaut, la valeur est 1.accelerator-type
: type de GPU. Cliquez ici pour connaître les types acceptés. Dans cet exemple, nous avons spécifié un GPU NVIDIA Tesla V100.accelerator-count
: nombre de GPU à utiliser par chaque VM du pool de nœuds de calcul. Par défaut, la valeur est 1.executor-image-uri
: URI d'une image de conteneur qui exécutera le package fourni. Ceci est défini sur notre image de base.local-package-path
: chemin d'accès local d'un dossier contenant le code d'entraînement.python-module
: nom du module Python à exécuter dans le package fourni.
Comme lors de l'exécution de la commande locale, vous verrez l'image Docker en cours de création, puis le job d'entraînement démarrer. Sauf qu'au lieu de voir le résultat du job d'entraînement, le message suivant confirme que le job d'entraînement a bien été lancé. Notez que la première fois que vous exécutez la commande custom-jobs create
, la création et le transfert de l'image peuvent prendre quelques minutes.
Revenez à la section "Vertex AI Training" (Entraînement Vertex AI) de la console Cloud. Sous JOBS PERSONNALISÉS (Tâches personnalisées), vous devriez voir votre tâche en cours d'exécution.
L'opération prendra environ 20 minutes.
Une fois l'opération terminée, les artefacts de modèle enregistrés suivants devraient s'afficher dans le répertoire model_output
de votre bucket.
🎉 Félicitations ! 🎉
Vous savez désormais utiliser Vertex AI pour :
- Conteneuriser et exécuter du code d'entraînement en local
- Envoyer des jobs d'entraînement à Vertex AI Training avec le packaging automatique
Pour en savoir plus sur les différentes parties de Vertex AI, consultez la documentation.
8. Nettoyage
Comme le notebook est configuré pour expirer au bout de 60 minutes d'inactivité, il n'est pas nécessaire d'arrêter l'instance. Si vous souhaitez arrêter l'instance manuellement, cliquez sur le bouton "Arrêter" dans la section "Vertex AI Workbench" de la console. Si vous souhaitez supprimer le notebook définitivement, cliquez sur le bouton "Supprimer".
Pour supprimer le bucket de stockage, utilisez le menu de navigation de Cloud Console pour accéder à Stockage > Cloud Storage, sélectionnez votre bucket puis cliquez sur "Supprimer" :