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é sur Vertex AI utilisent des conteneurs. Si vous ne souhaitez pas créer votre propre image, vous pouvez utiliser l'empaquetage automatique, qui créera une image Docker personnalisée basée sur votre code, la stockera dans Container Registry et démarrera un CustomJob basé sur l'image.
Objectifs
Vous allez apprendre à effectuer les opérations suivantes :
- Utiliser le mode local pour tester votre code.
- Configurer et lancer 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 un avis sur un film est positif ou négatif. L'ensemble de données sera téléchargé à partir de la bibliothèque d'ensembles de données Hugging Face, et le modèle Bert à partir de la bibliothèque de transformateurs Hugging Face.
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()
Voici quelques points à noter concernant le code :
CHECKPOINTest le modèle que nous voulons affiner. Dans ce cas, nous utilisons Bert.- La méthode
TFAutoModelForSequenceClassificationcharge l'architecture du modèle de langage spécifié + les pondérations dans TensorFlow et ajoute un en-tête de classification avec des pondérations initialisées 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=2pour ce classificateur.
6. Conteneuriser et exécuter du code d'entraînement en local
Vous pouvez exécuter la commande gcloud ai custom-jobs local-run pour créer une image de conteneur Docker à partir de votre code d'entraînement et l'exécuter en tant que conteneur sur votre ordinateur local. Un conteneur lancé en local exécute votre code d'entraînement de la même manière que sur Vertex AI Training. Il peut vous aider à résoudre des problèmes liés à votre code avant d'effectuer un entraînement personnalisé sur Vertex AI.
Dans notre job d'entraînement, nous allons exporter le 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 en avez déjà un, n'hésitez pas à l'utiliser.
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 utiliserons une image basée sur le processeur pour les tests locaux. Dans cet exemple, nous utilisons un conteneur prédéfini Vertex AI Training.
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 bibliothèques d'ensembles de données et 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 fournir en tant que exigences. Pour ce faire, nous allons créer un fichier requirements.txt dans notre répertoire autopkg-codelab.
Vérifiez que vous vous trouvez dans le répertoire autopkg-codelab, puis saisissez la commande suivante dans votre terminal.
touch requirements.txt
Votre répertoire autopkg-codelab doit maintenant contenir les éléments suivants :
+ requirements.txt
+ trainer/
+ task.py
Ouvrez le fichier d'exigences et collez-y le contenu 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 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 doit être en cours de création. Les dépendances que nous avons ajoutées au fichier requirements.txt seront installées via 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 en local, l'entraînement du modèle prendra beaucoup de temps. Vous pouvez appuyer sur Ctrl+c et annuler l'entraînement local au lieu d'attendre la fin du job.
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é d'empaquetage automatique pour lancer notre job d'entraînement personnalisé sur Vertex AI Training. Avec une seule commande, cette fonctionnalité effectue les opérations suivantes :
- Créer une image Docker personnalisée basée sur votre code
- Stocker l'image dans Container Registry
- Démarrer une opération
CustomJobbasée sur l'image
Revenez au terminal et utilisez la commande cd pour accéder au 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 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. Cette commande crée d'abord une image Docker personnalisée basée sur le code d'entraînement. L'image de base est le conteneur prédéfini Vertex AI Training que nous avons défini comme BASE_GPU_IMAGE. La fonctionnalité d'empaquetage automatique installe ensuite les bibliothèques d'ensembles de données et de transformateurs comme spécifié dans notre 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 caractéristiques des pools de nœuds de calcul afin de créer une tâche personnalisée 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 compatibles.replica-count: nombre de répliques de nœuds de calcul à utiliser pour ce pool de nœuds de calcul. La valeur par défaut est 1.accelerator-type: type de GPU. Cliquez ici pour connaître les types compatibles. Dans cet exemple, nous avons spécifié un GPU NVIDIA Tesla V100.accelerator-count: nombre de GPU à utiliser pour chaque VM du pool de nœuds de calcul. La valeur par défaut est 1.executor-image-uri: URI d'une image de conteneur qui exécutera le package fourni. Cette valeur est définie 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 lorsque vous avez exécuté la commande locale, l'image Docker est créée, puis le job d'entraînement est lancé. Au lieu de voir le résultat du job d'entraînement, vous verrez le message suivant confirmant que votre job d'entraînement a été lancé. Notez que la première fois que vous exécutez la commande custom-jobs create, la création et le stockage de l'image peuvent prendre quelques minutes.

Revenez à la section Vertex AI Training de la console Cloud. Votre job doit s'exécuter sous JOBS PERSONNALISÉS.

L'exécution du job prendra environ 20 minutes.
Une fois l'opération terminée, les artefacts de modèle enregistrés suivants doivent 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 l'empaquetage 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" :
