Todos os produtos
Search
Central de documentação

Container Service for Kubernetes:Cloud Native AI Suite developer guide

Última atualização: Sep 16, 2026

Este guia utiliza o conjunto de dados open-source Fashion-MNIST para demonstrar como os desenvolvedores usam o Cloud Native AI Suite para executar cargas de trabalho de deep learning no ACK, otimizar o treinamento distribuído, depurar modelos e implantar o modelo treinado no cluster.

Contexto

O Cloud Native AI Suite fornece componentes implantáveis de forma independente (K8s Helm charts) para acelerar a engenharia de IA.

O Cloud Native AI Suite possui duas funções de usuário: administrador e desenvolvedor.

  • Administrator: Gerencia usuários, permissões, recursos do cluster, armazenamento externo e conjuntos de dados, além de monitorar o uso do cluster por meio do painel.

  • Developer: Envia jobs utilizando recursos do cluster. Requer uma conta criada pelo administrador com as permissões concedidas. Utiliza ferramentas como Arena CLI e Jupyter Notebook para desenvolvimento.

Pré-requisitos

Certifique-se de que um administrador concluiu as seguintes tarefas:

  • Um cluster Kubernetes foi criado.

    • Cada nó no cluster deve ter pelo menos 300 GB de espaço em disco.

    • Para obter os melhores resultados de aceleração de dados, utilize quatro instâncias, cada uma equipada com oito GPUs V100.

    • Para obter os melhores resultados de reconhecimento de topologia, utilize duas instâncias V100.

  • O Cloud Native AI Suite está instalado.

  • Você tem acesso ao AI Dashboard.

  • Você tem acesso ao AI Developer Console.

    Nota

    A partir de 22 de janeiro de 2025, o AI Console da Alibaba Cloud, que inclui o AI Developer Console e o AI Dashboard, tornará-se um recurso disponível apenas via lista de permissões. Essa alteração não afeta implantações existentes. Usuários fora da lista de permissões podem instalar e configurar o AI Console a partir da comunidade open-source. Para mais detalhes, consulte Open-source AI Console.

  • O conjunto de dados Fashion MNIST foi baixado e enviado para o OSS.

  • Você possui a URL do repositório Git, o nome de usuário e a senha para o código de teste.

  • Um cliente kubectl está conectado ao cluster.

  • O Arena CLI está configurado.

Ambiente do tutorial

Utilize o Cloud Native AI Suite para desenvolver, treinar, acelerar, avaliar e implantar uma carga de trabalho Fashion-MNIST em seu cluster ACK.

O cluster utilizado neste tutorial consiste nos seguintes nós:

Host name

IP

Role

GPUs

vCPUs

Memory

cn-beijing.192.168.0.13

192.168.0.13

jump server

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

Objetivos

Após concluir este guia, você poderá:

  • Gerenciar um conjunto de dados

  • Configurar um ambiente de desenvolvimento com Jupyter Notebook

  • Enviar um job de treinamento standalone

  • Enviar um job de treinamento distribuído

  • Acelerar um job de treinamento com Fluid

  • Acelerar um job de treinamento com o ACK AI Task Scheduler

  • Gerenciar um modelo

  • Avaliar modelos

  • Implantar um service de inferência

Etapa 1: Criar uma conta e alocar recursos

Solicite ao seu administrador os seguintes recursos:

  • Nome de usuário e senha.

  • Uma cota de recursos.

  • O endpoint do AI Developer Console (caso envie jobs pelo console).

    Nota

    O AI Console da Alibaba Cloud, que inclui o AI Developer Console e o O&M Console, tornará-se um recurso permitido via lista de permissões a partir de 22 de janeiro de 2025. Se você implantou o AI Developer Console ou O&M Console antes dessa data, seu uso não será afetado. Caso não esteja na lista de permissões, é possível instalar e configurar o console do AI Suite a partir da comunidade open-source. Para instruções detalhadas de configuração, consulte Open-source AI Console.

  • Se você enviar um job usando o Arena CLI, obtenha o kubeconfig do cluster. Para instruções, consulte Obtain the kubeconfig and connect to a cluster.

