Tous les produits
Search
Centre de documentation

Container Service for Kubernetes:Guide du développeur Cloud Native AI Suite

Dernière mise à jour :Aug 12, 2026

Ce guide utilise le jeu de données open-source Fashion-MNIST pour illustrer comment les développeurs exploitent Cloud Native AI Suite afin d'exécuter des charges de travail d'apprentissage profond sur ACK, d'optimiser l'entraînement distribué, de déboguer les modèles et de déployer le modèle entraîné sur le cluster.

Contexte

La suite cloud-native AI fournit des composants déployables indépendamment (charts Helm K8s) pour accélérer l'ingénierie IA.

La suite cloud-native AI distingue deux rôles utilisateurs : administrateur et développeur.

  • Administrateur : Gère les utilisateurs, les permissions, les ressources du cluster, le stockage externe et les jeux de données, tout en supervisant l'utilisation du cluster via le tableau de bord.

  • Développeur : Soumet des tâches en utilisant les ressources du cluster. Ce rôle nécessite un compte créé par l'administrateur avec les permissions appropriées. Le développement s'effectue à l'aide d'outils tels que Arena CLI et Jupyter Notebook.

Prérequis

Assurez-vous qu'un administrateur a effectué les opérations suivantes :

  • Un cluster Kubernetes est créé.

    • Chaque nœud du cluster dispose d'au moins 300 Go d'espace disque.

    • Pour obtenir les meilleurs résultats d'accélération des données, utilisez quatre instances équipées chacune de huit GPU V100.

    • Pour une prise en compte optimale de la topologie, utilisez deux instances V100.

  • La suite cloud-native AI est installée.

  • Vous avez accès au AI Dashboard.

  • Vous avez accès à l'AI Developer Console.

    Remarque

    À partir du 22 janvier 2025, l'AI Console d'Alibaba Cloud, qui comprend l'AI Developer Console et l'AI Dashboard, deviendra une fonctionnalité sur liste d'autorisation uniquement. Cette modification n'affecte pas les déploiements existants. Les utilisateurs ne figurant pas sur la liste d'autorisation peuvent installer et configurer l'AI Console depuis la communauté open-source. Pour plus de détails, consultez Open-source AI Console.

  • Le jeu de données Fashion MNIST est téléchargé et importé vers OSS.

  • Vous disposez de l'URL du dépôt Git, du nom d'utilisateur et du mot de passe pour le code de test.

  • Un client kubectl est connecté au cluster.

  • L'Arena CLI est configuré.

Environnement du tutoriel

Utilisez la suite cloud-native AI pour développer, entraîner, accélérer, évaluer et déployer une charge de travail Fashion-MNIST sur votre cluster ACK.

Le cluster utilisé dans ce tutoriel se compose des nœuds suivants :

Nom d'hôte

IP

Rôle

GPU

vCPU

Mémoire

cn-beijing.192.168.0.13

192.168.0.13

serveur de rebond

1

8

30580004 KiB

cn-beijing.192.168.0.16

192.168.0.16

worker

1

8

30580004 KiB

cn-beijing.192.168.0.17

192.168.0.17

worker

1

8

30580004 KiB

cn-beijing.192.168.0.240

192.168.0.240

worker

1

8

30580004 KiB

cn-beijing.192.168.0.239

192.168.0.239

worker

1

8

30580004 KiB

Objectifs

Une fois ce guide terminé, vous serez capable de :

  • Gérer un jeu de données

  • Configurer un environnement de développement avec Jupyter Notebook

  • Soumettre une tâche d'entraînement autonome

  • Soumettre une tâche d'entraînement distribué

  • Accélérer une tâche d'entraînement avec Fluid

  • Accélérer une tâche d'entraînement avec l'AI Task Scheduler ACK

  • Gérer un modèle

  • Effectuer une évaluation de modèle

  • Déployer un service d'inférence

Étape 1 : Créer un compte et allouer des ressources

Contactez votre administrateur pour obtenir les ressources suivantes :

  • Un nom d'utilisateur et un mot de passe.

  • Un quota de ressources.

  • L'endpoint de l'AI Developer Console (si vous soumettez des tâches via la console).

    Remarque

    L'AI Console d'Alibaba Cloud, qui inclut l'AI Developer Console et l'O&M Console, deviendra une fonctionnalité sur liste d'autorisation à partir du 22 janvier 2025. Si vous avez déployé l'AI Developer Console ou l'O&M Console avant cette date, votre utilisation ne sera pas affectée. Si vous n'êtes pas sur la liste d'autorisation, vous pouvez installer et configurer la console de la suite AI depuis la communauté open-source. Pour des instructions de configuration détaillées, consultez Open-source AI Console.

  • Si vous soumettez une tâche à l'aide de l'Arena CLI, obtenez le kubeconfig du cluster. Pour les instructions, consultez Obtenir le kubeconfig et se connecter à un cluster.

Étape 2 : Créer un jeu de données

Les jeux de données sont gérés par un administrateur. Cet exemple utilise le jeu de données fashion-mnist.

Étape 1 : créer le jeu de données fashion-mnist

  1. Créez le fichier fashion-mnist.yaml en vous basant sur l'exemple YAML suivant.

    Cet exemple crée un volume persistant (PV) et une demande de volume persistant (PVC) de type OSS.

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: fashion-demo-pv
    spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 10Gi
      csi:
        driver: ossplugin.csi.alibabacloud.com
        volumeAttributes:
          bucket: fashion-mnist
          otherOpts: ""
          url: oss-cn-beijing.aliyuncs.com
          akId: "AKID"
          akSecret: "AKSECRET"
        volumeHandle: fashion-demo-pv
      persistentVolumeReclaimPolicy: Retain
      storageClassName: oss
      volumeMode: Filesystem
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: fashion-demo-pvc
      namespace: demo-ns
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
      selector:
        matchLabels:
          alicloud-pvname: fashion-demo-pv
      storageClassName: oss
      volumeMode: Filesystem
      volumeName: fashion-demo-pv
  2. Créez le jeu de données fashion-mnist.

    kubectl create -f fashion-mnist.yaml
  3. Vérifiez l'état du PV et du PVC.

    • Consultez l'état du PV.

      kubectl get pv fashion-mnist-jackwg

      Sortie attendue :

      NAME                   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                          STORAGECLASS   REASON   AGE
      fashion-mnist-jackwg   10Gi       RWX            Retain           Bound    ns1/fashion-mnist-jackwg-pvc   oss                     8h
    • Consultez l'état du PVC.

      kubectl get pvc fashion-mnist-jackwg-pvc -n ns1

      Sortie attendue :

      NAME                       STATUS   VOLUME                 CAPACITY   ACCESS MODES   STORAGECLASS   AGE
      fashion-mnist-jackwg-pvc   Bound    fashion-mnist-jackwg   10Gi       RWX            oss            8h

    Le PV et le PVC affichent tous deux l'état Bound.

Étape 2 : créer un jeu de données accéléré

