Implemente uma carga de trabalho de aprendizagem automática em lote

Este tutorial demonstra como usar o Google Kubernetes Engine (GKE) para gerir cargas de trabalho em lote tolerantes a falhas, mantendo os custos baixos. Siga este tutorial para saber como usar tarefas e pods de spot otimizados em função dos custos, bem como configurar uma fila de tarefas Redis no cluster no GKE.

Contexto

Um fluxo de trabalho em lote é um processo normalmente concebido para ter um ponto de início e um ponto de conclusão. Deve considerar cargas de trabalho em lote no GKE se a sua arquitetura envolver a introdução, o processamento e a saída de dados em vez de usar dados não processados. Áreas como a aprendizagem automática, a inteligência artificial e a computação de alto desempenho (HPC) apresentam diferentes tipos de cargas de trabalho em lote, como a preparação de modelos offline, a previsão em lote, a análise de dados, a simulação de sistemas físicos e o processamento de vídeo.

Ao criar cargas de trabalho em lote contentorizadas, pode tirar partido das seguintes vantagens do GKE:

  • Uma norma aberta, uma vasta comunidade e um serviço gerido.
  • Eficiência de custos através da orquestração eficaz da carga de trabalho e da infraestrutura, bem como de recursos de computação especializados.
  • Isolamento e portabilidade da contentorização, o que permite a utilização da nuvem como capacidade de overflow, mantendo a segurança dos dados.
  • Disponibilidade de capacidade de aumento, seguida de uma redução rápida dos clusters do GKE.

Prepare o ambiente

  1. Clone o repositório de exemplo usado neste tutorial:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/batch/aiml-workloads
    
  2. Crie um cluster do GKE Autopilot:

    gcloud container clusters create-auto batch-aiml \
        --location=us-central1
    

    Este passo pode demorar até 5 minutos a ser concluído.

Configure o armazenamento de conjuntos de dados com um sistema de arquivos de rede (NFS)

A carga de trabalho de aprendizagem automática requer uma solução de armazenamento para os conjuntos de dados e os ficheiros de saída. Nesta secção, cria uma instância do Filestore e concede acesso à instância através de um PersistentVolume e um PersistentVolumeClaim.

Para saber mais, veja como criar uma estratégia de armazenamento ideal e como aceder a instâncias do Filestore a partir de clusters do GKE.

Crie uma instância do Filestore

  1. Crie uma instância do Filestore:

    gcloud filestore instances create batch-aiml-filestore \
        --zone=us-central1-b \
        --tier=BASIC_HDD \
        --file-share=name="NFSVol",capacity=1TB \
        --network=name="default"
    

    Este comando especifica as seguintes opções:

    • tier: o nível de serviço da instância do Filestore. Este exemplo usa o nível básico. Para saber mais sobre as outras opções, consulte os Níveis de serviço.

    • network=name: O nome da rede da nuvem virtual privada (VPC) para a instância do Filestore. O cluster do GKE tem de estar na mesma rede de VPC que a instância do Filestore.

    • capacity: o tamanho pretendido do volume. Especifique o valor de armazenamento numa das unidades suportadas descritas em Quantidades de recursos.

  2. Verifique se a instância do Filestore foi implementada:

    gcloud filestore instances list \
        --project=PROJECT_ID \
        --zone=us-central1-b
    

    Substitua PROJECT_ID pelo seu Google Cloud ID do projeto.

    O resultado é semelhante ao seguinte:

    INSTANCE_NAME: batch-aiml-filestore
    LOCATION: us-central1-b
    TIER: BASIC_HDD
    CAPACITY_GB: 1024
    FILE_SHARE_NAME: NFSVol
    IP_ADDRESS: 203.0.113.54
    STATE: READY
    CREATE_TIME: 2022-03-15T18:23:51
    
  3. Tome nota do valor no campo IP_ADDRESS para usar na secção seguinte.

Crie um PersistentVolume

Uma especificação de PersistentVolume do Kubernetes permite que o cluster do GKE se ligue à instância do Filestore.

  1. Atualize o ficheiro kubernetes-manifests/persistent-volume.yaml com o endereço IP da instância do Filestore:

    sed -i "\
      s/<FILESTORE_IP_ADDRESS>/IP_ADDRESS/g" \
      kubernetes-manifests/persistent-volume.yaml
    

    Substitua IP_ADDRESS pelo endereço IP que anotou quando criou a instância do Filestore na secção anterior.

  2. Implemente o PersistentVolume:

    kubectl apply -f kubernetes-manifests/persistent-volume.yaml
    