Etapa 2: Criar um conjunto de dados

Os conjuntos de dados são gerenciados por um administrador. Este exemplo utiliza o conjunto de dados fashion-mnist.

Etapa 1: criar o conjunto de dados fashion-mnist

  1. Crie o arquivo fashion-mnist.yaml com base no seguinte exemplo YAML.

    Este exemplo cria um persistent volume (PV) e um persistent volume claim (PVC) do tipo 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. Crie o conjunto de dados fashion-mnist.

    kubectl create -f fashion-mnist.yaml
  3. Verifique o status do PV e do PVC.

    • Verifique o status do PV.

      kubectl get pv fashion-mnist-jackwg

      Saída esperada:

      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
    • Verifique o status do PVC.

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

      Saída esperada:

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

    Tanto o PV quanto o PVC devem apresentar o status Bound.

Etapa 2: criar um conjunto de dados acelerado

Os administradores utilizam o AI Dashboard para acelerar conjuntos de dados.

  1. Acesse o AI Dashboard como administrador.

  2. No painel de navegação à esquerda do AI Dashboard, escolha Dataset > Dataset List.

  3. Na página Dataset List, clique em Accelerate na coluna Actions do conjunto de dados desejado.

    Após acelerar o conjunto de dados, suas informações são atualizadas na página Dataset List. A lista inclui colunas como Task name, Namespace, Data source, Accelerated e Status. Para o conjunto de dados acelerado, a coluna Accelerated exibe Yes, e seu Status muda de NotReady para Ready assim que a aceleração for concluída.

Etapa 3: Desenvolver o modelo

Configure um ambiente de desenvolvimento com Jupyter Notebook:

  1. (Opcional) Crie um Jupyter Notebook a partir de uma imagem personalizada.

  2. Desenvolva e teste seu modelo em um Jupyter Notebook.

  3. Envie o código para um repositório Git a partir do Jupyter Notebook.

  4. Envie um job de treinamento usando o Arena SDK.

(Opcional) Etapa 1: Criar um notebook a partir de uma imagem personalizada

O AI Developer Console oferece Jupyter Notebooks com imagens pré-construídas para diferentes versões do TensorFlow e PyTorch. Caso essas imagens não atendam aos seus requisitos, crie uma imagem personalizada.

  1. Crie um arquivo chamado Dockerfile com base no seguinte modelo.

    Consulte Create and use notebooks para requisitos de imagens personalizadas.

    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. Construa a imagem a partir do Dockerfile.

    docker build -f dockerfile .

    Saída esperada:

    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. Envie a imagem para o seu registro de contêiner.

    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. Crie um image pull secret para baixar a imagem do seu registro de contêiner privado.

    Consulte Create a Secret to pull an image from a private registry.

    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. Crie um Jupyter Notebook no AI Developer Console.

    Consulte Create and use notebooks.

    Configure os parâmetros do Jupyter Notebook da seguinte forma: Na seção Notebook Basic Information à esquerda, configure o Notebook Name e a Notebook Image (é possível selecionar uma imagem personalizada) e especifique o Namespace e o Image Pull Secret. Para Data Configuration, selecione o conjunto de dados para exibir o persistent volume claim correspondente e o diretório de armazenamento local. Se você ativar o Workspace PVC, deverá especificar o Target PVC e o Mount Path. Na seção Notebook Resource Configuration à direita, defina CPU (Cores), Memory (GB) e GPU (Units). Após concluir a configuração, clique em Create Notebook.