Les administrateurs utilisent l'AI Dashboard pour accélérer les jeux de données.

  1. Accédez à l'AI Dashboard en tant qu'administrateur.

  2. Dans le volet de navigation de gauche de l'AI Dashboard, choisissez Dataset > Dataset List.

  3. Sur la page Dataset List, cliquez sur Accelerate dans la colonne Actions du jeu de données cible.

    Après l'accélération du jeu de données, ses informations sont mises à jour sur la page Dataset List. La liste comprend des colonnes telles que Task name, Namespace, Data source, Accelerated et Status. Pour le jeu de données accéléré, la colonne Accelerated affiche Yes, et son Status passe de NotReady à Ready une fois l'accélération terminée.

Étape 3 : Développer le modèle

Configurez un environnement de développement avec Jupyter Notebook :

  1. (Facultatif) Créez un Jupyter Notebook à partir d'une image personnalisée.

  2. Développez et testez votre modèle dans un Jupyter Notebook.

  3. Poussez le code vers un dépôt Git depuis le Jupyter Notebook.

  4. Soumettez une tâche d'entraînement à l'aide du SDK Arena.

(Facultatif) Étape 1 : Créer un notebook à partir d'une image personnalisée

L'AI Developer Console fournit des Jupyter Notebooks avec des images préconstruites pour différentes versions de TensorFlow et PyTorch. Si ces images ne répondent pas à vos besoins, vous pouvez créer une image personnalisée.

  1. Créez un fichier nommé Dockerfile basé sur le modèle suivant.

    Consultez Créer et utiliser des notebooks pour connaître les exigences relatives aux images personnalisées.

    cat<<EOF >dockerfile
    FROM tensorflow/tensorflow:1.15.5-gpu
    USER root
    RUN pip install jupyter && \
        pip install ipywidgets && \
        jupyter nbextension enable --py widgetsnbextension && \
        pip install jupyterlab && jupyter serverextension enable --py jupyterlab
    EXPOSE 8888
    #USER jovyan
    CMD ["sh", "-c", "jupyter-lab --notebook-dir=/home/jovyan --ip=0.0.0.0 --no-browser --allow-root --port=8888 --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*' --NotebookApp.base_url=${NB_PREFIX} --ServerApp.authenticate_prometheus=False"]
    EOF
  2. Construisez l'image à partir du Dockerfile.

    docker build -f dockerfile .

    Sortie attendue :

    Sending build context to Docker daemon  9.216kB
    Step 1/5 : FROM tensorflow/tensorflow:1.15.5-gpu
     ---> 73be11373498
    Step 2/5 : USER root
     ---> Using cache
     ---> 7ee21dc7e42e
    Step 3/5 : RUN pip install jupyter &&     pip install ipywidgets &&     jupyter nbextension enable --py widgetsnbextension &&     pip install jupyterlab && jupyter serverextension enable --py jupyterlab
     ---> Using cache
     ---> 23bc51c5e16d
    Step 4/5 : EXPOSE 8888
     ---> Using cache
     ---> 76a55822ddae
    Step 5/5 : CMD ["sh", "-c", "jupyter-lab --notebook-dir=/home/jovyan --ip=0.0.0.0 --no-browser --allow-root --port=8888 --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.allow_origin='*' --NotebookApp.base_url=${NB_PREFIX} --ServerApp.authenticate_prometheus=False"]
     ---> Using cache
     ---> 3692f04626d5
    Successfully built 3692f04626d5
  3. Poussez l'image vers votre registre de conteneurs.

    docker tag ${IMAGE_ID} registry-vpc.cn-beijing.aliyuncs.com/${DOCKER_REPO}/jupyter:fashion-mnist-20210802a
    docker push registry-vpc.cn-beijing.aliyuncs.com/${DOCKER_REPO}/jupyter:fashion-mnist-20210802a
  4. Créez un secret d'extraction d'image pour récupérer l'image depuis votre registre de conteneurs privé.

    Consultez Créer un Secret pour extraire une image d'un registre privé.

    kubectl create secret docker-registry regcred \
      --docker-server=<your-registry-server> \
      --docker-username=<your-username> \
      --docker-password=<your-password> \
      --docker-email=<your-email-address>
  5. Créez un Jupyter Notebook dans l'AI Developer Console.

    Consultez Créer et utiliser des notebooks.

    Configurez les paramètres du Jupyter Notebook comme suit : Dans la section Notebook Basic Information à gauche, configurez le Notebook Name et la Notebook Image (vous pouvez sélectionner une image personnalisée), puis spécifiez le Namespace et l'Image Pull Secret. Pour la Data Configuration, sélectionnez le jeu de données afin d'afficher la demande de volume persistant correspondante et le répertoire de stockage local. Si vous activez Workspace PVC, vous devez spécifier le Target PVC et le Mount Path. Dans la section Notebook Resource Configuration à droite, définissez les CPU (Cores), la Memory (GB) et les GPU (Units). Une fois la configuration terminée, cliquez sur Create Notebook.

