将对象检测模型作为服务托管#

Ray Serve 是一个可扩展的模型服务框架,允许将机器学习模型部署为微服务。本教程使用 Ray Serve 部署一个对象检测模型,该模型使用 Faster R-CNN。该模型可检测人员是否正确佩戴口罩、错误佩戴口罩或未佩戴口罩。

Anyscale 特定配置

注意:本教程针对 Anyscale 平台进行了优化。在开源 Ray 上运行时,需要额外的配置。例如,您需要手动

  • 配置您的 Ray 集群:设置您的多节点环境,包括头节点和工作节点,并管理资源分配,如自动扩展和 GPU/CPU 分配,而无需 Anyscale 的自动化。有关详细信息,请参阅 Ray 集群
  • 管理依赖项:在每个节点上安装和管理依赖项,因为您将无法使用 Anyscale 基于 Docker 的依赖项管理。有关在环境中安装和更新 Ray 的说明,请参阅 环境依赖项
  • 设置存储:配置您自己的分布式或共享存储系统,而不是依赖 Anyscale 的集成集群存储。有关设置共享存储解决方案的建议,请参阅 配置持久存储

为什么使用 Ray Serve 和 Anyscale#

可扩展性和性能#

  • 自动扩展:Ray Serve 支持水平扩展,这意味着您的部署可以通过将负载分布到多个机器和 GPU 来处理不断增长的请求数量。此功能对于流量可能不可预测的生产环境特别有用。

  • 高效的资源利用:通过诸如分数 GPU 分配和动态调度等功能,Ray Serve 可高效地利用资源,从而降低运营成本,同时保持高吞吐量的模型推理。

框架无关的模型服务#

  • 广泛的兼容性:无论您使用的是 PyTorch、TensorFlow 或 Keras 等深度学习框架,还是 Scikit-Learn 等传统库,Ray Serve 都提供了一个统一的平台来部署这些模型。

  • 灵活的 API 开发:除了服务模型外,您还可以集成任何 Python 业务逻辑。此功能使得将多个模型组合到单个推理管道中以及集成其他服务更加容易。

面向现代应用程序的高级功能#

  • 动态请求批处理:此功能允许将多个小型推理请求一起批处理,从而降低每个请求的开销并提高整体效率。

  • 响应流式传输:对于需要返回大型输出或实时流式传输数据的应用程序,响应流式传输可以改善用户体验并降低延迟。

  • 模型组合:您可以构建复杂的、多步的推理管道,这些管道集成了各种模型,从而使您能够构建结合机器学习和自定义业务逻辑的端到端服务。

在 Ray Serve 的基础上,Anyscale Service 通过提供一个完全托管的平台来简化基础设施管理,从而提升了此部署。它会自动扩展资源,与云服务无缝集成,并提供强大的监控和安全功能。Ray Serve 和 Anyscale Service 一起使您能够在生产环境中将口罩检测模型部署为可扩展、高效且可靠的微服务,从而有效地抽象出运营复杂性,同时确保最佳性能。

检查 object_detection.py#

首先,检查文件 object_detection.py。此模块使用 FastAPI 为对象检测服务实现了 Ray Serve 部署。

该代码初始化一个 FastAPI 应用,并使用 Ray Serve 部署两个类,一个用于处理 HTTP 请求(APIIngress),另一个用于执行对象检测(ObjectDetection)。这种关注点分离——APIIngress 用于 HTTP 接口,ObjectDetection 用于图像处理——允许可扩展、高效地处理请求,Ray Serve 则负责资源分配和副本管理。

APIIngress 使用 FastAPI 作为 HTTP 请求的入口点,公开一个接受图像 URL 并返回处理后图像的终结点(“/detect”)。当请求到达此终结点时,APIIngress 通过调用 ObjectDetection 服务的 detect 方法,异步地将其任务委托给该服务。

以下是对 APIIngress 类装饰器的解释

  • @serve.deployment(num_replicas=1):此装饰器表示入口服务,该服务主要使用 FastAPI 路由 HTTP 请求,将作为单个实例运行。对于此示例,它主要充当轻量级路由器,将请求转发到实际的检测服务。通常一个副本就足够了。要处理生产环境中的高流量,请增加此数字。

  • @serve.ingress(app):此装饰器将 FastAPI 应用与 Ray Serve 集成。它使得 FastAPI 应用中定义的 API 终结点可以通过部署进行访问。本质上,它允许直接通过此部署提供 HTTP 流量。

ObjectDetection 负责核心功能:加载预训练的 Faster R-CNN 模型,处理传入的图像,运行对象检测以识别口罩佩戴状态,并用边界框和标签对图像进行可视化标注。

