You need to enable JavaScript to run this app.
导航
基于 Ray Serve 构建模型在线推理服务
最近更新时间:2025.04.30 17:58:28首次发布时间:2025.04.30 17:58:28
我的收藏
有用
有用
无用
无用

Ray Serve 是依托于 Ray 分布式计算框架之上构建的模型在线服务库,提供基于给定模型构建高性能、低延迟在线推理服务的能力。基于 Ray Serve 构建在线推理服务具有如下优势:

  • 异构计算:支持根据模型对资源的需求,灵活地将模型部署并运行于 CPU 或 GPU 类型的节点上。
  • 弹性伸缩:支持依据请求负载,在预设范围内自动调整集群规模,以平衡推理性能与资源开销。火山 EMR Ray 在社区 Autoscale 能力的基础上进一步优化,支持自定义扩缩容指标和策略。
  • 失败容错:支持多副本部署以抵御单副本故障,同时提供针对系统级、应用级的故障恢复能力,当副本或节点出现故障时,可通过重试、重调度等方式确保服务持续运行。
  • 多模型融合:支持在单个 Ray Serve 应用中编排部署多个模型,这些模型可以独立或组合对外提供服务,同时针对各个模型可以独立配置资源调度、弹性伸缩等。
  • 动态批处理:支持按照请求数量和时间跨度对多个请求进行合并,然后批量发送给模型进行处理,通过借助硬件(如 GPU)的并行计算能力,能够在显著提升吞吐量的同时,尽量维持低延迟。
  • 模型多路复用:针对需加载大量模型的应用场景(例如个性化推荐),允许单个应用加载多个模型并向外部提供服务,然而出于资源考量,也会对应用内单副本可加载的模型在数量上加以限制。同时,Ray Serve 会尽可能将请求路由至已完成模型加载的副本进行处理,以平衡推理性能与资源消耗。
  • 支持原生集成 vLLM 实现推理加速:提供与 vLLM 引擎的原生集成能力,通过简单配置即可复用 vLLM 在推理场景中引入的 PagedAttention、动态批处理等多项优化技术,以提升模型推理性能和资源利用率。
  • 支持集成 Nvidia Triton Inference Server 实现优势互补:Triton 针对单机推理场景进行了大量的优化以提升性能,但生产化部署还需要具备负载均衡、弹性伸缩、失败容错,以及模型编排等多方面的能力,通过集成 Triton,能够实现双方优势的有效互补。在集成形态下,Triton 作为单机版的模型推理服务,而 Ray Serve 则承担上层路由与管理职责,提供整体的请求路由、负载均衡、多模型编排,以及弹性伸缩等能力。
  • 简洁的编程模型便于进行本地开发与调试,仅需进行简单修改便可进行线上部署。
  • Python Native。

部署 Ray Serve 作业

说明

现阶段 EMR on VKE 形态仅支持在已创建的 Ray Cluster 中部署 Ray Serve 应用,不支持通过 RayService 方式部署。

参考 EMR Ray on VKE 产品文档 在集群详情页通过 “服务列表 - Ray - 部署拓扑 - KubeRayOperator - 添加 Ray Cluster” 路径新建 Ray Cluster 集群,并采用 YAML 方式新建。鉴于 Ray Serve 应用需开放端口以向外提供 HTTP 服务,您需在 YAML 模板里修改 Ingress 配置并添加以下内容:

- backend:
    service:
      name: ingress-release-name-head-svc
      port:
        number: 8000
  path: /ingress-namespace/ingress-release-name-serve/(.*)
  pathType: Exact

当 Ray Cluster 集群创建成功后,您需跳转至 VKE 产品控制台登录集群的 head 节点,然后执行 serve deploy 命令提交您的 Ray Serve 应用。

推理加速

vLLM 和 Triton Inference Server(严格来说是 Triton Inference Server + Backend) 是目前市面上主流的两款推理加速引擎,分别针对不同场景提供了高效的解决方案。二者核心的区别如下表所示:

vLLM

Triton

功能定位

专为 LLM 推理设计,优化高吞吐、低显存占用场景

通用推理服务器,支持多模型、多框架混合部署,注重灵活性和企业级功能

模型支持

专注于 Transformer 架构,但现阶段仅支持 pyTorch 框架模型

支持多种深度学习框架模型,包括 TensorFlow、PyTorch、ONNX 等,以及其他类型模型,如计算机视觉模型、语音模型、语言模型等

