Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Neste artigo, você configurará e implantará um cluster do Ray no Serviço de Kubernetes do Azure (AKS) usando o KubeRay. Você também aprenderá a usar o cluster do Ray para treinar um modelo de machine learning simples e exibir os resultados no Painel do Ray.
Este artigo fornece dois métodos para implantar o cluster do Ray no AKS:
-
Implantação não interativa: usar o script
deploy.shno repositório do GitHub para implantar a amostra completa do Ray de forma não interativa. - Implantação manual: seguir as etapas de implantação manual para implantar a amostra do Ray no AKS.
Pré-requisitos
- Examine a Visão geral do cluster do Ray no AKS para entender os componentes e o processo de implantação.
- Uma assinatura do Azure. Caso você não tenha uma assinatura do Azure, crie uma conta gratuita aqui.
- A CLI do Azure instalada em seu computador local. Você pode instalá-la usando as instruções em Como instalar a CLI do Azure.
- A extensão de versão prévia do Serviço de Kubernetes do Azure instalada.
- O Helm instalado.
- Ferramentas de cliente do Terraform ou OpenTofu instalados. Este artigo usa o Terraform, mas os módulos usados devem ser compatíveis com o OpenTofu.
Implantar a amostra do Ray de forma não interativa
Se você quiser implantar o exemplo completo do Ray de forma não interativa, é possível usar o script deploy.sh no repositório do GitHub (https://github.com/Azure-Samples/aks-ray-sample). Este script conclui as etapas descritas na seção Processo de implantação do Ray.
Clone o repositório GitHub localmente e altere para a raiz do repositório usando os seguintes comandos:
git clone https://github.com/Azure-Samples/aks-ray-sample cd aks-ray-sampleImplante o exemplo completo usando os seguintes comandos:
chmod +x deploy.sh ./deploy.shDepois que a implantação for concluída, examine a saída dos logs e do grupo de recursos no portal do Azure para ver a infraestrutura que foi criada.
Implantar manualmente a amostra do Ray
O MNIST de Moda é um conjunto de dados de imagens de artigo da Zalando que consistem em um conjunto de treinamento de 60.000 exemplos e um conjunto de testes de 10.000 exemplos. Cada exemplo é uma imagem de escala de cinza 28x28 associada a um rótulo de dez classes. Neste guia, você treinará um modelo PyTorch simples neste conjunto de dados usando o cluster do Ray.
Implantar a especificação do RayJob
Para treinar o modelo, você precisa enviar uma especificação de trabalho do Ray para o operador KubeRay em execução em um cluster privado do AKS. A especificação de trabalho do Ray é um arquivo YAML que descreve os recursos necessários para executar o trabalho, incluindo a imagem do Docker, o comando a ser executado e o número de trabalhos a serem usados.
Examinando a descrição de trabalho do Ray, talvez seja necessário modificar alguns campos para corresponder ao seu ambiente:
- O campo
replicasna seçãoworkerGroupSpecsemrayClusterSpecespecifica o número de pods de trabalho agendados pelo KubeRay para o cluster do Kubernetes. Cada pod de trabalho requer 3 CPUs e 4 GB de memória. O pod principal requer 1 CPU e 4 GB de memória. Definir o camporeplicascomo 2 requer 8 vCPUs no pool de nós usado para implementar o RayCluster para o trabalho. - O campo
NUM_WORKERSabaixo deruntimeEnvYAMLemspecespecifica o número de atores do Ray a serem iniciados. Cada ator do Ray deve ser atendido por um pod de trabalho no cluster do Kubernetes – portanto, este campo deve ser menor ou igual ao camporeplicas. Neste exemplo, definimosNUM_WORKERScomo 2, que corresponde ao camporeplicas. - O campo
CPUS_PER_WORKERdeve ser definido como menor ou igual ao número de CPUs alocadas para cada pod de trabalho menos 1. Neste exemplo, a solicitação de recurso da CPU por pod de trabalho é 3, portantoCPUS_PER_WORKERé definido como 2.
Para resumir, você precisa de um total de 8 vCPUs no pool de nós para executar o trabalho de treinamento do modelo PyTorch. Como adicionamos um taint no pool de nós do sistema para que nenhum pod de usuário possa ser agendado nele, devemos criar um novo pool de nós com pelo menos 8 vCPUs para hospedar o cluster do Ray.
Baixe o arquivo de especificação de trabalho do Ray usando o seguinte comando:
curl -LO https://raw.githubusercontent.com/ray-project/kuberay/master/ray-operator/config/samples/pytorch-mnist/ray-job.pytorch-mnist.yamlFaça as modificações necessárias no arquivo de especificação de trabalho do Ray.
Inicie o trabalho de treinamento do modelo do PyTorch usando o comando
kubectl apply.kubectl apply -n kuberay -f ray-job.pytorch-mnist.yaml
Verificar a implantação do RayJob
Verifique se você tem dois pods de trabalho e um pod principal em execução no namespace usando o comando
kubectl get pods.kubectl get pods -n kuberaySeu resultado deve ser semelhante ao seguinte exemplo de saída:
NAME READY STATUS RESTARTS AGE kuberay-operator-7d7998bcdb-9h8hx 1/1 Running 0 3d2h pytorch-mnist-raycluster-s7xd9-worker-small-group-knpgl 1/1 Running 0 6m15s pytorch-mnist-raycluster-s7xd9-worker-small-group-p74cm 1/1 Running 0 6m15s rayjob-pytorch-mnist-fc959 1/1 Running 0 5m35s rayjob-pytorch-mnist-raycluster-s7xd9-head-l24hn 1/1 Running 0 6m15sVerifique o status do RayJob usando o comando
kubectl get.kubectl get rayjob -n kuberaySeu resultado deve ser semelhante ao seguinte exemplo de saída:
NAME JOB STATUS DEPLOYMENT STATUS START TIME END TIME AGE rayjob-pytorch-mnist RUNNING Running 2024-11-22T03:08:22Z 9m36sAguarde até que o RayJob seja concluído. Isso pode levar alguns minutos. Quando o
JOB STATUSforSUCCEEDED, você poderá verificar os logs de treinamento. Você pode fazer isso primeiro obtendo o nome do pod executando o RayJob usando o comandokubectl get pods.kubectl get pods -n kuberayNa saída, você deve ver um pod com um nome que começa com
rayjob-pytorch-mnist, semelhante à seguinte saída de exemplo:NAME READY STATUS RESTARTS AGE kuberay-operator-7d7998bcdb-9h8hx 1/1 Running 0 3d2h pytorch-mnist-raycluster-s7xd9-worker-small-group-knpgl 1/1 Running 0 14m pytorch-mnist-raycluster-s7xd9-worker-small-group-p74cm 1/1 Running 0 14m rayjob-pytorch-mnist-fc959 0/1 Completed 0 13m rayjob-pytorch-mnist-raycluster-s7xd9-head-l24hn 1/1 Running 0 14mExiba os logs do RayJob usando o comando
kubectl logs. Certifique-se de substituirrayjob-pytorch-mnist-fc959pelo nome do pod que executa o RayJob.kubectl logs -n kuberay rayjob-pytorch-mnist-fc959Na saída, você deverá ver os logs de treinamento para o modelo do PyTorch, semelhantes à seguinte saída de exemplo:
2024-11-21 19:09:04,986 INFO cli.py:39 -- Job submission server address: http://rayjob-pytorch-mnist-raycluster-s7xd9-head-svc.kuberay.svc.cluster.local:8265 2024-11-21 19:09:05,712 SUCC cli.py:63 -- ------------------------------------------------------- 2024-11-21 19:09:05,713 SUCC cli.py:64 -- Job 'rayjob-pytorch-mnist-hndpx' submitted successfully 2024-11-21 19:09:05,713 SUCC cli.py:65 -- ------------------------------------------------------- 2024-11-21 19:09:05,713 INFO cli.py:289 -- Next steps 2024-11-21 19:09:05,713 INFO cli.py:290 -- Query the logs of the job: 2024-11-21 19:09:05,713 INFO cli.py:292 -- ray job logs rayjob-pytorch-mnist-hndpx 2024-11-21 19:09:05,713 INFO cli.py:294 -- Query the status of the job: ... View detailed results here: /home/ray/ray_results/TorchTrainer_2024-11-21_19-11-23 To visualize your results with TensorBoard, run: `tensorboard --logdir /tmp/ray/session_2024-11-21_19-08-24_556164_1/artifacts/2024-11-21_19-11-24/TorchTrainer_2024-11-21_19-11-23/driver_artifacts` Training started with configuration: ╭─────────────────────────────────────────────────╮ │ Training config │ ├─────────────────────────────────────────────────┤ │ train_loop_config/batch_size_per_worker 16 │ │ train_loop_config/epochs 10 │ │ train_loop_config/lr 0.001 │ ╰─────────────────────────────────────────────────╯ (RayTrainWorker pid=1193, ip=10.244.4.193) Setting up process group for: env:// [rank=0, world_size=2] (TorchTrainer pid=1138, ip=10.244.4.193) Started distributed worker processes: (TorchTrainer pid=1138, ip=10.244.4.193) - (node_id=3ea81f12c0f73ebfbd5b46664e29ced00266e69355c699970e1d824b, ip=10.244.4.193, pid=1193) world_rank=0, local_rank=0, node_rank=0 (TorchTrainer pid=1138, ip=10.244.4.193) - (node_id=2b00ea2b369c9d27de9596ce329daad1d24626b149975cf23cd10ea3, ip=10.244.1.42, pid=1341) world_rank=1, local_rank=0, node_rank=1 (RayTrainWorker pid=1341, ip=10.244.1.42) Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz (RayTrainWorker pid=1193, ip=10.244.4.193) Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz to /home/ray/data/FashionMNIST/raw/train-images-idx3-ubyte.gz (RayTrainWorker pid=1193, ip=10.244.4.193) 0%| | 0.00/26.4M [00:00<?, ?B/s] (RayTrainWorker pid=1193, ip=10.244.4.193) 0%| | 65.5k/26.4M [00:00<01:13, 356kB/s] (RayTrainWorker pid=1193, ip=10.244.4.193) 100%|██████████| 26.4M/26.4M [00:01<00:00, 18.9MB/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Extracting /home/ray/data/FashionMNIST/raw/train-images-idx3-ubyte.gz to /home/ray/data/FashionMNIST/raw (RayTrainWorker pid=1341, ip=10.244.1.42) 100%|██████████| 26.4M/26.4M [00:01<00:00, 18.7MB/s] ... Training finished iteration 1 at 2024-11-21 19:15:46. Total running time: 4min 22s ╭───────────────────────────────╮ │ Training result │ ├───────────────────────────────┤ │ checkpoint_dir_name │ │ time_this_iter_s 144.9 │ │ time_total_s 144.9 │ │ training_iteration 1 │ │ accuracy 0.805 │ │ loss 0.52336 │ ╰───────────────────────────────╯ (RayTrainWorker pid=1193, ip=10.244.4.193) Test Epoch 0: 97%|█████████▋| 303/313 [00:01<00:00, 269.60it/s] Test Epoch 0: 100%|██████████| 313/313 [00:01<00:00, 267.14it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Train Epoch 1: 0%| | 0/1875 [00:00<?, ?it/s] (RayTrainWorker pid=1341, ip=10.244.1.42) Test Epoch 0: 100%|██████████| 313/313 [00:01<00:00, 270.44it/s] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 0: 100%|█████████▉| 1866/1875 [00:24<00:00, 82.49it/s] [repeated 35x across cluster] (RayTrainWorker pid=1193, ip=10.244.4.193) Train Epoch 0: 100%|██████████| 1875/1875 [00:24<00:00, 77.99it/s] Train Epoch 0: 100%|██████████| 1875/1875 [00:24<00:00, 76.19it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Test Epoch 0: 0%| | 0/313 [00:00<?, ?it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Test Epoch 0: 88%|████████▊ | 275/313 [00:01<00:00, 265.39it/s] [repeated 19x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 1: 19%|█▉ | 354/1875 [00:04<00:18, 82.66it/s] [repeated 80x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 1: 0%| | 0/1875 [00:00<?, ?it/s] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 1: 40%|████ | 757/1875 [00:09<00:13, 83.01it/s] [repeated 90x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 1: 62%|██████▏ | 1164/1875 [00:14<00:08, 83.39it/s] [repeated 92x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 1: 82%|████████▏ | 1533/1875 [00:19<00:05, 68.09it/s] [repeated 91x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 1: 91%|█████████▏| 1713/1875 [00:22<00:02, 70.20it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Train Epoch 1: 91%|█████████ | 1707/1875 [00:22<00:02, 70.04it/s] [repeated 47x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Test Epoch 1: 0%| | 0/313 [00:00<?, ?it/s] (RayTrainWorker pid=1341, ip=10.244.1.42) Test Epoch 1: 8%|▊ | 24/313 [00:00<00:01, 237.98it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Test Epoch 1: 96%|█████████▋| 302/313 [00:01<00:00, 250.76it/s] Test Epoch 1: 100%|██████████| 313/313 [00:01<00:00, 262.94it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Train Epoch 2: 0%| | 0/1875 [00:00<?, ?it/s] (RayTrainWorker pid=1341, ip=10.244.1.42) Test Epoch 1: 92%|█████████▏| 289/313 [00:01<00:00, 222.57it/s] Training finished iteration 2 at 2024-11-21 19:16:12. Total running time: 4min 48s ╭───────────────────────────────╮ │ Training result │ ├───────────────────────────────┤ │ checkpoint_dir_name │ │ time_this_iter_s 25.975 │ │ time_total_s 170.875 │ │ training_iteration 2 │ │ accuracy 0.828 │ │ loss 0.45946 │ ╰───────────────────────────────╯ (RayTrainWorker pid=1341, ip=10.244.1.42) Test Epoch 1: 100%|██████████| 313/313 [00:01<00:00, 226.04it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Train Epoch 1: 100%|██████████| 1875/1875 [00:24<00:00, 76.24it/s] [repeated 45x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 2: 13%|█▎ | 239/1875 [00:03<00:24, 67.30it/s] [repeated 64x across cluster] (RayTrainWorker pid=1193, ip=10.244.4.193) Test Epoch 1: 0%| | 0/313 [00:00<?, ?it/s] (RayTrainWorker pid=1341, ip=10.244.1.42) Test Epoch 1: 85%|████████▍ | 266/313 [00:01<00:00, 222.54it/s] [repeated 20x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) .. Training completed after 10 iterations at 2024-11-21 19:19:47. Total running time: 8min 23s 2024-11-21 19:19:47,596 INFO tune.py:1009 -- Wrote the latest version of all result files and experiment state to '/home/ray/ray_results/TorchTrainer_2024-11-21_19-11-23' in 0.0029s. Training result: Result( metrics={'loss': 0.35892221605786073, 'accuracy': 0.872}, path='/home/ray/ray_results/TorchTrainer_2024-11-21_19-11-23/TorchTrainer_74867_00000_0_2024-11-21_19-11-24', filesystem='local', checkpoint=None ) (RayTrainWorker pid=1341, ip=10.244.1.42) Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz [repeated 7x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz to /home/ray/data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz [repeated 7x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Extracting /home/ray/data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to /home/ray/data/FashionMNIST/raw [repeated 7x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 9: 91%|█████████ | 1708/1875 [00:21<00:01, 83.84it/s] [repeated 23x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Train Epoch 9: 100%|██████████| 1875/1875 [00:23<00:00, 78.52it/s] [repeated 37x across cluster] (RayTrainWorker pid=1341, ip=10.244.1.42) Test Epoch 9: 0%| | 0/313 [00:00<?, ?it/s] (RayTrainWorker pid=1193, ip=10.244.4.193) Test Epoch 9: 89%|████████▉ | 278/313 [00:01<00:00, 266.46it/s] [repeated 19x across cluster] (RayTrainWorker pid=1193, ip=10.244.4.193) Test Epoch 9: 97%|█████████▋| 305/313 [00:01<00:00, 256.69it/s] Test Epoch 9: 100%|██████████| 313/313 [00:01<00:00, 267.35it/s] 2024-11-21 19:19:51,728 SUCC cli.py:63 -- ------------------------------------------ 2024-11-21 19:19:51,728 SUCC cli.py:64 -- Job 'rayjob-pytorch-mnist-hndpx' succeeded 2024-11-21 19:19:51,728 SUCC cli.py:65 -- ------------------------------------------
Exibir os resultados do treinamento no Painel do Ray
Quando o RayJob for concluído com sucesso, você poderá exibir os resultados do treinamento no Painel do Ray. O Painel do Ray fornece monitoramento e visualizações em tempo real de clusters do Ray. Você pode usar o Painel do Ray para monitorar o status de clusters do Ray, exibir logs e visualizar os resultados de trabalhos de machine learning.
Para acessar o Painel do Ray, você precisa expor o serviço de cabeçalho do Ray para a Internet pública criando um shim de serviço para expor o serviço de cabeçalho do Ray na porta 80 em vez da porta 8265.
Observação
O deploy.sh descrito na seção anterior expõe automaticamente o serviço de cabeçalho do Ray para a Internet pública. As etapas a seguir são incluídas no script deploy.sh.
Obtenha o nome do serviço de cabeçalho do Ray e salve-o em uma variável de shell usando o seguinte comando:
rayclusterhead=$(kubectl get service -n $kuberay_namespace | grep 'rayjob-pytorch-mnist-raycluster' | grep 'ClusterIP' | awk '{print $1}')Crie o shim de serviço para expor o serviço de cabeçalho do Ray na porta 80 usando o comando
kubectl expose service.kubectl expose service $rayclusterhead \ -n $kuberay_namespace \ --port=80 \ --target-port=8265 \ --type=NodePort \ --name=ray-dashCrie a entrada para expor o shim de serviço usando o controlador de entrada usando o seguinte comando:
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ray-dash namespace: kuberay annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: webapprouting.kubernetes.azure.com rules: - http: paths: - backend: service: name: ray-dash port: number: 80 path: / pathType: Prefix EOFObtenha o endereço IP público do controlador de entrada usando o comando
kubectl get service.kubectl get service -n app-routing-systemNa saída, você deverá ver o endereço IP público do balanceador de carga anexado ao controlador de entrada. Copie o endereço IP público e cole-o em um navegador da Web. Você deverá ver o Painel do Ray.
Limpar os recursos
Para limpar os recursos criados neste guia, você pode excluir o grupo de recursos do Azure que contém o cluster do AKS.
Próximas etapas
Para saber mais sobre cargas de trabalho de IA e machine learning no AKS, confira os seguintes artigos:
- Implantar um aplicativo que usa o OpenAI no Serviço de Kubernetes do Azure (AKS)
- Criar e implantar pipelines de dados e machine learning com o Flyte no Serviço de Kubernetes do Azure (AKS)
- Implantar um modelo de IA no Serviço de Kubernetes do Azure (AKS) com o operador da cadeia de ferramentas de IA
Colaboradores
A Microsoft atualiza este artigo. Os seguintes colaboradores o escreveram originalmente:
- Russell de Pina | Diretor de TPM
- Ken Kilty | Diretor de TPM
- Erin Schaffer | Desenvolvedora de Conteúdo 2
- Adrian Joian | Engenheiro de Clientes Chefe
- Ryan Graham | Especialista Técnico Chefe