Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans cet article, vous configurez et déployez un cluster Ray sur Azure Kubernetes Service (AKS) à l’aide de KubeRay. Vous allez également découvrir comment utiliser le cluster Ray pour entraîner un modèle simple d’apprentissage automatique et afficher les résultats sur le tableau de bord Ray.
Cet article décrit deux méthodes pour déployer le cluster Ray sur AKS :
- Le déploiement non interactif : Utilisez le script
deploy.shdans le référentiel GitHub pour déployer l’échantillon complet de Ray de manière non interactive. - Le déploiement manuel : Suivez les étapes du déploiement manuel pour déployer l’échantillon Ray sur AKS.
Prérequis
- Pour comprendre les composants et le processus de déploiement, consultez Vue d’ensemble du cluster Ray sur AKS.
- Un abonnement Azure. Si vous n’avez pas d’abonnement Azure, vous pouvez créer un compte gratuit ici.
- L’interface Azure CLI est installée sur votre ordinateur local. Vous pouvez l’installer en suivant les instructions fournies dans Comment installer l’interface Azure CLI.
- L’Extension de préversion d’Azure Kubernetes Service est installée.
- Helm installé.
- Les outils clients Terraform ou OpenTofu sont installés. Cet article utilise Terraform, mais les modules utilisés doivent être compatibles avec OpenTofu.
Déployer l’échantillon Ray de manière non interactive
Si vous souhaitez déployer l’échantillon complet de Ray de manière non interactive, vous pouvez utiliser le script deploy.sh dans le référentiel GitHub (https://github.com/Azure-Samples/aks-ray-sample). Ce script complète les étapes décrites dans la Section sur le processus de déploiement de Ray.
Clonez le référentiel GitHub en local et modifiez la racine du référentiel à l’aide des commandes suivantes :
git clone https://github.com/Azure-Samples/aks-ray-sample cd aks-ray-sampleDéployez l’échantillon complet à l’aide des commandes suivantes :
chmod +x deploy.sh ./deploy.shUne fois le déploiement terminé, passez en revue la sortie des journaux et le groupe de ressources dans le Portail Azure pour vérifier l’infrastructure qui a été créée.
Déployez manuellement l’échantillon Ray
Fashion MNIST est un ensemble de données d’images d’articles de Zalando composé d’un jeu d’apprentissage de 60 000 exemples et d’un jeu de test de 10 000 exemples. Chaque exemple est une image en nuances de gris de 28x28 associée à une étiquette de dix classes. Dans ce guide, vous entraînez un modèle PyTorch simple sur ce jeu de données à l’aide du cluster Ray.
Déployez la spécification RayJob
Pour entraîner le modèle, vous devez envoyer une spécification Ray Job à l’opérateur KubeRay qui s’exécute sur un cluster AKS privé. La spécification Ray Job est un fichier YAML qui décrit les ressources nécessaires à l’exécution du travail, notamment l’image Docker, la commande à exécuter et le nombre de Workers à utiliser.
En examinant la description du Ray Job, il se peut que vous deviez modifier certains champs pour les adapter à votre environnement :
- Le champ
replicassous la sectionworkerGroupSpecsdansrayClusterSpecspécifie le nombre de pods worker que KubeRay planifie pour le cluster Kubernetes. Chaque pod worker nécessite 3 processeurs et 4 Go de mémoire. Le pod principal nécessite 1 processeur et 4 Go de mémoire. La définition du champreplicassur 2 nécessite 8 processeurs virtuels dans le pool de nœuds utilisé pour implémenter le RayCluster pour le travail. - Le champ
NUM_WORKERSsousruntimeEnvYAMLdansspecspécifie le nombre d’acteurs Ray à lancer. Chaque acteur Ray doit être desservi par un pod worker dans le cluster Kubernetes, de sorte que ce champ doit être inférieur ou égal au champreplicas. Dans cet exemple, nous avons définiNUM_WORKERSsur 2, ce qui correspond au champreplicas. - Le champ
CPUS_PER_WORKERdoit être défini comme étant inférieur ou égal au nombre de CPU alloués à chaque pod worker moins 1. Dans cet exemple, la demande de ressources processeur par pod worker est de 3. Par conséquent.CPUS_PER_WORKERest donc définie sur 2.
En résumé, vous avez besoin d’un total de 8 processeurs virtuels dans le pool de nœuds pour exécuter la tâche d’apprentissage du modèle PyTorch. Étant donné que nous avons ajouté une altération sur le pool de nœuds du système afin qu’aucun pod utilisateur ne puisse être planifié sur celui-ci, nous devons créer un nouveau pool de nœuds avec au moins 8 processeurs virtuels pour héberger le cluster Ray.
Téléchargez le fichier de spécification du Ray Job à l’aide de la commande suivante :
curl -LO https://raw.githubusercontent.com/ray-project/kuberay/master/ray-operator/config/samples/pytorch-mnist/ray-job.pytorch-mnist.yamlApportez toutes les modifications nécessaires au fichier de spécification du Ray Job.
Lancez le travail d’apprentissage du modèle PyTorch à l’aide de la commande
kubectl apply.kubectl apply -n kuberay -f ray-job.pytorch-mnist.yaml
Vérifiez le déploiement de RayJob
Vérifiez que vous disposez de deux pods worker et d’un pod principal qui fonctionnent dans l’espace de noms à l’aide de la commande
kubectl get pods.kubectl get pods -n kuberayVous devez obtenir un résultat semblable à l’exemple de sortie qui suit :
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 6m15sVérifiez l’état du RayJob à l’aide de la commande
kubectl get.kubectl get rayjob -n kuberayVous devez obtenir un résultat semblable à l’exemple de sortie qui suit :
NAME JOB STATUS DEPLOYMENT STATUS START TIME END TIME AGE rayjob-pytorch-mnist RUNNING Running 2024-11-22T03:08:22Z 9m36sAttendez que le RayJob soit terminé. Cette opération peut prendre quelques minutes. Une fois que le
JOB STATUSestSUCCEEDED, vous pouvez vérifier les journaux d’apprentissage. Vous pouvez le faire en obtenant d’abord le nom du pod qui exécute le RayJob à l’aide de la commandekubectl get pods.kubectl get pods -n kuberayDans la sortie, vous devriez voir un pod dont le nom commence par
rayjob-pytorch-mnist, comme dans l’exemple de sortie suivant :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 14mAffichez les journaux du RayJob à l’aide de la commande
kubectl logs. Veillez à remplacerrayjob-pytorch-mnist-fc959par le nom du pod qui exécute votre RayJob.kubectl logs -n kuberay rayjob-pytorch-mnist-fc959Dans la sortie, vous devriez voir les journaux d’apprentissage du modèle PyTorch, comme dans l’exemple de sortie suivant :
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 -- ------------------------------------------
Visualiser les résultats de l’apprentissage sur le tableau de bord Ray
Lorsque le RayJob est terminé, vous pouvez consulter les résultats de l’apprentissage sur le tableau de bord Ray. Le tableau de bord Ray permet de surveiller et de visualiser les clusters Ray en temps réel. Vous pouvez utiliser le tableau de bord Ray pour surveiller l’état des clusters Ray, consulter les journaux et visualiser les résultats des travaux d’apprentissage automatique.
Pour accéder au tableau de bord Ray, vous devez exposer le service principal Ray à l’Internet public en créant un shim de service pour exposer le service principal Ray sur le port 80 au lieu du port 8265.
Remarque
La deploy.sh décrite dans la section précédente expose automatiquement le service principal Ray à l’Internet public. Les étapes suivantes sont incluses dans le script deploy.sh.
Obtenez le nom du service principal Ray et enregistrez-le dans une variable d’interpréteur de commandes à l’aide de la commande suivante :
rayclusterhead=$(kubectl get service -n $kuberay_namespace | grep 'rayjob-pytorch-mnist-raycluster' | grep 'ClusterIP' | awk '{print $1}')Créez le shim de service pour exposer le service principal Ray sur le port 80 à l’aide de la commande
kubectl expose service.kubectl expose service $rayclusterhead \ -n $kuberay_namespace \ --port=80 \ --target-port=8265 \ --type=NodePort \ --name=ray-dashCréez l’entrée pour exposer le shim de service à l’aide du contrôleur d’entrée à l’aide de la commande suivante :
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 EOFObtenez l’adresse IP publique du contrôleur d’entrée à l’aide de la commande
kubectl get service.kubectl get service -n app-routing-systemDans la sortie, vous devriez voir l’adresse IP publique de l’équilibreur de charge attaché au contrôleur d’entrée. Copiez l’adresse IP publique et collez-la dans un navigateur web. Vous devriez voir le tableau de bord Ray.
Nettoyer les ressources
Pour nettoyer les ressources créées dans ce guide, vous pouvez supprimer le groupe de ressources Azure qui contient le cluster AKS.
Étapes suivantes
Pour en savoir plus sur les charges de travail d’IA et d’apprentissage automatique sur AKS, consultez les articles suivants :
- Déployer une application qui utilise OpenAI sur Azure Kubernetes Service (AKS)
- Créer et déployer des pipelines de données et d’apprentissage automatique avec Flyte sur Azure Kubernetes Service (AKS)
- Déployer un modèle IA sur Azure Kubernetes Service (AKS) avec l’opérateur de chaîne d’outils IA
Contributeurs
Microsoft gère cet article. Les contributeurs suivants ont rédigé sa version d’origine :
- Russell de Pina | Responsable de programme technique principal
- Ken Kitty | Responsable de programme technique principal
- Erin Schaffer | Développeuse de contenu 2
- Adrian Joian | Ingénieur client principal
- Ryan Graham | Spécialiste technique principal