以下是对 ObjectDetection 类装饰器的解释

  • ray_actor_options={"num_gpus": 1}:此配置为 ObjectDetection 服务的每个副本分配一个 GPU。考虑到该服务加载了用于口罩检测的深度学习模型(Faster R-CNN),GPU 资源对于加速推理至关重要。如果您的基础设施具有可用的 GPU 资源,并且您希望每个 actor 利用硬件加速,那么此参数是合理的。

  • autoscaling_config={"min_replicas": 1, "max_replicas": 10}min_replicas: 1 确保至少有一个副本始终运行,提供基线可用性。max_replicas: 10 将副本的最大数量限制为 10,这有助于控制资源使用,同时适应潜在的流量高峰。

然后,使用可选参数将部署与构造函数bind以定义一个应用。最后,使用 serve.run(或等效的 serve run CLI 命令)部署生成的应用。

有关更多详细信息,请参阅:https://docs.rayai.org.cn/en/latest/serve/configure-serve-deployment.html

使用 Ray Serve 运行对象检测服务#

要启动对象检测服务,请从 Anyscale 工作空间启动终端并使用以下命令

! serve run object_detection:entrypoint --non-blocking

向服务发送请求#

要测试已部署的模型,请使用 Python 发送 HTTP 请求到该服务。以下代码会获取一张图像,将其发送到检测服务,并显示输出

import requests
from PIL import Image
from io import BytesIO
from IPython.display import display

image_url = "https://face-masks-data.s3.us-east-2.amazonaws.com/all/images/maksssksksss5.png"
resp = requests.get(f"http://127.0.0.1:8000/detect?image_url={image_url}")

# Display the image
image = Image.open(BytesIO(resp.content))
display(image)

关闭服务#

使用以下命令关闭服务

!serve shutdown --yes

生产部署#

对于生产部署,请使用 Anyscale Services 将 Ray Serve 应用部署到专用集群,而无需修改代码。Anyscale 可确保可扩展性、容错能力和负载均衡,使服务能够抵御节点故障、高流量和滚动更新。

部署为 Anyscale 服务#

使用以下命令一键部署 my_service

!anyscale service deploy object_detection:entrypoint --name=face_mask_detection_service

检查服务状态#

要获取 my_service 的状态,请运行以下命令

!anyscale service status --name=face_mask_detection_service

查询服务#

部署时,您会公开一个公共可访问的 IP 地址,您可以向其发送请求。

在前面的单元格输出中,复制 API_KEY 和 BASE_URL。例如,它们的值如下所示

  • API_KEY: xkRQv_4MENV7iq34gUprbQrX3NUqpk6Bv6UQpiq6Cbc

  • BASE_URL: https://face-mask-detection-service-bxauk.cld-kvedzwag2qa8i5bj.s.anyscaleuserdata.com

在以下 Python 请求对象中填写 BASE_URL 和 API_KEY 的占位符值

import requests

API_KEY = "xkRQv_4MENV7iq34gUprbQrX3NUqpk6Bv6UQpiq6Cbc"  # PASTE HERE
BASE_URL = "https://face-mask-detection-service-bxauk.cld-kvedzwag2qa8i5bj.s.anyscaleuserdata.com"  # PASTE HERE, remove the slash as the last character.

def detect_masks(image_url: str):
    response: requests.Response = requests.get(
        f"{BASE_URL}/detect",
        params={"image_url": image_url},
        headers={
            "Authorization": f"Bearer {API_KEY}",
        },
    )
    response.raise_for_status()
    return response  

然后,您可以调用服务 API 并获取检测结果

from PIL import Image
from io import BytesIO
from IPython.display import display

image_url = "https://face-masks-data.s3.us-east-2.amazonaws.com/all/images/maksssksksss5.png"
resp = detect_masks(image_url)
# Display the image.
image = Image.open(BytesIO(resp.content))
display(image)

高级配置#

对于生产环境,Anyscale 建议使用 Serve config YAML 文件,该文件提供了一种集中管理系统级设置和应用特定配置的方法。通过修改配置文件并应用更改而不中断服务,您可以实现部署的无缝更新和扩展。有关配置 Ray Serve 部署的全面指南,请参阅官方文档:https://docs.rayai.org.cn/en/latest/serve/configure-serve-deployment.html

终止您的服务#

请记住在测试后终止您的服务,否则它会一直运行

anyscale service terminate –name=face_mask_detection_service

清理集群存储#

您可以查看 cluster_storage 中存储了哪些文件。您可以看到为快速模型加载和提供服务而创建的 fasterrcnn_model_mask_detection.pth 文件。

ls -lah /mnt/cluster_storage/

请记住通过删除来清理集群存储

rm -rf /mnt/cluster_storage/fasterrcnn_model_mask_detection.pth