Crie um PersistentVolumeClaim

Um PersistentVolumeClaim do Kubernetes permite que os pods e os trabalhos do Kubernetes acedam aos recursos de armazenamento de um PersistentVolume.

Implemente o PersistentVolumeClaim:

kubectl apply -f kubernetes-manifests/persistent-volume-claim.yaml

Consuma o PersistentVolumeClaim

Com o PersistentVolume e o PersistentVolumeClaim configurados no cluster do GKE, pode configurar o servidor Redis e os trabalhos em lote para consumir o PersistentVolumeClaim. Este aparece como um volume de armazenamento montável.

Inspecione os ficheiros kubernetes-manifests/redis-pod.yaml e kubernetes-manifests/workload.yaml. As configurações do manifesto são semelhantes às seguintes:

  spec:
  
  containers:
  - name: workload
    image: "us-central1-docker.pkg.dev/gke-batch-aiml/batch-aiml-docker-repo/workload"
    volumeMounts:
    - mountPath: /mnt/fileserver
      name: workload-pvc
  volumes:
  - name: workload-pvc
    persistentVolumeClaim:
      claimName: fileserver-claim
      readOnly: false

Neste manifesto:

  • spec.volumes especifica o PersistentVolumeClaim a consumir.
  • spec.containers.volumeMounts especifica o caminho do ficheiro local onde o Pod pode aceder à partilha de ficheiros do Filestore.

Configure uma fila de tarefas do Redis

O fluxo de trabalho processa dados em lotes para preparar iterativamente um modelo de deteção de fraudes. Para gerir os conjuntos de dados que estão a ser processados atualmente ou que ainda estão na fila, implemente o servidor Redis no cluster do GKE.

Para este tutorial, inicia uma única instância do Redis. Para implementar o Redis de forma escalável e redundante, consulte o artigo Crie uma aplicação Web de vários níveis com o Redis e o PHP.

  1. Implemente a especificação do servidor Redis.

    kubectl apply -f kubernetes-manifests/redis-pod.yaml
    
  2. Verifique se o Pod está em execução:

    kubectl get pods
    

    O resultado é semelhante ao seguinte:

    NAME           READY   STATUS    RESTARTS   AGE
    redis-leader   1/1     Running   0          118s
    

    O Pod pode demorar até dois minutos a começar a funcionar.

  3. Transfira os ficheiros que contêm os conjuntos de dados de preparação e de testes para o volume NFS.

    sh scripts/transfer-datasets.sh
    

    Este script copia os ficheiros do repositório de código de exemplo para o diretório /mnt/fileserver/datasets/ no pod redis-leader.

  4. Preencha a fila do Redis.

    sh scripts/queue-jobs.sh
    

    Este script envia os caminhos dos ficheiros para os conjuntos de dados de preparação para uma lista denominada datasets na base de dados Redis. Esta fila vai ser usada pela carga de trabalho para localizar o conjunto de dados seguinte a processar.

  5. Implemente o serviço para tornar o servidor Redis detetável no cluster do GKE.

    kubectl apply -f ./kubernetes-manifests/redis-service.yaml
    

Execute a carga de trabalho em lote

Neste ponto, preparou o cluster do GKE, a fila de tarefas do Redis e a partilha de ficheiros. Agora, pode executar a carga de trabalho em lote.

Nesta secção, usa uma imagem de contentor de uma carga de trabalho de exemplo para formar um modelo de deteção de fraudes com lotes de dados de transações financeiras. O processo de preparação pode ser resumido da seguinte forma:

  1. Um cliente Redis reivindica tarefas (caminhos de ficheiros para conjuntos de dados) na fila Redis e remove-as da fila quando concluídas.

  2. Uma classe de gestor de preparação de modelos, FraudDetectionModelTrainer, carrega um novo lote de dados e, opcionalmente, um estado guardado de um modelo de aprendizagem automática. O conjunto de dados é usado para refinar o modelo (um processo conhecido como preparação de "início rápido").

  3. O novo estado do modelo e um relatório dos detalhes do lote e das classificações de desempenho são guardados no volume NFS do Filestore, que pode ser acedido no cluster do GKE através de um PersistentVolumeClaim.

