Questo tutorial mostra come orchestrare un ambiente di addestramento distribuito per il reinforcement learning 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.
Questo tutorial si concentra sulla pipeline di addestramento dell'ottimizzazione relativa dei criteri di 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 apprendimento per rinforzo (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.
Sfondo
Le sezioni seguenti forniscono una breve panoramica dei concetti utilizzati in questo tutorial.
Apprendimento per rinforzo
L'RL insegna ai modelli attraverso l'esperienza, l'esplorazione e il feedback, anziché l'imitazione statica. Mentre il pre-addestramento insegna a un modello cosa dire, l'apprendimento per rinforzo, in particolare 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?
Volcano Engine Reinforcement Learning (verl)
verl è un framework ad alte prestazioni progettato per gestire i complessi pattern di memoria e calcolo dell'RL basato su LLM.
Per saperne di più, consulta verl.
Ottimizzazione delle policy relative al gruppo (GRPO)
GRPO, un algoritmo reso popolare da DeepSeek, offre un'alternativa efficiente in termini 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.
Obiettivi
Questo tutorial mostra come configurare l'apprendimento per rinforzo su GKE con verl completando i seguenti passaggi:
- Configura un cluster GKE con GPU B200 o 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 workload.
-
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 abilitata 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 abilitata 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 le GPU B200 e H200. Per saperne di più, consulta Pianificare la quota di GPU e Quota di GPU.
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 seguenti variabili di ambiente:
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_VERSIONSostituisci i seguenti valori:
CONTROL_PLANE_LOCATION: la regione Compute Engine per il control plane del cluster GKE.GPU_TYPE: l'acceleratore che hai prenotato nella prenotazione di capacità di Compute Engine. Deve essere uno dei seguenti valori:nvidia-b200: NVIDIA B200 (180GB)nvidia-h200-141gb: NVIDIA H200 (141GB)
NODE_LOCATION: la zona per i nodi GKE. Seleziona una zona in cui sono disponibili le GPU NVIDIA B200 o H200.CLUSTER_NAME: il nome del tuo cluster GKE.BUCKET_NAME: il nome di base del bucket Cloud Storage. Non è necessario specificare il prefissogs://.YOUR_HUGGING_FACE_TOKEN: il token Hugging Face per l'accesso al modello.MACHINE_TYPE: il tipo di macchina da utilizzare. Le opzioni valide sonoc2standard8oc2standard16.GKE_VERSION: la versione di GKE da utilizzare:- Per le GPU NVIDIA B200 (180 GB), utilizza
1.32.2-gke.1422000o versioni successive. - Per le GPU NVIDIA H200 (141 GB), utilizza
1.31.4-gke.1183000o versioni successive.
- Per le GPU NVIDIA B200 (180 GB), utilizza
Crea le seguenti variabili di ambiente per la rete:
export GVNIC_NETWORK_PREFIX="GVNIC-NAME" export RDMA_NETWORK_PREFIX="RDMA-NAME"Sostituisci i seguenti valori:
GVNIC-NAME: il prefisso per il nome della rete gVNIC. Puoi utilizzare qualsiasi prefisso.RDMA-NAME: il prefisso per la rete di accesso diretto alla memoria (RDMA) remota. Puoi utilizzare qualsiasi prefisso.
Configurazione dell'infrastruttura
In questa sezione crei una rete RDMA e un cluster GKE.
Crea la rete RDMA e le subnet
Crea una rete VPC per l'interfaccia 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/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=${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 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
Puoi impostare verl in un cluster GKE Autopilot o Standard. Ti consigliamo di utilizzare un cluster Autopilot per un'esperienza Kubernetes completamente gestita. Per scegliere la modalità operativa GKE più adatta ai tuoi workload, consulta Scegliere una modalità operativa GKE.
Autopilot
Crea un cluster Autopilot:
gcloud container clusters create-auto ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_LOCATION} \ --enable-multi-networking \ --enable-ray-operatorRecupera le credenziali per il tuo cluster:
gcloud container clusters get-credentials ${CLUSTER_NAME} \ --location=${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_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-autoscalingRecupera le credenziali per il tuo cluster:
gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${ZONE}Crea il pool di nodi GPU (utilizzando istanze spot per l'efficienza in termini di costi):
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-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
Configurare i mapping di rete
Ispeziona il manifest
network-mapping.yaml:Applica il manifest:
kubectl apply -f network-mapping.yaml
Preparare i dati e lo spazio di archiviazione
Crea un bucket Cloud Storage:
gcloud storage buckets create gs://${GS_BUCKET} --location=${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:
kubectl apply -f gcsfuse-storage.yaml
Prepara il modello e i dati
Puoi eseguire questi comandi localmente o su un pod GKE per popolare il bucket.
Clona il repository verl:
git clone https://github.com/volcengine/verl.gitScarica il modello Qwen2.5-32B-Instruct utilizzando Hugging Face CLI:
huggingface-cli download Qwen/Qwen2.5-32B-Instruct --local-dir Qwen2.5-32B-InstructPreelabora il set di dati GSM8K:
python examples/data_preprocess/gsm8k.py --local_save_dir ~/data/gsm8kCarica 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_BUCKET}
Esegui il deployment della risorsa personalizzata RayCluster
Esegui il deployment di una risorsa personalizzata RayCluster, che in genere è costituita da un pod di sistema e più pod worker.
Autopilot
Esegui il deployment di RayCluster. Salva quanto segue in
ray-cluster-auto.yaml:Applica il RayCluster:
kubectl apply -f ray-cluster.yaml
Standard
Esegui il deployment di RayCluster. Salva quanto segue in
ray-cluster.yaml:Applica il RayCluster:
kubectl apply -f ray-cluster.yaml
Avvia il job GRPO
Configura il port forwarding al nodo della dashboard Ray:
kubectl port-forward svc/b200-ray-cluster-head-svc 8265:8265Ispeziona il manifest
runtime-env.yaml:Se utilizzi GPU H200, modifica
NCCL_TUNER_CONFIG_PATHin/usr/local/gib/configs/tuner_config_a3u.txtpb.Questo file viene utilizzato dal client Ray. Non è necessario 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=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.logMonitora i log nella dashboard Ray o nell'output. Cerca
critic/score/meanper aumentare, indicando l'apprendimento.
Esegui la pulizia
Per evitare che ti vengano addebitati dei costi, elimina le risorse:
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}