Etapa 2: Desenvolver e testar em um notebook

  1. Acesse o AI Developer Console

  2. No painel de navegação à esquerda do AI Developer Console, clique em Notebook.

  3. Na página Notebook, clique no nome do Jupyter Notebook desejado que tenha o Status como Running.

  4. Abra um novo terminal e execute os seguintes comandos para verificar se os dados foram montados corretamente:

    pwd
    /root/data
    ls -alh

    Saída esperada:

    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. No seu ambiente Jupyter Notebook, crie um novo arquivo de notebook para desenvolver o modelo fashion-mnist e inicialize-o com o seguinte código:

    #!/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()
    Importante

    No código, dataset_path e model_path devem ser definidos com os caminhos de montagem da fonte de dados no Notebook. Isso permite que o Notebook acesse o conjunto de dados montado no sistema de arquivos local.

  6. No Notebook desejado, clique no ícone Run icon para executar o código.

    Saída esperada:

    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

Etapa 3: Enviar código para um repositório Git

Envie o código diretamente para o seu repositório Git a partir do Notebook.

  1. Instale o Git.

    apt-get update
    apt-get install git
  2. Inicialize a configuração do Git e armazene suas credenciais.

    git config --global credential.helper store
    git pull ${YOUR_GIT_REPO}
  3. Envie o código para o repositório Git.

    git push origin fashion-test

    Saída esperada:

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

Etapa 4: Enviar um job de treinamento usando o Arena SDK

  1. Instale as dependências do Arena SDK.

    !pip install coloredlogs
  2. Crie um novo arquivo Python e inicialize-o com o seguinte código:

    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: Neste exemplo, o job de treinamento é enviado para o namespace demo-ns.

    • with_sync_source: A URL do repositório Git.

    • with_envs: O nome de usuário e a senha para o repositório Git.

  3. No Notebook desejado, clique no ícone Run icon para executar o código.

    Saída esperada:

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

Etapa 4: Treinar o modelo

Os exemplos a seguir abrangem treinamento standalone, treinamento distribuído, treinamento acelerado com Fluid e agendamento com reconhecimento de topologia usando o AI job scheduler.

Exemplo 1: Enviar um job de treinamento TensorFlow standalone

Envie um job de treinamento com o Arena CLI ou AI Developer Console.

Método 1: Usar o 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étodo 2: Usar o AI Developer Console

  1. Configure a data source.

    A tabela a seguir descreve alguns dos principais parâmetros.

    Parameter

    Example

    Required

    Name

    fashion-demo

    Yes

    Namespace

    demo-ns

    Yes

    PersistentVolumeClaim

    fashion-demo-pvc

    Yes

    Local storage directory

    /root/data

    No

  2. Configure a source code repository.

    Parameter

    Example

    Required

    Name

    fashion-git

    Yes

    Git URL

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

    Yes

    Default branch

    master

    No

    Local storage directory

    /root/

    No

    Private Git username

    O nome de usuário do seu repositório Git privado.

    No

    Private Git password or token

    A senha ou token de acesso pessoal do seu repositório Git privado.

    No

  3. Submit a standalone training job.

    Após configurar os parâmetros de treinamento, clique em Submit. Em seguida, visualize o job de treinamento na página Job List. A tabela a seguir descreve os parâmetros de envio do job.

    Parameter

    Description

    Task Name

    Neste exemplo, o nome do job é fashion-tf-ui.

    Job type

    Para este exemplo, selecione Tensorflow Standalone.

    Namespace

    Neste exemplo, use demo-ns. Deve ser o mesmo namespace do conjunto de dados.

    Data source configuration

    Para este exemplo, selecione fashion-demo, configurado na Etapa 1.

    Code configuration

    Para este exemplo, selecione fashion-git, configurado na Etapa 2.

    Code branch

    Neste exemplo, use master.

    Command

    Neste exemplo, use "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

    Se utilizar um repositório privado, forneça o nome de usuário e a senha.

    Instance count

    O valor padrão é 1.

    Image

    Neste exemplo, use tensorflow/tensorflow:2.2.2-gpu.

    Image pull secret

    Se estiver usando uma imagem de um registro privado, crie primeiro um image pull secret.

    CPU (cores)

    O valor padrão é 4.

    Memory (GB)

    O valor padrão é 8.

    Consulte Arena CLI parameters for TFJob.

  4. Após enviar o job, visualize seus logs.

    1. No painel de navegação à esquerda do AI Developer Console, clique em Tasks.

    2. Na página Tasks, clique no nome do job desejado.

    3. Na página de detalhes do job, clique na aba Instance. Em seguida, na coluna Actions da instância desejada, clique em Logs.

      O trecho a seguir mostra a saída de log para este exemplo:

      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. Visualize as métricas de treinamento no TensorBoard.

    Encaminhe a porta do service do TensorBoard para sua máquina local usando kubectl port-forward.

    1. Obtenha os detalhes do service do TensorBoard.

      kubectl get svc -n demo-ns

      Saída esperada:

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

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

      Saída esperada:

      Forwarding from 127.0.0.1:6006 -> 6006
      Forwarding from [::1]:6006 -> 6006
      Handling connection for 6006
      Handling connection for 6006
    3. Em um navegador web, abra http://localhost:6006/ para visualizar o painel do TensorBoard.

      A aba GRAPHS exibe o grafo computacional do modelo, mostrando as conexões e o fluxo de dados entre camadas como Conv1, flatten e Softmax. O painel lateral fornece propriedades detalhadas para o nó selecionado.

