更新时间:2026-05-21 GMT+08:00
分享

Kthena ModelServing

随着大语言模型(LLM)参数规模的指数级增长,单一计算节点的显存与算力瓶颈日益凸显。为突破物理资源限制,业界正加速向PD分离(Prefill-Decode Disaggregation)与大/小模型混部等创新架构演进。这一变革促使推理任务的执行模式从单Pod独享转向多Pod协作的分布式形态。

多Pod协作在推理任务中的核心定位:无论是传统的单节点同质化部署,还是复杂的PD分离架构,多Pod协作已成为提升算力利用率、保障端到端延迟(E2E Latency)以及支撑超大规模并行(TP/PP)的必然选择。

Kthena ModelServing专为云原生环境下的LLM推理设计,提供声明式的生命周期管理。其核心目标是突破Kubernetes原生负载(如Deployment/StatefulSet)在拓扑感知、原子调度及复杂推理工作流编排上的局限,为PD分离等高级模式构建坚实底座。

架构设计

为解决Kubernetes原生资源(如Deployment或StatefulSet)在处理多角色协作场景下的局限性,Kthena采用ModelServing → ServingGroup → Role的三层结构,每一层承担不同的职责,共同协作以实现高性能、可扩展的推理服务。

表1 架构层级与职责

层级

管理对象

核心职责

ModelServing

ServingGroup集合

作为全生命周期的统一控制平面,负责维护全局配置一致性,实现版本控制(Revision),提供推理集群的状态查询能力。提供统一接口,管理全局副本和版本。

ServingGroup

Role集合

作为推理服务的独立功能单元,是连接顶层控制与底层执行的逻辑分组。包含完成一次端到端推理所需的所有角色,确保推理逻辑的完整性和独立性。

Role

Pod集合

作为最小的功能执行单元,负责具体的计算任务,由一组具有确定性编号的Pod组成。执行特定的计算或分发任务,例如Prefill和Decode角色的执行。

在Role层级内部,Kthena采用双Pod模板设计,以支持分布式推理场景中的职责解耦,并通过定义特定的环境变量对Pod进行精细化控制和协作。

  • Entry Pod:充当流量入口与任务协调器 。负责接收外部请求并分发计算任务。
  • Worker Pod:计算执行单元。专注于执行实际的张量计算与推理任务。

    为便于客户在业务中识别Pod的角色身份,控制器将自动为Entry和Worker Pod注入以下关键环境变量。

    表2 关键环境变量

    环境变量

    说明

    GROUP_SIZE

    定义当前Role实例中Pod的总数,用于协调Pod之间的协作逻辑。

    ENTRY_ADDRESS

    Entry Pod的内网地址(格式为Headless Service),用于Worker Pod通信。

    WORKER_INDEX

    每个Worker Pod在当前Role实例中的唯一索引,用于身份识别与任务分配。

前提条件

  • 已创建CCE Standard/Turbo集群,集群版本建议为v1.29及以上。
  • 已安装1.21.5及以上版本的Volcano插件:在CCE控制台“插件中心”中搜索并安装 “Volcano调度器” 插件。

    若使用弹性伸缩功能,需安装1.22.3及以上版本的Volcano插件。

在使用Volcano作为调度器时,建议将集群中所有相关工作负载统一使用Volcano调度,以避免调度冲突。

约束与限制

  • ModelServing依赖Volcano调度器插件,若集群未安装该插件,相关功能将无法生效。
  • 当前CCE控制台暂不支持图形化创建ModelServing,需通过kubectl或YAML文件进行部署。
  • 若使用minRoleReplicas,需确保集群资源充足,否则可能导致作业长期处于Pending状态。

