Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Neste artigo, você configura e implanta um cluster Ray no Serviço Kubernetes do Azure (AKS) usando o KubeRay. Você também aprende a usar o cluster Ray para treinar um modelo simples de aprendizado de máquina e exibir os resultados no Ray Dashboard.
Este artigo fornece dois métodos para implantar o cluster Ray no AKS:
-
Implantação não interativa: Use o
deploy.shscript no repositório GitHub para implantar o exemplo completo do Ray de forma não interativa. - Implantação manual: siga as etapas de implantação manual para implantar a amostra Ray no AKS.
Pré-requisitos
- Analise a visão geral do cluster Ray no AKS para entender os componentes e o processo de implantação.
- Uma subscrição do Azure. Se não tiver uma subscrição do Azure, pode criar uma conta gratuita aqui.
- A CLI do Azure instalada em sua máquina local. Você pode instalá-lo usando as instruções em Como instalar a CLI do Azure.
- A extensão Azure Kubernetes Service Preview foi instalada.
- Helm instalado.
- Ferramentas cliente Terraform ou OpenTofu instaladas. Este artigo usa Terraform, mas os módulos usados devem ser compatíveis com OpenTofu.
Implantar a amostra Ray de forma não interativa
Se quiser implantar o exemplo completo do Ray de forma não interativa, você pode usar o deploy.sh script no repositório GitHub (https://github.com/Azure-Samples/aks-ray-sample). Esse script conclui as etapas descritas na seção Processo de implantação do Ray.
Clone o repositório GitHub localmente e mude 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.shQuando a implantação for concluída, examine a saída dos logs e o grupo de recursos no portal do Azure para ver a infraestrutura que foi criada.
Implantar manualmente o exemplo de Ray
Fashion MNIST é um conjunto de dados de imagens de artigos de Zalando que consiste em um conjunto de treinamento de 60.000 exemplos e um conjunto de teste de 10.000 exemplos. Cada exemplo é uma imagem em tons de cinza 28x28 associada a um rótulo de dez classes. Neste guia, você treina um modelo PyTorch simples neste conjunto de dados usando o cluster Ray.
Implantar a especificação RayJob
Para treinar o modelo, é necessário submeter uma especificação Ray Job ao operador KubeRay em execução num cluster AKS privado. A especificação Ray Job é 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 trabalhadores a serem usados.
Observando a descrição do Ray Job, talvez seja necessário modificar alguns campos para corresponder ao seu ambiente:
- O
replicascampo sob aworkerGroupSpecsseção emrayClusterSpecespecifica o número de pods de trabalho que o KubeRay agenda 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 oreplicascampo como 2 requer 8 vCPUs no pool de nós usado para implementar o RayCluster para o trabalho. - O
NUM_WORKERScampo abaixoruntimeEnvYAMLespecificaspeco número de atores Ray a serem lançados. Cada ator Ray deve ser atendido por um pod de trabalho no cluster do Kubernetes, portanto, esse campo deve ser menor ou igual aoreplicascampo. Neste exemplo, definimosNUM_WORKERScomo 2, que corresponde aoreplicascampo. - O
CPUS_PER_WORKERcampo deve ser definido como menor ou igual ao número de CPUs alocadas a cada pod de trabalhador 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 adicionámos uma restrição no pool de nós do sistema para que nenhum pod de utilizador possa ser alocado nele, devemos criar um novo pool de nós com pelo menos 8 vCPUs para hospedar o cluster Ray.
Baixe o arquivo de especificação do Ray Job 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 do Ray Job.
Inicie o trabalho de treinamento do modelo PyTorch usando o
kubectl applycomando.kubectl apply -n kuberay -f ray-job.pytorch-mnist.yaml
Verificar a implantação do RayJob
Verifica se tens dois pods de trabalho e um pod de controlo em execução no namespace usando o comando
kubectl get pods.kubectl get pods -n kuberaySua saída deve ser semelhante à saída de exemplo a seguir:
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
kubectl getcomando.kubectl get rayjob -n kuberaySua saída deve ser semelhante à saída de exemplo a seguir:
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. Isto poderá demorar alguns minutos. Uma vez que o
JOB STATUSéSUCCEEDED, pode-se verificar os registos de treino. Você pode fazer isso primeiro obtendo o nome do pod que executa o RayJob usando okubectl get podscomando.kubectl get pods -n kuberayNa saída, você verá um pod com um nome que começa com
rayjob-pytorch-mnist, 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 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 14mVisualize os logs do RayJob usando o
kubectl logscomando. Certifique-se de substituirrayjob-pytorch-mnist-fc959pelo nome do pod que executa seu RayJob.kubectl logs -n kuberay rayjob-pytorch-mnist-fc959Na saída, deverá ver os registos de treino para o modelo PyTorch, semelhante ao exemplo de saída a seguir.
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 -- ------------------------------------------
Veja os resultados do treinamento no Ray Dashboard
Quando o RayJob for concluído com sucesso, você poderá visualizar os resultados do treinamento no Painel do Ray. O Ray Dashboard fornece monitoramento e visualizações em tempo real de clusters Ray. Você pode usar o Ray Dashboard para monitorar o status de clusters Ray, visualizar logs e visualizar os resultados de trabalhos de aprendizado de máquina.
Para acessar o Ray Dashboard, você precisa expor o serviço Ray head à internet pública criando um shim de serviço para expor o serviço Ray head na porta 80 em vez da porta 8265.
Nota
O deploy.sh descrito na seção anterior expõe automaticamente o serviço principal do Ray para a Internet pública. As etapas a seguir estão incluídas no deploy.sh script.
Obtenha o nome do serviço principal Ray e guarde-o numa 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 Ray head na porta 80 usando o
kubectl expose servicecomando.kubectl expose service $rayclusterhead \ -n $kuberay_namespace \ --port=80 \ --target-port=8265 \ --type=NodePort \ --name=ray-dashCrie o ingress para expor o service shim com o controlador de ingress 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
kubectl get servicecomando.kubectl get service -n app-routing-systemNa saída, você deve ver o endereço IP público do balanceador de carga conectado ao controlador de entrada. Copie o endereço IP público e cole-o em um navegador da Web. Você deve ver o Ray Dashboard.
Limpar recursos
Para limpar os recursos criados neste guia, você pode excluir o grupo de recursos do Azure que contém o cluster AKS.
Próximos passos
Para saber mais sobre cargas de trabalho de IA e aprendizado de máquina no AKS, consulte os seguintes artigos:
- Implantar um aplicativo que usa OpenAI no Serviço Kubernetes do Azure (AKS)
- Crie e implante pipelines de dados e aprendizado de máquina com o Flyte no Serviço Kubernetes do Azure (AKS)
- Implantar um modelo de IA no Serviço Kubernetes do Azure (AKS) com o operador da cadeia de ferramentas de IA
Contribuidores
A Microsoft mantém este artigo. Os seguintes colaboradores escreveram-no originalmente:
- Russell de Pina - Brasil | Principal TPM
- Ken Kilty - Brasil | Principal TPM
- Erin Schaffer | Desenvolvedora de Conteúdo 2
- Adrian Joian | Engenheiro Principal de Clientes
- Ryan Graham | Especialista Técnico Principal