Questo tutorial mostra come orchestrare un ambiente di addestramento distribuito per l'apprendimento per rinforzo su Google Kubernetes Engine (GKE). Utilizzi Ray e il framework verl (Volcano Engine Reinforcement Learning) per configurare un ambiente di addestramento distribuito per ottimizzare un modello Qwen2.5-32B-Instruct sul set di dati GSM8K.
Questo tutorial si concentra sulla pipeline di addestramento dell'ottimizzazione delle norme relative al gruppo (GRPO) su GKE con Ray e verl. GRPO è un algoritmo di apprendimento per rinforzo progettato per migliorare la capacità di ragionamento di un modello. Questo algoritmo efficiente in termini di memoria semplifica il processo di reinforcement learning (RL) eliminando il Critic, o modello di valore, e utilizzando invece un calcolo relativo basato sul gruppo.
Questo tutorial è un buon punto di partenza se devi configurare un ambiente di addestramento distribuito in cui dati, pesi del modello e motore di addestramento sono disaccoppiati per una maggiore efficienza.
Questo tutorial supporta le seguenti architetture GPU:
- Nodi GPU basati su Intel o AMD: configura ed esegui lo scale utilizzando le GPU NVIDIA B200 o H200.
- Nodi A4X (GB200) basati su Arm: configura ed esegui lo scale utilizzando i superchip NVIDIA GB200 Grace Blackwell, utilizzando l'allocazione dinamica delle risorse (DRA) di GKE e NVLink multi-nodo (IMEX).
Sfondo
Le sezioni seguenti forniscono una breve panoramica dei concetti utilizzati in questo tutorial.
Apprendimento per rinforzo (RL)
L'RL insegna ai modelli attraverso l'esperienza, l'esplorazione e il feedback, anziché l'imitazione statica. Anche se il pre-addestramento insegna a un modello cosa dire, l'apprendimento per rinforzo con feedback umano (RLHF) gli insegna a essere utile, sicuro e logico. L'RL funge da ponte tra un modello di base e un modello ottimizzato per un caso d'uso specializzato.
Per saperne di più, consulta Che cos'è l'apprendimento per rinforzo?
Ottimizzazione delle policy relative al gruppo (GRPO)
GRPO, un algoritmo reso popolare da DeepSeek, offre un'alternativa a basso consumo di memoria all'ottimizzazione delle norme prossimali (PPO) per l'allineamento degli LLM rimuovendo il modello Critic. Anziché una rete di critici, GRPO genera un gruppo di risposte per lo stesso prompt e utilizza la ricompensa media di quel gruppo come baseline.
Per saperne di più, consulta GRPO.
Volcano Engine Reinforcement Learning (verl)
verl è un framework ad alte prestazioni progettato per gestire i complessi pattern di memoria e di calcolo dell'RL basato su LLM.
Per saperne di più, consulta verl.
Obiettivi
Questo tutorial mostra come configurare l'apprendimento per rinforzo su GKE con verl completando i seguenti passaggi:
- Configura un cluster GKE con A4X (GB200 Superchip), A4 (GPU B200) o A3 Ultra (GPU H200).
- Configura KubeRay per gestire un cluster Ray distribuito.
- Utilizza Cloud Storage FUSE per montare un bucket Cloud Storage su tutti i nodi.
- Esegui un job di addestramento GRPO utilizzando verl per allineare il modello Qwen2.5-32B-Instruct con il set di dati GSM8K.
Prima di iniziare
- Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei carichi di lavoro.
-
Installa Google Cloud CLI.
-
Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.
-
Per inizializzare gcloud CLI, esegui questo comando:
gcloud init -
Crea o seleziona un Google Cloud progetto.
Ruoli richiesti per selezionare o creare un progetto
- Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
-
Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto
(
roles/resourcemanager.projectCreator), che contiene l'autorizzazioneresourcemanager.projects.create. Scopri come concedere i ruoli.
-
Creare un progetto Google Cloud :
gcloud projects create PROJECT_ID
Sostituisci
PROJECT_IDcon un nome per il progetto Google Cloud che stai creando. -
Seleziona il progetto Google Cloud che hai creato:
gcloud config set project PROJECT_ID
Sostituisci
PROJECT_IDcon il nome del progetto Google Cloud .
-
Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .
Abilita le API richieste:
Ruoli richiesti per abilitare le API
Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (
roles/serviceusage.serviceUsageAdmin), che include l'autorizzazioneserviceusage.services.enable. Scopri come concedere i ruoli.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Installa Google Cloud CLI.
-
Se utilizzi un provider di identità (IdP) esterno, devi prima accedere a gcloud CLI con la tua identità federata.
-
Per inizializzare gcloud CLI, esegui questo comando:
gcloud init -
Crea o seleziona un Google Cloud progetto.
Ruoli richiesti per selezionare o creare un progetto
- Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
-
Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto
(
roles/resourcemanager.projectCreator), che contiene l'autorizzazioneresourcemanager.projects.create. Scopri come concedere i ruoli.
-
Creare un progetto Google Cloud :
gcloud projects create PROJECT_ID
Sostituisci
PROJECT_IDcon un nome per il progetto Google Cloud che stai creando. -
Seleziona il progetto Google Cloud che hai creato:
gcloud config set project PROJECT_ID
Sostituisci
PROJECT_IDcon il nome del progetto Google Cloud .
-
Verifica che la fatturazione sia attivata per il tuo progetto Google Cloud .
Abilita le API richieste:
Ruoli richiesti per abilitare le API
Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (
roles/serviceusage.serviceUsageAdmin), che include l'autorizzazioneserviceusage.services.enable. Scopri come concedere i ruoli.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Concedi ruoli al tuo account utente. Esegui il seguente comando una volta per ciascuno dei seguenti ruoli IAM:
roles/container.admin, roles/iam.serviceAccountAdmin, roles/storage.admingcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
Sostituisci quanto segue:
PROJECT_ID: il tuo ID progetto.USER_IDENTIFIER: l'identificatore del tuo account utente . Ad esempio:myemail@example.com.ROLE: il ruolo IAM che concedi al tuo account utente.
- Crea un account Hugging Face, se non ne hai già uno.
- Assicurati di avere un token Hugging Face.
- Assicurati che il tuo progetto disponga di una quota sufficiente per A4X (GB200 Superchip), A4 (GPU B200) o A3 Ultra (GPU H200). Per scoprire di più, consulta Pianificare la quota di GPU e Quota di GPU.
- Assicurati di avere una prenotazione della capacità attiva per il tipo di macchina GPU. Per ulteriori informazioni, vedi Riservare capacità tramite il team dell'account.
- Per la configurazione di A4X (GB200), assicurati di aver installato Helm.
prepara l'ambiente
In questo tutorial utilizzi Cloud Shell.
Vai alla consoleGoogle Cloud .
Nella parte superiore della finestra della console Google Cloud , fai clic sul pulsante Attiva Cloud Shell.
Imposta le variabili di ambiente:
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CONTROL_PLANE_REGION=CONTROL_PLANE_REGION export NODE_ZONE=NODE_ZONE export CLUSTER_NAME=CLUSTER_NAME export KSA_NAME=KSA_NAME export GS_BUCKET=BUCKET_NAME-${PROJECT_ID} export NAMESPACE=default export GPU_TYPE=GPU_TYPE export MACHINE_TYPE=MACHINE_TYPE export RESERVATION=RESERVATION export HF_TOKEN=YOUR_HUGGING_FACE_TOKEN # A4 (B200 GPUs) or A3 Ultra (H200 GPUs) only variables export GVNIC_NETWORK_PREFIX=YGVNIC_NAME export RDMA_NETWORK_PREFIX=RDMA_NAME # A4X (GB200 Superchips) only variables export NUM_GPU_NODES=4 export VERL_IMAGE=verlai/verl:vllm023.aarch64.dev1 export VERL_REF=ddbcdb7Sostituisci i seguenti valori:
CONTROL_PLANE_REGION: la regione Compute Engine per il control plane del cluster GKE.NODE_ZONE: la zona in cui sono riservati i nodi. Per saperne di più, consulta Disponibilità delle GPU.CLUSTER_NAME: il nome del tuo cluster GKE.KSA_NAME: il nome del tuo account di servizio Kubernetes.BUCKET_NAME: il nome di base del bucket Cloud Storage. Non è necessario specificare il prefissogs://.GPU_TYPE: l'acceleratore che hai prenotato nella prenotazione di capacità di Compute Engine. Deve essere uno dei seguenti valori:nvidia-gb200: A4X (GB200 Superchips)nvidia-b200: A4 (GPU B200)nvidia-h200-141gb: A3 Ultra (GPU H200)
MACHINE_TYPE: il tipo di macchina da utilizzare:- Per A4X (GB200 Superchips), utilizza
a4x-highgpu-4g. - Per A4 (GPU B200), utilizza
a4-highgpu-8go versioni successive. - Per A3 Ultra (GPU H200), utilizza
a3-ultragpu-8go versioni successive.
- Per A4X (GB200 Superchips), utilizza
RESERVATION: il nome della prenotazione di capacità.YOUR_HUGGING_FACE_TOKEN: il tuo token Hugging Face.GVNIC_NAME(solo A4 o A3 Ultra): il prefisso per il nome della rete gVNIC. Puoi utilizzare qualsiasi prefisso.RDMA_NAME(solo A4 o A3 Ultra): il prefisso per la rete di accesso diretto alla memoria (RDMA) remoto. Puoi utilizzare qualsiasi prefisso.
Configurazione dell'infrastruttura
In questa sezione, creerai reti VPC standard e il cluster GKE.
Crea la rete RDMA e le subnet (solo A4 e A3 Ultra)
Questa sezione è obbligatoria solo per le GPU A4 e A3 Ultra.
Se utilizzi GPU A4X (GB200), salta questa sezione e vai direttamente a
Crea il cluster GKE. Per le GPU A4X (GB200), GKE
crea automaticamente le reti quando il pool di nodi utilizza il profilo di rete dell'acceleratore auto. Il progetto base di Cluster Toolkit
attiva questo profilo utilizzando il flag enable_dranet:true.
Crea una rete VPC per l'interfaccia gVNIC:
gcloud compute networks create ${GVNIC_NETWORK_PREFIX}-net \ --subnet-mode=custom \ --project=${PROJECT_ID} gcloud compute networks subnets create ${GVNIC_NETWORK_PREFIX}-sub \ --network=${GVNIC_NETWORK_PREFIX}-net \ --region=${CONTROL_PLANE_REGION} \ --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/16Crea una rete VPC e subnet per RDMA con 8 subnet per 8 GPU:
gcloud beta compute networks create ${RDMA_NETWORK_PREFIX}-net \ --network-profile=${NODE_ZONE}-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 \ --region=${CONTROL_PLANE_REGION} \ --range=192.168.$((N+1)).0/24 & done waitClona il repository di esempio:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samplesVai alla directory di lavoro:
cd ai-ml/verl-on-gke
Crea il cluster GKE
Crea il cluster GKE corrispondente alla tua architettura GPU:
A4 e A3 Ultra
Seleziona la modalità cluster GKE che vuoi utilizzare:
Autopilot
Crea un cluster Autopilot:
gcloud container clusters create-auto ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_REGION} \ --enable-multi-networking \ --enable-ray-operatorRecupera le credenziali per il tuo cluster:
gcloud container clusters get-credentials ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_REGION}Installa il programma di installazione NCCL RDMA per Autopilot:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/refs/heads/master/gpudirect-rdma/nccl-rdma-installer-autopilot.yaml
Standard
Crea un cluster standard:
gcloud container clusters create ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_REGION} \ --enable-dataplane-v2 \ --workload-pool=${PROJECT_ID}.svc.id.goog \ --enable-ip-alias \ --enable-multi-networking \ --addons=RayOperator,GcsFuseCsiDriver \ --machine-type=c2-standard-16 \ --num-nodes=1 \ --min-nodes=1 \ --max-nodes=5 \ --enable-autoscalingRecupera le credenziali per il tuo cluster:
gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${CONTROL_PLANE_REGION}Crea il pool di nodi GPU. Questi node pool utilizzano la prenotazione per garantire la disponibilità. Iniziamo con due nodi:
gcloud container node-pools create gpu-pool \ --cluster=${CLUSTER_NAME} \ --location=${CONTROL_PLANE_REGION} \ --node-locations=${NODE_ZONE} \ --machine-type=${MACHINE_TYPE} \ --accelerator=type=${GPU_TYPE},count=8,gpu-driver-version=DEFAULT \ --reservation-affinity=specific \ --reservation=${RESERVATION} \ --enable-autoscaling \ --num-nodes=2 \ --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-7Installa il programma di installazione NCCL RDMA utilizzato per i cluster standard:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/refs/heads/master/gpudirect-rdma/nccl-rdma-installer.yaml
A4X
Crea il cluster GKE e il pool di nodi utilizzando il blueprint Cluster Toolkit
gke-a4x. Il blueprint esegue il provisioning del cluster GKE, incluso il pool di nodi A4X associato alla tua prenotazione, le reti di acceleratori (una gVNIC aggiuntiva più quattro guide RDMA) e il driver DRANET gestito che espone le NIC CX-7 come dispositivi DRA.Utilizza le istruzioni di deployment del progetto per configurare i parametri (ad esempio
PROJECT_ID,CONTROL_PLANE_REGION,NODE_ZONE, prenotazione eNUM_GPU_NODES), quindi esegui il deployment del cluster. In alternativa, puoi seguire la guida alla creazione del cluster GKE A4X per creare il cluster manualmente.Recupera le credenziali per il tuo cluster:
gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${CONTROL_PLANE_REGION}Verifica che il cluster esponga le NIC RDMA tramite DRA:
kubectl get deviceclassesL'output deve includere
mrdma.google.com.Verifica che siano presenti i nodi A4X:
kubectl get nodes -l cloud.google.com/gke-accelerator=nvidia-gb200Installa il plug-in gIB NCCL (variante A4X):
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-rdma/nccl-rdma-installer-a4x.yamlInstalla il driver NVIDIA DRA, che fornisce canali
ComputeDomain(IMEX) per NVLink multimodale:helm repo add nvidia https://helm.ngc.nvidia.com/nvidia && helm repo update kubectl create namespace nvidia-dra-driver-gpu kubectl apply -f - <<EOF apiVersion: v1 kind: ResourceQuota metadata: name: nvidia-dra-driver-gpu-quota namespace: nvidia-dra-driver-gpu spec: hard: pods: "$((2 * NUM_GPU_NODES + 1))" scopeSelector: matchExpressions: - operator: In scopeName: PriorityClass values: - system-node-critical - system-cluster-critical EOF helm upgrade --install nvidia-dra-driver-gpu nvidia/nvidia-dra-driver-gpu \ --version=25.3.1 --namespace nvidia-dra-driver-gpu \ --set nvidiaDriverRoot=/home/kubernetes/bin/nvidia \ --set resources.gpus.enabled=false \ --set kubeletPlugin.tolerations[0].key=nvidia.com/gpu \ --set kubeletPlugin.tolerations[0].operator=Exists \ --set kubeletPlugin.tolerations[1].key=kubernetes.io/arch \ --set kubeletPlugin.tolerations[1].operator=ExistsInstalla l'operatore KubeRay, con ambito limitato allo spazio dei nomi del carico di lavoro:
kubectl create namespace ${NAMESPACE} helm repo add kuberay https://ray-project.github.io/kuberay-helm/ && helm repo update helm upgrade --install kuberay-operator kuberay/kuberay-operator \ --namespace ${NAMESPACE} \ --set singleNamespaceInstall=true --set "watchNamespace={${NAMESPACE}}"
Configura mappature di rete (solo A4 e A3 Ultra)
Questo passaggio è obbligatorio per le configurazioni GPU standard (solo A4 e A3 Ultra). Se utilizzi A4X (GB200), GKE gestisce automaticamente le interfacce di rete, quindi ignora questa sezione.
Ispeziona il manifest
network-mapping.yaml:Applica il manifest:
envsubst < network-mapping.yaml > network-mapping-updated.yaml kubectl apply -f network-mapping-updated.yaml
Preparare dati e spazio di archiviazione
Configura le risorse Cloud Storage e Kubernetes:
Crea un bucket Cloud Storage:
gcloud storage buckets create gs://${GS_BUCKET} \ --location=${CONTROL_PLANE_REGION} \ --enable-hierarchical-namespace \ --uniform-bucket-level-accessCrea un service account Kubernetes (KSA) e associalo al 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"Crea il secret per Hugging Face:
kubectl create secret generic hf-secret --from-literal=hf_api_token=${HF_TOKEN}Ispeziona il manifest
gcsfuse-storage.yaml:Applica il manifest:
envsubst < gcsfuse-storage.yaml > gcsfuse-storage-updated.yaml kubectl apply -f gcsfuse-storage-updated.yaml
Preparare il modello e i dati
Riempi il bucket Cloud Storage con i pesi del modello e i set di dati. Puoi eseguire questi comandi localmente o su un pod GKE per popolare il bucket:
Clona il repository verl, prepara l'ambiente virtuale ed elabora il set di dati GSM8K:
git clone https://github.com/volcengine/verl.git git -C verl checkout ${VERL_REF} VENV_DIR=.venv python3 -m venv $VENV_DIR source $VENV_DIR/bin/activate pip install verl python verl/examples/data_preprocess/gsm8k.py --local_save_dir ~/data/gsm8kScarica il modello Qwen2.5-32B-Instruct utilizzando la CLI Hugging Face (richiede circa 66 GB di spazio su disco):
hf download Qwen/Qwen2.5-32B-Instruct --local-dir Qwen2.5-32B-InstructCarica il modello, i dati e il codice verl nel 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://${GS_BUCKET}/gsm8k/
Esegui il deployment della risorsa personalizzata RayCluster
Esegui il deployment di una risorsa personalizzata RayCluster, costituita da un pod head di sistema e da più pod worker supportati da GPU.
A4 e A3 Ultra
Seleziona la modalità cluster GKE che hai utilizzato per creare il cluster:
Autopilot
Esegui il deployment di RayCluster. Salva il seguente codice in
ray-cluster-auto.yaml:Applica il RayCluster:
envsubst < ray-cluster-auto.yaml > ray-cluster-auto-updated.yaml kubectl apply -f ray-cluster-auto-updated.yaml
Standard
Esegui il deployment di RayCluster. Salva la seguente configurazione in
ray-cluster-standard.yaml:Applica il RayCluster:
envsubst < ray-cluster-standard.yaml > ray-cluster-updated.yaml kubectl apply -f ray-cluster-updated.yaml
A4X
Crea
ResourceClaimTemplateRDMA eComputeDomainNVIDIA. Ogni pod worker GPU rivendica quattro NIC RDMA (tutte le guide del suo nodo) e un canale IMEX. Salva il seguente manifest incompute-domain-a4x.yaml:apiVersion: resource.k8s.io/v1 kind: ResourceClaimTemplate metadata: name: verl-rdma-nic namespace: ${NAMESPACE} spec: spec: devices: requests: - name: nic exactly: deviceClassName: mrdma.google.com allocationMode: ExactCount count: 1 --- apiVersion: resource.nvidia.com/v1beta1 kind: ComputeDomain metadata: name: verl-compute-domain namespace: ${NAMESPACE} spec: numNodes: ${NUM_GPU_NODES} channel: resourceClaimTemplate: name: verl-compute-domain-channelApplica il manifest:
kubectl apply -f compute-domain-a4x.yamlEsegui il deployment di RayCluster. Il pod Ray head viene eseguito su un nodo A4X senza richiedere GPU (poiché l'immagine è solo
arm64). Salva le seguenti configurazioni inray-cluster-a4x.yaml:apiVersion: ray.io/v1 kind: RayCluster metadata: name: gb200-ray-cluster namespace: ${NAMESPACE} spec: rayVersion: '2.49.0' headGroupSpec: rayStartParams: dashboard-host: '0.0.0.0' num-cpus: "0" template: metadata: annotations: gke-gcsfuse/volumes: "true" spec: serviceAccountName: ${KSA_NAME} nodeSelector: cloud.google.com/gke-accelerator: nvidia-gb200 tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule - key: kubernetes.io/arch operator: Exists effect: NoSchedule containers: - name: ray-head image: ${VERL_IMAGE} lifecycle: postStart: exec: command: - /bin/bash - -c - pip3 install --quiet TransferQueue==0.1.8 ports: - containerPort: 6379 name: gcs-server - containerPort: 8265 name: dashboard - containerPort: 10001 name: client resources: limits: cpu: "12" memory: 32Gi ephemeral-storage: 20Gi requests: cpu: "12" memory: 32Gi ephemeral-storage: 20Gi volumeMounts: - mountPath: /tmp/ray name: ray-logs - name: training-bucket-vol mountPath: /data volumes: - name: ray-logs emptyDir: {} - name: training-bucket-vol persistentVolumeClaim: claimName: training-bucket-pvc workerGroupSpecs: - replicas: ${NUM_GPU_NODES} minReplicas: ${NUM_GPU_NODES} maxReplicas: ${NUM_GPU_NODES} groupName: gpu-group rayStartParams: num-cpus: "120" template: metadata: annotations: gke-gcsfuse/volumes: "true" spec: serviceAccountName: ${KSA_NAME} nodeSelector: cloud.google.com/gke-accelerator: nvidia-gb200 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: ray.io/group: gpu-group topologyKey: kubernetes.io/hostname tolerations: - key: nvidia.com/gpu operator: Exists effect: NoSchedule - key: kubernetes.io/arch operator: Exists effect: NoSchedule containers: - name: ray-worker image: ${VERL_IMAGE} lifecycle: postStart: exec: command: - /bin/bash - -c - pip3 install --quiet TransferQueue==0.1.8 env: - name: LD_LIBRARY_PATH value: /usr/local/nvidia/lib64 resources: limits: cpu: "120" memory: 600Gi nvidia.com/gpu: "4" ephemeral-storage: 500Gi requests: cpu: "120" memory: 600Gi nvidia.com/gpu: "4" ephemeral-storage: 500Gi claims: - name: rdma-nic-0 - name: rdma-nic-1 - name: rdma-nic-2 - name: rdma-nic-3 - name: compute-domain-channel volumeMounts: - name: nvidia mountPath: /usr/local/nvidia - name: gib mountPath: /usr/local/gib - name: shared-memory mountPath: /dev/shm - name: ray-tmp-storage mountPath: /tmp - name: training-bucket-vol mountPath: /data resourceClaims: - name: rdma-nic-0 resourceClaimTemplateName: verl-rdma-nic - name: rdma-nic-1 resourceClaimTemplateName: verl-rdma-nic - name: rdma-nic-2 resourceClaimTemplateName: verl-rdma-nic - name: rdma-nic-3 resourceClaimTemplateName: verl-rdma-nic - name: compute-domain-channel resourceClaimTemplateName: verl-compute-domain-channel volumes: - name: gib hostPath: path: /home/kubernetes/bin/gib - name: nvidia hostPath: path: /home/kubernetes/bin/nvidia - name: shared-memory emptyDir: medium: Memory sizeLimit: 200Gi - name: ray-tmp-storage emptyDir: {} - name: training-bucket-vol persistentVolumeClaim: claimName: training-bucket-pvcApplica il manifest RayCluster:
envsubst < ray-cluster-a4x.yaml | kubectl apply -f -Attendi che un pod head e quattro pod worker siano nello stato
Running:kubectl get pods -w
Avvia il job GRPO
Configura e invia il job di addestramento per l'apprendimento per rinforzo:
A4 e A3 Ultra
Configura il port forwarding al nodo della dashboard Ray. Utilizza una finestra del terminale separata per questa operazione, poiché questo comando bloccherà il terminale per tutto il tempo in cui è in esecuzione. Utilizza Ctrl+C per interromperlo:
kubectl port-forward svc/b200-ray-cluster-head-svc 8265:8265Ispeziona il manifest
runtime-env.yaml:Se utilizzi le GPU H200, modifica
NCCL_TUNER_CONFIG_PATHin/usr/local/gib/configs/tuner_config_a3u.txtpb.Questo file viene utilizzato dal client Ray. Non devi applicare questo manifest al cluster.
Invia il job utilizzando
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=/data/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 \ trainer.default_local_dir=/data/verl/checkpoints \ algorithm.adv_estimator=grpo \ actor_rollout_ref.rollout.n=8 \ trainer.total_epochs=2"Monitora i log nella dashboard Ray o nell'output della console. Cerca
critic/score/meanper aumentare, indicando l'apprendimento.Al termine dell'addestramento, i checkpoint del modello addestrato si trovano in
gs://$GS_BUCKET/verl/checkpoints.
A4X
Recupera il nome del pod principale di Ray:
export HEAD_POD=$(kubectl get pod -n ${NAMESPACE} -l ray.io/node-type=head -o jsonpath='{.items[0].metadata.name}')Configura il file dell'ambiente di runtime Ray direttamente sul pod head:
kubectl exec ${HEAD_POD} -c ray-head -- bash -c 'mkdir -p /tmp/submit && cat > /tmp/submit/runtime-env.yaml <<EOF working_dir: "." env_vars: PYTHONPATH: "/data/verl" LD_LIBRARY_PATH: "/usr/local/nvidia/lib64:/usr/local/gib/lib64" NCCL_DEBUG: "INFO" NCCL_ENV_PLUGIN: "gcp" HF_HOME: "/data/huggingface_cache" GLOO_SOCKET_IFNAME: "eth0" EOF'Invia il job di addestramento GRPO eseguendolo sul pod head di Ray:
kubectl exec ${HEAD_POD} -c ray-head -- bash -c 'cd /tmp/submit && \ ray job submit --runtime-env runtime-env.yaml --no-wait -- \ python3 -m verl.trainer.main_ppo \ algorithm.adv_estimator=grpo \ 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=/data/Qwen2.5-32B-Instruct \ actor_rollout_ref.actor.optim.lr=1e-5 \ actor_rollout_ref.actor.ppo_mini_batch_size=64 \ actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=8 \ actor_rollout_ref.actor.use_kl_loss=True \ actor_rollout_ref.actor.strategy=fsdp2 \ actor_rollout_ref.rollout.name=vllm \ actor_rollout_ref.rollout.tensor_model_parallel_size=4 \ actor_rollout_ref.rollout.gpu_memory_utilization=0.6 \ actor_rollout_ref.rollout.n=8 \ actor_rollout_ref.rollout.log_prob_micro_batch_size_per_gpu=16 \ actor_rollout_ref.ref.log_prob_micro_batch_size_per_gpu=16 \ algorithm.kl_ctrl.kl_coef=0.001 \ trainer.logger=console \ trainer.n_gpus_per_node=4 \ trainer.nnodes=4 \ trainer.save_freq=10 \ trainer.test_freq=10 \ trainer.total_epochs=2 \ trainer.default_local_dir=/data/verl/checkpoints'Monitora i log del job (utilizzando l'ID univoco restituito da
ray job submit):kubectl exec ${HEAD_POD} -c ray-head -- ray job logs <var>JOB_ID</var> --followSostituisci
JOB_ID. Verifica che NVLink cross-node sia attivo cercando le righe NCCL nei log contenentivia P2P/MNNVL.
Esegui la pulizia
Per evitare che ti vengano addebitati dei costi, elimina le risorse:
A4 e A3 Ultra
kubectl delete raycluster b200-ray-cluster
gcloud container clusters delete ${CLUSTER_NAME} --location=${CONTROL_PLANE_REGION}
gcloud storage rm -r gs://${GS_BUCKET}
A4X
kubectl delete raycluster gb200-ray-cluster
kubectl delete computedomain verl-compute-domain
gcloud storage rm -r gs://${GS_BUCKET}
gcloud container clusters delete ${CLUSTER_NAME} --location=${CONTROL_PLANE_REGION}
Passaggi successivi
- Scopri di più su Ray su GKE
- Scopri di più sulla creazione di cluster A4X su GKE
- Esplora la documentazione di VERL