快速提交Ray任务

更新时间:
复制 MD 格式

Ray是一个通用的分布式计算框架,广泛用于分布式训练、数据处理和模型服务等场景。PAI-DLC支持直接提交Ray任务,并自动完成Ray集群的创建、任务提交及资源管理,无需用户手动搭建集群或配置 Kubernetes。

前提条件

如果使用SDK提交训练任务,需要配置环境变量。详情请参见安装Credentials工具和在Linux、macOS和Windows系统配置环境变量。

准备工作

准备节点镜像

Ray集群包含至少Head和Worker两种节点,DLC可以使用同一镜像搭建两种节点。创建任务后,DLC自动构建Ray集群,并启动submitter节点向集群提交任务。

Ray镜像版本应>=2.6,同时必须至少安装了ray[default]所包含的组件。支持使用的镜像如下:

  • PAI官方镜像:PAI平台提供了安装有Ray基础组件的官方镜像供您使用。

    DLC 平台镜像:在镜像配置弹窗中,将 框架 筛选为 Ray,可选用以下镜像:

    • ray:2.39.0-cpu-py312-ubuntu22.04(3.90 GiB,CPU 版本)

    • ray:2.39.0-gpu-py312-cu118-ubuntu22.04(13.61 GiB,GPU 版本)

  • Ray社区镜像:

    使用GPU时需提供支持CUDA的镜像,更多支持的镜像版本,请查看官方Docker镜像文档。

准备启动命令和脚本文件

DLC任务的启动命令会被用作 ray job submit 所提交的entrypoint命令。启动命令可以填写多行或单行,例如python /root/code/sample.py,其中:

  • sample.py为运行的Python脚本文件,您可以通过数据集或代码配置方式,将脚本文件挂载到DLC容器中。示例内容如下:

    import ray
    import os
    
    ray.init()
    
    @ray.remote
    class Counter:
        def __init__(self):
            # Used to verify runtimeEnv
            self.name = os.getenv("counter_name")
            # assert self.name == "ray"
            self.counter = 0
    
        def inc(self):
            self.counter += 1
    
        def get_counter(self):
            return "{} got {}".format(self.name, self.counter)
    
    counter = Counter.remote()
    
    for _ in range(50000):
        ray.get(counter.inc.remote())
        print(ray.get(counter.get_counter.remote()))
  • /root/code/为挂载路径。

提交训练任务

