本教學課程說明如何在 Google Kubernetes Engine (GKE) 上,為強化學習編排分散式訓練環境。您可以使用 Ray 和 verl (Volcano Engine Reinforcement Learning) 架構,設定分散式訓練環境,微調 Qwen2.5-32B-Instruct 模型。
本教學課程著重於使用 Ray 和 verl,在 GKE 上進行群組相對政策最佳化 (GRPO) 訓練。GRPO 是一種增強學習演算法,旨在提升模型的推理能力。這項演算法可節省記憶體,並透過淘汰 Critic 或價值模型,改用相對群組計算,簡化強化學習 (RL) 程序。
如果您需要設定分散式訓練環境,以便將資料、模型權重和訓練引擎分離,提高效率,建議先參閱本教學課程。
背景
以下各節簡要說明本教學課程使用的概念。
增強學習 (RL)
RL 是透過經驗、探索和回饋來訓練模型,而不是靜態模仿。預先訓練會教導模型該說什麼,而人類回饋增強學習 (RLHF) 則會教導模型如何提供實用、安全且合乎邏輯的內容。RL 可做為基礎模型與針對特定用途微調模型的橋樑。
詳情請參閱「什麼是強化學習?」一文。
群組相對政策最佳化 (GRPO)
GRPO 是 DeepSeek 普及的演算法,可移除 Critic 模型,為 LLM 對齊提供記憶體效率高的 PPO (近端策略最佳化) 替代方案。GRPO 不會使用 Critic 網路,而是針對相同提示產生一組回應,並以該組回應的平均獎勵做為基準。
詳情請參閱 GRPO。
火山引擎強化學習 (verl)
verl 是高效能架構,可處理以 LLM 為基礎的 RL 複雜記憶體和運算模式。
詳情請參閱 verl。
目標
本教學課程說明如何透過 verl 在 GKE 上設定強化學習,方法是完成下列步驟:
- 設定搭載 B200 或 H200 GPU 的 GKE 叢集。
- 設定 KubeRay,管理分散式 Ray 叢集。
- 使用 Cloud Storage FUSE 在所有節點上掛接 Cloud Storage bucket。
- 使用 verl 執行 GRPO 訓練工作,將 Qwen2.5-32B-Instruct 模型與 GSM8K 資料集對齊。
事前準備
- 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
-
安裝 Google Cloud CLI。
-
若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI。
-
執行下列指令,初始化 gcloud CLI:
gcloud init -
選取或建立專案所需的角色
- 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
-
建立專案:如要建立專案,您需要具備專案建立者角色 (
roles/resourcemanager.projectCreator),其中包含resourcemanager.projects.create權限。瞭解如何授予角色。
-
建立 Google Cloud 專案:
gcloud projects create PROJECT_ID
將
PROJECT_ID替換為您要建立的 Google Cloud 專案名稱。 -
選取您建立的 Google Cloud 專案:
gcloud config set project PROJECT_ID
將
PROJECT_ID替換為 Google Cloud 專案名稱。
啟用必要的 API:
啟用 API 時所需的角色
如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (
roles/serviceusage.serviceUsageAdmin),其中包含serviceusage.services.enable權限。瞭解如何授予角色。gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
安裝 Google Cloud CLI。
-
若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI。
-
執行下列指令,初始化 gcloud CLI:
gcloud init -
選取或建立專案所需的角色
- 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
-
建立專案:如要建立專案,您需要具備專案建立者角色 (
roles/resourcemanager.projectCreator),其中包含resourcemanager.projects.create權限。瞭解如何授予角色。
-
建立 Google Cloud 專案:
gcloud projects create PROJECT_ID
將
PROJECT_ID替換為您要建立的 Google Cloud 專案名稱。 -
選取您建立的 Google Cloud 專案:
gcloud config set project PROJECT_ID
將
PROJECT_ID替換為 Google Cloud 專案名稱。
啟用必要的 API:
啟用 API 時所需的角色
如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (
roles/serviceusage.serviceUsageAdmin),其中包含serviceusage.services.enable權限。瞭解如何授予角色。gcloud services enable container.googleapis.com
storage.googleapis.com compute.googleapis.com -
將角色授予使用者帳戶。針對下列每個 IAM 角色,執行一次下列指令:
roles/container.admin, roles/iam.serviceAccountAdmin, roles/storage.admingcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE
更改下列內容:
PROJECT_ID:專案 ID。USER_IDENTIFIER:使用者帳戶的 ID。 例如:myemail@example.com。ROLE:授予使用者帳戶的 IAM 角色。
- 如果您沒有 Hugging Face 帳戶,請先建立一個。
- 確認您擁有 Hugging Face 權杖。
- 請確認專案有足夠的 B200 和 H200 GPU 配額。詳情請參閱「規劃 GPU 配額」和「GPU 配額」。
準備環境
在本教學課程中,您將使用 Cloud Shell。
在 Google Cloud 主控台視窗頂端,按一下「啟用 Cloud Shell」按鈕。
請設定下列環境變數:
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_VERSION替換下列值:
CONTROL_PLANE_LOCATION:GKE 叢集控制層的 Compute Engine 區域。GPU_TYPE:您在 Compute Engine 容量預留中預留的加速器。必須是下列其中一個值:nvidia-b200:NVIDIA B200 (180 GB)nvidia-h200-141gb:NVIDIA H200 (141 GB)
NODE_LOCATION:GKE 節點的可用區。選取提供 NVIDIA B200 或 H200 GPU 的區域。CLUSTER_NAME:GKE 叢集名稱。BUCKET_NAME:Cloud Storage bucket 的基本名稱。您不需要指定gs://前置字元。YOUR_HUGGING_FACE_TOKEN:Hugging Face 權杖,用於存取模型。MACHINE_TYPE:要使用的機器類型:- 如要使用 NVIDIA B200 (180 GB) GPU,請使用
a4-highgpu-8g以上版本。 - 如要使用 NVIDIA H200 (141 GB) GPU,請使用
a3-ultragpu-8g以上版本。
- 如要使用 NVIDIA B200 (180 GB) GPU,請使用
GKE_VERSION:要使用的 GKE 版本:- 如要使用 NVIDIA B200 (180 GB) GPU,請使用
1.32.2-gke.1422000以上版本。 - 如要使用 NVIDIA H200 (141 GB) GPU,請使用
1.31.4-gke.1183000以上版本。
- 如要使用 NVIDIA B200 (180 GB) GPU,請使用
為網路建立下列環境變數:
export GVNIC_NETWORK_PREFIX="GVNIC-NAME" export RDMA_NETWORK_PREFIX="RDMA-NAME"替換下列值:
GVNIC-NAME:gVNIC 網路名稱的前置字串。你可以使用任何前置字元。RDMA-NAME:遠端直接記憶體存取 (RDMA) 網路的前置字元。你可以使用任何前置字元。
設定基礎架構
在本節中,您將建立 RDMA 網路和 GKE 叢集。
建立 RDMA 網路和子網路
為 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/16為 RDMA 建立虛擬私有雲網路和子網路,並為 8 個 GPU 建立 8 個子網路:
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 wait複製範例存放區:
git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git cd kubernetes-engine-samples前往工作目錄:
cd ai-ml/verl-on-gke
建立 GKE 叢集
您可以在 GKE Autopilot 或 Standard 叢集中設定 verl。建議您使用 Autopilot 叢集,享有全代管 Kubernetes 體驗。如要為工作負載選擇最合適的 GKE 作業模式,請參閱「選擇 GKE 作業模式」。
Autopilot
建立 Autopilot 叢集:
gcloud container clusters create-auto ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_LOCATION} \ --enable-multi-networking \ --enable-ray-operator取得叢集憑證:
gcloud container clusters get-credentials ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_LOCATION}安裝 Autopilot 適用的 NCCL RDMA 安裝程式:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/refs/heads/master/gpudirect-rdma/nccl-rdma-installer-autopilot.yaml
標準
建立 Standard 叢集:
gcloud container clusters create ${CLUSTER_NAME} \ --location=${CONTROL_PLANE_LOCATION} \ --enable-dataplane-v2 \ --enable-ip-alias \ --enable-multi-networking \ --addons=RayOperator,GcsFuseCsiDriver \ --machine-type=c2standard8 \ --num-nodes=1 \ --min-nodes=1 \ --max-nodes=5 \ --enable-autoscaling取得叢集憑證:
gcloud container clusters get-credentials ${CLUSTER_NAME} --location=${ZONE}建立 GPU 節點集區。這些節點集區使用 Spot VM 執行個體,可節省成本:
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-7安裝用於標準叢集的 NCCL RDMA 安裝程式:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/container-engine-accelerators/refs/heads/master/gpudirect-rdma/nccl-rdma-installer.yaml
設定網路對應
檢查
network-mapping.yaml資訊清單:套用資訊清單:
kubectl apply -f network-mapping.yaml
準備資料和儲存空間
建立 Cloud Storage bucket:
gcloud storage buckets create gs://${GS_BUCKET} --location=${REGION} --enable-hierarchical-namespace --uniform-bucket-level-access建立 Kubernetes 服務帳戶 (KSA),並繫結至 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"為 Hugging Face 建立 Secret:
kubectl create secret generic hf-secret --from-literal=hf_api_token=${HF_TOKEN}檢查
gcsfuse-storage.yaml資訊清單:套用資訊清單:
kubectl apply -f gcsfuse-storage.yaml
準備模型和資料
您可以在本機或 GKE Pod 上執行這些指令,將資料填入 bucket。
複製 verl 存放區:
git clone https://github.com/volcengine/verl.git使用 Hugging Face CLI 下載 Qwen2.5-32B-Instruct 模型:
huggingface-cli download Qwen/Qwen2.5-32B-Instruct --local-dir Qwen2.5-32B-Instruct預先處理 GSM8K 資料集:
python examples/data_preprocess/gsm8k.py --local_save_dir ~/data/gsm8k將模型、資料和 verl 程式碼上傳到 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}
部署 RayCluster 自訂資源
部署 RayCluster 自訂資源,通常包含一個系統 Pod 和多個工作站 Pod。
Autopilot
部署 RayCluster。將下列內容儲存至
ray-cluster-auto.yaml:套用 RayCluster:
kubectl apply -f ray-cluster.yaml
標準
部署 RayCluster。將下列內容儲存至
ray-cluster.yaml:套用 RayCluster:
kubectl apply -f ray-cluster.yaml
啟動 GRPO 工作
設定通訊埠轉送至 Ray 資訊主頁節點:
kubectl port-forward svc/b200-ray-cluster-head-svc 8265:8265檢查
runtime-env.yaml資訊清單:如果您使用 H200 GPU,請將
NCCL_TUNER_CONFIG_PATH變更為/usr/local/gib/configs/tuner_config_a3u.txtpb。Ray 用戶端會使用這個檔案。您不需要將這個資訊清單套用至叢集。
使用
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.log在 Ray 資訊主頁或輸出內容中監控記錄。尋找
critic/score/mean符號,表示學習成效有所提升。
清除所用資源
為避免產生費用,請刪除資源:
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}