Étape 2 : Développer et tester dans un notebook

  1. Accédez à l'AI Developer Console

  2. Dans le volet de navigation de gauche de l'AI Developer Console, cliquez sur Notebook.

  3. Sur la page Notebook, cliquez sur le nom du Jupyter Notebook cible dont le Status est Running.

  4. Ouvrez un nouveau terminal et exécutez les commandes suivantes pour vérifier que les données sont montées correctement :

    pwd
    /root/data
    ls -alh

    Sortie attendue :

    total 30M
    drwx------ 1 root root    0 Jan  1  1970 .
    drwx------ 1 root root 4.0K Aug  2 04:15 ..
    drwxr-xr-x 1 root root    0 Aug  1 14:16 saved_model
    -rw-r----- 1 root root 4.3M Aug  1 01:53 t10k-images-idx3-ubyte.gz
    -rw-r----- 1 root root 5.1K Aug  1 01:53 t10k-labels-idx1-ubyte.gz
    -rw-r----- 1 root root  26M Aug  1 01:54 train-images-idx3-ubyte.gz
    -rw-r----- 1 root root  29K Aug  1 01:53 train-labels-idx1-ubyte.gz
  5. Dans votre environnement Jupyter Notebook, créez un nouveau fichier notebook pour développer le modèle fashion-mnist et initialisez-le avec le code suivant :

    #!/usr/bin/python
    # -*- coding: UTF-8 -*-
    
    import os
    import gzip
    import numpy as np
    import tensorflow as tf
    from tensorflow import keras
    print('TensorFlow version: {}'.format(tf.__version__))
    dataset_path = "/root/data/"
    model_path = "./model/"
    model_version =  "v1"
    
    def load_data():
        files = [
            'train-labels-idx1-ubyte.gz',
            'train-images-idx3-ubyte.gz',
            't10k-labels-idx1-ubyte.gz',
            't10k-images-idx3-ubyte.gz'
        ]
        paths = []
        for fname in files:
            paths.append(os.path.join(dataset_path, fname))
        with gzip.open(paths[0], 'rb') as labelpath:
            y_train = np.frombuffer(labelpath.read(), np.uint8, offset=8)
        with gzip.open(paths[1], 'rb') as imgpath:
            x_train = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
        with gzip.open(paths[2], 'rb') as labelpath:
            y_test = np.frombuffer(labelpath.read(), np.uint8, offset=8)
        with gzip.open(paths[3], 'rb') as imgpath:
            x_test = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
        return (x_train, y_train),(x_test, y_test)
    
    def train():
        (train_images, train_labels), (test_images, test_labels) = load_data()
    
        # scale the values to 0.0 to 1.0
        train_images = train_images / 255.0
        test_images = test_images / 255.0
    
        # reshape for feeding into the model
        train_images = train_images.reshape(train_images.shape[0], 28, 28, 1)
        test_images = test_images.reshape(test_images.shape[0], 28, 28, 1)
    
        class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
                    'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
    
        print('\ntrain_images.shape: {}, of {}'.format(train_images.shape, train_images.dtype))
        print('test_images.shape: {}, of {}'.format(test_images.shape, test_images.dtype))
    
        model = keras.Sequential([
        keras.layers.Conv2D(input_shape=(28,28,1), filters=8, kernel_size=3,
                            strides=2, activation='relu', name='Conv1'),
        keras.layers.Flatten(),
        keras.layers.Dense(10, activation=tf.nn.softmax, name='Softmax')
        ])
        model.summary()
        testing = False
        epochs = 5
        model.compile(optimizer='adam',
                    loss='sparse_categorical_crossentropy',
                    metrics=['accuracy'])
        logdir = "/training_logs"
        tensorboard_callback = keras.callbacks.TensorBoard(log_dir=logdir)
        model.fit(train_images,
            train_labels,
            epochs=epochs,
            callbacks=[tensorboard_callback],
        )
        test_loss, test_acc = model.evaluate(test_images, test_labels)
        print('\nTest accuracy: {}'.format(test_acc))
        export_path = os.path.join(model_path, model_version)
        print('export_path = {}\n'.format(export_path))
        tf.keras.models.save_model(
            model,
            export_path,
            overwrite=True,
            include_optimizer=True,
            save_format=None,
            signatures=None,
            options=None
        )
        print('\nSaved model success')
    if __name__ == '__main__':
        train()
    Important

    Dans le code, dataset_path et model_path doivent correspondre aux chemins de montage de la source de données dans le Notebook. Cela permet au Notebook d'accéder au jeu de données monté sur le système de fichiers local.

  6. Dans le Notebook cible, cliquez sur l'icône Run icon pour exécuter le code.

    Sortie attendue :

    TensorFlow version: 1.15.5
    
    train_images.shape: (60000, 28, 28, 1), of float64
    test_images.shape: (10000, 28, 28, 1), of float64
    Model: "sequential_2"
    _________________________________________________________________
    Layer (type)                 Output Shape              Param #
    =================================================================
    Conv1 (Conv2D)               (None, 13, 13, 8)         80
    _________________________________________________________________
    flatten_2 (Flatten)          (None, 1352)              0
    _________________________________________________________________
    Softmax (Dense)              (None, 10)                13530
    =================================================================
    Total params: 13,610
    Trainable params: 13,610
    Non-trainable params: 0
    _________________________________________________________________
    Train on 60000 samples
    Epoch 1/5
    60000/60000 [==============================] - 3s 57us/sample - loss: 0.5452 - acc: 0.8102
    Epoch 2/5
    60000/60000 [==============================] - 3s 52us/sample - loss: 0.4103 - acc: 0.8555
    Epoch 3/5
    60000/60000 [==============================] - 3s 55us/sample - loss: 0.3750 - acc: 0.8681
    Epoch 4/5
    60000/60000 [==============================] - 3s 55us/sample - loss: 0.3524 - acc: 0.8757
    Epoch 5/5
    60000/60000 [==============================] - 3s 53us/sample - loss: 0.3368 - acc: 0.8798
    10000/10000 [==============================] - 0s 37us/sample - loss: 0.3770 - acc: 0.8673
    
    Test accuracy: 0.8672999739646912
    export_path = ./model/v1
    Saved model success

Étape 3 : Pousser le code vers un dépôt Git

Poussez le code vers votre dépôt Git directement depuis le Notebook.

  1. Installez Git.

    apt-get update
    apt-get install git
  2. Initialisez la configuration Git et stockez vos identifiants.

    git config --global credential.helper store
    git pull ${YOUR_GIT_REPO}
  3. Poussez le code vers le dépôt Git.

    git push origin fashion-test

    Sortie attendue :

    Total 0 (delta 0), reused 0 (delta 0)
    To codeup.aliyun.com:60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git
     * [new branch]      fashion-test -> fashion-test

