 Ray 集群的完整指南)
使用 Ray Cluster Launcher 在 GCP 上啟動(dòng) Ray 集群的完整指南【免費(fèi)下載鏈接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.項(xiàng)目地址: https://gitcode.com/gh_mirrors/ra/ray本指南講解如何借助 Ray 自帶的集群?jiǎn)?dòng)器Cluster Launcher在 Google Cloud PlatformGCP上創(chuàng)建、連接并銷毀 Ray 集群。你將掌握ray up/ray attach/ray down三個(gè)核心命令的完整使用流程理解 GCP 專屬集群配置YAML中每一項(xiàng)參數(shù)的含義并學(xué)會(huì)通過(guò) Service Account、搶占式實(shí)例、GPU 與 TPU 等配置按需定制集群同時(shí)結(jié)合本倉(cāng)庫(kù)源碼python/ray/autoscaler/gcp 與 python/ray/autoscaler/_private/gcp深入理解其底層實(shí)現(xiàn)原理。核心概念Ray Cluster Launcher 與 GCPRay 集群?jiǎn)?dòng)器是rayCLI 的組成部分。它讀取一個(gè) YAML 配置文件通過(guò)調(diào)用云廠商 API在 GCP 上即 Google API Client自動(dòng)完成實(shí)例創(chuàng)建、SSH 密鑰注入、Ray 運(yùn)行時(shí)部署等一整套工作。常用命令包括ray up config.yaml創(chuàng)建或更新集群結(jié)束后打印 SSH 登錄頭節(jié)點(diǎn)head node的命令ray attach config.yaml在頭節(jié)點(diǎn)上打開(kāi)一個(gè)遠(yuǎn)程交互終端ray down config.yaml銷毀集群。在 GCP 場(chǎng)景下啟動(dòng)器通過(guò)google-api-python-client與 Compute Engine、Cloud Resource Manager、IAM 等 API 交互完成從「項(xiàng)目校驗(yàn)」「Service Account 創(chuàng)建」「SSH 密鑰注入」到「實(shí)例調(diào)度」的全流程具體邏輯集中在 python/ray/autoscaler/_private/gcp/config.py 與 python/ray/autoscaler/_private/gcp/node_provider.py 中。第一步安裝 Ray Cluster Launcher集群?jiǎn)?dòng)器隨rayPython 包分發(fā)使用ray[default]安裝即可獲得完整功能包含 autoscaler 所需依賴# 安裝 ray pip install -U ray[default]更詳細(xì)的安裝方式conda、源碼編譯等可參考 Ray 安裝文檔。本倉(cāng)庫(kù)在 python/ray/autoscaler/gcp/defaults.yaml 中給出了各節(jié)點(diǎn)初始化階段的自動(dòng)安裝命令which ray || pip install -U ray[default] ...說(shuō)明在首次啟動(dòng)節(jié)點(diǎn)時(shí)若節(jié)點(diǎn)上未安裝 Ray啟動(dòng)器也會(huì)自動(dòng)補(bǔ)齊。第二步安裝與配置 Google API Client準(zhǔn)備 GCP 項(xiàng)目如果你還沒(méi)有創(chuàng)建過(guò) Google APIs Console 項(xiàng)目需要先前往 Google Cloud 控制臺(tái)的「管理項(xiàng)目」頁(yè)面創(chuàng)建一個(gè)新項(xiàng)目。Ray 啟動(dòng)器要求項(xiàng)目 IDproject_id全局唯一該值將在集群配置中作為必填項(xiàng)使用。安裝 Google API Client啟動(dòng)器通過(guò) Google API Client 與 GCP 的各類 REST API 通信安裝命令如下# Install the Google API Client. pip install google-api-python-client關(guān)于憑據(jù)的加載從 python/ray/autoscaler/_private/gcp/config.py#L314-L376 的construct_clients_from_provider_config可以看到兩條路徑若集群配置的provider段未提供gcp_credentials則回退到標(biāo)準(zhǔn)環(huán)境變量GOOGLE_APPLICATION_CREDENTIALS自動(dòng)發(fā)現(xiàn)憑據(jù)若提供了gcp_credentials則要求其包含type與credentials兩個(gè)字段type為service_account時(shí)credentials必須是合法 JSON 格式的服務(wù)賬號(hào)密鑰type為credentials_token時(shí)則直接作為 OAuth token 使用。無(wú)論哪種方式最終都會(huì)構(gòu)建出四個(gè) API 客戶端Cloud Resource Managercrm、IAM、Computecompute以及可選的 TPU 客戶端。第三步理解 GCP 集群配置文件官方在 python/ray/autoscaler/gcp 目錄下提供了多份可直接使用的示例配置其中 example-full.yaml 是最常用的一份它創(chuàng)建一個(gè)按需on-demand的n1-standard-2頭節(jié)點(diǎn)并配置為最多自動(dòng)擴(kuò)容到兩個(gè)n1-standard-2搶占式preemptible工作節(jié)點(diǎn)。使用前你必須將其中的project_id替換為自己的項(xiàng)目 ID。下面逐節(jié)解析該配置文件與 defaults.yaml 對(duì)比可看到哪些是默認(rèn)值、哪些是可覆蓋項(xiàng)集群元信息cluster_name: default # 頭節(jié)點(diǎn)與工作節(jié)點(diǎn)共用的集群唯一標(biāo)識(shí) max_workers: 2 # 除頭節(jié)點(diǎn)外最多啟動(dòng)的工作節(jié)點(diǎn)數(shù) upscaling_speed: 1.0 # 擴(kuò)容速度因子 0越大擴(kuò)容越快 idle_timeout_minutes: 5 # 節(jié)點(diǎn)空閑超過(guò)該分鐘數(shù)將被回收其中upscaling_speed控制擴(kuò)容節(jié)奏autoscaler 會(huì)按upscaling_speed * 當(dāng)前運(yùn)行節(jié)點(diǎn)數(shù)的增量分批擴(kuò)容避免一次性創(chuàng)建過(guò)多實(shí)例。Docker 容器化運(yùn)行可選docker: image: rayproject/ray-ml:latest-gpu # 可改為 latest-cpu 以加快啟動(dòng) container_name: ray_container pull_before_run: True run_options: - --ulimit nofile65536:65536開(kāi)啟后所有命令都在容器內(nèi)執(zhí)行Ray 所需的端口也會(huì)自動(dòng)開(kāi)放。pull_before_run: True表示每次啟動(dòng)前都拉取最新鏡像run_options可向docker run追加額外參數(shù)。你還可以用head_image/worker_image分別指定頭節(jié)點(diǎn)與工作節(jié)點(diǎn)的不同鏡像例如 GPU 頭節(jié)點(diǎn) CPU 工作節(jié)點(diǎn)。provider 段GCP 關(guān)鍵配置provider: type: gcp region: us-west1 availability_zone: us-west1-a project_id: null # 全局唯一的項(xiàng)目 ID必填type: gcp讓 Ray 加載 node_provider.py 中的GCPNodeProvider。從 config.py#L409-L413 可以看到project_id為空時(shí)啟動(dòng)器會(huì)直接斷言報(bào)錯(cuò)project_id must be set in the provider section因此這一項(xiàng)無(wú)法省略。region與availability_zone決定了實(shí)例的創(chuàng)建位置也用于后續(xù)子網(wǎng)subnet自動(dòng)探測(cè)。auth 段SSH 認(rèn)證auth: ssh_user: ubuntu # 默認(rèn)自動(dòng)生成密鑰對(duì)也可指定自有私鑰 # ssh_private_key: /path/to/your/key.pem默認(rèn)情況下 Ray 會(huì)生成新的密鑰對(duì)并寫(xiě)入項(xiàng)目級(jí)元數(shù)據(jù)commonInstanceMetadata中的ssh-keys源碼位于 config.py#L482-L610 的_configure_key_pair。如果你設(shè)置了自己的ssh_private_key則需要在頭/工作節(jié)點(diǎn)的node_config中同步配置對(duì)應(yīng)的KeyName并預(yù)先將公鑰加入項(xiàng)目級(jí)元數(shù)據(jù)。available_node_types 段節(jié)點(diǎn)類型定義available_node_types: ray_head_default: resources: {CPU: 2} node_config: machineType: n1-standard-2 disks: - boot: true autoDelete: true type: PERSISTENT initializeParams: diskSizeGb: 50 sourceImage: projects/deeplearning-platform-release/global/images/common-cpu-v20240922 ray_worker_small: min_workers: 1 max_workers: 2 resources: {CPU: 2} node_config: machineType: n1-standard-2 disks: - boot: true autoDelete: true type: PERSISTENT initializeParams: diskSizeGb: 50 sourceImage: projects/deeplearning-platform-release/global/images/common-cpu-v20240922 # 默認(rèn)工作節(jié)點(diǎn)使用搶占式實(shí)例去掉該段即為按需 scheduling: - preemptible: true要點(diǎn)說(shuō)明resources聲明該節(jié)點(diǎn)類型提供的 Ray 資源如{CPU: 2}、{GPU: 1}用于調(diào)度任務(wù)min_workers/max_workers控制該類型工作節(jié)點(diǎn)的伸縮區(qū)間max_workers優(yōu)先級(jí)更高node_config直接對(duì)應(yīng) GCP Compute Engine 的instances.insert請(qǐng)求體支持machineType、disks、networkInterfaces、guestAccelerators、metadata、scheduling等字段scheduling: [{preemptible: true}]讓工作節(jié)點(diǎn)以搶占式實(shí)例運(yùn)行成本更低但隨時(shí)可能被回收適合容錯(cuò)型批處理任務(wù)若同時(shí)為頭節(jié)點(diǎn)和工作節(jié)點(diǎn)都顯式配置了networkInterfaces則使用手動(dòng)網(wǎng)絡(luò)配置否則 Ray 會(huì)從當(dāng)前 region 自動(dòng)探測(cè)并選用一個(gè)已有子網(wǎng)邏輯見(jiàn) config.py#L613-L664 的_configure_subnet。文件同步與初始化命令head_node_type: ray_head_default file_mounts: {} # 遠(yuǎn)程路徑 - 本地路徑 映射復(fù)制到所有節(jié)點(diǎn) cluster_synced_files: [] # 從頭節(jié)點(diǎn)同步到工作節(jié)點(diǎn)的文件 rsync_exclude: [**/.git, **/.git/**] initialization_commands: [] # Docker 啟用時(shí)在容器外執(zhí)行的命令 setup_commands: [] # 節(jié)點(diǎn)通用安裝命令 head_setup_commands: # 頭節(jié)點(diǎn)專用安裝命令 - pip install google-api-python-client1.7.8 worker_setup_commands: [] head_start_ray_commands: # 頭節(jié)點(diǎn)啟動(dòng)命令一般無(wú)需修改 - ray stop - ray start --head --port6379 --object-manager-port8076 --autoscaling-config~/ray_bootstrap_config.yaml worker_start_ray_commands: # 工作節(jié)點(diǎn)啟動(dòng)命令 - ray stop - ray start --address$RAY_HEAD_IP:6379 --object-manager-port8076head_node_type指定頭節(jié)點(diǎn)使用哪一種節(jié)點(diǎn)類型。file_mounts用「遠(yuǎn)程路徑 : 本地路徑」字典將本地文件/目錄在啟動(dòng)時(shí)同步到所有節(jié)點(diǎn)。啟動(dòng)命令段默認(rèn)會(huì)關(guān)閉舊進(jìn)程ray stop再以指定端口啟動(dòng)其中--autoscaling-config指向 Ray 生成的最終 bootstrap 配置$RAY_HEAD_IP由 autoscaler 注入工作節(jié)點(diǎn)用于定位頭節(jié)點(diǎn)地址。第四步集群的完整生命周期ray up / attach / down配置文件準(zhǔn)備就緒后在本地機(jī)器上執(zhí)行以下命令即可完成一次完整的集群生命周期驗(yàn)證# 下載示例配置也可直接從倉(cāng)庫(kù) python/ray/autoscaler/gcp/example-full.yaml 獲取 wget https://raw.githubusercontent.com/ray-project/ray/master/python/ray/autoscaler/gcp/example-full.yaml # 編輯 example-full.yaml 中的 project_id # vi example-full.yaml # 創(chuàng)建或更新集群命令結(jié)束時(shí)將打印可用于 SSH 登錄頭節(jié)點(diǎn)的命令 ray up example-full.yaml # 在頭節(jié)點(diǎn)上打開(kāi)遠(yuǎn)程終端 ray attach example-full.yaml # 嘗試運(yùn)行一個(gè) Ray 程序 python -c import ray; ray.init() exit # 銷毀集群 ray down example-full.yaml執(zhí)行ray up時(shí)后臺(tái)會(huì)依次發(fā)生對(duì)應(yīng) config.py#L379-L397 的bootstrap_gcp流程_configure_project校驗(yàn)項(xiàng)目存在且生命周期狀態(tài)為ACTIVE不存在則嘗試創(chuàng)建_configure_iam_role確保默認(rèn)服務(wù)賬號(hào)ray-autoscaler-sa-v1project-id.iam.gserviceaccount.com存在并綁定 IAM 角色見(jiàn)下文同時(shí)把頭節(jié)點(diǎn)的serviceAccounts注入配置_configure_key_pair創(chuàng)建/復(fù)用 SSH 密鑰對(duì)并寫(xiě)入項(xiàng)目元數(shù)據(jù)_configure_subnet探測(cè)可用子網(wǎng)并填充networkInterfaces之后由GCPNodeProvider調(diào)用 node.py 中GCPCompute.create_instance等 API 創(chuàng)建實(shí)例并執(zhí)行各階段命令。ray attach實(shí)際是在 SSH 通道上為頭節(jié)點(diǎn)打開(kāi)交互式 shellray down則逐個(gè)銷毀實(shí)例并釋放資源避免持續(xù)產(chǎn)生費(fèi)用。第五步為工作節(jié)點(diǎn)配置 Service AccountGCP 專屬配置默認(rèn)情況下只有頭節(jié)點(diǎn)會(huì)以 Service Accountray-autoscaler-sa-v1project-id.iam.gserviceaccount.com運(yùn)行該賬號(hào)由啟動(dòng)器自動(dòng)創(chuàng)建并綁定角色。要讓工作節(jié)點(diǎn)也使用同一 Service Account例如需要訪問(wèn) Google Cloud Storage 或 GCR 時(shí)請(qǐng)?jiān)趯?duì)應(yīng)工作節(jié)點(diǎn)類型的node_config中加入serviceAccounts配置available_node_types: ray.worker.default: node_config: ... serviceAccounts: - email: ray-autoscaler-sa-v1YOUR_PROJECT_ID.iam.gserviceaccount.com scopes: - https://www.googleapis.com/auth/cloud-platform在 example-full.yaml 的工作節(jié)點(diǎn)段中這段配置以注釋形式給出取消注釋并替換project_id即可啟用。從源碼 config.py#L40-L47 可以看到該服務(wù)賬號(hào)默認(rèn)綁定四個(gè) IAM 角色roles/storage.objectAdmin管理 GCS 對(duì)象存儲(chǔ)roles/compute.admin創(chuàng)建/管理 Compute Engine 實(shí)例工作節(jié)點(diǎn)由頭節(jié)點(diǎn)拉起所必需roles/iam.serviceAccountUser允許頭節(jié)點(diǎn)以該服務(wù)賬號(hào)身份創(chuàng)建工作節(jié)點(diǎn)roles/iam.roleViewer允許頭節(jié)點(diǎn)執(zhí)行bootstrap_gcp讀取角色信息。若配置中包含 TPU 節(jié)點(diǎn)還會(huì)額外追加roles/tpu.admin見(jiàn) config.py#L46-L47。此外scopes中的cloud-platform全平臺(tái) scope 只是訪問(wèn)邊界最終實(shí)際權(quán)限仍以 IAM 角色為準(zhǔn)見(jiàn) config.py#L468-L477 的注釋說(shuō)明。進(jìn)階場(chǎng)景一GPU 集群若需要 GPU 加速參考 example-gpu-docker.yaml。關(guān)鍵差異點(diǎn)如下node_config: machineType: n1-standard-2 sourceImage: projects/ml-images/global/images/c0-deeplearning-common-cu121-v20231209-debian-11 guestAccelerators: - acceleratorType: nvidia-tesla-t4 acceleratorCount: 1 metadata: items: - key: install-nvidia-driver value: True scheduling: - onHostMaintenance: TERMINATEguestAccelerators聲明 GPU 型號(hào)與數(shù)量對(duì)應(yīng)resources: {GPU: 1}啟用 GPU 時(shí)必須將scheduling.onHostMaintenance設(shè)為T(mén)ERMINATEGPU 不支持熱遷移配置鏡像需選用帶 CUDA 的深度學(xué)習(xí)鏡像initialization_commands中會(huì)等待nvidia-smi可用確認(rèn)驅(qū)動(dòng)安裝完成Docker 鏡像使用rayproject/ray:latest-gpu純 Ray或rayproject/ray-ml:latest-gpu含 ML 依賴?yán)「?。底層?chuàng)建實(shí)例時(shí)node.py#L486-L522 的_convert_resources_to_urls會(huì)自動(dòng)把machineType規(guī)范化為zones/zone/machineTypes/type全路徑把a(bǔ)cceleratorType規(guī)范化為projects/project/zones/zone/acceleratorTypes/type因此配置中可直接寫(xiě)簡(jiǎn)寫(xiě)形式。進(jìn)階場(chǎng)景二TPU 集群Ray 的 GCP 支持同時(shí)覆蓋 Compute 與 TPU 兩種資源node.py#L109-L122 中的GCPNodeType枚舉配置示例見(jiàn) example-tpu-pod.yamlavailable_node_types: ray_head_default: min_workers: 0 max_workers: 0 resources: {CPU: 0} node_config: machineType: n1-standard-4 # ... 普通 Compute 頭節(jié)點(diǎn) ray_tpu: min_workers: 1 max_workers: 1 resources: {TPU: 1} # 代碼中通過(guò)自定義資源 TPU 使用 node_config: acceleratorType: v4-16 runtimeVersion: tpu-vm-v4-baseTPU 節(jié)點(diǎn)類型不寫(xiě)machineType而用acceleratorType如v4-16或acceleratorConfigtype topology 組合見(jiàn) example-tpu-pod-topology.yaml例如type: V4topology: 2x2x1會(huì)生成 v4-8TPU作為自定義資源寫(xiě)入resources供應(yīng)用層調(diào)度節(jié)點(diǎn)名以-tpu后綴結(jié)尾啟動(dòng)器據(jù)此區(qū)分資源類型node.py#L124-L131從源碼 node_provider.py#L279-L320 可以看出TPU pod 還會(huì)自動(dòng)填充TPU-type-head資源用于支持 pod 的擴(kuò)容調(diào)度。需要注意TPU pod 中所有 host 必須執(zhí)行同一程序因此當(dāng)前倉(cāng)庫(kù)對(duì) TPU pod 的「嚴(yán)格自動(dòng)伸縮」并不完全適用相關(guān) warning 見(jiàn) config.py#L187-L194。另外配置文件會(huì)開(kāi)啟enableExternalIps以保證 SSH 可達(dá)node.py#L776-L781。進(jìn)階場(chǎng)景三最小化配置如果只想快速驗(yàn)證example-minimal.yaml 僅需四組字段即可啟動(dòng)auth: ssh_user: ubuntu cluster_name: minimal provider: availability_zone: us-west1-a project_id: null # TODO: 設(shè)置你的 GCP 項(xiàng)目 ID region: us-west1 type: gcp其余字段節(jié)點(diǎn)類型、資源、命令等都會(huì)由啟動(dòng)器從 defaults.yaml 自動(dòng)補(bǔ)全??梢?jiàn) Ray 在 GCP 上的「默認(rèn)即可用」設(shè)計(jì)只要填好項(xiàng)目與區(qū)域啟動(dòng)器就能自行完成密鑰注入、子網(wǎng)探測(cè)與服務(wù)賬號(hào)創(chuàng)建。底層實(shí)現(xiàn)速覽從配置到實(shí)例的調(diào)用鏈結(jié)合源碼可以梳理出一次ray up在 GCP 側(cè)的完整調(diào)用鏈ray up解析 YAML 后調(diào)用GCPNodeProvider.bootstrap_confignode_provider.py#L275-L277最終落到bootstrap_gcpconfig.py#L379-L397依次完成項(xiàng)目、IAM 角色、密鑰對(duì)、子網(wǎng)四項(xiàng)配置GCPNodeProvider.create_nodenode_provider.py#L170-L209根據(jù)節(jié)點(diǎn)配置判斷類型Compute 或 TPU批量調(diào)用GCPCompute.create_instances/GCPTPU.create_instance實(shí)例創(chuàng)建后wait_for_operation以輪詢方式默認(rèn)最多 12 次、間隔 5 秒見(jiàn) node.py#L46-L53等待 GCP 操作完成TPU 的輪詢上限放大為 96 次以適配其慢啟動(dòng)特性節(jié)點(diǎn)命名遵循[名稱]-[8位UUID]-[compute|tpu]格式node.py#L92-L106autoscaler 通過(guò)后綴反推節(jié)點(diǎn)所屬資源集群關(guān)閉或縮容時(shí)terminate_node默認(rèn)直接刪除實(shí)例若在 provider 中開(kāi)啟cache_stopped_nodes則會(huì)改為停止stop實(shí)例以便復(fù)用node_provider.py#L231-L254。常見(jiàn)問(wèn)題與注意事項(xiàng)project_id 必填且全局唯一未填寫(xiě)時(shí)ray up會(huì)在配置校驗(yàn)階段直接報(bào)錯(cuò)config.py#L410-L413憑據(jù)來(lái)源二選一推薦使用GOOGLE_APPLICATION_CREDENTIALS環(huán)境變量或在配置的provider.gcp_credentials中內(nèi)嵌服務(wù)賬號(hào) JSON注意 JSON 需格式正確否則啟動(dòng)器會(huì)拋出「formatted improperly」錯(cuò)誤搶占式實(shí)例的取舍preemptible: true能顯著降低成本但實(shí)例可能隨時(shí)被回收適合無(wú)狀態(tài)、可重試的分布式任務(wù)端口與文件描述符示例配置中默認(rèn)使用--port6379與--object-manager-port8076部分示例在啟動(dòng)前通過(guò)ulimit -n 65536提高文件描述符上限見(jiàn) defaults.yaml 的啟動(dòng)命令段費(fèi)用控制測(cè)試結(jié)束后務(wù)必執(zhí)行ray down避免頭節(jié)點(diǎn)與工作節(jié)點(diǎn)持續(xù)計(jì)費(fèi)對(duì)于不再需要的集群也可以直接手動(dòng)在 GCP 控制臺(tái)刪除對(duì)應(yīng)實(shí)例。至此你已經(jīng)掌握了在 GCP 上以配置驅(qū)動(dòng)方式啟動(dòng)、連接與銷毀 Ray 集群的完整方法并理解了從 YAML 配置到 GCP API 調(diào)用的底層實(shí)現(xiàn)鏈路可以據(jù)此按需組合搶占式實(shí)例、GPU、TPU 與 Service Account 等能力構(gòu)建適合自己工作負(fù)載的 Ray 集群?!久赓M(fèi)下載鏈接】rayRay is an AI compute engine. Ray consists of a core distributed runtime and a set of AI Libraries for accelerating ML workloads.項(xiàng)目地址: https://gitcode.com/gh_mirrors/ra/ray創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考