https://www.anyscale.com/blog/llm-apis-ray-data-serve 译文


一、引言

2025年4月2日,我们激动地宣布在 Ray Data 和 Ray Serve 中为 LLM 推理提供原生 API。

随着 LLM 在现代 AI 基础设施部署中变得越来越核心,平台需要能够高效地部署和扩展这些模型。虽然 Ray Data 和 Ray Serve 很适合快速部署和扩展这些模型,但开发人员必须编写大量冗余代码才能利用这些库来扩展 LLM 应用程序。

  • 在 Ray 2.44 中,我们正式发布 Ray Data LLM 和 Ray Serve LLM。

  • Ray Data LLM 提供用于现有 Ray Data pipeline 中对 LLM 进行离线批量推理的 API。

  • Ray Serve LLM 提供用于 Ray Serve 应用程序中为在线推理部署 LLM 的 API。

这两个模块均支持与 vLLM 和 OpenAI 兼容的endpoint的无缝集成。

二、Ray Data LLM

ray.data.llm 模块与关键的大型语言模型(LLM)推理引擎和已部署模型集成,以实现 LLM 批量推理。

Ray Data LLM 旨在解决开发人员在批量推理过程中遇到的几个常见痛点:

  • 我们发现许多用户正在为高吞吐量的批量推理构建临时解决方案。这些解决方案一般需要启动多个在线推理服务器,并构建额外的代理/负载均衡工具来最大化吞吐量。为了解决这个问题,我们希望利用 Ray Data 并利用其预先构建的分布式数据加载和处理功能。

  • 我们发现用户常将批量数据发送至现有推理服务器。为了解决这个问题,我们希望确保用户可以将其数据pipeline与 OpenAI 兼容的 API endpoint集成,并为用户提供灵活的模板化查询功能,以便向服务器发送查询。

  • 我们观察到用户正在将大型语言模型(LLMs)集成到现有的 Ray Data pipeline中(链接 LLM 后处理阶段)。为了解决这个问题,我们希望确保该 API 与现有的惰性加载和函数式的 Ray Data API 兼容。

图片

在使用 Ray Data LLM时,用户可以创建一个 Processor 对象,该对象可以对 Ray Data Dataset 进行调用,并返回一个 Ray Data Dataset。其中该 Processor 对象将包含如下配置:

  • 提示词和模板

  • OpenAI 兼容的采样参数,这些参数可以按行进行指定

  • vLLM 引擎配置(如果适用)

import ray
from ray.data.llm import vLLMEngineProcessorConfig, build_llm_processor
import numpy as np
config = vLLMEngineProcessorConfig(
    model="meta-llama/Llama-3.1-8B-Instruct",
    engine_kwargs={
        "enable_chunked_prefill": True,
        "max_num_batched_tokens": 4096,
        "max_model_len": 16384,
    },
    concurrency=1,
    batch_size=64,
)
processor = build_llm_processor(
    config,
    preprocess=lambda row: dict(
        messages=[
            {"role": "system", "content": "You are a bot that responds with haikus."},
            {"role": "user", "content": row["item"]}
        ],
        sampling_params=dict(
            temperature=0.3,
            max_tokens=250,
        )
    ),
    postprocess=lambda row: dict(
        answer=row["generated_text"],
        **row  # This will return all the original columns in the dataset.
    ),
)
ds = ray.data.from_items(["Start of the haiku is: Complete this for me..."])
ds = processor(ds)
ds.show(limit=1)

在上面这个特定示例中,Processor 对象将:

  • 执行必要的预处理和后处理,以正确处理 LLM 的输出。

  • 根据指定的并发度和提供的引擎配置,实例化并配置多个 vLLM 副本。这些副本本身也可以进一步分布式部署。

  • 通过利用 Ray 中的异步 actor 持续为每个副本提供数据,以利用连续批处理并最大化吞吐量。

  • 调用各种 Ray Data 方法(map、map_batches),这些方法可以在执行过程中由 Ray Data 将他们与pipeline中的其他预处理阶段进行融合和优化。

正如您所见,Ray Data LLM 可以轻松简化在您现有数据pipeline中使用 LLM 的过程。更多详情请参阅文档

三、Ray Serve LLM

Ray Serve LLM API 允许用户使用熟悉的 Ray Serve API 同时部署多个 LLM 模型,同时兼容 OpenAI API

Ray Serve LLM 的设计具有以下特点:

  • 自动扩展和负载均衡

  • 统一的多节点多模型部署

  • OpenAI 兼容性

  • 支持多 LoRA 模型并共享基础模型

  • 与推理引擎(从 vLLM 开始)的深度集成

  • 可组合的多模型 LLM 管道

尽管 vLLM 在过去一年中发展迅速,但我们观察到越来越多的用户开始利用Ray Serve部署vLLM以支持多个模型,并构建更复杂的pipeline。

对于生产部署,Ray Serve + vLLM 可以绝佳的互补。

图片

vLLM 提供了一个简单的抽象层,能够以高吞吐量和低延迟的方式支持数百个不同的模型。然而,vLLM 仅负责单个模型实例,而在生产部署中,通常需要一个编排层,以便能够自动扩展、处理不同的微调适配器、处理分布式模型并行,以及构建可能非常复杂的多模型复合 AI pipeline。

Ray Serve 的构建旨在弥补 vLLM 在扩展和生产化方面的不足。Ray Serve 提供:

  • 用于自动扩展的 Pythonic 风格API

  • 内置对模型复用的支持

  • 提供一种 Python 风格的、命令式的方式来编写复杂的多模型/部署管道

  • 通过利用 Ray,为分布式模型并行提供了一流的支持。

以下是一个简单示例,演示如何使用 Ray Serve 在本地计算机上部署一个 Qwen 模型,该计算机配备两块GPU并连接至与OpenAI兼容的路由器,然后使用 OpenAI 客户端对其进行查询。

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

llm_config = LLMConfig(
    model_loading_config=dict(
        model_id="qwen-0.5b",
        model_source="Qwen/Qwen2.5-0.5B-Instruct",
    ),
    deployment_config=dict(
        autoscaling_config=dict(
            min_replicas=1, max_replicas=2,
        )
    ),
    # 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,
    ),
)

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

然后使用 OpenAI Python API 对其进行查询:

from openai import OpenAI

# Initialize client
client = OpenAI(base_url="http://localhost:8000/v1", api_key="fake-key")

# Basic chat completion with streaming
response = client.chat.completions.create(
    model="qwen-0.5b",
    messages=[{"role": "user", "content": "Hello!"}],
    stream=True
)

for chunk in response:
    if chunk.choices[0].delta.content is not None:
        print(chunk.choices[0].delta.content, end="", flush=True)

更多详情请访问文档

Ray Serve LLM 也可以通过使用 KubeRay 在 Kubernetes 上进行部署。更多详情请参阅Ray Serve production guide

四、未来发展

欢迎试用这些新功能并向我们反馈!如果您有兴趣与开发人员交流,欢迎加入the Ray Slack讨论,并在此处关注 Ray Serve LLM 和 Ray Data LLM 的路线图以获取未来更新。

Ray 中文社区

Ray 是 UC Berkeley RISELab 针对机器学习领域开源的一种新的分布式计算引擎,用于构建在任何规模下运行的分布式应用。在国内,Ray 中文社区是由蚂蚁集团和 Anyscale 共同运营的针对中国技术爱好者的宣传沟通渠道。

  • GitHub:https://github.com/ray-project/ray

  • Ray 中文问答:https://ray.osanswer.net 

  • Anyscale官网:https://www.anyscale.com

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