Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit artikel configureert en implementeert u een Ray-cluster in Azure Kubernetes Service (AKS) met behulp van KubeRay. U leert ook hoe u het Ray-cluster gebruikt om een eenvoudig machine learning-model te trainen en de resultaten weer te geven op het Ray-dashboard.
Dit artikel bevat twee methoden voor het implementeren van het Ray-cluster op AKS:
-
Niet-interactieve implementatie: gebruik het
deploy.shscript in de GitHub-opslagplaats om het volledige Ray-voorbeeld niet-interactief te implementeren. - Handmatige implementatie: volg de handmatige implementatiestappen om het Ray-voorbeeld te implementeren in AKS.
Vereisten
- Bekijk het Ray-cluster op AKS-overzicht om inzicht te hebben in de onderdelen en het implementatieproces.
- Een Azure-abonnement. Als u geen Azure-abonnement hebt, kunt u hier een gratis account maken.
- De Azure CLI is geïnstalleerd op uw lokale computer. U kunt deze installeren met behulp van de instructies in De Azure CLI installeren.
- De Azure Kubernetes Service Preview-extensie is geïnstalleerd.
- Helm is geïnstalleerd.
- Terraform-clienthulpprogramma's of OpenTofu geïnstalleerd. In dit artikel wordt Terraform gebruikt, maar de gebruikte modules moeten compatibel zijn met OpenTofu.
Het Ray-voorbeeld niet-interactief implementeren
Als u het volledige Ray-voorbeeld niet-interactief wilt implementeren, kunt u het deploy.sh script gebruiken in de GitHub-opslagplaats (https://github.com/Azure-Samples/aks-ray-sample). Met dit script worden de stappen voltooid die worden beschreven in de sectie Ray-implementatieproces.
Kloon de GitHub-opslagplaats lokaal en ga naar de hoofdmap van de opslagplaats met behulp van de volgende commando's:
git clone https://github.com/Azure-Samples/aks-ray-sample cd aks-ray-sampleImplementeer het volledige voorbeeld met behulp van de volgende opdrachten:
chmod +x deploy.sh ./deploy.shZodra de implementatie is voltooid, controleert u de uitvoer van de logboeken en de resourcegroep in Azure Portal om de infrastructuur te zien die is gemaakt.
Het Ray-voorbeeld handmatig implementeren
Fashion MNIST is een gegevensset van zalando's artikelafbeeldingen die bestaan uit een trainingsset van 60.000 voorbeelden en een testset van 10.000 voorbeelden. Elk voorbeeld is een 28x28 grijswaarde-afbeelding die gekoppeld is aan een label uit tien klassen. In deze handleiding traint u een eenvoudig PyTorch-model op deze gegevensset met behulp van het Ray-cluster.
De RayJob-specificatie implementeren
Als je het model wilt trainen, moet je een Ray Job-specificatie verzenden naar de KubeRay-operator die draait op een privé-AKS-cluster. De Ray-taakspecificatie is een YAML-bestand dat de resources beschrijft die nodig zijn om de taak uit te voeren, waaronder de Docker-afbeelding, de opdracht om uit te voeren en het aantal workers dat moet worden gebruikt.
Als u de beschrijving van de Ray-taak bekijkt, moet u mogelijk enkele velden wijzigen zodat deze overeenkomen met uw omgeving:
- Het
replicasveld onder deworkerGroupSpecssectie inrayClusterSpecspecificeert het aantal worker-pods dat KubeRay naar het Kubernetes-cluster plant. Elke werkpod vereist 3 CPU's en 4 GB aan geheugen. De hoofdpod vereist 1 CPU en 4 GB geheugen. Voor het instellen van hetreplicasveld op 2 zijn 8 vCPU's in de knooppuntgroep vereist die worden gebruikt om de RayCluster voor de taak te implementeren. - Het veld
NUM_WORKERSonderruntimeEnvYAMLinspecspecificeert het aantal Ray-acteurs dat moet worden gestart. Elke Ray-actor moet worden onderhouden door een worker pod in het Kubernetes-cluster, dus dit veld moet kleiner dan of gelijk aan hetreplicasveld zijn. In dit voorbeeld stellen weNUM_WORKERSin op 2, wat overeenkomt met hetreplicasveld. - Het
CPUS_PER_WORKERveld moet worden ingesteld op een waarde die minder dan of gelijk is aan het aantal processoren dat aan elke werknemerpod is toegewezen, verminderd met 1. In dit voorbeeld is de CPU-resourceaanvraag per werkpod 3, dusCPUS_PER_WORKERingesteld op 2.
Samenvattend hebt u in totaal 8 vCPU's in de knooppuntgroep nodig om de pyTorch-modeltrainingstaak uit te voeren. Omdat we een taint hebben toegevoegd aan de systeemknooppuntgroep, zodat er geen gebruikerspods op kunnen worden gepland, moeten we een nieuwe knooppuntgroep maken met ten minste 8 vCPU's om het Ray-cluster te hosten.
Download het specificatiebestand van Ray Job met behulp van de volgende opdracht:
curl -LO https://raw.githubusercontent.com/ray-project/kuberay/master/ray-operator/config/samples/pytorch-mnist/ray-job.pytorch-mnist.yamlBreng de benodigde wijzigingen aan in het specificatiebestand van Ray Job.
Start de trainingstaak van het PyTorch-model met behulp van de
kubectl applyopdracht.kubectl apply -n kuberay -f ray-job.pytorch-mnist.yaml
De implementatie van RayJob controleren
Controleer of u twee worker pods en één head pod hebt die in de naamruimte draaien met behulp van de
kubectl get podsopdracht.kubectl get pods -n kuberayDe uitvoer moet er ongeveer uitzien als in de volgende voorbeelduitvoer:
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 6m15sControleer de status van de RayJob met behulp van de
kubectl getopdracht.kubectl get rayjob -n kuberayDe uitvoer moet er ongeveer uitzien als in de volgende voorbeelduitvoer:
NAME JOB STATUS DEPLOYMENT STATUS START TIME END TIME AGE rayjob-pytorch-mnist RUNNING Running 2024-11-22T03:08:22Z 9m36sWacht totdat de RayJob is voltooid. Dit kan enkele minuten duren. Zodra de
JOB STATUSSUCCEEDEDis, kunt u de logboeken controleren. U kunt dit doen door eerst de naam op te halen van de pod waarop de RayJob wordt uitgevoerd met behulp van dekubectl get podsopdracht.kubectl get pods -n kuberayIn de uitvoer ziet u een pod met een naam die begint met
rayjob-pytorch-mnist, vergelijkbaar met de volgende voorbeelduitvoer: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 14mBekijk de logboeken van de RayJob met behulp van de
kubectl logsopdracht. Zorg ervoor dat urayjob-pytorch-mnist-fc959vervangt door de naam van de pod waarop uw RayJob wordt uitgevoerd.kubectl logs -n kuberay rayjob-pytorch-mnist-fc959In de uitvoer ziet u de trainingslogboeken voor het PyTorch-model, vergelijkbaar met de volgende voorbeelduitvoer:
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 -- ------------------------------------------
Trainingsresultaten weergeven op het Ray-dashboard
Wanneer de RayJob is voltooid, kunt u de trainingsresultaten bekijken op het Ray-dashboard. Het Ray Dashboard biedt realtime bewaking en visualisaties van Ray-clusters. U kunt het Ray-dashboard gebruiken om de status van Ray-clusters te bewaken, logboeken weer te geven en de resultaten van machine learning-taken te visualiseren.
Voor toegang tot het Ray-dashboard moet u de Ray-hoofdservice beschikbaar maken op het openbare internet door een service-shim te maken om de Ray-hoofdservice beschikbaar te maken op poort 80 in plaats van poort 8265.
Notitie
De deploy.sh sectie die in de vorige sectie wordt beschreven, maakt de Ray-hoofdservice automatisch beschikbaar op het openbare internet. De volgende stappen zijn opgenomen in het deploy.sh script.
Haal de naam van de Ray-hoofdservice op en sla deze op in een shellvariabele met behulp van de volgende opdracht:
rayclusterhead=$(kubectl get service -n $kuberay_namespace | grep 'rayjob-pytorch-mnist-raycluster' | grep 'ClusterIP' | awk '{print $1}')Maak de service-shim om de Ray-hoofdservice beschikbaar te maken op poort 80 met behulp van de
kubectl expose serviceopdracht.kubectl expose service $rayclusterhead \ -n $kuberay_namespace \ --port=80 \ --target-port=8265 \ --type=NodePort \ --name=ray-dashMaak de ingress om de service shim beschikbaar te maken met de ingress-controller met behulp van de volgende opdracht:
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 EOFHaal het openbare IP-adres van de ingangscontroller op met behulp van de
kubectl get serviceopdracht.kubectl get service -n app-routing-systemIn de uitvoer ziet u het openbare IP-adres van de load balancer die is gekoppeld aan de ingangscontroller. Kopieer het openbare IP-adres en plak het in een webbrowser. U zou het Ray-dashboard moeten zien.
Resources opschonen
Als u de resources wilt opschonen die in deze handleiding zijn gemaakt, kunt u de Azure-resourcegroep verwijderen die het AKS-cluster bevat.
Volgende stappen
Zie de volgende artikelen voor meer informatie over AI- en machine learning-workloads in AKS:
- Een toepassing implementeren die gebruikmaakt van OpenAI in Azure Kubernetes Service (AKS)
- Gegevens- en machine learning-pijplijnen bouwen en implementeren met Flyte in Azure Kubernetes Service (AKS)
- Een AI-model implementeren in Azure Kubernetes Service (AKS) met de AI-toolchainoperator
Bijdragers
Microsoft onderhoudt dit artikel. De volgende inzenders hebben het oorspronkelijk geschreven:
- Russell de Tina | Principal TPM
- Ken Kilty | Hoofd TPM
- Erin Schaffer | Inhoudsontwikkelaar 2
- Adrian Joian | Hoofdklantingenieur
- Ryan Graham | Belangrijkste technische specialist