通过控制台提交

  1. 进入新建任务页面。

    1. 登录PAI控制台,在页面上方选择目标地域,并在右侧选择目标工作空间,然后单击进入DLC。

    2. 在分布式训练(DLC)页面,单击新建任务。

  2. 在新建任务页面,配置以下关键参数,其他参数配置详情,请参见创建训练任务。

    参数

    描述

    示例值

    环境信息

    节点镜像

    在官方镜像页签,选择预置的Ray官方镜像。

    ray:2.39.0-cpu-py312-ubuntu22.04

    启动命令

    提交给Ray集群的任务命令。

    python /root/code/sample.py

    环境变量

    通过运行时环境(runtime_env)配置Ray节点的环境变量。

    三方库配置

    支持通过配置三方库列表来配置Ray的环境运行依赖(runtime_env)。

    说明

    在生产环境中,强烈建议使用已经打包好的镜像来执行任务,避免因为临时安装依赖库造成的任务失败。

    无需配置

    代码配置

    通过在线配置或本地上传的方式,将准备好的脚本文件上传到DLC容器中。

    使用本地上传方式:

    • 示例代码文件:sample.py。

    • 挂载路径:/root/code/。

    资源信息

    资源来源

    选择使用公共资源或资源配额。

    公共资源

    框架

    框架类型。

    Ray

    任务资源

    • 节点角色:

      Head节点角色为必选,且有至少一个Worker角色。可以按需添加多个Worker分组类型。

    • 任务节点数量:

      Head节点数量固定为1,默认仅运行entrypoint脚本。通常还需至少一个Worker节点用于执行计算任务,也可以按需配置弹性伸缩指定节点数量范围。每个Ray任务会自动生成一个Submitter节点执行启动命令,您可通过其日志查看任务运行情况。

    • 节点弹性伸缩:

      当使用资源配额时,单击image图标,Worker节点支持弹性扩缩容。设定最大和最小实例数后,当任务所需最小资源得到满足后会进入运行状态,系统根据资源和负载自动调整运行实例数。

      单击更多配置,填写角色数量、GPU、CPU、内存大小,选择合适的伸缩策略,伸缩策略支持:

      • Default-节点最大化:系统会在有充足资源的情况下会尽可能将节点数量最大化。

      • RayAutoscaler-动态伸缩:仅支持Ray任务,Ray Autoscaler会根据集群负载情况自动调整节点数量。

        重要

        使用RayAutoscaler策略需要给实例绑定一个拥有读写DLC Job权限的RAM角色,通常情况下选择PAI默认角色即可。

      • CloudMonitorMetric-云监控指标:系统会根据云监控指标自动调整节点数量(云监控指标支持配置CPU使用率、内存使用率、GPU算力使用率、GPU显存使用率的目标值)。

    • 资源数量:

      Ray集群Worker节点上的逻辑资源与您在提交任务时配置的物理资源一致。例如,当您配置了1个8卡的GPU节点时,Ray集群Worker节点默认的资源大小也为8卡GPUs。

      为保证集群稳定性,Head节点上的CPU逻辑资源默认为0,不参与计算调度。Head节点建议至少2 GiB内存,并随 Task/Actor数量增加而扩大,以避免OOM错误。资源配置需匹配任务需求,推荐使用少量大节点而非大量小节点。

      说明

      可以通过添加高级参数配置{"RayHeadScheduling": "true"}启用Head作为计算节点调度。

    • 节点角色:Head和Worker

    • 节点数量:均为1。

    • 资源规格:选择ecs.g6.xlarge。

    容错与诊断

    Head节点容错

    DLC任务配置专有网络后,可添加一个Redis实例用于Head节点容错。

    创建Redis实例后,需要配置VPC访问白名单使得DLC任务VPC可以访问Redis实例(白名单可直接添加VPC使用的网段),并配置用户名与密码。

    重要

    Redis默认用户名为default,仅Ray 2.41以上版本支持配置用户名。

    Submitter重试次数

    Submitter向Ray Cluster提交的最大重试次数。

    Ray日志采集

    在Ray集群销毁前,可将Ray集群日志、框架日志及task日志持久化到OSS,便于后续调试分析。

    重要

    Ray日志采集必须为实例绑定一个拥有该OSS读写权限的角色。注意:PAI默认角色仅拥有当前工作空间下的默认存储权限。

    后续用户可以在OSS存储空间中直接下载文件,或者在AI资产管理>任务中新建一个Ray History Server,并配置相同的存储路径,用于查看历史Ray集群的节点日志和任务状态。

  3. 参数配置完成后,单击确定。

