Delen via


Een Ray-cluster configureren en implementeren in Azure Kubernetes Service (AKS)

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:

Vereisten

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.

  1. 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-sample
    
  2. Implementeer het volledige voorbeeld met behulp van de volgende opdrachten:

    chmod +x deploy.sh
    ./deploy.sh
    
  3. Zodra 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 replicas veld onder de workerGroupSpecs sectie in rayClusterSpec specificeert 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 het replicas veld op 2 zijn 8 vCPU's in de knooppuntgroep vereist die worden gebruikt om de RayCluster voor de taak te implementeren.
  • Het veld NUM_WORKERS onder runtimeEnvYAML in spec specificeert 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 het replicas veld zijn. In dit voorbeeld stellen we NUM_WORKERS in op 2, wat overeenkomt met het replicas veld.
  • Het CPUS_PER_WORKER veld 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, dus CPUS_PER_WORKER ingesteld 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.

  1. 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.yaml
    
  2. Breng de benodigde wijzigingen aan in het specificatiebestand van Ray Job.

  3. Start de trainingstaak van het PyTorch-model met behulp van de kubectl apply opdracht.

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

De implementatie van RayJob controleren

  1. Controleer of u twee worker pods en één head pod hebt die in de naamruimte draaien met behulp van de kubectl get pods opdracht.

    kubectl get pods -n kuberay
    

    De 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          6m15s
    
  2. Controleer de status van de RayJob met behulp van de kubectl get opdracht.

    kubectl get rayjob -n kuberay
    

    De 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              9m36s
    
  3. Wacht totdat de RayJob is voltooid. Dit kan enkele minuten duren. Zodra de JOB STATUSSUCCEEDED is, 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 de kubectl get pods opdracht.

    kubectl get pods -n kuberay
    

    In 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          14m
    
  4. Bekijk de logboeken van de RayJob met behulp van de kubectl logs opdracht. Zorg ervoor dat u rayjob-pytorch-mnist-fc959 vervangt door de naam van de pod waarop uw RayJob wordt uitgevoerd.

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

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

  1. 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}')
    
  2. Maak de service-shim om de Ray-hoofdservice beschikbaar te maken op poort 80 met behulp van de kubectl expose service opdracht.

    kubectl expose service $rayclusterhead \
    -n $kuberay_namespace \
    --port=80 \
    --target-port=8265 \
    --type=NodePort \
    --name=ray-dash
    
  3. Maak 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
    EOF
    
  4. Haal het openbare IP-adres van de ingangscontroller op met behulp van de kubectl get service opdracht.

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

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