Not
Åtkomst till denna sida kräver auktorisation. Du kan prova att logga in eller byta katalog.
Åtkomst till denna sida kräver auktorisation. Du kan prova att byta katalog.
I den här artikeln konfigurerar och distribuerar du ett Ray-kluster på Azure Kubernetes Service (AKS) med KubeRay. Du lär dig också hur du använder Ray-klustret för att träna en enkel maskininlärningsmodell och visa resultaten på Ray-instrumentpanelen.
Den här artikeln innehåller två metoder för att distribuera Ray-klustret på AKS:
-
Icke-interaktiv distribution: Använd skriptet
deploy.shpå GitHub-lagringsplatsen för att distribuera hela Ray-exemplet icke-interaktivt. - Manuell distribution: Följ de manuella distributionsstegen för att distribuera Ray-exemplet till AKS.
Förutsättningar
- Granska översikten över Ray-klustret på AKS för att förstå komponenterna och distributionsprocessen.
- En Azure-prenumeration Om du inte har någon Azure-prenumeration skapar du ett kostnadsfritt utvärderingskonto här.
- Azure CLI installerat på din lokala dator. Du kan installera den med hjälp av anvisningarna i Installera Azure CLI.
- Azure Kubernetes Service Preview-tillägget har installerats.
- Helm installerat.
- Terraform-klientverktyg eller OpenTofu installerat. Den här artikeln använder Terraform, men de moduler som används bör vara kompatibla med OpenTofu.
Distribuera Ray-exemplet icke-interaktivt
Om du vill distribuera det fullständiga Ray-exemplet icke-interaktivt kan du använda skriptet deploy.sh på GitHub-lagringsplatsen (https://github.com/Azure-Samples/aks-ray-sample). Det här skriptet slutför de steg som beskrivs i avsnittet Ray-distributionsprocessen.
Klona GitHub-lagringsplatsen lokalt och ändra till lagringsplatsens rot med hjälp av följande kommandon:
git clone https://github.com/Azure-Samples/aks-ray-sample cd aks-ray-sampleDistribuera det fullständiga exemplet med hjälp av följande kommandon:
chmod +x deploy.sh ./deploy.shNär distributionen är klar granskar du utdata från loggarna och resursgruppen i Azure Portal för att se infrastrukturen som skapades.
Distribuera Ray-exemplet manuellt
Fashion MNIST är en datamängd av Zalandos artikelbilder som består av en träningsuppsättning med 60 000 exempel och en testuppsättning med 10 000 exempel. Varje exempel är en 28x28-gråskalebild som är associerad med en etikett från tio klasser. I den här guiden tränar du en enkel PyTorch-modell på den här datauppsättningen med hjälp av Ray-klustret.
Distribuera RayJob-specifikationen
För att träna modellen måste du skicka en Ray Job-specifikation till KubeRay-operatorn som körs i ett privat AKS-kluster. Ray Job-specifikationen är en YAML-fil som beskriver de resurser som krävs för att köra jobbet, inklusive Docker-avbildningen, kommandot som ska köras och antalet arbetare som ska användas.
Om du tittar på beskrivningen av Ray-jobbet kan du behöva ändra vissa fält så att de matchar din miljö:
- Fältet
replicasunder avsnittetworkerGroupSpecsirayClusterSpecanger antalet arbetspoddar som KubeRay schemalägger för Kubernetes-klustret. Varje arbetspodd kräver 3 processorer och 4 GB minne. Huvudpodden kräver 1 PROCESSOR och 4 GB minne. Om du anger fältetreplicastill 2 krävs 8 vCPU:er i nodpoolen som används för att implementera RayCluster för jobbet. - Fältet
NUM_WORKERSunderruntimeEnvYAMLispecanger antalet Ray-aktörer som ska startas. Varje Ray-aktör måste betjänas av en worker pod i Kubernetes-klustret, så det här fältet måste vara mindre än eller lika med fältetreplicas. I det här exemplet angerNUM_WORKERSvi till 2, vilket matchar fältetreplicas. - Fältet
CPUS_PER_WORKERmåste anges till mindre än eller lika med antalet CPU:er som har allokerats till varje arbetspod minus 1. I det här exemplet är cpu-resursbegäran per arbetspodd 3, såCPUS_PER_WORKERden ställs in på 2.
För att sammanfatta behöver du totalt 8 vCPU:er i nodpoolen för att köra träningsjobbet för PyTorch-modellen. Eftersom vi har lagt till en taint i systemnodpoolen för att inga användarpoddar ska kunna schemaläggas där, måste vi skapa en ny nodpool med minst 8 vCPU:er för att hysa Ray-klustret.
Ladda ned Ray Job-specifikationsfilen med följande kommando:
curl -LO https://raw.githubusercontent.com/ray-project/kuberay/master/ray-operator/config/samples/pytorch-mnist/ray-job.pytorch-mnist.yamlGör nödvändiga ändringar i Ray Job-specifikationsfilen.
Starta träningsjobbet för PyTorch-modellen med kommandot
kubectl apply.kubectl apply -n kuberay -f ray-job.pytorch-mnist.yaml
Verifiera RayJob-distributionen
Kontrollera att du har två arbetspoddar och en huvudpodd som körs i namnområdet med kommandot
kubectl get pods.kubectl get pods -n kuberayDina utdata bör se ut ungefär som följande exempelutdata:
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 6m15sKontrollera statusen för RayJob med hjälp av
kubectl getkommandot .kubectl get rayjob -n kuberayDina utdata bör se ut ungefär som följande exempelutdata:
NAME JOB STATUS DEPLOYMENT STATUS START TIME END TIME AGE rayjob-pytorch-mnist RUNNING Running 2024-11-22T03:08:22Z 9m36sVänta tills RayJob är färdig. Det kan ta några minuter. När
JOB STATUSärSUCCEEDEDkan du kontrollera träningsloggarna. Du kan göra detta genom att först hämta namnet på podden som kör RayJob med kommandotkubectl get pods.kubectl get pods -n kuberayI utdata bör du se en podd med ett namn som börjar med
rayjob-pytorch-mnist, ungefär som i följande exempelutdata: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 14mVisa loggarna för RayJob med kommandot
kubectl logs. Ersättrayjob-pytorch-mnist-fc959med namnet på podden som kör ditt RayJob.kubectl logs -n kuberay rayjob-pytorch-mnist-fc959I utdata bör du se träningsloggarna för PyTorch-modellen, ungefär som i följande exempelutdata:
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 -- ------------------------------------------
Visa träningsresultat på Ray-instrumentpanelen
När RayJob har slutförts kan du visa träningsresultaten på Ray-instrumentpanelen. Ray-instrumentpanelen tillhandahåller övervakning i realtid och visualiseringar av Ray-kluster. Du kan använda Ray-instrumentpanelen för att övervaka status för Ray-kluster, visa loggar och visualisera resultatet av maskininlärningsjobb.
För att få åtkomst till Ray-instrumentpanelen måste du exponera Ray-huvudtjänsten för det offentliga Internet genom att skapa en tjänstshim för att exponera Ray-huvudtjänsten på port 80 i stället för port 8265.
Kommentar
Det deploy.sh som beskrivs i föregående avsnitt exponerar automatiskt Ray-huvudtjänsten för det offentliga Internet. Följande steg ingår i skriptet deploy.sh .
Hämta namnet på Ray-huvudtjänsten och spara den i en gränssnittsvariabel med hjälp av följande kommando:
rayclusterhead=$(kubectl get service -n $kuberay_namespace | grep 'rayjob-pytorch-mnist-raycluster' | grep 'ClusterIP' | awk '{print $1}')Skapa service-shim för att exponera huvudtjänsten Ray på port 80 med kommandot
kubectl expose service.kubectl expose service $rayclusterhead \ -n $kuberay_namespace \ --port=80 \ --target-port=8265 \ --type=NodePort \ --name=ray-dashSkapa ingressen för att exponera tjänstens shim med hjälp av ingresskontrollanten med hjälp av följande kommando:
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 EOFHämta den offentliga IP-adressen för ingresskontrollanten
kubectl get servicemed hjälp av kommandot .kubectl get service -n app-routing-systemI utdata bör du se den offentliga IP-adressen för lastbalanseraren som är kopplad till ingresskontrollanten. Kopiera den offentliga IP-adressen och klistra in den i en webbläsare. Du bör se Ray-instrumentpanelen.
Rensa resurser
Om du vill rensa resurserna som skapas i den här guiden kan du ta bort azure-resursgruppen som innehåller AKS-klustret.
Nästa steg
Mer information om AI- och maskininlärningsarbetsbelastningar i AKS finns i följande artiklar:
- Distribuera ett program som använder OpenAI på Azure Kubernetes Service (AKS)
- Skapa och distribuera data- och maskininlärningspipelines med Flyte i Azure Kubernetes Service (AKS)
- Distribuera en AI-modell på Azure Kubernetes Service (AKS) med AI-verktygskedjans operatör
Deltagare
Microsoft underhåller den här artikeln. Följande deltagare skrev den ursprungligen:
- Russell de Pina | Ledande TPM
- Ken Kilty | Huvudansvarig för TPM
- Erin Schaffer | Innehållsutvecklare 2
- Adrian Joian | Huvudkundtekniker
- Ryan Graham | Teknisk huvudspecialist