Para saber mais, explore o código fonte.

Defina o trabalho

O manifesto seguinte descreve o trabalho do Kubernetes para a imagem da carga de trabalho em lote. Um controlador de tarefas no Kubernetes cria um ou mais pods e garante que executam com êxito uma tarefa específica.

apiVersion: batch/v1
kind: Job
metadata:
  name: workload
spec:
  parallelism: 1
  template:
    metadata:
      name: workload
    spec:
      nodeSelector:
        cloud.google.com/gke-spot: "true"
      containers:
      - name: workload
        image: "us-docker.pkg.dev/google-samples/containers/gke/batch-ml-workload"
        volumeMounts:
        - mountPath: /mnt/fileserver
          name: workload-pvc
      volumes:
      - name: workload-pvc
        persistentVolumeClaim:
          claimName: fileserver-claim
          readOnly: false
      restartPolicy: OnFailure

Implemente a carga de trabalho

  1. Implemente a tarefa:

    kubectl apply -f ./kubernetes-manifests/workload.yaml
    
  2. Verifique se o estado do workload-XXX Pod é Completed:

    watch kubectl get pods
    

    Pode demorar alguns segundos. Pode voltar à linha de comandos premindo Ctrl+C.

    O resultado é semelhante ao seguinte:

    NAME             READY   STATUS      RESTARTS   AGE
    redis-leader     1/1     Running     0          16m
    workload-4p55d   0/1     Completed   0          83s
    
  3. Verifique os registos da tarefa workload:

    kubectl logs job/workload
    

    O resultado é semelhante ao seguinte:

    Worker with sessionID: b50f9459-ce7f-4da8-9f84-0ab5c3233a72
    Initial queue state: empty=False
    Processing dataset: datasets/training/2018-04-04.pkl
    Processing dataset: datasets/training/2018-04-03.pkl
    Processing dataset: datasets/training/2018-04-02.pkl
    Processing dataset: datasets/training/2018-04-01.pkl
    Queue empty, exiting
    

    Os ficheiros .pkl são serializações de conjuntos de dados que contêm um lote de transações de cartão de crédito, marcadas como válidas ou fraudulentas. A tarefa workload itera nestes ficheiros, descompactando os conjuntos de dados e usando-os para preparar o modelo de aprendizagem automática, antes de os remover da fila do Redis. A carga de trabalho continua a processar os dados em lotes até que a fila do Redis fique vazia, antes de terminar com êxito.

Explore o volume NFS

Durante o seu funcionamento, a carga de trabalho cria ficheiros no volume NFS montado, acessíveis no cluster por outros trabalhos em lote ou aplicações online.

  1. Indique os ficheiros criados pela carga de trabalho:

    kubectl exec --stdin --tty redis-leader -- /bin/sh -c "ls -1 /mnt/fileserver/output"
    

    O resultado deve ser o seguinte:

    model_cpt_2018-04-01.pkl
    model_cpt_2018-04-02.pkl
    model_cpt_2018-04-03.pkl
    model_cpt_2018-04-04.pkl
    report.txt
    

    Foram criados pontos de verificação para o modelo preparado (nomes de ficheiros como model_cpt_XXX.pkl) e um relatório do desempenho do modelo (report.txt) no diretório /mnt/fileserver/output no volume NFS.

  2. Inspeccione o relatório de desempenho do modelo:

    kubectl exec --stdin --tty redis-leader -- /bin/sh -c "cat /mnt/fileserver/output/report.txt"
    

    Segue-se um fragmento do resultado:

    Report generated on: 2022-02-09 14:19:42.303619
    Training dataset: 2018-04-04.pkl
    Model checkpoint: model_cpt_2018-04-04.pkl
    ---
    Accuracy on training data: 0.9981112277019937
    Accuracy on testing data: 0.9977204434773599
    

    O ficheiro contém entradas que detalham a hora da preparação, o conjunto de dados usado, a precisão alcançada e o nome do ficheiro do ponto de verificação do modelo associado à preparação.

Para saber mais sobre volumes NFS, consulte os guias do Filestore.