性能优化

  • 采用 PagedAttention 技术,通过分页管理 KV Cache 减少内存碎片化,提升显存利用率
  • 支持动态请求批处理,通过动态合并推理请求,提升吞吐量

通过动态批处理、多 GPU 并行推理等技术提升服务吞吐量,同时配合 TensorRT、ONNX 等 Backend 降低延迟

部署难度

相对容易,对于一些简单场景甚至无需复杂配置即可启动

相对复杂,需要编写一系列配置文件来描述模型的输入输出、数据类型、批大小等

尽管 vLLM 和 Triton 在推理场景中表现出卓越性能,但它们主要聚焦于单机场景,而模型在线推理通常需要多机分布式协作,以保障服务的可用性和可扩展性。通过与 Ray Serve 集成,可在在发挥 vLLM 和 Triton 各自固有优势的同时,弥补二者在分布式场景下的不足。

集成 vLLM 实现推理加速

vLLM 是由加州大学伯克利分校(UC Berkeley)开源的一款具备高吞吐量和内存高效性的 LLM 推理与服务引擎。该引擎借助 PagedAttention、动态批处理、多 GPU 并行推理等多种优化技术,针对 LLM 场景实现了快速、灵活且易用的推理与服务,您可以访问 官方文档 了解关于 vLLM 的更多信息。
Ray Serve 自 2.43 版本开始对 vLLM 提供了原生支持。通过集成 vLLM,在发挥 Ray Serve 固有优势的同时,能够针对 LLM Serving 场景在推理速度和资源利用率等方面进行进一步优化。

说明

LLM APIs 作为 Ray 新引入特性,极大简化了 Ray Data/Serve 集成推理加速引擎(例如 vLLM、SGLang)部署 LLM 的复杂度,但相关 API 也在快速迭代和演进中,如果上述示例不能正常运行,您可以访问 官方文档 了解最新的 API 定义。

本小节以 Llama 3.2 模型介绍如何将 Ray Serve 与 vLLM 进行集成,示例如下:

from ray.serve.llm import LLMConfig, LLMServer, LLMRouter

llm_config = LLMConfig(
    model_loading_config=dict(
        model_id="meta-llama/Llama-3.2-1B-Instruct",
        model_source="/opt/workspace/models/llama/Llama-3.2-1B-Instruct"
    ),
    deployment_config=dict(
        autoscaling_config=dict(
            min_replicas=1, max_replicas=5,
        )
    ),

    # Pass the desired accelerator type (e.g. A10G, L4, etc.)
    accelerator_type="A10G",

    # You can customize the engine arguments (e.g. vLLM engine kwargs)
    engine_kwargs=dict(
        tensor_parallel_size=2,
        pipeline_parallel_size=2,
        dtype='half'
    )
)

# Deploy the application
deployment = LLMServer \
    .as_deployment(llm_config.get_serve_options(name_prefix="vLLM:")) \
    .bind(llm_config)
app = LLMRouter.as_deployment().bind([deployment])

通过执行 serve deploy 命令,可将上述 Ray Serve 应用部署至目标 Ray Cluster 集群。应用成功启动后,可通过以下 POST 请求向模型发送推理请求:

curl --location 'http://127.0.0.1:8000/v1/chat/completions' \
--header 'Content-Type: application/json' \
--data '{
  "model": "meta-llama/Llama-3.2-1B-Instruct",
  "messages": [
    {
      "role": "user",
      "content": "介绍一下 Ray Serve 集成 vLLM 的优势"
    }
  ]
}'

集成 Triton 实现推理加速

Triton Inference Server (简称 Triton)是 Nvidia 推出的高性能推理服务器,支持多种模型框架和硬件平台,关于 Triton 的更多内容可以参考 官方文档。Triton 与 Ray Serve 在功能定位方面存在相同之处,不过二者也各有优势:

  • Ray Serve 原生支持以分布式模式运行,可在单一应用中编排并部署多个模型,以满足复杂推理场景的需求。同时,其内置的弹性伸缩功能能够有效平衡用户请求与资源开销。
  • Triton 主要专注于单机推理场景,兼容多种硬件平台。通过引入动态批处理、多 GPU 并行推理等技术以提升模型推理性能,同时支持以 Backend 插件形式集成多种模型框架,并对外提供统一的接入 API。

如下图所示,通过将 Ray Serve 与 Triton 集成能够让二者的优势形成互补:

