资源分配#
本指南帮助你配置 Ray Serve 以实现以下目标:
通过指定副本数量来水平扩展你的部署
根据流量变化自动向上和向下扩缩容
为每个部署分配硬件资源(CPU、GPU、其他加速器等)
资源管理(CPU、GPU、加速器)#
你可能希望指定部署的资源需求,以保留集群资源,例如 GPU 或其他加速器。要为每个副本分配硬件资源,你可以将资源需求传递给 ray_actor_options
。默认情况下,每个副本保留一个 CPU。要了解可传入的选项,请查看 Actors 资源指南。
例如,要创建一个部署,其中每个副本使用单个 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#
假设你有两个模型,并且每个模型都不能完全饱和一个 GPU。你可能希望通过为每个模型分配 0.5 个 GPU 来让它们共享一个 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。使用 "num_cpus"
也可以对 CPU 进行多路复用。
自定义资源、加速器类型等#
你还可以在 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>
。为了避免争用,如果任务/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()
检查配置。