关键特性解析

  • 作业调度(Gang Scheduling)

    Kthena深度集成了Volcano调度器,支持“All or Nothing”的原子调度逻辑,有效避免了在分布式推理组中由于部分Pod无法就绪而导致的调度死锁和资源浪费问题。其核心思想为检查Job下的Pod已调度数量是否满足了最小运行数量,当Job的最小运行数量得到满足时,为Job下的所有Pod执行调度动作,否则不执行。

    系统通过minMember计算每个ModelServing实例所需的最小Pod数,保障调度的高效与可控。minMember计算逻辑如下:

    • 默认模式:若未配置minRoleReplicas,系统将基于所有Role的副本数进行统一计算。
      minMember = replicas × role.replicas × (1 + role.workerReplicas)
    • 精细化模式:若配置了minRoleReplicas,系统将根据索引逻辑(从0至minRoleReplicas[roleName] - 1),为每个Role独立计算其必须就绪的最小Pod数量,从而支持更灵活的启动策略。

      配置示例:在本示例中,prefill和decode两个Role各有4个副本,但系统将确保至少2个副本成功调度和就绪,从而提升整体调度效率和资源利用率。

      apiVersion: workload.serving.volcano.sh/v1alpha1
      kind: ModelServing
      metadata:
        name: sample
        namespace: default
      spec:
        schedulerName: volcano
        replicas: 1  # servingGroup replicas
        template:
          restartGracePeriodSeconds: 60
          gangPolicy:
            minRoleReplicas:
              prefill: 2
              decode: 2
          roles:
            - name: prefill
              replicas: 4 
              # ... additional role pod configuration
            - name: decode
              replicas: 4
              # ... additional role pod configuration
  • 滚动更新(Rolling Update)

    Kthena提供了支持基于Partition参数的顺序滚动更新(Rolling Update)的功能。更新策略遵循从最高序号副本(Last Pod)开始的原则,以确保整个更新流程的有序性和稳定性。本文以4副本(R-0至R-3)为例描述状态迁移:

    1. 初始状态:所有副本均为旧版本(R-0至R-3均为就绪状态)。
    2. 更新启动:首先重建序号最高的R-3(状态:重启中)。
    3. 就绪切换:R-3就绪后,开始更新R-2(状态:R-3新版,R-2重启中)。
    4. 持续推进:依次更新R-1、R-0。
    5. 更新完成:所有副本均已完成更新(R-0至R-3均为就绪状态)。

    Partition参数用于设置滚动更新的边界范围。只处理索引值大于或等于Partition的副本。控制器仅在当前副本状态由Pending变为Running,并通过就绪检查后,才会推进到下一个序号副本的更新。

    由于滚动更新需要在新副本running后才会处理下一个副本,如果系统资源不足,导致第一个滚动副本都无法正常启动和就绪,整个更新过程将被阻塞。因此,建议提前预留足够的资源,确保第一个副本能够顺利启动和进入就绪状态,从而避免滚动更新停滞。

  • 重启策略(Recovery Policy)

    该策略定义了当Pod发生故障时,模型的粒度控制与行为模式:

    • ServingGroupRecreate:以ServingGroup为粒度控制。若组内任意一个Pod发生故障,系统将重建该ServingGroup下的所有Pod,以确保整个服务组的高度一致性。
    • RoleRecreate:以Role为粒度控制。若某个Role下的任意Pod发生故障,系统将重建该Role下的所有Pod。

      配置示例:以下YAML展示了如何定义ModelServing资源,其中recoveryPolicy配置为RoleRecreate。

      apiVersion: workload.serving.volcano.sh/v1alpha1
      kind: ModelServing
      metadata:
        name: sample
        namespace: default
      spec:
        schedulerName: volcano
        replicas: 1  # servingGroup replicas
        recoveryPolicy: RoleRecreate
        template:
        # ...

使用示例:ModelServing负载完整用例(以Nginx负载为例)

本示例包含prefill和decode两个Role,其中prefill角色有2个副本,每个副本包含1个Entry和1个Worker,共两个Pod;Decode角色有3个副本,每个副本包含1个Entry和2个Worker,共3个Pod。关于其他调度特性的描述,请查看关键特性解析

apiVersion: workload.serving.volcano.sh/v1alpha1
kind: ModelServing
metadata:
  name: sample
  namespace: default
spec:
  schedulerName: volcano
  replicas: 1  # servingGroup replicas
  recoveryPolicy: RoleRecreate # 重启策略
  template:
    restartGracePeriodSeconds: 60
    gangPolicy: # Gang Scheduling策略
      minRoleReplicas:
        prefill: 2
        decode: 1
    roles:
      - name: prefill
        replicas: 2       # role replicas
        entryTemplate:
          spec:
            containers:
              - name: worker
                image: nginx:latest
                resources:
                  limits:
                    cpu: 250m
                    memory: 512Mi
                  requests:
                    cpu: 250m
                    memory: 512Mi
            imagePullSecrets:
            - name: default-secret
        workerReplicas: 1
        workerTemplate:
          spec:
            containers:
              - name: worker
                image: nginx:latest
                resources:
                  limits:
                    cpu: 250m
                    memory: 512Mi
                  requests:
                    cpu: 250m
                    memory: 512Mi
            imagePullSecrets:
            - name: default-secret
      - name: decode
        replicas: 3  # role replicas
        entryTemplate:
          spec:
            containers:
              - name: worker
                image: nginx:latest
                resources:
                  limits:
                    cpu: 250m
                    memory: 512Mi
                  requests:
                    cpu: 250m
                    memory: 512Mi
            imagePullSecrets:
            - name: default-secret
        workerReplicas: 2
        workerTemplate:
          spec:
            containers:
              - name: worker
                image: nginx:latest
                resources:
                  limits:
                    cpu: 250m
                    memory: 512Mi
                  requests:
                    cpu: 250m
                    memory: 512Mi
            imagePullSecrets:
            - name: default-secret

