资源分配#

本指南将帮助您配置 Ray Serve 以

  • 通过指定副本数量来横向扩展您的部署

  • 自动向上和向下扩展以响应变化的流量

  • 为每个部署分配硬件资源(CPU、GPU、其他加速器等)

资源管理(CPU、GPU、加速器)#

您可能希望指定部署的资源需求,以保留集群资源,如 GPU 或其他加速器。要为每个副本分配硬件资源,您可以将资源需求传递给 ray_actor_options。默认情况下,每个副本会保留一个 CPU。要了解可以传递的选项,请查看 Actor 资源指南

例如,要创建一个部署,其中每个副本使用单个 GPU,您可以这样做

@serve.deployment(ray_actor_options={"num_gpus": 1})
def func(*args):
    return do_something_with_my_gpu()

或者,如果您想创建一个部署,其中每个副本使用另一种加速器类型,例如 HPU,请按照下面的示例操作

@serve.deployment(ray_actor_options={"resources": {"HPU": 1}})
def func(*args):
    return do_something_with_my_hpu()

CPU 和 GPU 的分数#

要做到这一点,在 ray_actor_options 中指定的资源可以是分数。例如,如果您有两个模型,每个模型都不能完全饱和一个 GPU,您可能希望通过为每个模型分配 0.5 个 GPU 来让它们共享一个 GPU。

@serve.deployment(ray_actor_options={"num_gpus": 0.5})
def func_1(*args):
    return do_something_with_my_gpu()

@serve.deployment(ray_actor_options={"num_gpus": 0.5})
def func_2(*args):
    return do_something_with_my_gpu()

在此示例中,每个部署的每个副本将被分配 0.5 个 GPU。同样的操作也可以用于 CPU 的复用,使用 "num_cpus"

自定义资源、加速器类型等#

您还可以通过 ray_actor_options 指定 自定义资源,例如确保部署被调度到特定节点。例如,如果您有一个部署需要 2 个单位的 "custom_resource" 资源,您可以这样指定

@serve.deployment(ray_actor_options={"resources": {"custom_resource": 2}})
def func(*args):
    return do_something_with_my_custom_resource()

您还可以通过 ray_actor_options 中的 accelerator_type 参数指定 加速器类型

以下是 ray_actor_options 中支持的选项的完整列表;有关每个选项的更多详细信息,请参阅相关的 Ray Core 文档

  • accelerator_type

  • memory

  • num_cpus

  • num_gpus

  • object_store_memory

  • resources

  • runtime_env

使用 OMP_NUM_THREADS 配置并行性#

PyTorch 和 TensorFlow 等深度学习模型在执行推理时通常使用多线程。它们使用的 CPU 数量由 OMP_NUM_THREADS 环境变量控制。Ray 默认将 OMP_NUM_THREADS=<num_cpus> 设置为 <num_cpus>。为了避免争用,如果任务/ Actor 未指定 num_cpus,Ray 会将 OMP_NUM_THREADS 设置为 1,以减少在单个线程中运行的 Actor/任务之间的争用。如果您确实希望在 Serve 部署中启用此并行性,只需将 num_cpus(推荐)设置为所需值,或在启动 Ray 时或在函数/类定义中手动设置 OMP_NUM_THREADS 环境变量。

OMP_NUM_THREADS=12 ray start --head
OMP_NUM_THREADS=12 ray start --address=$HEAD_NODE_ADDRESS
@serve.deployment
class MyDeployment:
    def __init__(self, parallelism: str):
        os.environ["OMP_NUM_THREADS"] = parallelism
        # Download model weights, initialize model, etc.

    def __call__(self):
        pass


serve.run(MyDeployment.bind("12"))

注意

其他一些库可能不遵循 OMP_NUM_THREADS,它们有自己的方式来配置并行性。例如,如果您正在使用 OpenCV,您需要使用 cv2.setNumThreads(num_threads) 手动设置线程数(设置为 0 可禁用多线程)。您可以使用 cv2.getNumThreads()cv2.getNumberOfCPUs() 检查配置。