最新n1n v2.0.1 正式上线!企业级大模型接口聚合平台 (LLM API Gateway),为您接入 500+ AI Models,价格低至 1 折, 立即尝试

从 TorchServe 迁移至 Ray Serve 深度学习容器并在 Amazon EKS 上部署

作者
  • avatar
    姓名
    Nino
    职业
    Senior Tech Editor

随着生产级机器学习基础设施的不断演进,开源模型推理服务的技术栈迎来了重大转折。过去几年中,由 AWS 和 PyTorch 团队共同维护的 TorchServe 一直是 PyTorch 模型大规模部署的行业标准。然而,随着 TorchServe 项目维护活力的逐渐衰退,MLOps 与基础架构团队正面临严峻挑战:不得不自行承担整个复杂且易变的 GPU 推理栈的维护工作。在企业内部维护底层 CUDA 驱动、PyTorch 运行时依赖、C++ 编译层以及上层服务框架,带来了巨大的运维负担。

为了解决这一痛点,AWS 官方推出了 Ray Serve 深度学习容器 (Deep Learning Containers, DLC)。这些预先经过严格测试与优化的容器镜像集成了完整的 GPU 驱动程序栈、Python 运行环境、Ray 核心框架以及 vLLM 和 FlashAttention 等底层推理加速组件。通过采用 Ray Serve DLC,工程团队能够彻底摒弃自行维护且脆弱的自定义 Docker 镜像,全面拥抱获得长期支持的云原生 AI 生态。

在构建可扩展的 AI 服务架构时,高可用性部署往往需要将基于 Ray Serve 的自建微服务与像 n1n.ai 这样的外部 API 聚合服务相结合,以应对流量高峰突发、故障转移路由以及对顶级商业模型的混合调用需求。本文将详细讲解如何从 TorchServe 迁移至 Amazon EKS 上的 Ray Serve DLC,并在单 GPU 节点上实现视觉语言模型 (VLM) 的部署与优化。


技术演进:TorchServe 与 Ray Serve DLC 架构对比

TorchServe 采用了 Java 前端与 Python 工作进程相结合的双层架构,这不可避免地引入了跨进程通信 (IPC) 瓶颈与数据序列化开销。此外,在支持现代大语言模型 (LLM) 和视觉语言模型 (VLM) 的核心特性(如动态 Token 流式传输、PagedAttention 内存管理以及流水线并行)时,TorchServe 需要编写极其复杂的自定义 Handle 逻辑。

相比之下,Ray Serve 构建于分布式 Ray Core 运行时之上,采用了纯 Python 的 Actor 模型。这一架构设计天然契合现代 AI 软件栈的发展趋势。

架构特性TorchServeAWS Ray Serve DLC
维护状态逐渐停止维护 / 社区活跃度低AWS 与 Anyscale 官方持续维护
控制平面核心Java (结合 C++ / IPC 接口)原生 Python Ray Actor
多节点扩展依赖复杂的外部编排基于 Ray Core 实现原生集群管理
现代 LLM/VLM 支持需要手动集成底层引擎预装主流加速库 (vLLM, FlashAttention-2)
驱动与依赖栈需要手动构建 DockerfileAWS 预先测试封装 (CUDA, PyTorch, Ray, vLLM)
细粒度 GPU 分配自定义 Worker 管理困难原生支持 num_gpus=0.5 共享分配

深入剖析:AWS Ray Serve 深度学习容器架构

AWS Ray Serve DLC 通过预先打包与 AWS EC2 GPU 实例(例如 g5p4dp5 系列)硬件高度兼容的软件层,彻底消除了“依赖地狱”问题。

+-----------------------------------------------------------------------+
|                       Ray Serve 应用层 (Application Layer)              |
|         (Python FastAPI 端点、模型弹性扩缩容与路由逻辑)                     |
+-----------------------------------------------------------------------+
|                    LLM / VLM 推理引擎层 (Inference Engines)             |
|             (vLLM, Transformers, HuggingFace Accelerate)              |
+-----------------------------------------------------------------------+
|                        Ray Core 分布式引擎层                           |
|             (Ray Actors, 任务调度器, 分布式 Plasma 内存存储)             |
+-----------------------------------------------------------------------+
|                   CUDA / cuDNN / NCCL / FlashAttention 基础库          |
+-----------------------------------------------------------------------+
|               基础操作系统 (Ubuntu)PyTorch GPU 运行时               |
+-----------------------------------------------------------------------+

在构建企业级 AI 应用时,使用预验证的容器镜像能够确保极高的基础性能。然而,对于要求零停机时间和在开源模型与商业闭源模型之间实现自动故障转移的应用,在 EKS 集群之外集成像 n1n.ai 这样的统一 API 聚合平台,能够为架构师提供跨自建端点与托管大模型 API 的无缝路由能力。


实战指南:在 Amazon EKS 上部署视觉语言模型 (VLM)

接下来,我们将使用 AWS Ray Serve DLC 在配备 NVIDIA A10G GPU 的 Amazon EKS 节点(如 g5.xlarge 实例)上部署一个轻量级视觉语言模型。

第一步:集群准备与 KubeRay Operator 安装

首先,请确保您的 EKS 集群已配置好 NVIDIA GPU Operator。使用 Helm 安装 KubeRay Operator:

helm repo add kuberay https://ray-project.github.io/helm-charts/
helm repo update

# 安装 KubeRay Operator
helm install kuberay-operator kuberay/kuberay-operator --version 1.1.0 \
  --namespace kuberay-operator \
  --create-namespace

第二步:编写 Ray Serve VLM 服务端代码

创建一个名为 vlm_serve.py 的 Python 脚本。该脚本定义了一个异步 Ray Serve 部署,利用 PyTorch 和 HuggingFace Transformers 加载视觉语言模型(例如 SmolVLMQwen2-VL):

import torch
from PIL import Image
import io
import base64
from fastapi import FastAPI, UploadFile, File, Form
from ray import serve
from transformers import AutoProcessor, AutoModelForVision2Seq

app = FastAPI()

@serve.deployment(
    num_replicas=1,
    ray_actor_options=\{"num_gpus": 1, "num_cpus": 4\}
)
@serve.ingress(app)
class VLMDeployment:
    def __init__(self):
        # 指定模型权重路径
        self.model_id = "HuggingFaceTB/SmolVLM-Instruct"
        print(f"正在将模型 \{self.model_id\} 加载至 GPU...")
        
        self.processor = AutoProcessor.from_pretrained(self.model_id)
        self.model = AutoModelForVision2Seq.from_pretrained(
            self.model_id,
            torch_dtype=torch.bfloat16,
            device_map="auto"
        )
        print("VLM 模型初始化完成。")

    @app.post("/v1/analyze")
    async def analyze_image(
        self, 
        prompt: str = Form(...), 
        image: UploadFile = File(...)
    ):
        # 异步读取上传的图像数据
        image_bytes = await image.read()
        pil_image = Image.open(io.BytesIO(image_bytes)).convert("RGB")

        # 按照模型规范构建 Prompt 消息结构
        messages = [
            \{
                "role": "user