Étape 4 : Soumettre une tâche d'entraînement à l'aide du SDK Arena

  1. Installez les dépendances pour le SDK Arena.

    !pip install coloredlogs
  2. Créez un nouveau fichier Python et initialisez-le avec le code suivant :

    import os
    import sys
    import time
    from arenasdk.client.client import ArenaClient
    from arenasdk.enums.types import *
    from arenasdk.exceptions.arena_exception import *
    from arenasdk.training.tensorflow_job_builder import *
    from arenasdk.logger.logger import LoggerBuilder
    
    def main():
        print("start to test arena-python-sdk")
        client = ArenaClient("","demo-ns","info","arena-system") # The job is submitted to the demo-ns namespace.
        print("create ArenaClient succeed.")
        print("start to create tfjob")
        job_name = "arena-sdk-distributed-test"
        job_type = TrainingJobType.TFTrainingJob
        try:
            # build the training job
            job =  TensorflowJobBuilder().with_name(job_name)\
                .with_workers(1)\
                .with_gpus(1)\
                .with_worker_image("tensorflow/tensorflow:1.5.0-devel-gpu")\
                .with_ps_image("tensorflow/tensorflow:1.5.0-devel")\
                .with_ps_count(1)\
                .with_datas({"fashion-demo-pvc":"/data"})\
                .enable_tensorboard()\
                .with_sync_mode("git")\
                .with_sync_source("https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git")\  # URL of the Git repository.
                .with_envs({\
                    "GIT_SYNC_USERNAME":"USERNAME", \   # Username for the Git repository.
                    "GIT_SYNC_PASSWORD":"PASSWORD",\    # Password for the Git repository.
                    "TEST_TMPDIR":"/",\
                })\
                .with_command("python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py").build()
            # If the training job already exists, delete it
            if client.training().get(job_name, job_type):
                print("The job {} already exists. Deleting it.".format(job_name))
                client.training().delete(job_name, job_type)
                time.sleep(3)
    
            output = client.training().submit(job)
            print(output)
    
            count = 0
            # Wait for the training job to start running.
            while True:
                if count > 160:
                    raise Exception("Timeout waiting for the job to start running")
                jobInfo = client.training().get(job_name,job_type)
                if jobInfo.get_status() == TrainingJobStatus.TrainingJobPending:
                    print("job status is PENDING,waiting...")
                    count = count + 1
                    time.sleep(5)
                    continue
                print("current status is {} of job {}".format(jobInfo.get_status().value,job_name))
                break
            # get the training job logs
            logger = LoggerBuilder().with_accepter(sys.stdout).with_follow().with_since("5m")
            #jobInfo.get_instances()[0].get_logs(logger)
            # display the training job information
            print(str(jobInfo))
            # delete the training job
            #client.training().delete(job_name, job_type)
        except ArenaException as e:
            print(e)
    
    main()
    • namespace : Dans cet exemple, la tâche d'entraînement est soumise au namespace demo-ns.

    • with_sync_source : L'URL du dépôt Git.

    • with_envs : Le nom d'utilisateur et le mot de passe pour le dépôt Git.

  3. Dans le Notebook cible, cliquez sur l'icône Run icon pour exécuter le code.

    Sortie attendue :

    2021-11-02/08:57:28 DEBUG util.py[line:19] - execute command: [arena get --namespace=demo-ns --arena-namespace=arena-system --loglevel=info arena-sdk-distributed-test --type=tfjob -o json]
    2021-11-02/08:57:28 DEBUG util.py[line:19] - execute command: [arena submit --namespace=demo-ns --arena-namespace=arena-system --loglevel=info tfjob --name=arena-sdk-distributed-test --workers=1 --gpus=1 --worker-image=tensorflow/tensorflow:1.5.0-devel-gpu --ps-image=tensorflow/tensorflow:1.5.0-devel --ps=1 --data=fashion-demo-pvc:/data --tensorboard --sync-mode=git --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git --env=GIT_SYNC_USERNAME=kubeai --env=GIT_SYNC_PASSWORD=kubeai@ACK123 --env=TEST_TMPDIR=/ python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py]
    start to test arena-python-sdk
    create ArenaClient succeed.
    start to create tfjob
    2021-11-02/08:57:29 DEBUG util.py[line:19] - execute command: [arena get --namespace=demo-ns --arena-namespace=arena-system --loglevel=info arena-sdk-distributed-test --type=tfjob -o json]
    service/arena-sdk-distributed-test-tensorboard created
    deployment.apps/arena-sdk-distributed-test-tensorboard created
    tfjob.kubeflow.org/arena-sdk-distributed-test created
    
    job status is PENDING,waiting...
    2021-11-02/09:00:34 DEBUG util.py[line:19] - execute command: [arena get --namespace=demo-ns --arena-namespace=arena-system --loglevel=info arena-sdk-distributed-test --type=tfjob -o json]
    current status is RUNNING of job arena-sdk-distributed-test
    {
        "allocated_gpus": 1,
        "chief_name": "arena-sdk-distributed-test-worker-0",
        "duration": "185s",
        "instances": [
            {
                "age": "13s",
                "gpu_metrics": [],
                "is_chief": false,
                "name": "arena-sdk-distributed-test-ps-0",
                "node_ip": "192.168.5.8",
                "node_name": "cn-beijing.192.168.5.8",
                "owner": "arena-sdk-distributed-test",
                "owner_type": "tfjob",
                "request_gpus": 0,
                "status": "Running"
            },
            {
                "age": "13s",
                "gpu_metrics": [],
                "is_chief": true,
                "name": "arena-sdk-distributed-test-worker-0",
                "node_ip": "192.168.5.8",
                "node_name": "cn-beijing.192.168.5.8",
                "owner": "arena-sdk-distributed-test",
                "owner_type": "tfjob",
                "request_gpus": 1,
                "status": "Running"
            }
        ],
        "name": "arena-sdk-distributed-test",
        "namespace": "demo-ns",
        "priority": "N/A",
        "request_gpus": 1,
        "tensorboard": "http://192.168.5.6:31068",
        "type": "tfjob"
    }

Étape 4 : Entraîner le modèle

Les exemples suivants couvrent l'entraînement autonome, l'entraînement distribué, l'entraînement accéléré par Fluid et la planification consciente de la topologie avec le planificateur de tâches IA.

Exemple 1 : Soumettre une tâche d'entraînement TensorFlow autonome

Soumettez une tâche d'entraînement avec l'Arena CLI ou l'AI Developer Console.

Méthode 1 : Utiliser l'Arena CLI

arena \
  submit \
  tfjob \
  -n ns1 \
  --name=fashion-mnist-arena \
  --data=fashion-mnist-jackwg-pvc:/root/data/ \
  --env=DATASET_PATH=/root/data/ \
  --env=MODEL_PATH=/root/saved_model \
  --env=MODEL_VERSION=1 \
  --env=GIT_SYNC_USERNAME=<GIT_USERNAME> \
  --env=GIT_SYNC_PASSWORD=<GIT_PASSWORD> \
  --sync-mode=git \
  --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
  --image="tensorflow/tensorflow:2.2.2-gpu" \
  "python /root/code/tensorflow-fashion-mnist-sample/train.py --log_dir=/training_logs"

