En este instructivo, se muestra cómo organizar un entorno de entrenamiento distribuido para el aprendizaje por refuerzo en Google Kubernetes Engine (GKE). Usarás Ray y el framework de verl (Volcano Engine Reinforcement Learning) para configurar un entorno de entrenamiento distribuido y ajustar un modelo de Qwen2.5-32B-Instruct en el conjunto de datos de GSM8K.
Este instructivo se centra en la canalización de entrenamiento de la optimización de políticas relativas de grupos (GRPO) en GKE con Ray y verl. GRPO es un algoritmo de aprendizaje por refuerzo diseñado para mejorar la capacidad de razonamiento de un modelo. Este algoritmo con uso eficiente de la memoria simplifica el proceso de aprendizaje por refuerzo (RL) eliminando el crítico, o modelo de valor, y usando un cálculo relativo basado en grupos en su lugar.
Este instructivo es un buen punto de partida si necesitas configurar un entorno de entrenamiento distribuido en el que los datos, los pesos del modelo y el motor de entrenamiento estén desvinculados para mejorar la eficiencia.
Este instructivo admite las siguientes arquitecturas de GPU:
- Nodos de GPU basados en Intel o AMD: Configura y escala con GPUs NVIDIA B200 o H200, usando la Asignación dinámica de recursos (DRA) de GKE para la ruta de Autopilot.
- Nodos A4X (GB200) basados en Arm: Configura y escala con los superchips NVIDIA GB200 Grace Blackwell, usando la asignación dinámica de recursos (DRA) de GKE y NVLink de varios nodos (IMEX).
Fondo
En las siguientes secciones, se proporciona una breve descripción general de los conceptos que se usan en este instructivo.
Aprendizaje por refuerzo (RL)
El RL enseña a los modelos a través de la experiencia, la exploración y la retroalimentación, en lugar de la imitación estática. Aunque el entrenamiento previo le enseña a un modelo qué decir, el aprendizaje por refuerzo con retroalimentación humana (RLHF) le enseña a ser útil, seguro y lógico. El RL sirve como puente entre un modelo base y un modelo ajustado para un caso de uso especializado.
Para obtener más información, consulta ¿Qué es el aprendizaje por refuerzo?
Optimización de políticas relativas al grupo (GRPO)
GRPO, un algoritmo popularizado por DeepSeek, ofrece una alternativa con uso eficiente de la memoria a la optimización de políticas proximales (PPO) para la alineación de LLM, ya que quita el modelo de crítico. En lugar de una red de críticos, el GRPO genera un grupo de respuestas para la misma instrucción y usa la recompensa promedio de ese grupo como referencia.
Para obtener más información, consulta GRPO.
Volcano Engine Reinforcement Learning (verl)
verl es un framework de alto rendimiento diseñado para controlar los patrones complejos de memoria y procesamiento del RL basado en LLM.
Para obtener más información, consulta verl.
Objetivos
En este instructivo, se muestra cómo configurar el aprendizaje por refuerzo en GKE con verl. Para ello, completa los siguientes pasos:
- Configura un clúster de GKE con A4X (Superchips GB200), A4 (GPU B200) o A3 Ultra (GPU H200).
- Configurar KubeRay para administrar un clúster de Ray distribuido
- Usa Cloud Storage FUSE para activar un bucket de Cloud Storage en todos los nodos.
- Ejecuta un trabajo de entrenamiento de GRPO con verl para alinear el modelo Qwen2.5-32B-Instruct con el conjunto de datos GSM8K.
Antes de comenzar
- En este instructivo, se usa Cloud Shell, que incluye Google Cloud CLI y
kubectlpreinstalados. Si no usas Cloud Shell, instala e inicializa Google Cloud CLI, y instalakubectl.
- Accede a tu cuenta de Google Cloud . Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
-
Instala Google Cloud CLI.
-
Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente comando:
gcloud init -
Crea o selecciona un Google Cloud proyecto.
Roles necesarios para seleccionar o crear un proyecto
- Selecciona un proyecto: Para seleccionar un proyecto, no se requiere un rol de IAM específico. Puedes seleccionar cualquier proyecto en el que se te haya otorgado un rol.
-
Crea un proyecto: Para crear un proyecto, necesitas el rol de Creador de proyectos (
roles/resourcemanager.projectCreator), que contiene el permisoresourcemanager.projects.create. Obtén más información para otorgar roles.
-
Crea un proyecto de Google Cloud :
gcloud projects create PROJECT_ID
Reemplaza
PROJECT_IDpor un nombre para el proyecto de Google Cloud que estás creando. -
Selecciona el proyecto de Google Cloud que creaste:
gcloud config set project PROJECT_ID
Reemplaza
PROJECT_IDpor el nombre de tu proyecto de Google Cloud .
-
Verifica que la facturación esté habilitada para tu proyecto de Google Cloud .
Habilita las APIs necesarias, si aún no están habilitadas:
Roles necesarios para habilitar las APIs
Para habilitar APIs, necesitas el permiso
serviceusage.services.enable. Si creaste el proyecto, es probable que ya tengas este permiso a través del rol de propietario (roles/owner). De lo contrario, puedes obtenerlo a través del rol de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin). Obtén más información para otorgar roles.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Instala Google Cloud CLI.
-
Si usas un proveedor de identidad externo (IdP), primero debes acceder a la gcloud CLI con tu identidad federada.
-
Para inicializar gcloud CLI, ejecuta el siguiente comando:
gcloud init -
Crea o selecciona un Google Cloud proyecto.
Roles necesarios para seleccionar o crear un proyecto
- Selecciona un proyecto: Para seleccionar un proyecto, no se requiere un rol de IAM específico. Puedes seleccionar cualquier proyecto en el que se te haya otorgado un rol.
-
Crea un proyecto: Para crear un proyecto, necesitas el rol de Creador de proyectos (
roles/resourcemanager.projectCreator), que contiene el permisoresourcemanager.projects.create. Obtén más información para otorgar roles.
-
Crea un proyecto de Google Cloud :
gcloud projects create PROJECT_ID
Reemplaza
PROJECT_IDpor un nombre para el proyecto de Google Cloud que estás creando. -
Selecciona el proyecto de Google Cloud que creaste:
gcloud config set project PROJECT_ID
Reemplaza
PROJECT_IDpor el nombre de tu proyecto de Google Cloud .
-
Verifica que la facturación esté habilitada para tu proyecto de Google Cloud .
Habilita las APIs necesarias, si aún no están habilitadas:
Roles necesarios para habilitar las APIs
Para habilitar APIs, necesitas el permiso
serviceusage.services.enable. Si creaste el proyecto, es probable que ya tengas este permiso a través del rol de propietario (roles/owner). De lo contrario, puedes obtenerlo a través del rol de administrador de Service Usage (roles/serviceusage.serviceUsageAdmin). Obtén más información para otorgar roles.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Otorga roles a tu cuenta de usuario. Ejecuta el siguiente comando una vez para cada uno de los siguientes roles de IAM:
roles/container.admin, roles/iam.serviceAccountAdmin, roles/storage.admin, roles/iam.serviceAccountUsergcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
Reemplaza lo siguiente:
PROJECT_ID: ID del proyectoUSER_IDENTIFIER: Es el identificador de tu cuenta de usuario de . Por ejemplo,myemail@example.com.ROLE: Es el rol de IAM que otorgas a tu cuenta de usuario.
- Crea una cuenta de Hugging Face, si todavía no la tienes.
- Asegúrate de tener un token de Hugging Face.
- Asegúrate de que tu proyecto tenga la cuota suficiente para A4X (superchips GB200), A4 (GPU B200) o A3 Ultra (GPU H200). Para obtener más información, consulta Planifica la cuota de GPU y Cuota de GPU.
- Asegúrate de tener una reserva de capacidad activa para tu tipo de máquina de GPU. Para obtener más información, consulta Cómo reservar capacidad a través de tu equipo de cuentas.
- Para la configuración de A4X (GB200), asegúrate de tener instalado Helm.
Prepara el entorno
En este instructivo, usarás Cloud Shell.
Ve a la consola deGoogle Cloud .
En la parte superior de la ventana de la Google Cloud consola, haz clic en el botón Activar Cloud Shell.
Configura las variables de entorno:
A4 y A3 Ultra
Autopilot
Estándar
A4X
export PROJECT_ID=$(gcloud config get project) export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)") export CONTROL_PLANE_REGION=YOUR_REGION export NODE_ZONE=YOUR_ZONE export CLUSTER_NAME=YOUR_CLUSTER_NAME export KSA_NAME=YOUR_KSA_NAME export GS_BUCKET=YOUR_GCS_BUCKET-${PROJECT_ID} export NAMESPACE=default export GPU_TYPE=YOUR_GPU_TYPE export MACHINE_TYPE=YOUR_MACINE_TYPE export RESERVATION=YOUR_RESERVATION_NAME export HF_TOKEN=YOUR_HF_TOKEN # A4X (GB200 Superchips) only variables export NUM_GPU_NODES=4 export VERL_IMAGE=verlai/verl:vllm023.aarch64.dev1 export VERL_REF=ddbcdb7Reemplaza los siguientes valores:
YOUR_REGION: Es la región de Compute Engine para el plano de control del clúster de GKE.YOUR_ZONE: Es la zona en la que se reservan los nodos. Para obtener más información, consulta Disponibilidad de GPU.YOUR_CLUSTER_NAME: el nombre del clúster de GKE. Este nombre debe tener 40 caracteres o menos y estar compuesto por caracteres alfanuméricos en minúscula y guiones.YOUR_KSA_NAME: Es el nombre de tu cuenta de servicio de Kubernetes.YOUR_GCS_BUCKET: Es el nombre base de tu bucket de Cloud Storage. No es necesario especificar el prefijogs://.YOUR_GPU_TYPE: es el acelerador que reservaste en la reserva de capacidad de Compute Engine. Debe ser uno de los siguientes valores:nvidia-gb200: A4X (superchips GB200)nvidia-b200: A4 (GPU B200)nvidia-h200-141gb: A3 Ultra (GPU H200)
YOUR_MACHINE_TYPE: Es el tipo de máquina que se usará:- Para A4X (superchips GB200), usa
a4x-highgpu-4g. - Para A4 (GPU B200), usa
a4-highgpu-8go versiones posteriores. - Para A3 Ultra (GPU H200), usa
a3-ultragpu-8go una versión posterior.
- Para A4X (superchips GB200), usa
YOUR_CPU_MACHINE_TYPE: Es el tipo de máquina de Compute Engine para el grupo de nodos predeterminado de la CPU. Usa un tipo de máquinahighmemcon al menos 16 CPUs virtuales que sea compatible con la zona de tu clúster, comon4-highmem-16on2d-highmem-16.YOUR_RESERVATION_NAME: Es el nombre de tu reserva de capacidad.YOUR_HF_TOKEN: Es tu token de Hugging Face.- Usa las siguientes variables cuando configures tu entorno en clústeres de GKE Standard:
YOUR_GVNIC_NAME(solo para A4 o A3 Ultra): Es el prefijo del nombre de la red gVNIC. Puedes usar cualquier prefijo que desees.YOUR_RDMA_NAME(solo A4 o A3 Ultra): Es el prefijo de la red de acceso directo a la memoria remota (RDMA). Puedes usar cualquier prefijo que desees.
Clona el repositorio de ejemplo:
En el resto del instructivo, busca en tu clon del repositorio de muestra los archivos específicos que debes inspeccionar o aplicar.
Navega al directorio de trabajo del modo de GKE que elegiste:
A4 y A3 Ultra
Autopilot
Estándar
A4X
No es necesario cambiar el directorio. Puedes continuar directamente con la siguiente sección.
Configura la infraestructura
En esta sección, crearás redes de VPC estándar y el clúster de GKE.
Crea una red y subredes de RDMA (solo GKE Standard: A4 y A3 Ultra)
A4 y A3 Ultra
Autopilot
Esta sección solo es obligatoria para las GPU A4 y A3 Ultra de GKE Standard.
Si usas Autopilot, omite esta sección y continúa directamente con Crea un clúster de GKE. GKE aprovisiona automáticamente las redes y subredes de VPC necesarias, y usa DRANET administrado por GKE para asignar estos recursos a tus Pods. No es necesario que crees manualmente ninguna infraestructura de red.
Estándar
Crea una red de VPC para la interfaz de gVNIC:
Crea una red de VPC para RDMA:
Crea las 8 subredes de RDMA para las 8 GPUs:
A4X
Esta sección solo es obligatoria para las GPU A4 y A3 Ultra de GKE Standard.
Si usas GPUs A4X (GB200), omite esta sección y continúa directamente con
Crea un clúster de GKE. En el caso de las GPU A4X (GB200) o Autopilot, GKE crea las redes automáticamente cuando el grupo de nodos usa el perfil de red de aceleradores auto. El plano de Cluster Toolkit
habilita este perfil con la marca enable_dranet:true.
Crea un clúster de GKE
Crea un clúster de GKE que corresponda a tu arquitectura de GPU:
A4 y A3 Ultra
Selecciona el modo de clúster de GKE que quieres usar:
Autopilot
Crea un clúster de Autopilot:
Obtén credenciales para el clúster:
Estándar
Crea un clúster estándar:
Obtén credenciales para el clúster:
Crea el grupo de nodos de GPU. Estos grupos de nodos usan tu reserva para garantizar la disponibilidad. Comienzas con dos nodos:
Instala el instalador de RDMA de NCCL que se usa para los clústeres de Standard:
A4X
Crea un clúster de GKE y un grupo de nodos con el blueprint de Cluster Toolkit
gke-a4x. El blueprint aprovisiona el clúster de GKE, incluido el grupo de nodos A4X vinculado a tu reserva, las redes de aceleradores (una gVNIC adicional y cuatro carriles RDMA) y el controlador DRANET administrado que expone las NIC CX-7 como dispositivos DRA.Usa las instrucciones de implementación del plano para configurar tus parámetros (como
PROJECT_ID,CONTROL_PLANE_REGION,NODE_ZONE, reserva yNUM_GPU_NODES) y, luego, implementa el clúster. Como alternativa, puedes seguir la guía de creación de clúster de GKE A4X para crear un clúster de forma manual.- Obtén credenciales para el clúster:
gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${CONTROL_PLANE_REGION}Verifica que el clúster exponga NIC de RDMA a través de DRA:
kubectl get deviceclassesEl resultado debe incluir
mrdma.google.com.Verifica que los nodos A4X estén presentes:
kubectl get nodes -l cloud.google.com/gke-accelerator=nvidia-gb200Instala el complemento NCCL de gIB (variante A4X):
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-rdma/nccl-rdma-installer-a4x.yamlInstala el controlador de DRA de NVIDIA, que proporciona canales
ComputeDomain(IMEX) para NVLink de varios nodos: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=ExistsInstala el operador de KubeRay, con alcance al espacio de nombres de la carga de trabajo:
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 asignaciones de red (solo GKE Standard: A4 y A3 Ultra)
A4 y A3 Ultra
Autopilot
Este paso es obligatorio para las configuraciones de GPU de GKE Standard (solo A4 y A3 Ultra). Si usas A4X (GB200), GKE administra las interfaces de red automáticamente, por lo que puedes omitir esta sección.
Estándar
Inspecciona el manifiesto
network-mapping.yaml:Aplica el manifiesto
A4X
Este paso es obligatorio para las configuraciones de GPU de GKE Standard (solo A4 y A3 Ultra). Si usas A4X (GB200), GKE administra las interfaces de red automáticamente, por lo que puedes omitir esta sección.
Prepara los datos y el almacenamiento
Configura los recursos de Cloud Storage y Kubernetes:
Crea un bucket de Cloud Storage:
Crea una cuenta de servicio de Kubernetes (KSA) y vincúlala al bucket:
Crea el Secret para Hugging Face:
Inspecciona el manifiesto
gcsfuse-storage.yaml:Aplica el manifiesto
Configura DRANET
Configura tu DRANET:
A4 y A3 Ultra
Autopilot
Crea el manifiesto de ComputeClass:
Aplica el manifiesto
computeclass-dranet.yaml(creado en el paso anterior) y el manifiestoresourceclaim-dranet.yaml(incluido en el repositorio de muestra):
Estándar
No se requiere configuración de DRANET. Puedes continuar directamente con la siguiente sección.
A4X
Cluster Toolkit establece DRANET. Puedes continuar directamente con la siguiente sección.
Prepara el modelo y los datos
Propaga tu bucket de Cloud Storage con los pesos y los conjuntos de datos del modelo. Puedes ejecutar estos comandos de forma local o en un Pod de GKE para completar el bucket:
A4 y A3 Ultra
Autopilot
Inspecciona el manifiesto
data-prep-job.yaml, que configura el trabajo de preparación de datos:Inicia el trabajo:
Verifica el estado del Pod:
Después de que el Pod
data-prep-jobalcance el estadoRunning, presiona Control + C para dejar de supervisar.Supervisa el trabajo:
El comando
kubectl logsdevuelve un resultado mínimo o nulo hasta que el Pod alcanza el estadoRunning.
Estándar
Inspecciona el manifiesto
data-prep-job.yaml, que configura el trabajo de preparación de datos:Inicia el trabajo:
Supervisa el trabajo:
A4X
Clona el repositorio de verl, prepara el entorno virtual y procesa el conjunto de datos 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/gsm8kDescarga el modelo Qwen2.5-32B-Instruct con la CLI de Hugging Face (esta descarga requiere alrededor de 66 GB de espacio en el disco):
hf download Qwen/Qwen2.5-32B-Instruct --local-dir Qwen2.5-32B-InstructSube el modelo, los datos y el código de Verl a tu bucket de 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/
Implementa el recurso personalizado RayCluster
Implementa un recurso personalizado RayCluster, que consta de un Pod principal del sistema y varios Pods de trabajador respaldados por GPU.
A4 y A3 Ultra
Selecciona el modo de clúster de GKE que usaste para crear tu clúster:
Autopilot
Inspecciona la carga de trabajo de RayCluster:
Aplica el RayCluster:
Estándar
Inspecciona la carga de trabajo de RayCluster:
Aplica el RayCluster:
A4X
Crea el
ResourceClaimTemplatede RDMA y elComputeDomainde NVIDIA. Cada Pod de trabajador de GPU reclama cuatro NIC de RDMA (todos los rieles de su nodo) y un canal de IMEX. Guarda el siguiente manifiesto encompute-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-channelAplica el manifiesto
kubectl apply -f compute-domain-a4x.yamlImplementa el RayCluster. El Pod principal de Ray se ejecuta en un nodo A4X sin solicitar GPUs (ya que la imagen es solo para
arm64). Guarda los siguientes parámetros de configuración enray-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-pvcAplica el manifiesto de RayCluster:
envsubst < ray-cluster-a4x.yaml | kubectl apply -f -Espera hasta que un Pod principal y cuatro Pods de trabajador estén en el estado
Running:kubectl get pods -w
Inicia el trabajo de GRPO
Configura y envía el trabajo de entrenamiento de aprendizaje por refuerzo:
A4 y A3 Ultra
Selecciona el modo de clúster de GKE que usaste para crear tu clúster:
Autopilot
Configura el cliente de Ray:
Recupera el servicio de encabezado de Ray:
Configura la redirección de puertos al nodo del panel de Ray. El proceso se ejecuta en segundo plano, por lo que puedes seguir ejecutando comandos en la misma sesión de terminal.
Para detener el bucle de redirección de puertos, usa el comando
kill ${PF_LOOP_PID}.Inspecciona el manifiesto
runtime-env.yaml:Si usas GPUs H200, cambia el valor de la variable de entorno
NCCL_CONF_FILEpor/usr/local/gib/configs/nccl.a3u.conf.El cliente de Ray usa este archivo. No es necesario que apliques este manifiesto al clúster.
Envía el trabajo con el comando
ray job submit:Supervisa los registros del trabajo de entrenamiento y busca la métrica
critic/score/meanpara ver si aumenta, lo que indica que el modelo está aprendiendo:- Panel de Ray:
- Abre
http://localhost:8265en tu navegador. Si usas Cloud Shell, haz clic en Vista previa en la Web, selecciona Cambiar puerto y, luego, ingresa8265. - Ve a la pestaña Trabajos.
- Haz clic en tu ID de tarea.
- Filtra los registros por la palabra clave
criticpara inspeccionarcritic/score/mean.
- Abre
Terminal: Debido a que el trabajo se envía de forma asíncrona con la marca
--no-wait, transmite los registros del trabajo en tu terminal ejecutando el siguiente comando:
- Panel de Ray:
Una vez que finalice el entrenamiento, verifica que los puntos de control del modelo se hayan guardado en tu bucket de Cloud Storage. Para ello, enumera el contenido del directorio:
Como alternativa, puedes ver los puntos de control en la consola de Google Cloud . Para ello, ve a Cloud Storage > Buckets, selecciona
YOUR_GCS_BUCKETy abre la carpetaverl/checkpoints.
Estándar
Configura el cliente de Ray:
Recupera el servicio de encabezado de Ray:
Configura la redirección de puertos al nodo del panel de Ray. El proceso se ejecuta en segundo plano, por lo que puedes seguir ejecutando comandos en la misma sesión de terminal.
Para detener el bucle de reenvío de puertos, usa el comando
kill ${PF_PID}.Inspecciona el manifiesto
runtime-env.yaml:Si usas GPUs H200, cambia el valor de la variable de entorno
NCCL_TUNER_CONFIG_PATHpor/usr/local/gib/configs/tuner_config_a3u.txtpb.El cliente de Ray usa este archivo. No es necesario que apliques este manifiesto al clúster.
Envía el trabajo:
Supervisa los registros del trabajo de entrenamiento y busca que aumente la métrica
critic/score/mean, lo que indica que el modelo está aprendiendo:- Panel de Ray:
- Abre
http://localhost:8265en tu navegador. Si usas Cloud Shell, haz clic en Vista previa en la Web, selecciona Cambiar puerto y, luego, ingresa8265. - Ve a la pestaña Trabajos.
- Haz clic en tu ID de tarea.
- Filtra los registros por la palabra clave
criticpara inspeccionar la métricacritic/score/mean.
- Abre
Resultado de la consola: Debido a que el trabajo se envía de forma asíncrona con la marca
--no-wait, transmite los registros del trabajo en tu terminal ejecutando el siguiente comando:
- Panel de Ray:
Una vez que finalice el entrenamiento, verifica que los puntos de control del modelo se hayan guardado en tu bucket de Cloud Storage. Para ello, enumera el contenido del directorio:
Como alternativa, consulta los puntos de control en la consola de Google Cloud en Cloud Storage > Buckets, selecciona
YOUR_GCS_BUCKETy abre la carpetaverl/checkpoints.
A4X
Obtén el nombre del Pod principal de Ray:
export HEAD_POD=$(kubectl get pod -n ${NAMESPACE} -l ray.io/node-type=head -o jsonpath='{.items[0].metadata.name}')Configura el archivo del entorno de ejecución de Ray directamente en el Pod principal:
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'Envía el trabajo de entrenamiento de GRPO ejecutándolo en el Pod principal de 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'Supervisa los registros del trabajo (con el ID único que muestra
ray job submit):kubectl exec ${HEAD_POD} -c ray-head -- ray job logs <var>JOB_ID</var> --followReemplaza
JOB_ID. Para confirmar que NVLink entre nodos esté activo, busca líneas de NCCL en los registros que contenganvia P2P/MNNVL.
Realiza una limpieza
Para evitar que se generen cobros, borra los recursos:
A4 y A3 Ultra
Autopilot
Si el bucle de reenvío de puertos aún se ejecuta en tu sesión en segundo plano, finalízalo:
Borra el clúster de Ray:
Borra Cloud Storage FUSE:
Borra los recursos de DRANET:
Borra el bucket de Cloud Storage:
Borra el clúster de GKE:
Estándar
Si el bucle de redirección de puertos aún se está ejecutando en tu sesión en segundo plano, finalízalo:
Borra el clúster de Ray:
Borra Cloud Storage FUSE:
Borra el bucket de Cloud Storage:
Borra el clúster de GKE:
Borra las redes y subredes de VPC:
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}
¿Qué sigue?
- Más información sobre Ray en GKE
- Más información sobre la creación de clústeres de A4X en GKE
- Explora la documentación de verl