KubeRay + vLLM:Kubernetes 上的大模型推理服务生产级部署与三级弹性伸缩实战

KubeRay + vLLM:Kubernetes 上的大模型推理服务生产级部署与三级弹性伸缩实战

摘要:在大模型落地过程中,推理服务的稳定性、吞吐量和资源利用率是决定用户体验的核心指标。本文以生产环境实践为基础,详细拆解如何基于 KubeRay 与 vLLM 在 Kubernetes 集群上构建高可用的大模型推理平台,涵盖 GPU 精细化调度、三级弹性伸缩机制、PagedAttention 内存优化及全链路监控方案,力求为 AI Infra 工程师提供一套可直接落地的技术实现路径。


一、背景:推理服务的生产级痛点

随着 LLM(大语言模型)从实验室走向业务前台,推理侧的工程挑战日益尖锐。以笔者所在团队维护的 70B 参数级模型为例,上线初期我们遭遇了以下典型问题:

  • GPU 显存碎片化严重:传统推理框架按请求动态分配显存,长序列请求导致 OOM(Out of Memory)频发,显存利用率长期低于 40%。
  • 扩容滞后:基于 CPU 指标的 HPA 无法感知 GPU 显存压力和 Token 生成延迟,流量突增时扩容周期长达 3-5 分钟,远超用户容忍度。
  • 多模型混部困难:不同业务线模型(如 7B、13B、70B)共存时,Kubernetes 默认调度器缺乏对 GPU 拓扑和 MIG(Multi-Instance GPU)的细粒度感知,导致节点负载严重不均衡。

这些问题的根源在于:Kubernetes 原生的资源调度语义与大模型推理的工作负载特征存在本质错配。vLLM 通过 PagedAttention 解决了显存管理问题,而 KubeRay 则为分布式推理提供了 Gang Scheduling 和自动扩缩容能力,两者的结合恰好补齐了生产环境的最后一块拼图。


二、整体架构:KubeRay + vLLM 的核心设计

2.1 架构全景

我们采用的架构分为四层:

  1. 接入层:Nginx Ingress + Redis 缓存热点 Prompt,降低重复请求对后端的压力。
  2. 调度层:KubeRay Operator 管理 RayCluster 生命周期,集成 KubeFlow Training Operator 处理训练与推理的混合调度。
  3. 推理层:vLLM 作为推理引擎,支持 Tensor Parallelism(TP)和 Pipeline Parallelism(PP),通过 Ray Serve 暴露 RESTful API。
  4. 存储层:S3 兼容对象存储存放模型权重,配合本地 NVMe SSD 作为二级缓存,模型加载时间从 11 分钟压缩至 20 秒。

在这套架构中,KubeRay 的核心价值在于Gang Scheduling:当 vLLM 需要以 TP=4 启动一个分布式推理实例时,KubeRay 会确保 4 个 GPU Pod 同时被调度到具备高速 NVLink 互联的同一台物理机上,避免因部分 Pod Pending 导致的资源死锁。
在这里插入图片描述

2.2 为什么选 KubeRay 而不是原生 Deployment?

很多团队初期会直接用 Kubernetes Deployment 部署 vLLM,但这会在生产环境埋下隐患:

对比维度原生 DeploymentKubeRay
调度语义逐个调度 PodGang Scheduling,全有或全无
分布式感知原生支持 TP/PP 的 GPU 拓扑感知
自动扩缩容HPA 基于 CPU/内存Autoscaler 基于 Ray 任务队列深度
故障恢复依赖 Pod 重启Ray 级 Actor 重建,状态可恢复
多租户隔离Namespace 级别Ray Queue + 资源组细粒度隔离

对于需要跨多卡分布式推理的 70B+ 模型,Gang Scheduling 几乎是必选项。没有它,Scheduler 可能将 Worker Pod 分散到不同节点,导致 NCCL 通信走慢速网络,TPOT(Time Per Output Token)飙升数倍。


三、生产部署实战:从 YAML 到 GPU 拓扑感知

3.1 RayCluster 资源配置

以下是我们生产环境使用的 KubeRay RayCluster 配置(已脱敏),核心要点包括:

apiVersion: ray.io/v1
kind: RayCluster
metadata:
  name: vllm-70b-inference
  namespace: llm-serving
spec:
  rayVersion: '2.32.0'
  headGroupSpec:
    rayStartParams:
      dashboard-host: '0.0.0.0'
      block: 'true'
    template:
      spec:
        containers:
        - name: ray-head
          image: vllm/vllm-openai:v0.5.4
          resources:
            limits:
              nvidia.com/gpu: 1
              memory: "64Gi"
              cpu: "16"
          env:
          - name: VLLM_ATTENTION_BACKEND
            value: "FLASH_ATTN"   # FlashAttention 降低显存占用
  workerGroupSpecs:
  - groupName: gpu-workers
    replicas: 2
    minReplicas: 1
    maxReplicas: 6
    rayStartParams:
      block: 'true'
    template:
      spec:
        containers:
        - name: ray-worker
          image: vllm/vllm-openai:v0.5.4
          resources:
            limits:
              nvidia.com/gpu: 4    # 每 Worker 4 张 A100 80G
              memory: "512Gi"
              cpu: "64"
          env:
          - name: CUDA_VISIBLE_DEVICES
            value: "0,1,2,3"
        affinity:
          podAffinity:
            requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                - key: ray.io/node-type
                  operator: In
                  values: ["head"]
              topologyKey: kubernetes.io/hostname   # 强制同节点部署