Méthode 2 : Utiliser l'AI Developer Console

  1. Configurez une source de données.

    Le tableau suivant décrit certains des paramètres clés.

    Paramètre

    Exemple

    Obligatoire

    Name

    fashion-demo

    Oui

    Namespace

    demo-ns

    Oui

    PersistentVolumeClaim

    fashion-demo-pvc

    Oui

    Local storage directory

    /root/data

    Non

  2. Configurez un dépôt de code source.

    Paramètre

    Exemple

    Obligatoire

    Name

    fashion-git

    Oui

    Git URL

    https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git

    Oui

    Default branch

    master

    Non

    Local storage directory

    /root/

    Non

    Private Git username

    Le nom d'utilisateur de votre dépôt Git privé.

    Non

    Private Git password or token

    Le mot de passe ou le jeton d'accès personnel pour votre dépôt Git privé.

    Non

  3. Soumettez une tâche d'entraînement autonome.

    Après avoir configuré les paramètres d'entraînement, cliquez sur Submit. Vous pouvez ensuite consulter la tâche d'entraînement sur la page Job List. Le tableau suivant décrit les paramètres de soumission de la tâche.

    Paramètre

    Description

    Task Name

    Dans cet exemple, le nom de la tâche est fashion-tf-ui.

    Job type

    Pour cet exemple, sélectionnez Tensorflow Standalone.

    Namespace

    Dans cet exemple, utilisez demo-ns. Il doit s'agir du même namespace que celui du jeu de données.

    Data source configuration

    Pour cet exemple, sélectionnez fashion-demo, configuré lors de l'Étape 1.

    Code configuration

    Pour cet exemple, sélectionnez fashion-git, configuré lors de l'Étape 2.

    Code branch

    Dans cet exemple, utilisez master.

    Command

    Dans cet exemple, utilisez "export DATASET_PATH=/root/data/ &&export MODEL_PATH=/root/saved_model &&export MODEL_VERSION=1 &&python /root/code/tensorflow-fashion-mnist-sample/train.py".

    Private Git repository

    Si vous utilisez un dépôt privé, vous devez fournir le nom d'utilisateur et le mot de passe.

    Instance count

    La valeur par défaut est 1.

    Image

    Dans cet exemple, utilisez tensorflow/tensorflow:2.2.2-gpu.

    Image pull secret

    Si vous utilisez une image provenant d'un registre privé, vous devez d'abord créer un secret d'extraction d'image.

    CPU (cores)

    La valeur par défaut est 4.

    Memory (GB)

    La valeur par défaut est 8.

    Consultez Paramètres Arena CLI pour TFJob.

  4. Après avoir soumis la tâche, consultez ses journaux.

    1. Dans le volet de navigation de gauche de l'AI Developer Console, cliquez sur Tasks.

    2. Sur la page Tasks, cliquez sur le nom de la tâche cible.

    3. Sur la page de détails de la tâche, cliquez sur l'onglet Instance. Ensuite, dans la colonne Actions de l'instance cible, cliquez sur Logs.

      L'extrait suivant montre la sortie des journaux pour cet exemple :

      train_images.shape: (60000, 28, 28, 1), of float64
      test_images.shape: (10000, 28, 28, 1), of float64
      Model: "sequential"
      _________________________________________________________________
      Layer (type)                 Output Shape              Param #
      =================================================================
      Conv1 (Conv2D)               (None, 13, 13, 8)         80
      _________________________________________________________________
      flatten (Flatten)            (None, 1352)              0
      _________________________________________________________________
      Softmax (Dense)              (None, 10)                13530
      =================================================================
      Total params: 13,610
      Trainable params: 13,610
      Non-trainable params: 0
      _________________________________________________________________
      Epoch 1/5
      2021-08-01 14:21:17.532237: E tensorflow/core/profiler/internal/gpu/cupti_tracer.cc:1430] function cupti_interface_->EnableCallback( 0 , subscriber_, CUPTI_CB_DOMAIN_DRIVER_API, cbid)failed with error CUPTI_ERROR_INVALID_PARAMETER
      2021-08-01 14:21:17.532390: I tensorflow/core/profiler/internal/gpu/device_tracer.cc:216]  GpuTracer has collected 0 callback api events and 0 activity events.
      2021-08-01 14:21:17.533535: I tensorflow/core/profiler/rpc/client/save_profile.cc:168] Creating directory: /training_logs/train/plugins/profile/2021_08_01_14_21_17
      2021-08-01 14:21:17.533928: I tensorflow/core/profiler/rpc/client/save_profile.cc:174] Dumped gzipped tool data for trace.json.gz to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.trace.json.gz
      2021-08-01 14:21:17.534251: I tensorflow/core/profiler/utils/event_span.cc:288] Generation of step-events took 0 ms
      
      2021-08-01 14:21:17.534961: I tensorflow/python/profiler/internal/profiler_wrapper.cc:87] Creating directory: /training_logs/train/plugins/profile/2021_08_01_14_21_17Dumped tool data for overview_page.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.overview_page.pb
      Dumped tool data for input_pipeline.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.input_pipeline.pb
      Dumped tool data for tensorflow_stats.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.tensorflow_stats.pb
      Dumped tool data for kernel_stats.pb to /training_logs/train/plugins/profile/2021_08_01_14_21_17/fashion-mnist-arena-chief-0.kernel_stats.pb
      
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.5399 - accuracy: 0.8116
      Epoch 2/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.4076 - accuracy: 0.8573
      Epoch 3/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.3727 - accuracy: 0.8694
      Epoch 4/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.3512 - accuracy: 0.8769
      Epoch 5/5
      1875/1875 [==============================] - 3s 2ms/step - loss: 0.3351 - accuracy: 0.8816
      313/313 [==============================] - 0s 1ms/step - loss: 0.3595 - accuracy: 0.8733
      2021-08-01 14:21:34.820089: W tensorflow/python/util/util.cc:329] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
      WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py:1817: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
      Instructions for updating:
      If using Keras pass *_constraint arguments to layers.
      
      Test accuracy: 0.8733000159263611
      export_path = /root/saved_model/1
      
      Saved model success
  5. Consultez les métriques d'entraînement dans TensorBoard.

    Redirigez le port du service TensorBoard vers votre machine locale à l'aide de kubectl port-forward.

    1. Obtenez les détails du service TensorBoard.

      kubectl get svc -n demo-ns

      Sortie attendue :

      NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)               AGE
      tf-dist-arena-tensorboard   NodePort    172.16.XX.XX     <none>        6006:32226/TCP        80m
    2. Redirigez le port TensorBoard.

      kubectl port-forward svc/tf-dist-arena-tensorboard -n demo-ns 6006:6006

      Sortie attendue :

      Forwarding from 127.0.0.1:6006 -> 6006
      Forwarding from [::1]:6006 -> 6006
      Handling connection for 6006
      Handling connection for 6006
    3. Dans un navigateur web, ouvrez http://localhost:6006/ pour afficher le tableau de bord TensorBoard.

      L'onglet GRAPHS affiche le graphe de calcul du modèle, montrant les connexions et le flux de données entre les couches telles que Conv1, flatten et Softmax. Le panneau latéral fournit les propriétés détaillées du nœud sélectionné.

Exemple 2 : Soumettre une tâche d'entraînement TensorFlow distribué

Méthode 1 : Utiliser l'Arena CLI

  1. Soumettez la tâche d'entraînement.

    arena submit tf \
        -n demo-ns \
        --name=tf-dist-arena \
        --working-dir=/root/ \
        --data fashion-mnist-pvc:/data \
        --env=TEST_TMPDIR=/ \
        --env=GIT_SYNC_USERNAME=kubeai \
        --env=GIT_SYNC_PASSWORD=kubeai@ACK123 \
        --env=GIT_SYNC_BRANCH=master \
        --gpus=1 \
        --workers=2 \
        --worker-image=tensorflow/tensorflow:1.5.0-devel-gpu \
        --sync-mode=git \
        --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
        --ps=1 \
        --ps-image=tensorflow/tensorflow:1.5.0-devel \
        --tensorboard \
        "python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py --log_dir=/training_logs"
  2. Obtenez les détails du service TensorBoard.

    kubectl get svc -n demo-ns

    Sortie attendue :

    NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                 AGE
    tf-dist-arena-tensorboard   NodePort    172.16.204.248   <none>        6006:32226/TCP          80m
  3. Redirigez le port TensorBoard.

    kubectl port-forward svc/tf-dist-arena-tensorboard -n demo-ns 6006:6006

    Sortie attendue :

    Forwarding from 127.0.0.1:6006 -> 6006
    Forwarding from [::1]:6006 -> 6006
    Handling connection for 6006
    Handling connection for 6006
  4. Dans un navigateur web, ouvrez http://localhost:6006/ pour afficher le tableau de bord TensorBoard.

    L'onglet SCALARS affiche des graphiques pour des métriques telles que accuracy et cross_entropy pendant l'entraînement. Dans le panneau latéral, vous pouvez filtrer par exécutions train et test, et ajuster les options d'affichage du Smoothing et des axes.