本小节将阐述如何实现 Ray Serve 与 Triton 的集成。在集成模式下,Ray Serve 主要承担流量承接、负载均衡、模型编排以及弹性伸缩等职责;而 Triton 则作为单机版的模型推理服务,具备模型加载、推理及加速等功能。 以 Llama 3.2 模型为例,在开始集成前,你需要确保完成:

  1. 编译模型文件生成 TensorRT 引擎,利用 TensorRT-LLM Backend 实现与 Triton 集成,具体操作可以参考 官方文档
  2. 通过 TensorRT-LLM Backend 内置的模型集成配置模板对 Triton 模型仓库进行配置,以便 Triton 能够识别并部署上述模型,具体操作可以参考 官方文档

如下所示,TensorRT-LLM Backend 内置的模型集成配置模板位于 all_models/inflight_batcher_llm 目录下,主要包含 4 个模块,分别对应模型执行过程的不同阶段。

.
|-- ensemble
|   |-- 1
|   `-- config.pbtxt
|-- postprocessing
|   |-- 1
|   |   `-- model.py
|   `-- config.pbtxt
|-- preprocessing
|   |-- 1
|   |   `-- model.py
|   `-- config.pbtxt
`-- tensorrt_llm
    |-- 1
    |   |-- config.json
    |   |-- model.py
    |   `-- rank0.engine
    `-- config.pbtxt

说明

  • 模块 preprocessing 包含用于对输入进行 tokenizing 的脚本,支持将用户输入的 prompt 字符串转换成 input_id 列表。
  • 模块 postprocessing 包含用于对输出进行 de-tokenizing 的脚本,支持将模型输出的 output_id 列表转换成用户能够理解的字符串。
  • 模块 tensorrt_llm 包含用户编译生成的模型文件,负载加载并调用用户自定义模型完成推理操作。
  • 模块 ensemble 用于将 preprocessing、tensorrt_llm 和 postprocessing 模块串联在一起,指导 Triton 如何在这些模块之间传输数据以构建一个完整的推理流程。

注意

  • 由于 ensemble 模块是整个推理模型流程对外接口,因此加载的模型名称为 ensemble。
  • 对于需要 GPU 资源的模型,必须配置 num_gpus 参数,否则 Ray Serve 并不会将 Deployment 调度部署到 GPU 节点上,从而导致 Triton 加载失败。

Triton 提供了 In-Process Python API 用于支持 Python 生态与 Triton 进行集成,相较于发送 HTTP 请求的方式更为便捷。下面的示例通过 Triton In-Process Python API 实现了 Ray Serve 与 Triton 的集成:

import ctypes
from typing import Iterable

import numpy as np
import tritonserver
from fastapi import FastAPI
from ray import serve

api = FastAPI()


@serve.deployment(
    ray_actor_options=dict(
        num_gpus=1
    )
)
@serve.ingress(api)
class Generator:

    def __init__(self, model_path: str):
        import torch
        assert torch.cuda.is_available(), RuntimeError("CUDA is not available")

        self._server = tritonserver.Server(
            tritonserver.Options(
                model_repository=model_path,
                log_info=True,
                log_warn=True,
                log_error=True
            )
        )
        self._server.start(wait_until_ready=True)
        self._model = self._server.model("ensemble")

    @api.get("/generate")
    def generate(self, query: str):
        if not self._model.ready():
            raise RuntimeError("Model is not ready, Please try again later.")

        resp = list(self._model.infer(inputs={
            "text_input": [[query]],
            "max_tokens": np.array([[1024]], dtype=np.int32)
        }))[0]

        return self._to_string(resp.outputs["text_output"])

    def _to_string(self, tensor: tritonserver.Tensor) -> str:
        """
        This method is copied from https://github.com/triton-inference-server/server
        """
        ...


app = Generator.bind("/opt/workspace/models/llama/triton")

通过执行 serve deploy 命令,可将上述 Ray Serve 应用部署至目标 Ray Cluster 集群。应用成功启动后,可通过以下 POST 请求向模型发送推理请求:

curl --location 'http://127.0.0.1:8000/v1/chat/completions' \
--header 'Content-Type: application/json' \
--data '{
  "model": "meta-llama/Llama-3.2-1B-Instruct",
  "messages": [
    {
      "role": "user",
      "content": "介绍一下 Ray Serve 集成 Triton Inference Server 的优势"
    }
  ]
}'