Dela via


Konfigurera och distribuera ett Ray-kluster i Azure Kubernetes Service (AKS)

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.sh på 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

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.

  1. 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-sample
    
  2. Distribuera det fullständiga exemplet med hjälp av följande kommandon:

    chmod +x deploy.sh
    ./deploy.sh
    
  3. Nä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 replicas under avsnittet workerGroupSpecs i rayClusterSpec anger 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ältet replicas till 2 krävs 8 vCPU:er i nodpoolen som används för att implementera RayCluster för jobbet.
  • Fältet NUM_WORKERS under runtimeEnvYAML i spec anger 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ältet replicas. I det här exemplet anger NUM_WORKERS vi till 2, vilket matchar fältet replicas .
  • Fältet CPUS_PER_WORKER må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_WORKER den 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.

  1. 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.yaml
    
  2. Gör nödvändiga ändringar i Ray Job-specifikationsfilen.

  3. Starta träningsjobbet för PyTorch-modellen med kommandot kubectl apply .

    kubectl apply -n kuberay -f ray-job.pytorch-mnist.yaml
    

Verifiera RayJob-distributionen

  1. Kontrollera att du har två arbetspoddar och en huvudpodd som körs i namnområdet med kommandot kubectl get pods .

    kubectl get pods -n kuberay
    

    Dina 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          6m15s
    
  2. Kontrollera statusen för RayJob med hjälp av kubectl get kommandot .

    kubectl get rayjob -n kuberay
    

    Dina 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              9m36s
    
  3. Vänta tills RayJob är färdig. Det kan ta några minuter. När JOB STATUS är SUCCEEDED kan du kontrollera träningsloggarna. Du kan göra detta genom att först hämta namnet på podden som kör RayJob med kommandot kubectl get pods .

    kubectl get pods -n kuberay
    

    I 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          14m
    
  4. Visa loggarna för RayJob med kommandot kubectl logs . Ersätt rayjob-pytorch-mnist-fc959 med namnet på podden som kör ditt RayJob.

    kubectl logs -n kuberay rayjob-pytorch-mnist-fc959
    

    I 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 .

  1. 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}')
    
  2. 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-dash
    
  3. Skapa 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
    EOF
    
  4. Hämta den offentliga IP-adressen för ingresskontrollanten kubectl get service med hjälp av kommandot .

    kubectl get service -n app-routing-system
    
  5. I 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:

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