Méthode 2 : Utiliser l'AI Developer Console

  1. Configurez une source de données.

    Réutilise les données de l'Étape 1.

  2. Configurez un dépôt de code source.

    Réutilise le code de l'Étape 2.

  3. Soumettez la tâche d'entraînement TensorFlow distribué.

    Après avoir configuré les paramètres d'entraînement, cliquez sur Submit. Vous pouvez ensuite consulter la tâche sur la page Job List. Le tableau suivant décrit les paramètres clés de la tâche.

    Paramètre

    Description

    Task Name

    Dans cet exemple, utilisez fashion-ps-ui.

    Job type

    Sélectionnez TF Distributed.

    Namespace

    Dans cet exemple, utilisez demo-ns. Il doit s'agir du même namespace que celui du jeu de données.

    Data source configuration

    Dans cet exemple, sélectionnez fashion-demo, configuré lors de l'Étape 1 de l'exemple précédent.

    Code configuration

    Dans cet exemple, sélectionnez fashion-git, configuré lors de l'Étape 2 de l'exemple précédent.

    Command

    Dans cet exemple, utilisez "export TEST_TMPDIR=/root/ && python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py --log_dir=/training_logs".

    Image

    • Sous Task Resource Configuration, dans l'onglet Worker, définissez l'Image sur tensorflow/tensorflow:1.5.0-devel-gpu.

    • Sous Task Resource Configuration, dans l'onglet PS, définissez l'Image sur tensorflow/tensorflow:1.5.0-devel.

    Consultez Paramètres Arena CLI pour TFJob.

  4. Pour consulter TensorBoard, suivez les étapes 2 à 4 de la Méthode 1 : Utiliser l'Arena CLI.

Exemple 3 : Soumettre une tâche d'entraînement accélérée par Fluid

Accélérez un jeu de données depuis l'O&M console, soumettez une tâche avec le jeu de données accéléré et comparez les temps d'exécution :

  1. Un administrateur accélère un jeu de données existant depuis l'O&M console.

  2. Un développeur soumet une tâche d'entraînement qui utilise le jeu de données accéléré.

  3. Comparez les temps d'exécution des tâches à l'aide de la commande arena list.

  1. Accélérez un jeu de données existant.

    Ignorez cette étape si vous avez déjà accéléré fashion-demo-pvc lors de l'Étape 2 : Créer un jeu de données. Consultez Gérer les jeux de données.

  2. Soumettez une tâche qui utilise le jeu de données accéléré.

    Soumettez la tâche d'entraînement au namespace demo-ns. Différences clés pour les jeux de données accélérés :

    • --data : Le nom de la PersistentVolumeClaim (PVC) accélérée. Dans cet exemple, il s'agit de fashion-demo-pvc-acc.

    • --env=DATASET_PATH : Ce chemin est formé en ajoutant le nom du PVC (fashion-demo-pvc-acc) au chemin de montage (/root/data/) spécifié dans le paramètre --data.

    arena \
      submit \
      tfjob \
      -n demo-ns \
      --name=fashion-mnist-fluid \
      --data=fashion-demo-pvc-acc:/root/data/ \
      --env=DATASET_PATH=/root/data/fashion-demo-pvc-acc \
      --env=MODEL_PATH=/root/saved_model \
      --env=MODEL_VERSION=1 \
      --env=GIT_SYNC_USERNAME=${GIT_USERNAME} \
      --env=GIT_SYNC_PASSWORD=${GIT_PASSWORD} \
      --sync-mode=git \
      --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
      --image="tensorflow/tensorflow:2.2.2-gpu" \
      "python /root/code/tensorflow-fashion-mnist-sample/train.py --log_dir=/training_logs"
  3. Comparez les temps d'exécution des deux tâches d'entraînement.

    arena list -n demo-ns

    Sortie attendue :

    NAME                 STATUS     TRAINER  DURATION  GPU(Requested)  GPU(Allocated)  NODE
    fashion-mnist-fluid  SUCCEEDED  TFJOB    33s       0               N/A             192.168.5.7
    fashion-mnist-arena  SUCCEEDED  TFJOB    3m        0               N/A             192.168.5.8

    Avec le même code et les mêmes ressources, la tâche accélérée par Fluid s'est terminée en 33 secondes contre 3 minutes pour la tâche standard.

Exemple 4 : Accélérer une tâche d'entraînement distribué à l'aide du planificateur de tâches IA

Le planificateur de tâches IA est un plugin ACK pour les charges de travail d'IA et de Big Data, prenant en charge le Gang Scheduling, le Capacity Scheduling et la planification consciente de la topologie. Cet exemple illustre la planification consciente de la topologie GPU.

Le planificateur utilise les informations de topologie au niveau du nœud (liens GPU tels que NVLink et PCIe Switch, ou architecture NUMA du CPU) pour optimiser la planification des tâches d'IA. Consultez Planification consciente de la topologie GPU et Planification consciente de la topologie CPU.

Activez la planification consciente de la topologie GPU et comparez les performances des tâches.

  1. Créez une tâche d'entraînement sans planification consciente de la topologie.

    arena submit mpi \
      --name=tensorflow-4-vgg16 \
      --gpus=1 \
      --workers=4 \
      --image=registry.cn-hangzhou.aliyuncs.com/kubernetes-image-hub/tensorflow-benchmark:tf2.3.0-py3.7-cuda10.1 \
      "mpirun --allow-run-as-root -np "4" -bind-to none -map-by slot -x NCCL_DEBUG=INFO -x NCCL_SOCKET_IFNAME=eth0 -x LD_LIBRARY_PATH -x PATH --mca pml ob1 --mca btl_tcp_if_include eth0 --mca oob_tcp_if_include eth0 --mca orte_keep_fqdn_hostnames t --mca btl ^openib python /tensorflow/benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --model=vgg16 --batch_size=64 --variable_update=horovod"
  2. Créez une tâche d'entraînement avec la planification consciente de la topologie activée.

    Étiquetez le nœud. Remplacez cn-beijing.192.168.XX.XX par le nom réel de votre nœud.

    kubectl label node cn-beijing.192.168.XX.XX ack.node.gpu.schedule=topology --overwrite

    Créez la tâche d'entraînement. L'indicateur --gputopology=true active la prise en compte de la topologie dans Arena.

    arena submit mpi \
      --name=tensorflow-topo-4-vgg16 \
      --gpus=1 \
      --workers=4 \
      --gputopology=true \
      --image=registry.cn-hangzhou.aliyuncs.com/kubernetes-image-hub/tensorflow-benchmark:tf2.3.0-py3.7-cuda10.1 \
      "mpirun --allow-run-as-root -np "4" -bind-to none -map-by slot -x NCCL_DEBUG=INFO -x NCCL_SOCKET_IFNAME=eth0 -x LD_LIBRARY_PATH -x PATH --mca pml ob1 --mca btl_tcp_if_include eth0 --mca oob_tcp_if_include eth0 --mca orte_keep_fqdn_hostnames t --mca btl ^openib python /tensorflow/benchmarks/scripts/tf_cnn_benchmarks/tf_cnn_benchmarks.py --model=vgg16 --batch_size=64 --variable_update=horovod
  3. Comparez les performances des deux tâches.

    1. Comparez les temps d'exécution.

      arena list -n demo-ns

      Sortie attendue :

      NAME                             STATUS     TRAINER  DURATION  GPU(Requested)  GPU(Allocated)  NODE
      tensorflow-topo-4-vgg16          SUCCEEDED  MPIJOB   44s       4               N/A             192.168.4.XX1
      tensorflow-4-vgg16-image-warned  SUCCEEDED  MPIJOB   2m        4               N/A             192.168.4.XX0
    2. Consultez le débit de la tâche consciente de la topologie.

      arena logs tensorflow-topo-4-vgg16 -n demo-ns

      Sortie attendue :

      100 images/sec: 251.7 +/- 0.1 (jitter = 1.2)  7.262
      ----------------------------------------------------------------
      total images/sec: 1006.44
    3. Consultez le débit de la tâche standard.

      arena logs tensorflow-4-vgg16-image-warned -n demo-ns

      Sortie attendue :

      100 images/sec: 56.4 +/- 0.2 (jitter = 1.5)  7.261
      ----------------------------------------------------------------
      total images/sec: 225.50