使用示例:自动扩缩容用例(以vllm负载为例)

Kthena采用策略与目标解耦的设计模式,通过两个核心自定义资源(CRD)实现弹性伸缩的灵活配置:

  • AutoscalingPolicy:定义扩缩容策略,包含监控指标、目标值、稳定/紧急模式配置、观测窗口等参数。
  • AutoscalingPolicyBinding:定义伸缩目标,将策略绑定到具体的ModelServing或Role,并设置副本数限制、指标拉取端点等运行约束。

Pod需以Prometheus兼容格式(例如,vLLM内置的/metrics端点)暴露业务指标,Autoscaler将定期从此端点抓取指标以驱动扩缩容决策。

AutoscalingPolicy示例

以下示例展示了如何以vllm:num_requests_waiting为指标,对vllm-modelserving负载进行以ServingGroup或Role级别的扩缩配置。

apiVersion: workload.serving.volcano.sh/v1alpha1
kind: AutoscalingPolicy
metadata:
  name: vllm-scaling-policy
spec:
  metrics:
  - metricName: vllm:num_requests_waiting 
    targetValue: 100 
  tolerancePercent: 10 
  behavior:
    scaleUp:
      panicPolicy:
        panicThresholdPercent: 150
        panicModeHold: 5m
      stablePolicy:
        stabilizationWindow: 1m
        period: 30s
    scaleDown:
      stabilizationWindow: 5m
      period: 1m

字段

说明

metricName

从Pod/metrics端点抓取的指标名称。

targetValue

每个副本期望的指标平均值。观测值持续超过此值将触发扩容。

tolerancePercent

容差百分比。例如,10%表示指标在[90, 110]范围内时不触发伸缩,避免抖动。

scaleUp.panicPolicy

紧急扩容策略,用于流量激增时快速响应。

panicThresholdPercent

紧急模式的触发阈值(基于targetValue)。150%表示指标达到150 (100 * 1.5) 时立即进入紧急模式。

panicModeHold

紧急模式保持时长,防止频繁退出紧急模式并误缩容。

scaleUp.stablePolicy

标准的稳定扩容策略,基于持续趋势决策。

stabilizationWindow

稳定窗口时长。例如,1m表示必须连续1分钟观测到指标高于目标值,才执行扩容,防止误触发。

period

评估周期,Autoscaler按此周期计算指标并决策。

scaleDown

缩容配置,通常设较长的stabilizationWindow以避免Pod频繁启停。

AutoscalingPolicyBinding示例

  • 绑定到整个ModelServing(ServingGroup级别)
    apiVersion: workload.serving.volcano.sh/v1alpha1
    kind: AutoscalingPolicyBinding
    metadata:
      name: vllm-scaling-binding
    spec:
      policyRef:
        name: vllm-scaling-policy
      homogeneousTarget:
        target:
          targetRef:
            kind: ModelServing
            name: vllm-modelserving
            namespace: default
          metricEndpoint:
            uri: "/metrics"
            port: 8000
        minReplicas: 2
        maxReplicas: 8

    字段

    描述

    policyRef

    引用包含伸缩逻辑(指标、阈值等)的AutoscalingPolicy。

    homogeneousTarget

    当伸缩单实例类型时使用。包含目标识别信息和伸缩约束。

    targetRef

    指定要伸缩的顶层资源。

    minReplicas

    该ServingGroup允许的最小副本数。

    maxReplicas

    该ServingGroup允许的最大副本数。

  • 绑定到ModelServing中的特定Role(Role级别)
    apiVersion: workload.serving.volcano.sh/v1alpha1
    kind: AutoscalingPolicyBinding
    metadata:
      name: vllm-scaling-binding
    spec:
      policyRef:
        name: vllm-scaling-policy
      homogeneousTarget:
        target:
          subTargets:
            kind: Role
            name: decode
          targetRef:
            kind: ModelServing
            name: vllm-modelserving
            namespace: default
          metricEndpoint:
            uri: "/metrics"
            port: 8000
        minReplicas: 2
        maxReplicas: 8

    字段

    描述

    subTargets

    可选。用于对目标内部的特定组件进行精细化伸缩。

    subTargets.kind

    子目标类型,此处固定为Role。

    subTargets.name

    ModelServing中定义的角色名称(例如,decode)。

    minReplicas

    该特定Role允许的最小副本数。

    maxReplicas

    该特定Role允许的最大副本数。

相关文档