Exemplo 2: Enviar um job de treinamento TensorFlow distribuído

Método 1: Usar o Arena CLI

  1. Envie o job de treinamento.

    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. Obtenha os detalhes do service do TensorBoard.

    kubectl get svc -n demo-ns

    Saída esperada:

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

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

    Saída esperada:

    Forwarding from 127.0.0.1:6006 -> 6006
    Forwarding from [::1]:6006 -> 6006
    Handling connection for 6006
    Handling connection for 6006
  4. Em um navegador web, abra http://localhost:6006/ para visualizar o painel do TensorBoard.

    A aba SCALARS mostra gráficos para métricas como accuracy e cross_entropy durante o treinamento. No painel lateral, filtre pelas execuções de train e test e ajuste as opções de exibição de Smoothing e dos eixos.

Método 2: Usar o AI Developer Console

  1. Configure a data source.

    Reutiliza dados da Etapa 1.

  2. Configure a source code repository.

    Reutiliza código da Etapa 2.

  3. Submit the distributed TensorFlow training job.

    Após configurar os parâmetros de treinamento, clique em Submit. Em seguida, visualize o job na página Job List. A tabela a seguir descreve os principais parâmetros do job.

    Parameter

    Description

    Task Name

    Neste exemplo, use fashion-ps-ui.

    Job type

    Selecione TF Distributed.

    Namespace

    Neste exemplo, use demo-ns. Deve ser o mesmo namespace do conjunto de dados.

    Data source configuration

    Neste exemplo, selecione fashion-demo, configurado na Etapa 1 do exemplo anterior.

    Code configuration

    Neste exemplo, selecione fashion-git, configurado na Etapa 2 do exemplo anterior.

    Command

    Neste exemplo, use "export TEST_TMPDIR=/root/ && python code/tensorflow-fashion-mnist-sample/tf-distributed-mnist.py --log_dir=/training_logs".

    Image

    • Em Task Resource Configuration, na aba Worker, defina Image como tensorflow/tensorflow:1.5.0-devel-gpu.

    • Em Task Resource Configuration, na aba PS, defina Image como tensorflow/tensorflow:1.5.0-devel.

    Consulte Arena CLI parameters for TFJob.

  4. Para visualizar o TensorBoard, siga as etapas 2 a 4 em Método 1: Usar o Arena CLI.

Exemplo 3: Enviar um job de treinamento acelerado com Fluid