Le tableau suivant résume la comparaison des performances entre les deux tâches.

Tâche d'entraînement

Débit par GPU (images/sec)

Débit GPU total (images/sec)

Durée (secondes)

Planification consciente de la topologie activée

251,7

1006,44

44

Planification consciente de la topologie désactivée

56,4

225,50

120

Un nœud avec la planification consciente de la topologie activée ne prend plus en charge la planification GPU standard. Pour la restaurer, modifiez l'étiquette du nœud :

kubectl label node cn-beijing.192.168.XX.XX0 ack.node.gpu.schedule=default --overwrite

Étape 5 : Gérer le modèle

  1. Accédez à l'AI Developer Console

  2. Dans le volet de navigation de gauche de l'AI Developer Console, cliquez sur Model Manage.

  3. Sur la page Model Management, cliquez sur Create Model.

  4. Dans la boîte de dialogue Create, configurez le Model Name, la Model Version et le Job Name.

    Dans cet exemple, le nom du modèle est fashion-mnist-demo, la version du modèle est v1 et la tâche d'entraînement est tf-single.

  5. Cliquez sur OK. Le nouveau modèle apparaît dans la liste.

    Pour évaluer le modèle, cliquez sur New Model Evaluation dans la ligne du modèle.

Étape 6 : Évaluer le modèle

Soumettez des tâches d'évaluation de modèle avec Arena ou l'AI Developer Console. Cet exemple évalue un point de contrôle issu de l'entraînement Fashion-MNIST :

  1. Soumettez une tâche d'entraînement avec la création de points de contrôle activée à l'aide d'Arena.

  2. Soumettez une tâche d'évaluation de modèle à l'aide d'Arena.

  3. Comparez les résultats d'évaluation dans l'AI Developer Console.

  1. Soumettez une tâche d'entraînement avec la création de points de contrôle activée.

    Soumettez une tâche d'entraînement avec Arena. La tâche génère des points de contrôle sur le volume fashion-demo-pvc.

    arena \
      submit \
      tfjob \
      -n demo-ns \ # Set the namespace as needed.
      --name=fashion-mnist-arena-ckpt \
      --data=fashion-demo-pvc:/root/data/ \
      --env=DATASET_PATH=/root/data/ \
      --env=MODEL_PATH=/root/data/saved_model \
      --env=MODEL_VERSION=1 \
      --env=GIT_SYNC_USERNAME=${GIT_USERNAME} \ # Enter your Git username.
      --env=GIT_SYNC_PASSWORD=${GIT_PASSWORD} \ # Enter your Git password.
      --env=OUTPUT_CHECKPOINT=1 \
      --sync-mode=git \
      --sync-source=https://codeup.aliyun.com/60b4cf5c66bba1c04b442e49/tensorflow-fashion-mnist-sample.git \
      --image="tensorflow/tensorflow:2.2.2-gpu" \
      "python /root/code/tensorflow-fashion-mnist-sample/train.py --log_dir=/training_logs"
  2. Soumettez une tâche d'évaluation de modèle.

    1. Construisez l'image d'évaluation.

      Dans le répertoire kubeai-sdk, exécutez les commandes suivantes pour construire et pousser l'image.

      docker build . -t ${DOCKER_REGISTRY}:fashion-mnist
      docker push ${DOCKER_REGISTRY}:fashion-mnist
    2. Obtenez les détails du service MySQL.

      kubectl get svc -n kube-ai ack-mysql

      Sortie attendue :

      NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
      ack-mysql   ClusterIP   172.16.XX.XX    <none>        3306/TCP   28h
    3. Soumettez une tâche d'évaluation de modèle avec Arena.

      arena evaluate model \
       --namespace=demo-ns \
       --loglevel=debug \
       --name=evaluate-job \
       --image=registry.cn-beijing.aliyuncs.com/kube-ai/kubeai-sdk-demo:fashion-minist \
       --env=ENABLE_MYSQL=True \
       --env=MYSQL_HOST=172.16.77.227 \
       --env=MYSQL_PORT=3306 \
       --env=MYSQL_USERNAME=kubeai \
       --env=MYSQL_PASSWORD=kubeai@ACK \
       --data=fashion-demo-pvc:/data \
       --model-name=1 \
       --model-path=/data/saved_model/ \
       --dataset-path=/data/ \
       --metrics-path=/data/output \
       "python /kubeai/evaluate.py"
      Remarque

      Vous pouvez obtenir l'adresse IP et le port du service MySQL à l'étape précédente.

  3. Comparez les résultats d'évaluation.

    1. Dans le volet de navigation de gauche de l'AI Developer Console, cliquez sur Model Management.

      La page affiche une liste de tâches d'évaluation de modèle. La liste comprend des colonnes telles que Name, Model name, Model version, Namespace, Status, Creation time et End time. Pour les tâches terminées, la colonne Status affiche Complete. Vous pouvez comparer les résultats de plusieurs tâches en cliquant sur le bouton Compare Metrics en haut de la page.

    2. Dans les Tasks, cliquez sur un nom de tâche pour consulter ses métriques.

      Les résultats d'évaluation affichent les métriques suivantes : accuracy, precision, recall, F1_score et AUC. Une courbe ROC visualise également les performances de classification du modèle.

      Un graphique à barres compare visuellement les performances des tâches sélectionnées en fonction de métriques telles que l'AUC et l'accuracy.

Étape 7 : Déployer le modèle

Déployez votre modèle entraîné en tant que service d'inférence TensorFlow Serving. Arena prend également en charge d'autres frameworks tels que Triton et Seldon (consultez Documentation Arena serve).

