Udostępnij przez


Konfigurowanie i wdrażanie klastra Ray w usłudze Azure Kubernetes Service (AKS)

W tym artykule skonfigurujesz i wdrożysz klaster Ray w usłudze Azure Kubernetes Service (AKS) przy użyciu usługi KubeRay. Dowiesz się również, jak używać klastra Ray do trenowania prostego modelu uczenia maszynowego i wyświetlania wyników na pulpicie nawigacyjnym Ray.

Ten artykuł zawiera dwie metody wdrażania klastra Ray w usłudze AKS:

  • Wdrożenie nieinterakcyjne: użyj skryptu deploy.sh w repozytorium GitHub, aby wdrożyć kompletny przykład Ray nieinterakcyjny.
  • Wdrażanie ręczne: wykonaj kroki ręcznego wdrażania, aby wdrożyć przykład Ray w usłudze AKS.

Prerequisites

Wdrażanie przykładu Ray nieinterakcyjnego

Jeśli chcesz wdrożyć kompletny przykład Ray nieinterakcyjny, możesz użyć skryptu deploy.sh w repozytorium GitHub (https://github.com/Azure-Samples/aks-ray-sample). Ten skrypt wykonuje kroki opisane w sekcji Proces wdrażania Ray.

  1. Sklonuj repozytorium GitHub lokalnie i przejdź do katalogu głównego repozytorium przy użyciu następujących poleceń:

    git clone https://github.com/Azure-Samples/aks-ray-sample
    cd aks-ray-sample
    
  2. Wdróż kompletny przykład przy użyciu następujących poleceń:

    chmod +x deploy.sh
    ./deploy.sh
    
  3. Po zakończeniu wdrażania przejrzyj dane wyjściowe dzienników i grupę zasobów w witrynie Azure Portal, aby wyświetlić utworzoną infrastrukturę.

Ręczne wdrażanie przykładu Ray

Fashion MNIST to zestaw danych obrazów artykułów Zalando składających się z zestawu szkoleniowego 60 000 przykładów i zestawu testowego składającego się z 10 000 przykładów. Każdy przykład to obraz o skali szarości 28x28 skojarzony z etykietą z dziesięciu klas. W tym przewodniku wytrenujesz prosty model PyTorch na tym zestawie danych przy użyciu klastra Ray.

Wdrażanie specyfikacji obiektu RayJob

Aby wytrenować model, należy przesłać specyfikację zadania Raya do operatora KubeRay uruchomionego w prywatnym klastrze usługi AKS. Specyfikacja zadania raya to plik YAML opisujący zasoby wymagane do uruchomienia zadania, w tym obraz platformy Docker, polecenie do uruchomienia i liczbę procesów roboczych do użycia.

Patrząc na opis zadania raya, może być konieczne zmodyfikowanie niektórych pól, aby pasować do środowiska:

  • Pole replicas w workerGroupSpecs sekcji w sekcji rayClusterSpec określa liczbę zasobników procesu roboczego, które platforma KubeRay planuje do klastra Kubernetes. Każdy zasobnik procesu roboczego wymaga 3 procesorów CPU i 4 GB pamięci. Zasobnik główny wymaga 1 procesora CPU i 4 GB pamięci. replicas Ustawienie pola na 2 wymaga 8 procesorów wirtualnych w puli węzłów używanej do implementowania rayCluster dla zadania.
  • Pole NUM_WORKERS w obszarze runtimeEnvYAMLspec określa liczbę aktorów Ray do uruchomienia. Każdy aktor Ray musi być serwisowany przez zasobnik procesu roboczego w klastrze Kubernetes, więc to pole musi być mniejsze lub równe replicas polu. W tym przykładzie ustawiliśmy NUM_WORKERS wartość 2, która jest zgodna z polem replicas .
  • CPUS_PER_WORKER Pole musi być ustawione na mniejsze lub równe liczbie procesorów CPU przydzielonych do każdego zasobnika roboczego minus 1. W tym przykładzie żądanie zasobu procesora CPU na zasobnik procesu roboczego wynosi 3, więc CPUS_PER_WORKER ustawiono wartość 2.

Podsumowując, potrzebujesz łącznie 8 procesorów wirtualnych w puli węzłów, aby uruchomić zadanie trenowania modelu PyTorch. Ponieważ dodaliśmy defekt w puli węzłów systemowych, aby nie można było zaplanować żadnych zasobników użytkownika, musimy utworzyć nową pulę węzłów z co najmniej 8 procesorami wirtualnymi do hostowania klastra Ray.

  1. Pobierz plik specyfikacji zadania Ray przy użyciu następującego polecenia:

    curl -LO https://raw.githubusercontent.com/ray-project/kuberay/master/ray-operator/config/samples/pytorch-mnist/ray-job.pytorch-mnist.yaml
    
  2. Wprowadź wszelkie niezbędne modyfikacje w pliku specyfikacji zadania Raya.

  3. Uruchom zadanie trenowania modelu PyTorch przy użyciu kubectl apply polecenia .

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

Weryfikowanie wdrożenia usługi RayJob

  1. Sprawdź, czy masz dwa zasobniki robocze i jeden zasobnik główny uruchomiony w przestrzeni nazw przy użyciu kubectl get pods polecenia .

    kubectl get pods -n kuberay
    

    Dane wyjściowe powinny wyglądać podobnie do następujących przykładowych danych wyjściowych:

    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. Sprawdź stan zadania RayJob przy użyciu kubectl get polecenia .

    kubectl get rayjob -n kuberay
    

    Dane wyjściowe powinny wyglądać podobnie do następujących przykładowych danych wyjściowych:

    NAME                   JOB STATUS   DEPLOYMENT STATUS   START TIME             END TIME   AGE
    rayjob-pytorch-mnist   RUNNING      Running             2024-11-22T03:08:22Z              9m36s
    
  3. Poczekaj na ukończenie zadania RayJob. Może to potrwać kilka minut. Gdy parametr ma wartość JOB STATUSSUCCEEDED, możesz sprawdzić dzienniki trenowania. Możesz to zrobić, najpierw uzyskując nazwę zasobnika z uruchomionym obiektem RayJob za pomocą kubectl get pods polecenia .

    kubectl get pods -n kuberay
    

    W danych wyjściowych powinien zostać wyświetlony zasobnik o nazwie rozpoczynającej się od rayjob-pytorch-mnist, podobnie jak w następujących przykładowych danych wyjściowych:

    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. Wyświetl dzienniki zadania RayJob przy użyciu kubectl logs polecenia . Pamiętaj, aby zastąpić rayjob-pytorch-mnist-fc959 ciąg nazwą zasobnika uruchamiającego obiekt RayJob.

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

    W danych wyjściowych powinny zostać wyświetlone dzienniki trenowania modelu PyTorch podobne do następujących przykładowych danych wyjściowych:

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

Wyświetlanie wyników trenowania na pulpicie nawigacyjnym Ray

Po pomyślnym zakończeniu zadania RayJob możesz wyświetlić wyniki trenowania na pulpicie nawigacyjnym raya. Pulpit nawigacyjny Ray zapewnia monitorowanie i wizualizacje klastrów Ray w czasie rzeczywistym. Pulpit nawigacyjny raya umożliwia monitorowanie stanu klastrów Ray, wyświetlanie dzienników i wizualizowanie wyników zadań uczenia maszynowego.

Aby uzyskać dostęp do Ray Dashboard, musisz uwidocznić usługę głowy Ray w publicznym Internecie, tworząc podkładkę usługi w celu uwidocznienia usługi Ray head na porcie 80 zamiast portu 8265.

Note

Opisany deploy.sh w poprzedniej sekcji automatycznie uwidacznia usługę head Ray w publicznym Internecie. Poniższe kroki są zawarte w skry skrycie deploy.sh .

  1. Pobierz nazwę usługi head Ray i zapisz ją w zmiennej powłoki przy użyciu następującego polecenia:

    rayclusterhead=$(kubectl get service -n $kuberay_namespace | grep 'rayjob-pytorch-mnist-raycluster' | grep 'ClusterIP' | awk '{print $1}')
    
  2. Utwórz podkładki usługi, aby uwidocznić usługę ray head na porcie 80 przy użyciu kubectl expose service polecenia .

    kubectl expose service $rayclusterhead \
    -n $kuberay_namespace \
    --port=80 \
    --target-port=8265 \
    --type=NodePort \
    --name=ray-dash
    
  3. Utwórz ruch przychodzący w celu uwidocznienia podkładki usługi przy użyciu kontrolera ruchu przychodzącego przy użyciu następującego polecenia:

    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. Pobierz publiczny adres IP kontrolera ruchu przychodzącego przy użyciu kubectl get service polecenia .

    kubectl get service -n app-routing-system
    
  5. W danych wyjściowych powinien zostać wyświetlony publiczny adres IP modułu równoważenia obciążenia dołączony do kontrolera ruchu przychodzącego. Skopiuj publiczny adres IP i wklej go w przeglądarce internetowej. Powinien zostać wyświetlony pulpit nawigacyjny raya.

Uprzątnij zasoby

Aby wyczyścić zasoby utworzone w tym przewodniku, możesz usunąć grupę zasobów platformy Azure zawierającą klaster usługi AKS.

Dalsze kroki

Aby dowiedzieć się więcej na temat obciążeń sztucznej inteligencji i uczenia maszynowego w usłudze AKS, zobacz następujące artykuły:

Contributors

Firma Microsoft utrzymuje ten artykuł. Następujący współautorzy pierwotnie to napisali:

  • Russell de Pina | Moduł TPM podmiotu zabezpieczeń
  • Ken Kilty | Moduł TPM podmiotu zabezpieczeń
  • Erin Schaffer | Content Developer 2
  • Adrian Joian | Główny inżynier klienta
  • Ryan Graham | Główny specjalista techniczny