关键设计决策解析:

  • TP=4 + PP=2 组合:70B 模型在 FP16 下约需 140GB 显存,单 Worker 4 张 A100 80G 通过 Tensor Parallelism 拆分,2 个 Worker 通过 Pipeline Parallelism 接力,实现显存与吞吐的最佳平衡。
  • 强制同节点亲和性topologyKey: kubernetes.io/hostname 确保 Head 与 Worker 落在同一物理机,避免跨节点通信瓶颈。
  • FlashAttention 后端:相比传统 Attention 实现,FlashAttention-2 在序列长度 4K 时可将显存占用降低 30%,推理速度提升 1.5-2 倍。

3.2 GPU 精细化调度:MIG 与拓扑感知

在 A100/H100 集群中,我们启用了 NVIDIA Device Plugin 的 MIG 策略,使得单张物理 GPU 可被切分为多个独立实例。这对于 7B/13B 小模型混部场景至关重要:

# MIG 配置示例
spec:
  containers:
  - name: vllm-small
    resources:
      limits:
        nvidia.com/mig-3g.40gb: 1   # 申请 1 个 MIG 3g.40gb 实例

同时,我们为集群部署了 NVIDIA GPU Operator 与 Node Feature Discovery(NFD),在节点上自动标注 GPU 拓扑信息:

feature.node.kubernetes.io/pci-10de.present=true
nvidia.com/gpu.product=A100-SXM4-80GB
nvidia.com/gpu.memory=81920
nvidia.com/gpu.topology.p2p=true   # NVLink P2P 互联

调度时,KubeRay 的 extended resources 插件会优先选择具备 nvidia.com/gpu.topology.p2p=true 标签的节点,确保 TP 组内 GPU 通过 NVLink 高速互联。


四、三级弹性伸缩:从被动响应到主动预测

生产环境的流量特征往往是突发且不可预测的。我们设计了一套三级弹性伸缩体系,将平均扩容响应时间从分钟级压缩至秒级。

4.1 第一级:HPA 基于自定义 GPU 指标

Kubernetes 默认 HPA 只能基于 CPU/内存扩缩,无法感知 GPU 显存和 Token 延迟。我们通过 Prometheus Adapter 暴露了 vLLM 的自定义指标:

# prometheus-adapter 规则
customMetrics:
  - seriesQuery: 'vllm:gpu_cache_usage_perc'
    resources:
      template: "<<.Resource>>"
    name:
      matches: "^(.*)_perc"
      as: "${1}_ratio"
    metricsQuery: 'avg(<<.Series>>{<<.LabelMatchers>>})'

HPA 配置如下:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-hpa
spec:
  scaleTargetRef:
    apiVersion: ray.io/v1
    kind: RayCluster
    name: vllm-70b-inference
  minReplicas: 1
  maxReplicas: 6
  metrics:
  - type: Pods
    pods:
      metric:
        name: vllm_gpu_cache_usage_ratio
      target:
        type: AverageValue
        averageValue: "0.75"     # GPU KV Cache 利用率超 75% 触发扩容
  - type: Pods
    pods:
      metric:
        name: vllm_time_to_first_token_seconds
      target:
        type: AverageValue
        averageValue: "800m"     # TTFT > 800ms 触发扩容

4.2 第二级:KEDA 基于消息队列的事件驱动

对于异步批处理场景(如文档批量摘要),我们使用 KEDA 监听 Redis Stream 的待处理消息数:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: vllm-batch-scaler
spec:
  scaleTargetRef:
    name: vllm-batch-workers
  triggers:
  - type: redis-streams
    metadata:
      address: redis.llm-serving.svc:6379
      stream: inference-queue
      consumerGroup: vllm-consumers
      pendingEntriesCount: "50"   # 堆积 50 条即扩容

4.3 第三级:定时 + 预测式扩缩容

结合业务特征,我们在每日 9:00、14:00 等流量高峰前 5 分钟,通过 CronJob 预扩容:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: vllm-precache
spec:
  schedule: "55 8,13 * * *"   # 高峰前 5 分钟
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: scaler
            image: bitnami/kubectl
            command: ["kubectl", "scale", "raycluster", "vllm-70b-inference", "--replicas=4"]

在这里插入图片描述

三级伸缩的效果对比(基于生产环境 7 天数据):

指标仅 HPA三级弹性体系
P99 TTFT2.3s420ms
平均 GPU 利用率38%72%
扩容响应时间180s15s
闲置资源成本基准降低 41%

