Ce tutoriel explique comment orchestrer un environnement d'entraînement distribué pour l'apprentissage par renforcement sur Google Kubernetes Engine (GKE). Vous utilisez Ray et le framework verl (Volcano Engine Reinforcement Learning) pour configurer un environnement d'entraînement distribué afin d'affiner un modèle Qwen2.5-32B-Instruct.
Ce tutoriel se concentre sur le pipeline d'entraînement Group Relative Policy Optimization (GRPO) sur GKE avec Ray et verl. GRPO est un algorithme d'apprentissage par renforcement conçu pour améliorer la capacité de raisonnement d'un modèle. Cet algorithme économe en mémoire simplifie le processus d'apprentissage par renforcement (RL) en éliminant le Critic, ou modèle de valeur, et en utilisant à la place un calcul relatif basé sur des groupes.
Ce tutoriel est un bon point de départ si vous devez configurer un environnement d'entraînement distribué dans lequel les données, les pondérations du modèle et le moteur d'entraînement sont dissociés pour plus d'efficacité.
Arrière-plan
Les sections suivantes présentent brièvement les concepts utilisés dans ce tutoriel.
Apprentissage par renforcement
L'apprentissage par renforcement enseigne aux modèles par l'expérience, l'exploration et le retour d'informations plutôt que par l'imitation statique. Alors que le pré-entraînement apprend à un modèle quoi dire, l'apprentissage par renforcement (et plus précisément l'apprentissage par renforcement qui utilise le feedback humain, ou RLHF) lui apprend à être utile, sûr et logique. L'apprentissage par renforcement sert de pont entre un modèle de base et un modèle affiné pour un cas d'utilisation spécialisé.
Pour en savoir plus, consultez Qu'est-ce que l'apprentissage par renforcement ?
Volcano Engine Reinforcement Learning (verl)
verl est un framework hautes performances conçu pour gérer les modèles complexes de mémoire et de calcul du RL basé sur les LLM.
Pour en savoir plus, consultez verl.
Optimisation des stratégies relatives aux groupes (GRPO)
GRPO, un algorithme popularisé par DeepSeek, offre une alternative économe en mémoire à l'optimisation de la politique proximale (PPO) pour l'alignement des LLM en supprimant le modèle Critic. Au lieu d'un réseau Critic, GRPO génère un groupe de réponses pour la même requête et utilise la récompense moyenne de ce groupe comme référence.
Pour en savoir plus, consultez GRPO.
Objectifs
Ce tutoriel vous explique comment configurer l'apprentissage par renforcement sur GKE avec verl en suivant les étapes suivantes :
- Configurez un cluster GKE avec des GPU B200 ou H200.
- Configurez KubeRay pour gérer un cluster Ray distribué.
- Utilisez Cloud Storage FUSE pour installer un bucket Cloud Storage sur tous les nœuds.
- Exécutez un job d'entraînement GRPO à l'aide de verl pour aligner le modèle Qwen2.5-32B-Instruct avec l'ensemble de données GSM8K.
Avant de commencer
- Connectez-vous à votre compte Google Cloud . Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $de crédits sans frais pour exécuter, tester et déployer des charges de travail.
-
Installez la Google Cloud CLI.
-
Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.
-
Pour initialiser la gcloud CLI, exécutez la commande suivante :
gcloud init -
Créez ou sélectionnez un projet Google Cloud .
Rôles requis pour sélectionner ou créer un projet
- Sélectionnez un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique. Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
-
Créer un projet : pour créer un projet, vous devez disposer du rôle Créateur de projet (
roles/resourcemanager.projectCreator), qui contient l'autorisationresourcemanager.projects.create. Découvrez comment attribuer des rôles.
-
Créez un projet Google Cloud :
gcloud projects create PROJECT_ID
Remplacez
PROJECT_IDpar le nom du projet Google Cloud que vous créez. -
Sélectionnez le projet Google Cloud que vous avez créé :
gcloud config set project PROJECT_ID
Remplacez
PROJECT_IDpar le nom de votre projet Google Cloud .
-
Vérifiez que la facturation est activée pour votre projet Google Cloud .
Activez les API requises :
Rôles requis pour activer les API
Pour activer les API, vous avez besoin du rôle IAM Administrateur Service Usage (
roles/serviceusage.serviceUsageAdmin), qui contient l'autorisationserviceusage.services.enable. Découvrez comment attribuer des rôles.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Installez la Google Cloud CLI.
-
Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.
-
Pour initialiser la gcloud CLI, exécutez la commande suivante :
gcloud init -
Créez ou sélectionnez un projet Google Cloud .
Rôles requis pour sélectionner ou créer un projet
- Sélectionnez un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique. Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
-
Créer un projet : pour créer un projet, vous devez disposer du rôle Créateur de projet (
roles/resourcemanager.projectCreator), qui contient l'autorisationresourcemanager.projects.create. Découvrez comment attribuer des rôles.
-
Créez un projet Google Cloud :
gcloud projects create PROJECT_ID
Remplacez
PROJECT_IDpar le nom du projet Google Cloud que vous créez. -
Sélectionnez le projet Google Cloud que vous avez créé :
gcloud config set project PROJECT_ID
Remplacez
PROJECT_IDpar le nom de votre projet Google Cloud .
-
Vérifiez que la facturation est activée pour votre projet Google Cloud .
Activez les API requises :
Rôles requis pour activer les API
Pour activer les API, vous avez besoin du rôle IAM Administrateur Service Usage (
roles/serviceusage.serviceUsageAdmin), qui contient l'autorisationserviceusage.services.enable. Découvrez comment attribuer des rôles.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Attribuez des rôles à votre compte utilisateur. Exécutez la commande suivante une fois pour chacun des rôles IAM suivants :
roles/container.admin, roles/iam.serviceAccountAdmin, roles/storage.admingcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
Remplacez les éléments suivants :
PROJECT_ID: ID de votre projetUSER_IDENTIFIER: identifiant de votre compte d'utilisateur. Par exemple,myemail@example.com.ROLE: rôle IAM que vous accordez à votre compte utilisateur.
- Créez un compte Hugging Face si vous n'en possédez pas.
- Assurez-vous de disposer d'un jeton Hugging Face.
- Assurez-vous que votre projet dispose d'un quota suffisant pour les GPU B200 et H200. Pour en savoir plus, consultez Planifier le quota de GPU et Quota de GPU.
Préparer votre environnement
Dans ce tutoriel, vous utilisez Cloud Shell.
Accédez à la consoleGoogle Cloud .
En haut de la fenêtre de la console Google Cloud , cliquez sur le bouton Activer Cloud Shell.
Définissez les variables d'environnement suivantes :
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export GPU_TYPE=GPU_TYPE export CONTROL_PLANE_LOCATION=CONTROL_PLANE_LOCATION export NODE_LOCATION=NODE_LOCATION export CLUSTER_NAME=CLUSTER_NAME export KSA_NAME=CLUSTER_NAME export GS_BUCKET=BUCKET_NAME-${PROJECT_ID} export NAMESPACE=default export HF_TOKEN=YOUR_HUGGING_FACE_TOKEN export MACHINE_TYPE=MACHINE_TYPE export GKE_VERSION=GKE_VERSIONRemplacez les valeurs suivantes :
CONTROL_PLANE_LOCATION: région Compute Engine du plan de contrôle du cluster GKE.GPU_TYPE: accélérateur que vous avez réservé dans la réservation de capacité Compute Engine. Il doit s'agir de l'une des options suivantes :nvidia-b200: NVIDIA B200 (180 Go)nvidia-h200-141gb: NVIDIA H200 (141 Go)
NODE_LOCATION: zone des nœuds GKE. Sélectionnez une zone où les GPU NVIDIA B200 ou H200 sont disponibles.CLUSTER_NAME: nom de votre cluster GKE.BUCKET_NAME: nom de base de votre bucket Cloud Storage. Vous n'avez pas besoin de spécifier le préfixegs://.YOUR_HUGGING_FACE_TOKEN: votre jeton Hugging Face pour accéder au modèle.MACHINE_TYPE: type de machine à utiliser. Les options valides sontc2standard8ouc2standard16.GKE_VERSION: version de GKE à utiliser :- Pour les GPU NVIDIA B200 (180 Go), utilisez la version
1.32.2-gke.1422000ou ultérieure. - Pour les GPU NVIDIA H200 (141 Go), utilisez la version
1.31.4-gke.1183000ou ultérieure.
- Pour les GPU NVIDIA B200 (180 Go), utilisez la version
Créez les variables d'environnement suivantes pour le réseau :
export GVNIC_NETWORK_PREFIX="GVNIC-NAME" export RDMA_NETWORK_PREFIX="RDMA-NAME"Remplacez les valeurs suivantes :
GVNIC-NAME: préfixe du nom du réseau gVNIC. Vous pouvez utiliser le préfixe de votre choix.RDMA-NAME: préfixe du réseau d'accès direct à la mémoire à distance (RDMA). Vous pouvez utiliser le préfixe de votre choix.
Configurer l'infrastructure
Dans cette section, vous allez créer un réseau RDMA et un cluster GKE.
Créer un réseau et des sous-réseaux RDMA
Créez un réseau VPC pour l'interface gVNIC :
gcloud compute networks create ${GVNIC_NETWORK_PREFIX}-net \ --subnet-mode=custom \ --project=${PROJECT} gcloud compute networks subnets create ${GVNIC_NETWORK_PREFIX}-sub \ --network=${GVNIC_NETWORK_PREFIX}-net \ --location=${CONTROL_PLANE_LOCATION} \ --range=192.168.0.0/24 gcloud compute firewall-rules create ${GVNIC_NETWORK_PREFIX}-internal \ --network=${GVNIC_NETWORK_PREFIX}-net \ --action=ALLOW \ --rules=tcp:0-65535,udp:0-65535,icmp \ --source-ranges=192.168.0.0/16Créez un réseau VPC et des sous-réseaux pour RDMA avec huit sous-réseaux pour huit GPU :
gcloud beta compute networks create ${RDMA_NETWORK_PREFIX}-net \ --network-profile=${CONTROL_PLANE_LOCATION}-vpc-roce \ --subnet-mode=custom for N in $(seq 0 7); do gcloud compute networks subnets create ${RDMA_NETWORK_PREFIX}-sub-$N \ --network=${RDMA_NETWORK_PREFIX}-net \ --location=${CONTROL_PLANE_LOCATION} \ --range=192.168.$((N+1)).0/24 & done waitClonez l'exemple de dépôt :
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samplesAccédez au répertoire de travail :
cd ai-ml/verl-on-gke
Créer le cluster GKE
Vous pouvez définir verl dans un cluster GKE Autopilot ou Standard. Nous vous recommandons d'utiliser un cluster GKE Autopilot pour une expérience Kubernetes entièrement gérée. Pour choisir le mode de fonctionnement GKE le mieux adapté à vos charges de travail, consultez Choisir un mode de fonctionnement GKE.
Autopilot
Créez un cluster Autopilot :
gcloud container clusters create-auto ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_LOCATION} \ --enable-multi-networking \ --enable-ray-operatorObtenez les identifiants de votre cluster :
gcloud container clusters get-credentials ${CLUSTER_NAME} \ --location=${REGION}Installez le programme d'installation NCCL RDMA pour Autopilot :
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/refs/heads/master/gpudirect-rdma/nccl-rdma-installer-autopilot.yaml
Standard
Créez un cluster standard :
gcloud container clusters create ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_LOCATION} \ --location=${ZONE} \ --enable-dataplane-v2 \ --enable-ip-alias \ --enable-multi-networking \ --addons=RayOperator,GcsFuseCsiDriver \ --machine-type=${MACHINE_TYPE} \ --num-nodes=1 \ --min-nodes=1 \ --max-nodes=5 \ --enable-autoscalingObtenez les identifiants de votre cluster :
gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${ZONE}Créez le pool de nœuds GPU (en utilisant des instances Spot pour réduire les coûts) :
gcloud container node-pools create gpu-pool \ --cluster=${CLUSTER_NAME} \ --location=${NODE_LOCATION} \ --machine-type=${MACHINE_TYPE} \ --accelerator=type=${GPU_TYPE},count=8,gpu-driver-version=DEFAULT \ --spot \ --enable-autoscaling \ --num-nodes=0 \ --total-max-nodes=10 \ --additional-node-network=network=${GVNIC_NETWORK_PREFIX}-net,subnetwork=${GVNIC_NETWORK_PREFIX}-sub \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-0 \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-1 \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-2 \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-3 \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-4 \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-5 \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-6 \ --additional-node-network=network=${RDMA_NETWORK_PREFIX}-net,subnetwork=${RDMA_NETWORK_PREFIX}-sub-7Installez le programme d'installation NCCL RDMA utilisé pour les clusters standards :
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/refs/heads/master/gpudirect-rdma/nccl-rdma-installer.yaml
Configurer les mappages réseau
Inspectez le fichier manifeste
network-mapping.yaml:Appliquez le fichier manifeste :
kubectl apply -f network-mapping.yaml
Préparer les données et le stockage
Créez un bucket Cloud Storage :
gcloud storage buckets create gs://${GS_BUCKET} --location=${REGION} --enable-hierarchical-namespace --uniform-bucket-level-accessCréez un compte de service Kubernetes (KSA) et associez-le au bucket :
kubectl create serviceaccount ${KSA_NAME} --namespace ${NAMESPACE} gcloud storage buckets add-iam-policy-binding gs://${GS_BUCKET} \ --member "principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/${NAMESPACE}/sa/${KSA_NAME}" \ --role "roles/storage.objectUser"Créez le Secret pour Hugging Face :
kubectl create secret generic hf-secret --from-literal=hf_api_token=${HF_TOKEN}Inspectez le fichier manifeste
gcsfuse-storage.yaml:Appliquez le fichier manifeste :
kubectl apply -f gcsfuse-storage.yaml
Préparer le modèle et les données
Vous pouvez exécuter ces commandes en local ou sur un pod GKE pour remplir le bucket.
Clonez le dépôt verl :
git clone https://github.com/volcengine/verl.gitTéléchargez le modèle Qwen2.5-32B-Instruct à l'aide de la CLI Hugging Face :
huggingface-cli download Qwen/Qwen2.5-32B-Instruct --local-dir Qwen2.5-32B-InstructPrétraitez l'ensemble de données GSM8K :
python examples/data_preprocess/gsm8k.py --local_save_dir ~/data/gsm8kImportez le modèle, les données et le code de validation dans votre bucket Cloud Storage :
gcloud storage cp --recursive verl gs://${GS_BUCKET}/verl gcloud storage cp --recursive Qwen2.5-32B-Instruct gs://${GS_BUCKET}/Qwen2.5-32B-Instruct gcloud storage cp --recursive ~/data/gsm8k/* ${GS_BUCKET}
Déployer la ressource personnalisée RayCluster
Déployez une ressource personnalisée RayCluster, qui se compose généralement d'un pod système et de plusieurs pods de nœuds de calcul.
Autopilot
Déployez le RayCluster. Enregistrez le fichier suivant sous le nom
ray-cluster-auto.yaml:Appliquez le RayCluster :
kubectl apply -f ray-cluster.yaml
Standard
Déployez le RayCluster. Enregistrez le fichier suivant sous le nom
ray-cluster.yaml:Appliquez le RayCluster :
kubectl apply -f ray-cluster.yaml
Lancer le job GRPO
Configurez le transfert de port vers le nœud du tableau de bord Ray :
kubectl port-forward svc/b200-ray-cluster-head-svc 8265:8265Inspectez le fichier manifeste
runtime-env.yaml:Si vous utilisez des GPU H200, remplacez
NCCL_TUNER_CONFIG_PATHpar/usr/local/gib/configs/tuner_config_a3u.txtpb.Ce fichier est utilisé par le client Ray. Vous n'avez pas besoin d'appliquer ce fichier manifeste au cluster.
Envoyez le job à l'aide de
ray job submit:ray -- job submit \ --address "http://localhost:8265" \ --runtime-env runtime-env.yaml \ -- \ bash -c " cd /data/verl && PYTHONUNBUFFERED=1 python3 -m verl.trainer.main_ppo \ data.train_files=/data/gsm8k/train.parquet \ data.val_files=/data/gsm8k/test.parquet \ data.train_batch_size=256 \ data.max_prompt_length=512 \ data.max_response_length=512 \ actor_rollout_ref.model.path=Qwen/Qwen2.5-32B-Instruct \ actor_rollout_ref.actor.optim.lr=1e-5 \ actor_rollout_ref.actor.ppo_mini_batch_size=256 \ actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=64 \ actor_rollout_ref.rollout.name=vllm \ actor_rollout_ref.rollout.log_prob_micro_batch_size_per_gpu=8 \ actor_rollout_ref.rollout.tensor_model_parallel_size=8 \ actor_rollout_ref.rollout.gpu_memory_utilization=0.6 \ actor_rollout_ref.ref.log_prob_micro_batch_size_per_gpu=4 \ actor_rollout_ref.actor.strategy=fsdp2 \ algorithm.kl_ctrl.kl_coef=0.001 \ trainer.logger=console \ trainer.val_before_train=False \ trainer.n_gpus_per_node=8 \ trainer.nnodes=2 \ trainer.save_freq=10 \ trainer.test_freq=10 \ algorithm.adv_estimator=grpo \ actor_rollout_ref.rollout.n=8 \ trainer.total_epochs=2" 2>&1 | tee verl_demo.logSurveillez les journaux dans le tableau de bord ou la sortie Ray. Recherchez l'augmentation de
critic/score/mean, qui indique l'apprentissage.
Effectuer un nettoyage
Pour éviter que des frais ne vous soient facturés, supprimez les ressources :
kubectl delete raycluster b200-ray-cluster # change to variables
gcloud container clusters delete ${CLUSTER_NAME} --location=${CONTROL_PLANE_LOCATION}
gcloud storage rm -r gs://${GS_BUCKET}