Neste tutorial, mostramos como orquestrar um ambiente de treinamento distribuído para aprendizado por reforço no Google Kubernetes Engine (GKE). Você vai usar o Ray e o framework verl (Volcano Engine Reinforcement Learning) para configurar um ambiente de treinamento distribuído e ajustar um modelo Qwen2.5-32B-Instruct no conjunto de dados GSM8K.
Este tutorial se concentra no pipeline de treinamento de otimização de políticas relativas de grupo (GRPO, na sigla em inglês) no GKE com Ray e verl. O GRPO é um algoritmo de aprendizado por reforço projetado para melhorar a capacidade de raciocínio de um modelo. Esse algoritmo com uso eficiente de memória simplifica o processo de aprendizado por reforço (RL) eliminando o crítico ou o modelo de valor e usando um cálculo relativo baseado em grupo.
Este tutorial é um bom ponto de partida se você precisar configurar um ambiente de treinamento distribuído em que os dados, os pesos do modelo e o mecanismo de treinamento sejam dissociados para maior eficiência.
Este tutorial é compatível com as seguintes arquiteturas de GPU:
- Nós de GPU baseados em Intel ou AMD: configure e escalone usando GPUs NVIDIA B200 ou H200, com a alocação dinâmica de recursos (DRA) do GKE para o caminho do Autopilot.
- Nós A4X (GB200) baseados em Arm: configure e escalone usando os superchips NVIDIA GB200 Grace Blackwell, usando a alocação dinâmica de recursos (DRA) do GKE e o NVLink de vários nós (IMEX).
Contexto
As seções a seguir fornecem uma breve visão geral dos conceitos usados neste tutorial.
Aprendizado por reforço (RL)
A RL ensina modelos por experiência, exploração e feedback, em vez de imitação estática. Embora o pré-treinamento ensine ao modelo o que dizer, o aprendizado por reforço com feedback humano (RLHF) ensina como ser útil, seguro e lógico. O RL serve como ponte entre um modelo base e um modelo ajustado para um caso de uso especializado.
Para mais informações, consulte O que é aprendizado por reforço?
Otimização de política relativa de grupo (GRPO)
O GRPO, um algoritmo popularizado pela DeepSeek, oferece uma alternativa com eficiência de memória à otimização de política proximal (PPO) para o alinhamento de LLMs, removendo o modelo crítico. Em vez de uma rede de crítica, o GRPO gera um grupo de respostas para o mesmo comando e usa a recompensa média desse grupo como referência.
Para mais informações, consulte GRPO.
Volcano Engine Reinforcement Learning (verl)
O verl é um framework de alto desempenho projetado para lidar com os padrões complexos de memória e computação do RL baseado em LLM.
Para mais informações, consulte verl.
Objetivos
Neste tutorial, mostramos como configurar o aprendizado por reforço no GKE com o verl, concluindo as seguintes etapas:
- Configure um cluster do GKE com A4X (superchips GB200), A4 (GPUs B200) ou A3 Ultra (GPUs H200).
- Configurar o KubeRay para gerenciar um cluster do Ray distribuído.
- Use o Cloud Storage FUSE para montar um bucket do Cloud Storage em todos os nós.
- Execute um job de treinamento de GRPO usando verl para alinhar o modelo Qwen2.5-32B-Instruct com o conjunto de dados GSM8K.
Antes de começar
- Neste tutorial, usamos o Cloud Shell, que vem com a
Google Cloud CLI e o
kubectlpré-instalados. Se você não estiver usando o Cloud Shell, instale e inicialize a Google Cloud CLI e instale okubectl.
- Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloudagora, crie uma conta para avaliar o desempenho dos nossos produtos em situações reais. Clientes novos também recebem US $300 em créditos para executar, testar e implantar cargas de trabalho.
-
Instale a CLI do Google Cloud.
-
Ao usar um provedor de identidade (IdP) externo, primeiro faça login na CLI gcloud com sua identidade federada.
-
Para inicializar a CLI gcloud, execute o seguinte comando:
gcloud init -
Crie ou selecione um Google Cloud projeto.
Funções necessárias para selecionar ou criar um projeto
- Selecionar um projeto: não é necessário ter um papel específico do IAM para selecionar um projeto. É possível selecionar qualquer projeto em que você tenha um papel.
-
Criar um projeto: para criar um projeto, é preciso ter o papel de Criador de projetos
(
roles/resourcemanager.projectCreator), que contém a permissãoresourcemanager.projects.create. Saiba como conceder papéis.
-
Crie um projeto do Google Cloud :
gcloud projects create PROJECT_ID
Substitua
PROJECT_IDpor um nome para o projeto do Google Cloud que você está criando. -
Selecione o projeto do Google Cloud que você criou:
gcloud config set project PROJECT_ID
Substitua
PROJECT_IDpelo nome do projeto do Google Cloud .
-
Verifique se o faturamento está ativado para o projeto do Google Cloud .
Ative as APIs necessárias, caso alguma ainda não esteja ativada:
Funções necessárias para ativar APIs
Para ativar APIs, você precisa da permissão
serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de proprietário (roles/owner). Caso contrário, é possível conseguir essa permissão pelo papel de administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Instale a CLI do Google Cloud.
-
Ao usar um provedor de identidade (IdP) externo, primeiro faça login na CLI gcloud com sua identidade federada.
-
Para inicializar a CLI gcloud, execute o seguinte comando:
gcloud init -
Crie ou selecione um Google Cloud projeto.
Funções necessárias para selecionar ou criar um projeto
- Selecionar um projeto: não é necessário ter um papel específico do IAM para selecionar um projeto. É possível selecionar qualquer projeto em que você tenha um papel.
-
Criar um projeto: para criar um projeto, é preciso ter o papel de Criador de projetos
(
roles/resourcemanager.projectCreator), que contém a permissãoresourcemanager.projects.create. Saiba como conceder papéis.
-
Crie um projeto do Google Cloud :
gcloud projects create PROJECT_ID
Substitua
PROJECT_IDpor um nome para o projeto do Google Cloud que você está criando. -
Selecione o projeto do Google Cloud que você criou:
gcloud config set project PROJECT_ID
Substitua
PROJECT_IDpelo nome do projeto do Google Cloud .
-
Verifique se o faturamento está ativado para o projeto do Google Cloud .
Ative as APIs necessárias, caso alguma ainda não esteja ativada:
Funções necessárias para ativar APIs
Para ativar APIs, você precisa da permissão
serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de proprietário (roles/owner). Caso contrário, é possível conseguir essa permissão pelo papel de administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
Conceda papéis à sua conta de usuário. Execute uma vez o seguinte comando para cada um dos seguintes papéis do 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
Substitua:
PROJECT_ID: o ID do projeto.USER_IDENTIFIER: o identificador da sua conta de usuário . Por exemplo,myemail@example.com.ROLE: o papel do IAM que você concede à sua conta de usuário.
- Crie uma conta do Hugging Face caso ainda não tenha uma.
- Verifique se você tem um token do Hugging Face.
- Verifique se o projeto tem cota suficiente para A4X (superchips GB200), A4 (GPUs B200) ou A3 Ultra (GPUs H200). Para saber mais, consulte Planejar a cota de GPU e Cota de GPU.
- Verifique se você tem uma reserva de capacidade ativa para o tipo de máquina de GPU. Para mais informações, consulte Reservar capacidade com sua equipe de conta.
- Para a configuração do A4X (GB200), verifique se o Helm está instalado.
Preparar o ambiente
Neste tutorial, você vai usar o Cloud Shell.
Acesse o console doGoogle Cloud .
Na parte de cima da janela do console do Google Cloud , clique no botão Ativar o Cloud Shell.
Defina as variáveis de ambiente:
A4 e A3 Ultra
Piloto automático
Padrão
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=ddbcdb7Substitua os seguintes valores:
YOUR_REGION: a região do Compute Engine para o plano de controle do cluster do GKE.YOUR_ZONE: a zona em que os nós estão reservados. Para mais informações, consulte Disponibilidade de GPU.YOUR_CLUSTER_NAME: o nome do cluster do GKE. Esse nome precisa ter no máximo 40 caracteres e ser composto por caracteres alfanuméricos minúsculos e hifens.YOUR_KSA_NAME: o nome da conta de serviço do Kubernetes.YOUR_GCS_BUCKET: o nome base do bucket do Cloud Storage. Não é necessário especificar o prefixogs://.YOUR_GPU_TYPE: o acelerador que você reservou na reserva de capacidade do Compute Engine. Precisa ser um dos valores abaixo:nvidia-gb200: A4X (superchips GB200)nvidia-b200: A4 (GPUs B200)nvidia-h200-141gb: A3 Ultra (GPUs H200)
YOUR_MACHINE_TYPE: o tipo de máquina a ser usado:- Para A4X (superchips GB200), use
a4x-highgpu-4g. - Para A4 (GPUs B200), use
a4-highgpu-8gou mais recente. - Para A3 Ultra (GPUs H200), use
a3-ultragpu-8gou mais recente.
- Para A4X (superchips GB200), use
YOUR_CPU_MACHINE_TYPE: o tipo de máquina do Compute Engine para o pool de nós padrão da CPU. Use um tipo de máquinahighmemcom pelo menos 16 vCPUs que seja compatível com a zona do cluster, comon4-highmem-16oun2d-highmem-16.YOUR_RESERVATION_NAME: o nome da sua reserva de capacidade.YOUR_HF_TOKEN: seu token do Hugging Face.- Use as seguintes variáveis ao configurar o ambiente em clusters do GKE Standard:
YOUR_GVNIC_NAME(somente A4 ou A3 Ultra): o prefixo do nome da rede gVNIC. Você pode usar qualquer prefixo que quiser.YOUR_RDMA_NAME(somente A4 ou A3 Ultra): o prefixo da rede de acesso direto à memória remota (RDMA). Você pode usar qualquer prefixo que quiser.
Clone o repositório de amostra:
Acesse o diretório de trabalho do modo do GKE escolhido:
A4 e A3 Ultra
Piloto automático
Padrão
A4X
Não é necessário mudar o diretório. Você pode prosseguir diretamente para a próxima seção.
Configurar a infraestrutura
Nesta seção, você vai criar redes VPC padrão e o cluster do GKE.
Criar rede e sub-redes RDMA (GKE Standard - somente A4 e A3 Ultra)
A4 e A3 Ultra
Piloto automático
Esta seção é obrigatória apenas para GPUs GKE Standard A4 e A3 Ultra.
Se você usa o Autopilot, pule esta seção e vá direto para Criar um cluster do GKE. O GKE provisiona automaticamente as redes VPC e as sub-redes necessárias e usa a DRANET gerenciada pelo GKE para alocar esses recursos aos pods. Não é necessário criar manualmente nenhuma infraestrutura de rede.
Padrão
Crie uma rede VPC para a interface gVNIC:
Crie uma rede VPC para RDMA:
Crie as oito sub-redes RDMA para as oito GPUs:
A4X
Esta seção é obrigatória apenas para GPUs A4 e A3 Ultra do GKE Standard.
Se você usar GPUs A4X (GB200), pule esta seção e vá direto para
Criar um cluster do GKE. Para GPUs A4X (GB200) ou Autopilot, o GKE
cria as redes automaticamente quando o pool de nós usa o perfil de rede do acelerador
auto. O blueprint do Cluster Toolkit
ativa esse perfil usando a flag enable_dranet:true.
Criar um cluster do GKE
Crie um cluster do GKE correspondente à sua arquitetura de GPU:
A4 e A3 Ultra
Selecione o modo de cluster do GKE que você quer usar:
Piloto automático
Criar um cluster do Autopilot:
Receba as credenciais do cluster:
Padrão
Criar um cluster padrão
Receba as credenciais do cluster:
Crie o pool de nós de GPU. Esses pools de nós usam sua reserva para garantir a disponibilidade. Você começa com dois nós:
Instale o instalador do NCCL RDMA usado para clusters Standard:
A4X
Crie um cluster do GKE e um pool de nós usando o blueprint
gke-a4xdo Cluster Toolkit. O blueprint provisiona o cluster do GKE, incluindo o pool de nós A4X vinculado à sua reserva, as redes de aceleradores (uma gVNIC adicional e quatro trilhos RDMA) e o driver DRANET gerenciado que expõe as NICs CX-7 como dispositivos DRA.Use as instruções de implantação do blueprint para configurar os parâmetros (como
PROJECT_ID,CONTROL_PLANE_REGION,NODE_ZONE, reserva eNUM_GPU_NODES) e, em seguida, implante o cluster. Outra opção é seguir o guia de criação de cluster do GKE A4X para criar um cluster manualmente.- Receba as credenciais do cluster:
gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${CONTROL_PLANE_REGION}Verifique se o cluster expõe NICs de RDMA por meio da DRA:
kubectl get deviceclassesA saída precisa incluir
mrdma.google.com.Verifique se os nós A4X estão presentes:
kubectl get nodes -l cloud.google.com/gke-accelerator=nvidia-gb200Instale o plug-in NCCL do gIB (variante A4X):
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/master/gpudirect-rdma/nccl-rdma-installer-a4x.yamlInstale o driver NVIDIA DRA, que fornece canais
ComputeDomain(IMEX) para NVLink de vários nós: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=ExistsInstale o operador KubeRay, com escopo para o namespace da carga de trabalho:
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}}"
Configurar mapeamentos de rede (somente GKE Standard - A4 e A3 Ultra)
A4 e A3 Ultra
Piloto automático
Esta etapa é necessária para configurações de GPU do GKE Standard (somente A4 e A3 Ultra). Se você usa A4X (GB200), o GKE gerencia as interfaces de rede automaticamente. Portanto, pule esta seção.
Padrão
Inspecione o manifesto
network-mapping.yaml:Aplique o manifesto:
A4X
Esta etapa é necessária para configurações de GPU do GKE Standard (somente A4 e A3 Ultra). Se você usa o A4X (GB200), o GKE gerencia as interfaces de rede automaticamente. Portanto, pule esta seção.
Preparar dados e armazenamento
Configure os recursos do Cloud Storage e do Kubernetes:
Crie um bucket do Cloud Storage:
Crie uma conta de serviço do Kubernetes (KSA) e vincule-a ao bucket:
Crie o secret para o Hugging Face:
Inspecione o manifesto
gcsfuse-storage.yaml:Aplique o manifesto:
Configurar a DRANET
Configure sua DRANET:
A4 e A3 Ultra
Piloto automático
Crie o manifesto da ComputeClass:
Aplique o manifesto
computeclass-dranet.yaml(criado na etapa anterior) e o manifestoresourceclaim-dranet.yaml(incluído no repositório de exemplo):
Padrão
Não é necessário configurar a DRANET. Você pode prosseguir diretamente para a próxima seção.
A4X
DRANET é definido pelo Cluster Toolkit. Você pode passar direto para a próxima seção.
Preparar modelo e dados
Preencha o bucket do Cloud Storage com os pesos e conjuntos de dados do modelo. É possível executar esses comandos localmente ou em um pod do GKE para preencher o bucket:
A4 e A3 Ultra
Piloto automático
Inspecione o manifesto
data-prep-job.yaml, que configura o job de preparação de dados:Inicie o job:
Verifique o status do pod:
Depois que o pod
data-prep-jobatingir o statusRunning, pressione Control+C para parar de assistir.Monitore o job:
O comando
kubectl logsretorna uma saída mínima ou nenhuma saída até que o pod alcance o statusRunning.
Padrão
Inspecione o manifesto
data-prep-job.yaml, que configura o job de preparação de dados:Inicie o job:
Monitore o job:
A4X
Clone o repositório verl, prepare o ambiente virtual e processe o conjunto de dados 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/gsm8kFaça o download do modelo Qwen2.5-32B-Instruct usando a CLI do Hugging Face (o download requer cerca de 66 GB de espaço em disco):
hf download Qwen/Qwen2.5-32B-Instruct --local-dir Qwen2.5-32B-InstructFaça upload do modelo, dos dados e do código verl para o bucket do 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/
Implantar o recurso personalizado RayCluster
Implante um recurso personalizado RayCluster, que consiste em um pod principal do sistema e vários pods de worker com GPU.
A4 e A3 Ultra
Selecione o modo de cluster do GKE que você usou para criar o cluster:
Piloto automático
Inspecione a carga de trabalho do RayCluster:
Aplique o RayCluster:
Padrão
Inspecione a carga de trabalho do RayCluster:
Aplique o RayCluster:
A4X
Crie o
ResourceClaimTemplatede RDMA e oComputeDomainda NVIDIA. Cada pod de worker de GPU reivindica quatro NICs de RDMA (todos os rails do nó) e um canal IMEX. Salve o seguinte manifesto emcompute-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-channelAplique o manifesto:
kubectl apply -f compute-domain-a4x.yamlImplante o RayCluster. O pod principal do Ray é executado em um nó A4X sem solicitar GPUs, já que a imagem é apenas para
arm64. Salve as seguintes configurações emray-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-pvcAplique o manifesto do RayCluster:
envsubst < ray-cluster-a4x.yaml | kubectl apply -f -Aguarde até que um pod principal e quatro pods de worker estejam no estado
Running:kubectl get pods -w
Iniciar o job do GRPO
Configure e envie o job de treinamento de aprendizado por reforço:
A4 e A3 Ultra
Selecione o modo de cluster do GKE que você usou para criar o cluster:
Piloto automático
Configure o cliente do Ray:
Recupere o serviço do Ray Head:
Configure o encaminhamento de portas para o nó do painel do Ray. O processo é executado em segundo plano, para que você possa continuar executando comandos na mesma sessão do terminal.
Para interromper o loop de encaminhamento de porta, use o comando
kill ${PF_LOOP_PID}.Inspecione o manifesto
runtime-env.yaml:Se você estiver usando GPUs H200, mude o valor da variável de ambiente
NCCL_CONF_FILEpara/usr/local/gib/configs/nccl.a3u.conf.Esse arquivo é usado pelo cliente do Ray. Não é necessário aplicar esse manifesto ao cluster.
Envie o job usando o comando
ray job submit:Monitore os registros do job de treinamento e procure o aumento da métrica
critic/score/mean, o que indica que o modelo está aprendendo:- Painel do Ray:
- Abra
http://localhost:8265no seu navegador. Se você estiver usando o Cloud Shell, clique em Visualização da Web, selecione Alterar porta e insira8265. - Acesse a guia Jobs.
- Clique no código da tarefa.
- Filtre os registros pela palavra-chave
criticpara inspecionarcritic/score/mean.
- Abra
Terminal: como o job é enviado de forma assíncrona com a flag
--no-wait, transmita os registros do job no terminal executando o seguinte comando:
- Painel do Ray:
Depois que o treinamento terminar, verifique se os checkpoints do modelo foram salvos no bucket do Cloud Storage listando o conteúdo do diretório:
Como alternativa, confira os checkpoints no console do Google Cloud acessando Cloud Storage > Buckets, selecionando
YOUR_GCS_BUCKETe abrindo a pastaverl/checkpoints.
Padrão
Configure o cliente do Ray:
Recupere o serviço do Ray Head:
Configure o encaminhamento de portas para o nó do painel do Ray. O processo é executado em segundo plano, para que você possa continuar executando comandos na mesma sessão do terminal.
Para interromper o loop de encaminhamento de portas, use o comando
kill ${PF_PID}.Inspecione o manifesto
runtime-env.yaml:Se você estiver usando GPUs H200, mude o valor da variável de ambiente
NCCL_TUNER_CONFIG_PATHpara/usr/local/gib/configs/tuner_config_a3u.txtpb.Esse arquivo é usado pelo cliente do Ray. Não é necessário aplicar esse manifesto ao cluster.
Envie o job:
Monitore os registros do job de treinamento e procure a métrica
critic/score/meanpara aumentar, o que indica que o modelo está aprendendo:- Painel do Ray:
- Abra
http://localhost:8265no seu navegador. Se você estiver usando o Cloud Shell, clique em Visualização da Web, selecione Alterar porta e insira8265. - Acesse a guia Jobs.
- Clique no código da tarefa.
- Filtre os registros pela palavra-chave
criticpara inspecionar a métricacritic/score/mean.
- Abra
Saída do console: como o job é enviado de forma assíncrona com a flag
--no-wait, transmita os registros do job no terminal executando o seguinte comando:
- Painel do Ray:
Depois que o treinamento terminar, verifique se os checkpoints do modelo foram salvos no bucket do Cloud Storage listando o conteúdo do diretório:
Como alternativa, confira os checkpoints no console do Google Cloud acessando Cloud Storage > Buckets, selecionando
YOUR_GCS_BUCKETe abrindo a pastaverl/checkpoints.
A4X
Consiga o nome do pod principal do Ray:
export HEAD_POD=$(kubectl get pod -n ${NAMESPACE} -l ray.io/node-type=head -o jsonpath='{.items[0].metadata.name}')Configure o arquivo de ambiente de execução do Ray diretamente no 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'Envie o job de treinamento do GRPO executando-o no pod principal do 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'Monitore os registros do job (usando o ID exclusivo retornado por
ray job submit):kubectl exec ${HEAD_POD} -c ray-head -- ray job logs <var>JOB_ID</var> --followSubstitua
JOB_ID. Confirme se o NVLink entre nós está ativo procurando linhas do NCCL em registros que contenhamvia P2P/MNNVL.
Limpar
Para evitar cobranças, exclua os recursos:
A4 e A3 Ultra
Piloto automático
Se o loop de encaminhamento de portas ainda estiver em execução na sessão em segundo plano, encerre-o:
Exclua o cluster do Ray:
Exclua o Cloud Storage FUSE:
Exclua os recursos da DRANET:
Exclua o bucket do Cloud Storage:
Exclua o cluster do GKE:
Padrão
Se o loop de encaminhamento de portas ainda estiver em execução na sessão em segundo plano, encerre-o:
Exclua o cluster do Ray:
Exclua o Cloud Storage FUSE:
Exclua o bucket do Cloud Storage:
Exclua o cluster do GKE:
Exclua as redes VPC e as sub-redes:
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}
A seguir
- Aprenda Mais sobre o Ray no GKE
- Aprenda Mais sobre a criação de clusters A4X no GKE
- Explore a documentação do verl