Acelere um conjunto de dados pelo O&M console, envie um job com o conjunto de dados acelerado e compare os tempos de execução:

  1. Um administrador acelera um conjunto de dados existente pelo O&M console.

  2. Um desenvolvedor envia um job de treinamento que utiliza o conjunto de dados acelerado.

  3. Compare os tempos de execução dos jobs usando o comando arena list.

  1. Acelere um conjunto de dados existente.

    Ignore esta etapa se você já acelerou o fashion-demo-pvc na Etapa 2: Criar um conjunto de dados. Consulte Manage datasets.

  2. Envie um job que utilize o conjunto de dados acelerado.

    Envie o job de treinamento para o namespace demo-ns. Principais diferenças para conjuntos de dados acelerados:

    • --data: O nome do PersistentVolumeClaim (PVC) acelerado. Neste exemplo, é fashion-demo-pvc-acc.

    • --env=DATASET_PATH: Este caminho é formado anexando o nome do PVC (fashion-demo-pvc-acc) ao caminho de montagem (/root/data/) especificado no parâmetro --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. Compare os tempos de execução dos dois jobs de treinamento.

    arena list -n demo-ns

    Saída esperada:

    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

    Com o mesmo código e recursos, o job acelerado com Fluid foi concluído em 33 segundos, contra 3 minutos do job padrão.

Exemplo 4: Acelerar um job de treinamento distribuído usando o AI job scheduler

O AI job scheduler é um plugin do ACK para cargas de trabalho de IA e big data, suportando Gang Scheduling, Capacity Scheduling e agendamento com reconhecimento de topologia. Este exemplo demonstra o agendamento com reconhecimento de topologia de GPU.

O agendador utiliza informações de topologia no nível do nó (links de GPU como NVLink e PCIe Switch, ou arquitetura NUMA da CPU) para otimizar o agendamento de jobs de IA. Consulte GPU topology-aware scheduling e CPU topology-aware scheduling.

Ative o agendamento com reconhecimento de topologia de GPU e compare o desempenho dos jobs.

  1. Crie um job de treinamento sem agendamento com reconhecimento de topologia.

    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. Crie um job de treinamento com o agendamento com reconhecimento de topologia ativado.

    Rotule o nó. Substitua cn-beijing.192.168.XX.XX pelo nome real do seu nó.

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

    Crie o job de treinamento. A flag --gputopology=true ativa o reconhecimento de topologia no 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. Compare o desempenho dos dois jobs.

    1. Compare os tempos de execução.

      arena list -n demo-ns

      Saída esperada:

      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. Visualize o throughput do job com reconhecimento de topologia.

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

      Saída esperada:

      100 images/sec: 251.7 +/- 0.1 (jitter = 1.2)  7.262
      ----------------------------------------------------------------
      total images/sec: 1006.44
    3. Visualize o throughput do job padrão.

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

      Saída esperada:

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

A tabela a seguir resume a comparação de desempenho entre os dois jobs.

Training job

Throughput per GPU (images/sec)

Total GPU throughput (images/sec)

Duration (seconds)

Agendamento com reconhecimento de topologia ativado

251.7

1006.44

44

Agendamento com reconhecimento de topologia desativado

56.4

225.50

120

Um nó com agendamento com reconhecimento de topologia ativado não suporta mais o agendamento padrão de GPU. Para restaurá-lo, altere o rótulo do nó:

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

Etapa 5: Gerenciar o modelo

  1. Acesse o AI Developer Console

  2. No painel de navegação à esquerda do AI Developer Console, clique em Model Manage.

  3. Na página Model Management, clique em Create Model.

  4. Na caixa de diálogo Create, configure o Model Name, Model Version e Job Name.

    Neste exemplo, o nome do modelo é fashion-mnist-demo, a versão do modelo é v1 e o job de treinamento é tf-single.

  5. Clique em OK. O novo modelo aparece na lista.

    Para avaliar o modelo, clique em New Model Evaluation na linha do modelo.

