AIBrix StormService#
StormService 是一个专门组件,旨在管理和协调 Prefill/Decode 分离架构中推理容器的生命周期。此外,它还可用于监督各种部署模式,例如张量并行(TP)、流水线并行(PP),甚至单 GPU 模型部署。
三层架构#
StormService 采用三层架构,通过多个自定义资源定义(CRD)实现。此架构的示例如下所示:
StormService:这是封装整个服务的顶层 CRD。它定义了服务单元的规范并跟踪其状态,包括副本数(即 RoleSet)、RoleSet 的统一模板、更新策略和其他配置。有关详细定义,请参阅 stormservice_types.go 文件。
RoleSet:RoleSet 代表角色集合,其中每个角色都可以承担特定功能(例如 Prefill 或 Decode)。有关更多信息,请参阅 roleset_types.go 文件。
Pods:RoleSet 中的每个角色都包含多个 Pod,这些 Pod 是执行推理任务的实际容器。
遵循此分层设计,规范的更新从 StormService 传播到其 RoleSet,然后传播到单个角色。StormService 级别的协调器将 RoleSet 的状态与 StormService 规范(主要是 Replicas 字段)同步,而 RoleSet 级别的协调器将单个角色的状态与 RoleSet 规范同步。
StormService 在其级别支持两种操作模式:滚动更新和原地更新。在 RoleSet 级别,支持三种更新模式:并行、顺序和交错。这些将在下面详细解释。
部署模式#
Stormservice 支持两种部署模式:副本模式和池化模式。
注意
这两种模式互斥。没有专门的配置项来明确指定部署模式;它仅由 stormservice.spec.replicas 字段控制。
StormService 的部署模式是自动确定的,当 replicas > 1 时激活副本模式,当 replicas = 1 时激活池化模式。
副本模式#
副本模式将每个 RoleSet 视为服务的独立副本。如果您已经知道 P/D 比率,可以直接配置 RoleSet 并进行复制。
特性
独立副本:每个 RoleSet 独立运行,对一个 RoleSet 的更改不会直接影响其他 RoleSet。
RoleSet 级别的伸缩:伸缩操作通过添加或删除整个 RoleSet 实例来执行。
池化模式#
池化模式将 RoleSet 中的每个角色视为共享池的一部分。在此模式下,每个角色都应该是独立可伸缩的。它旨在处理不同角色具有不同伸缩需求的情况。
特性
资源池:Prefill 或 Decode 实例形成一个共享池。
独立角色伸缩:每个角色都可以根据其特定的负载和要求独立伸缩。
更新策略#
StormService 支持多种策略来更新托管的 RoleSet。这些策略旨在处理不同的操作模式,并确保更新过程中的服务可用性。以下是对每种策略的详细解释:
滚动更新#
专为副本模式设计,滚动更新策略逐步用新的 RoleSet 替换旧的 RoleSet。这种方法通过遵守 MaxUnavailable 和 MaxSurge 设置,确保服务在整个更新过程中保持可用。
工作原理
初始状态:开始时,所有 RoleSet 都运行旧版本。
创建新 RoleSet:控制器创建具有更新版本的新 RoleSet,确保 RoleSet 的总数(旧 + 新)不超过期望副本数和 MaxSurge 的总和。
删除旧 RoleSet:一旦新 RoleSet 准备就绪,控制器开始删除旧 RoleSet。它确保任何时候不可用的 RoleSet 数量不超过 MaxUnavailable。
重复:重复步骤 2 和 3,直到所有旧 RoleSet 都被新 RoleSet 替换。
配置参数
MaxUnavailable:此参数定义了在更新过程中可以不可用的最大 RoleSet 数量。它确保始终有最小数量的 RoleSet 可用于服务请求。
MaxSurge:此参数定义了在更新过程中可以创建的超出所需副本数量的最大 RoleSet 数量。它允许控制器暂时创建额外的 RoleSet 以加速更新。
示例
假设我们有一个具有 3 个副本的 StormService,MaxUnavailable 设置为 1,MaxSurge 设置为 1。滚动更新过程可能如下所示:
graph LR
classDef old fill:#FFCCCC,stroke:#CC0000,stroke-width:2px;
classDef new fill:#CCFFCC,stroke:#00CC00,stroke-width:2px;
A(Initial: 3 old RoleSets):::old --> B(Create 1 new RoleSet):::new
B --> C(Delete 1 old RoleSet):::old
C --> D(Create 1 new RoleSet):::new
D --> E(Delete 1 old RoleSet):::old
E --> F(Create 1 new RoleSet):::new
F --> G(Delete 1 old RoleSet):::old
G --> H(Result: 3 new RoleSets):::new
原地更新#
专为池化模式设计,原地更新策略将更改直接从 StormService 传播到所有关联的 RoleSet,而无需删除和创建新的 RoleSet。当您希望更新 RoleSet 的配置而不中断现有 Pod 时,此策略非常有用。工作原理:
工作原理
识别过时的 RoleSet:控制器识别所有未使用最新版本的 RoleSet。
更新 RoleSet:控制器直接将过时 RoleSet 的配置更新为最新版本。
同步状态:RoleSet 级别的协调器然后根据更新后的规范同步其状态。
优点
最小中断:由于没有 RoleSet 被删除或创建,服务在更新过程中保持可用。
快速更新:更新过程更快,因为它不涉及资源的创建和删除。
无需额外 GPU:它不需要创建新的 RoleSet,从而避免在升级时使用更多 GPU。
graph LR
classDef old fill:#FFCCCC,stroke:#CC0000,stroke-width:2px;
classDef new fill:#CCFFCC,stroke:#00CC00,stroke-width:2px;
A(Initial: 3 old RoleSets):::old --> B(Update 3 RoleSets in-place)
B --> C(Result: 3 new RoleSets):::new
滚动策略#
StormService 支持多种滚动策略来更新 RoleSet 中的角色。这些策略提供了不同的方法来管理更新,同时保持服务稳定性。
顺序:角色一个接一个地按顺序更新。
并行:所有角色同时更新。
交错:角色以交错方式更新。此策略将每个 Role 的更新过程划分为不同的步骤。每个更新步骤都在所有角色中进行协调以同步进行。在每个操作周期中,控制器根据最不先进的角色确定全局进度状态。它指示尚未达到当前步骤的角色继续更新,而跳过已达到当前步骤的角色。
有状态与无状态#
这由 StormService 和 RoleSet 规范中的 Stateful 字段决定。它定义 RoleSet 是使用 StatefulRoleSyncer 还是 StatelessRoleSyncer,这会导致不同的行为。
有状态:StatefulRoleSyncer 将每个 Pod 视为一个唯一的、不可互换的实体,为每个 Pod 分配一个稳定且唯一的索引。有 n 个副本就有 n 个槽位,更新以受控的方式逐槽位执行。
无状态:StatelessRoleSyncer 将所有 Pod 视为相同的副本。任何 Pod 都可以被替换而不会影响整个应用程序。Pod 被作为一个集体池进行管理,伸缩操作只是添加或随机删除 Pod。更新是在池级别执行的,而不是针对特定 Pod。
自动伸缩#
副本模式:StormService 在其 CRD 上启用了 /scale 子资源。伸缩单位是 RoleSet。它涉及使用动态标签选择器扩展 StormService 状态,并实现控制器逻辑以确保此选择器正确填充,从而允许外部自动伸缩器有效管理 StormService 副本。
池化模式:在池化模式下,RoleSet 中的每个角色都应该是独立可伸缩的。
警告
池化模式自动伸缩(每个角色的独立伸缩)尚未支持。有关更多详细信息,请参阅问题 #1260。作为替代方案,您可以在 RoleSet 规范中调整每个角色的副本数。
ControllerRevision#
在 Kubernetes 生态系统中,ControllerRevision 是一个关键的资源对象,用于记录控制器(如 Deployment、StatefulSet 等)的版本信息。在 AIBrix 项目中,ControllerRevision 机制被用于跟踪 StormService 的版本变化,为版本管理、回滚操作和系统状态可追溯性提供强有力的支持。
版本记录:ControllerRevision 存储 StormService 特定版本的配置信息,主要是 spec 部分。每当 StormService 的配置发生变化时,系统就会创建一个新的 ControllerRevision 对象,并将更改后的配置以序列化形式存储在此对象中。通过这种方式,系统可以清晰地记录 StormService 在不同时间点的配置状态。
版本回滚:当需要将 StormService 恢复到以前的配置状态时,可以根据 ControllerRevision 中保存的历史配置信息执行回滚操作。通过指定目标 ControllerRevision 的版本号,系统可以将 StormService 的配置恢复到与该版本对应的状态。
历史可追溯性:ControllerRevision 为系统运维和开发人员提供了追溯历史配置的能力。通过查看不同版本的 ControllerRevision 对象,可以了解 StormService 配置的变更历史,这有助于问题排查和系统审计。
kubectl get controllerrevisions
NAME CONTROLLER REVISION AGE
llm-xpyd-69df6b87d8 stormservice.orchestration.aibrix.ai/llm-xpyd 1 73s
llm-xpyd-75ddc56d8c stormservice.orchestration.aibrix.ai/llm-xpyd 2 3s