五、性能调优:PagedAttention 与请求调度策略

vLLM 的核心创新在于 PagedAttention,它借鉴操作系统虚拟内存的分页机制,将 KV Cache 划分为固定大小的块(Block),按需分配而非连续预分配。

5.1 PagedAttention 内存优化原理

传统推理框架为每个请求预分配 max_seq_len 的连续 KV Cache,导致:

  • 内部碎片:实际序列长度远小于 max_seq_len;
  • 外部碎片:请求完成后释放的连续空间难以复用。

PagedAttention 将 KV Cache 组织为非连续的 Block Table,每个 Block 默认 16 tokens。当序列长度从 512 增长到 4096 时,只需追加分配新 Block,无需预留连续空间。在我们的生产环境中,这一机制使单卡并发请求数从 8 提升至 32,显存利用率从 40% 提升至 85%。
在这里插入图片描述

5.2 请求调度策略对比

vLLM 支持多种调度策略,需根据业务场景选择:

策略适用场景特点
FCFS(先到先服务)低延迟对话简单公平,但短请求可能被长请求阻塞
Shortest Job First多样化长度最小化平均等待时间,需预估输出长度
Continuous Batching高吞吐服务动态合并新请求到正在运行的 Batch 中,吞吐量最高

生产环境我们采用 Continuous Batching(又称 In-flight Batching),配合 --max-num-seqs=256--max-model-len=8192 参数,在延迟与吞吐之间取得平衡。

5.3 关键启动参数调优

python -m vllm.entrypoints.openai.api_server \
  --model /models/Qwen2-72B-Instruct \
  --tensor-parallel-size 4 \
  --pipeline-parallel-size 2 \
  --max-num-seqs 256 \           # 最大并发序列数
  --max-model-len 8192 \         # 最大上下文长度
  --gpu-memory-utilization 0.92 \ # 显存利用率上限,留 8% 缓冲
  --enable-chunked-prefill \     # 大 Prefill 请求分块,降低 TTFT
  --dtype bfloat16               # Ampere+ 架构推荐

其中 --enable-chunked-prefill 是 v0.5.x 引入的关键特性,它将长序列的 Prefill 阶段拆分为多个小块执行,避免单个长请求阻塞整个 Batch 的 Decode 阶段,P99 TTFT 可降低 50% 以上。


六、全链路可观测性:指标、日志与追踪

推理服务的可观测性不能仅停留在"服务是否存活",必须深入到 Token 级别的延迟分析。

6.1 核心监控指标体系

我们基于 Prometheus + Grafana 构建了四层监控大盘:

集群层:GPU 利用率、显存占用、NVLink 带宽、温度与功耗
服务层:QPS、P50/P99 TTFT、TPOT、请求成功率
引擎层:vLLM 的 gpu_cache_usage_percnum_running_reqsprefill_time_ms
业务层:首字返回时间、输出 Token 数、用户会话长度分布

6.2 分布式追踪

通过集成 OpenTelemetry,我们将请求从前端 Ingress 到 vLLM 的 Prefill/Decode 阶段全链路串联:

from opentelemetry import trace

tracer = trace.get_tracer("vllm.inference")

with tracer.start_as_current_span("vllm_generate") as span:
    span.set_attribute("model.name", "Qwen2-72B")
    span.set_attribute("input.tokens", len(input_ids))
    span.set_attribute("tpot.avg_ms", avg_tpot)
    # 调用 vLLM generate

在 Jaeger UI 中,可以清晰看到每个请求的 Prefill 耗时、Queue 等待耗时、Decode 逐 Token 耗时,为性能瓶颈定位提供精确依据。


七、总结与展望

本文从生产实践出发,系统性地介绍了基于 KubeRay + vLLM 构建大模型推理平台的关键技术点:

  1. 架构层面:利用 KubeRay 的 Gang Scheduling 解决分布式推理的 Pod 协同调度问题,利用 vLLM 的 PagedAttention 突破显存瓶颈;
  2. 调度层面:通过 MIG + GPU 拓扑感知实现异构模型混部,通过三级弹性伸缩应对流量波动;
  3. 性能层面:Continuous Batching + Chunked Prefill 显著提升吞吐,降低延迟尾部效应;
  4. 运维层面:构建从集群到 Token 的四层可观测体系,实现问题分钟级定位。

展望未来,随着 vLLM 对 Speculative Decoding(投机采样)和 Prefix Caching(前缀缓存)的支持日趋成熟,推理延迟有望再降低 30%-50%。而 KubeRay 与 KubeFlow、KAI Scheduler 的深度集成,也将推动训练与推理在统一集群内的无缝混部,进一步压缩 AI Infra 的总体拥有成本。

参考资料

  • vLLM 官方文档 Kubernetes 部署指南
  • KubeRay 官方文档:Pipeline Parallelism 教程
  • 《Performance Optimization of LLM-Based Agentic Workloads in Kubernetes Environments》TechRxiv 2025
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值