通过SDK提交

  1. 安装Python DLC SDK。

    pip install alibabacloud_pai_dlc20201203==1.4.0
  2. 提交DLC Ray任务,示例代码如下。

    #!/usr/bin/env python3
    
    from alibabacloud_tea_openapi.models import Config
    from alibabacloud_credentials.client import Client as CredClient
    
    from alibabacloud_pai_dlc20201203.client import Client as DLCClient
    from alibabacloud_pai_dlc20201203.models import CreateJobRequest
    
    region_id = '<region-id>'
    cred = CredClient()
    workspace_id = '12****'
    
    dlc_client = DLCClient(
        Config(credential=cred,
               region_id=region_id,
               endpoint='pai-dlc.{}.aliyuncs.com'.format(region_id),
               protocol='http'))
    
    create_job_resp = dlc_client.create_job(CreateJobRequest().from_map({
        'WorkspaceId': workspace_id,
        'DisplayName': 'dlc-ray-job',
        'JobType': 'RayJob',
        'JobSpecs': [
            {
                "Type": "Head",
                "Image": "dsw-registry-vpc.<region-id>.cr.aliyuncs.com/pai/ray:2.39.0-gpu-py312-cu118-ubuntu22.04",
                "PodCount": 1,
                "EcsSpec": 'ecs.c6.large',
            },
            {
                "Type": "Worker",
                "Image": "dsw-registry-vpc.<region-id>.cr.aliyuncs.com/pai/ray:2.39.0-gpu-py312-cu118-ubuntu22.04",
                "PodCount": 1,
                "EcsSpec": 'ecs.c6.large',
            },
        ],
        "UserCommand": "echo 'Prepare your ray job entrypoint here' && sleep 1800 && echo 'DONE'",
    }))
    job_id = create_job_resp.body.job_id
    print(f'jobId is {job_id}')

    其中:

    • region_id:阿里云区域ID。例如华东1(杭州)为cn-hangzhou。

    • workspace_id:工作空间ID。请在工作空间详情页面进行查看,具体操作,请参见管理工作空间。

    • Image:请将<region-id>替换为实际的阿里云区域ID。例如华东1(杭州)为cn-hangzhou。

更多关于SDK的使用方法,请参见Python SDK。

通过CLI提交

  1. 下载DLC客户端工具,并完成用户认证。具体操作,请参见准备工作。

  2. 提交DLC Ray任务,示例代码如下。

    ./dlc submit rayjob --name=my_ray_job \
      --workers=1 \
      --worker_spec=ecs.g6.xlarge \
      --worker_image=dsw-registry-vpc.<region-id>.cr.aliyuncs.com/pai/ray:2.39.0-cpu-py312-ubuntu22.04 \
      --heads=1 \
      --head_image=dsw-registry-vpc.<region-id>.cr.aliyuncs.com/pai/ray:2.39.0-cpu-py312-ubuntu22.04 \
      --head_spec=ecs.g6.xlarge \
      --command="echo 'Prepare your ray job entrypoint here' && sleep 1800 && echo 'DONE'" \
      --workspace_id=4****

    通过CLI提交任务的更多配置方法,请参见提交命令。

常见问题

Q:为什么Ray任务因环境准备耗时过长而超时失败?

  • 检查Head节点的日志,观察Ray环境是否正常启动。如果没有则说明相关实例中Ray不可用,请参照准备工作章节准备支持Ray的镜像。

    Ray 环境正常启动后,日志中将输出如下信息:

    -- --------------------
    -- Ray runtime started.
    -- --------------------
    
    -- Next steps
    -- To add another node to this Ray cluster, run
    --     ray start --address='192.168.128.203:6379'
    -- To connect to this Ray cluster:
    -- import ray
    -- ray.init()
    -- To terminate the Ray runtime, run
    --     ray stop
    -- To view the status of the cluster, use
    --     ray status
    -- --block
    -- This command will now block forever until terminated by a signal.
  • 建议检查Head节点的事件日志,如果显示错误Readiness probe failed...,可能意味着该镜像缺失Readiness check相关依赖或部分间接依赖不可用。建议在原镜像中使用pip或conda重新安装ray[default]组件,或者尝试基于Ray官方镜像重新构建镜像。

附录:Ray框架高级配置

参数

类型

描述

默认值

RayRuntimeEnv

string

运行时环境依赖

RayRedisAddress

string

外部 GCS Redis 地址

RayRedisUsername

string

外部 GCS Redis 用户名。仅Ray 2.41以上版本

RayRedisPassword

string

外部 GCS Redis 密码

RaySubmitterBackoffLimit

int

Submitter 重试次数

0

RayObjectStoreMemoryBytes

int

Object store memory内存

30%可用内存

RayHeadScheduling

bool

Head节点是否参与调度

false

RayLogStoragePath

string

Ray日志持久化bucket路径