Cet exemple utilise le modèle de l'Étape 4, stocké dans le PVC fashion-demo-pvc de l'Étape 2. Si votre modèle utilise un type de stockage différent, créez d'abord un PVC correspondant.

  1. Déployez le modèle TensorFlow sur TensorFlow Serving avec Arena.

    arena serve tensorflow \
      --loglevel=debug \
      --namespace=demo-ns \
      --name=fashion-mnist \
      --model-name=1  \
      --gpus=1  \
      --image=tensorflow/serving:1.15.0-gpu \
      --data=fashion-demo-pvc:/data \
      --model-path=/data/saved_model/ \
      --version-policy=latest
  2. Obtenez le nom du service d'inférence déployé.

    arena serve list -n demo-ns

    Sortie attendue :

    NAME           TYPE        VERSION       DESIRED  AVAILABLE  ADDRESS         PORTS                   GPU
    fashion-mnist  Tensorflow  202111031203  1        1          172.16.XX.XX    GRPC:8500,RESTFUL:8501  1

    Vous pouvez utiliser les valeurs ADDRESS et PORTS dans la sortie pour appeler le service depuis l'intérieur du cluster.

  3. Dans Jupyter, créez un nouveau fichier Notebook pour envoyer des requêtes au service HTTP TensorFlow Serving.

    Cet exemple utilise le Jupyter Notebook créé lors de l'Étape 3 : Développer le modèle pour envoyer des requêtes.

    • Dans le code d'initialisation suivant, remplacez la valeur de server_ip par l'ADDRESS (172.16.XX.XX) renvoyée à l'étape précédente.

    • Définissez server_http_port sur le port RESTFUL (8501) renvoyé à l'étape précédente.

    Le code d'initialisation pour le fichier Notebook est le suivant :

    import os
    import gzip
    import numpy as np
    # import matplotlib.pyplot as plt
    import random
    import requests
    import json
    
    server_ip = "172.16.XX.XX"
    server_http_port = 8501
    
    dataset_dir = "/root/data/"
    
    def load_data():
            files = [
                'train-labels-idx1-ubyte.gz',
                'train-images-idx3-ubyte.gz',
                't10k-labels-idx1-ubyte.gz',
                't10k-images-idx3-ubyte.gz'
            ]
    
            paths = []
            for fname in files:
                paths.append(os.path.join(dataset_dir, fname))
    
            with gzip.open(paths[0], 'rb') as labelpath:
                y_train = np.frombuffer(labelpath.read(), np.uint8, offset=8)
            with gzip.open(paths[1], 'rb') as imgpath:
                x_train = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_train), 28, 28)
            with gzip.open(paths[2], 'rb') as labelpath:
                y_test = np.frombuffer(labelpath.read(), np.uint8, offset=8)
            with gzip.open(paths[3], 'rb') as imgpath:
                x_test = np.frombuffer(imgpath.read(), np.uint8, offset=16).reshape(len(y_test), 28, 28)
    
            return (x_train, y_train),(x_test, y_test)
    
    def show(idx, title):
      plt.figure()
      plt.imshow(test_images[idx].reshape(28,28))
      plt.axis('off')
      plt.title('\n\n{}'.format(title), fontdict={'size': 16})
    
    class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
                   'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
    
    (train_images, train_labels), (test_images, test_labels) = load_data()
    train_images = train_images / 255.0
    test_images = test_images / 255.0
    
    # reshape for feeding into the model
    train_images = train_images.reshape(train_images.shape[0], 28, 28, 1)
    test_images = test_images.reshape(test_images.shape[0], 28, 28, 1)
    
    print('\ntrain_images.shape: {}, of {}'.format(train_images.shape, train_images.dtype))
    print('test_images.shape: {}, of {}'.format(test_images.shape, test_images.dtype))
    
    rando = random.randint(0,len(test_images)-1)
    #show(rando, 'An Example Image: {}'.format(class_names[test_labels[rando]]))
    
    # !pip install -q requests
    
    # import requests
    # headers = {"content-type": "application/json"}
    # json_response = requests.post('http://localhost:8501/v1/models/fashion_model:predict', data=data, headers=headers)
    # predictions = json.loads(json_response.text)['predictions']
    
    # show(0, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(
    #   class_names[np.argmax(predictions[0])], np.argmax(predictions[0]), class_names[test_labels[0]], test_labels[0]))
    
    def request_model(data):
        headers = {"content-type": "application/json"}
        json_response = requests.post('http://{}:{}/v1/models/1:predict'.format(server_ip, server_http_port), data=data, headers=headers)
        print('=======response:', json_response, json_response.text)
        predictions = json.loads(json_response.text)['predictions']
    
        print('The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(class_names[np.argmax(predictions[0])], np.argmax(predictions[0]), class_names[test_labels[0]], test_labels[0]))
        #show(0, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(
        #  class_names[np.argmax(predictions[0])], np.argmax(predictions[0]), class_names[test_labels[0]], test_labels[0]))
    
    # def request_model_version(data):
    #     headers = {"content-type": "application/json"}
    #     json_response = requests.post('http://{}:{}/v1/models/1/version/1:predict'.format(server_ip, server_http_port), data=data, headers=headers)
    #     print('=======response:', json_response, json_response.text)
    
    #     predictions = json.loads(json_response.text)
    #     for i in range(0,3):
    #       show(i, 'The model thought this was a {} (class {}), and it was actually a {} (class {})'.format(
    #         class_names[np.argmax(predictions[i])], np.argmax(predictions[i]), class_names[test_labels[i]], test_labels[i]))
    
    data = json.dumps({"signature_name": "serving_default", "instances": test_images[0:3].tolist()})
    print('Data: {} ... {}'.format(data[:50], data[len(data)-52:]))
    #request_model_version(data)
    request_model(data)

    Cliquez sur l'icône Run icon dans le Jupyter Notebook pour voir la sortie suivante :

    train_images.shape: (60000, 28, 28, 1), of float64
    test_images.shape: (10000, 28, 28, 1), of float64
    Data: {"signature_name": "serving_default", "instances": ...  [0.0], [0.0], [0.0], [0.0], [0.0], [0.0], [0.0]]]]}
    =======response: <Response [200]> {
        "predictions": [[7.42696e-07, 6.91237556e-09, 2.66364452e-07, 2.27735413e-07, 4.0373439e-07, 0.00490919966, 7.27086217e-06, 0.0316713452, 0.0010733594, 0.962337255], [0.00685342, 1.8516447e-08, 0.9266119, 2.42278338e-06, 0.0603800081, 4.01338771e-12, 0.00613868702, 4.26091073e-15, 1.35764185e-05, 3.38685469e-10], [1.09047969e-05, 0.999816835, 7.98738e-09, 0.000122893631, 4.85748023e-05, 1.50353979e-10, 3.57102294e-07, 1.89657579e-09, 4.4604468e-07, 9.23274524e-09]
        ]
    }
    The model thought this was a Ankle boot (class 9), and it was actually a Ankle boot (class 9)

FAQ

  • Comment installer un logiciel dans la console Jupyter Notebook ?

    Pour installer un logiciel, exécutez la commande suivante dans la console Jupyter Notebook.

    apt-get install <software-name>
  • Comment corriger les caractères illisibles dans la console Jupyter Notebook ?

    Modifiez le fichier /etc/locale pour qu'il contienne ce qui suit, puis rouvrez le terminal.

    LC_CTYPE="da_DK.UTF-8"
    LC_NUMERIC="da_DK.UTF-8"
    LC_TIME="da_DK.UTF-8"
    LC_COLLATE="da_DK.UTF-8"
    LC_MONETARY="da_DK.UTF-8"
    LC_MESSAGES="da_DK.UTF-8"
    LC_PAPER="da_DK.UTF-8"
    LC_NAME="da_DK.UTF-8"
    LC_ADDRESS="da_DK.UTF-8"
    LC_TELEPHONE="da_DK.UTF-8"
    LC_MEASUREMENT="da_DK.UTF-8"
    LC_IDENTIFICATION="da_DK.UTF-8"
    LC_ALL=