Etapa 6: Avaliar o modelo

Envie jobs de avaliação de modelo com o Arena ou o AI Developer Console. Este exemplo avalia um checkpoint do treinamento Fashion-MNIST:

  1. Envie um job de treinamento com checkpointing ativado usando o Arena.

  2. Envie um job de avaliação de modelo usando o Arena.

  3. Compare os resultados da avaliação no AI Developer Console.

  1. Envie um job de treinamento com checkpointing ativado.

    Envie um job de treinamento com o Arena. O job gera checkpoints no 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. Envie um job de avaliação de modelo.

    1. Construa a imagem de avaliação.

      No diretório kubeai-sdk, execute os seguintes comandos para construir e enviar a imagem.

      docker build . -t ${DOCKER_REGISTRY}:fashion-mnist
      docker push ${DOCKER_REGISTRY}:fashion-mnist
    2. Obtenha os detalhes do service MySQL.

      kubectl get svc -n kube-ai ack-mysql

      Saída esperada:

      NAME        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
      ack-mysql   ClusterIP   172.16.XX.XX    <none>        3306/TCP   28h
    3. Envie um job de avaliação de modelo com o 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"
      Nota

      Obtenha o endereço IP e a porta do service MySQL na etapa anterior.

  3. Compare os resultados da avaliação.

    1. No painel de navegação à esquerda do AI Developer Console, clique em Model Management.

      A página exibe uma lista de jobs de avaliação de modelo. A lista inclui colunas como Name, Model name, Model version, Namespace, Status, Creation time e End time. Para jobs concluídos, a coluna Status mostra Complete. Compare os resultados de vários jobs clicando no botão Compare Metrics na parte superior da página.

    2. Em Tasks, clique no nome de um job para visualizar suas métricas.

      Os resultados da avaliação exibem as seguintes métricas: accuracy, precision, recall, F1_score e AUC. Uma curva ROC também visualiza o desempenho de classificação do modelo.

      Um gráfico de barras compara visualmente o desempenho dos jobs selecionados com base em métricas como AUC e accuracy.

Etapa 7: Implantar o modelo

Implante seu modelo treinado como um service de inferência TensorFlow Serving. O Arena também suporta outros frameworks, como Triton e Seldon (consulte Arena serve documentation).

Este exemplo usa o modelo da Etapa 4, armazenado no PVC fashion-demo-pvc da Etapa 2. Se o seu modelo usar um tipo de armazenamento diferente, crie primeiro um PVC correspondente.

  1. Implante o modelo TensorFlow no TensorFlow Serving com o 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. Obtenha o nome do service de inferência implantado.

    arena serve list -n demo-ns

    Saída esperada:

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

    Use os valores ADDRESS e PORTS na saída para chamar o service de dentro do cluster.

  3. No Jupyter, crie um novo arquivo Notebook para enviar requisições ao service HTTP do TensorFlow Serving.

    Este exemplo usa o Jupyter Notebook criado na Etapa 3: Desenvolver o modelo para enviar requisições.

    • No código de inicialização a seguir, substitua o valor de server_ip pelo ADDRESS (172.16.XX.XX) retornado na etapa anterior.

    • Defina server_http_port como a porta RESTFUL (8501) retornada na etapa anterior.

    O código de inicialização para o arquivo Notebook é o seguinte:

    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)

    Clique no ícone Run icon no Jupyter Notebook para ver a seguinte saída:

    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)

Perguntas frequentes

  • Como instalo software no console do Jupyter Notebook?

    Para instalar software, execute o seguinte comando no console do Jupyter Notebook.

    apt-get install <software-name>
  • Como corrijo caracteres ilegíveis no console do Jupyter Notebook?

    Edite o arquivo /etc/locale para conter o seguinte e reabra o 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=