构建AI应用的团队需要一条从模型配置到可用推理端点的可重复路径。NVIDIA Dynamo 是一个分布式推理框架,用于协调跨 GPU 工作节点的模型服务。在 Kubernetes 上部署它只是第一步。成功的模型部署还需要更多:GPU 驱动程序、资源分配、调度、网络和监控都必须协同工作。解决这些依赖关系会占用本应用于测试模型行为、服务性能和应用集成的时间。
NVIDIA DSX AI Factory Platform 汇集了多项技术,帮助生态系统设计、构建和运行更高效的 AI 工厂,Dynamo 就是其中之一。为了让基础设施依赖关系的管理更加轻松,该平台包含 NVIDIA AI Cluster Runtime(AICR)。它将 NVIDIA Dynamo 及其配套基础设施打包成经过验证的方案(recipe)。每个方案都针对特定环境和工作负载定义了相应配置,包括固定的组件版本、兼容性约束和验证检查。AICR 为平台团队提供了一种可重复的方式来部署和检查运行时,从而为开发者提供用于服务模型和测试应用的一致基础。
本文将介绍支持 Dynamo 在 Kubernetes 上运行的基础设施,比较两种路由选项,并展示如何使用 AICR 部署和验证运行时。
为什么底层运行时对 Dynamo 很重要
在 Kubernetes 上使用 Dynamo 运行模型,始于 DynamoGraphDeployment,它指定了 vLLM、SGLang 或 NVIDIA TensorRT LLM 应如何在集群的 Pod 中运行。但这个图(graph)只是技术栈的顶层。生产级推理集群在其下方还需要一个运行时层,它必须解答以下问题:
是否安装了与节点匹配的驱动堆栈的 NVIDIA GPU Operator?
GPU 节点是否已被标记且可被发现?
集群是否通过预期的动态资源分配(DRA)驱动程序来暴露 GPU?
调度器能否按所需的拓扑结构和成组调度(gang scheduling)语义来部署 GPU 工作节点?
在工作负载落到异常节点之前,节点健康信号是否可用?
Prometheus 是否可以访问 Dynamo 和加速器的相关指标?
当部署需要在入口处实现 Kubernetes 原生方式时,是否配置了 Gateway API / Endpoint Picker(EPP)路径?
AICR 在方案中捕获了这些运行时需求。
AICR 为 Dynamo 提供了什么
一个 AICR Dynamo 方案打包了 Dynamo 本身及其所依赖的集群运行时组件。
AICR 提供了 1.4.2 版本的 dynamo-platform chart,其中包括 Dynamo 操作器(operator)、Dynamo 运行时镜像,以及诸如 nvidia.com/v1beta1 DynamoGraphDeployment 自定义资源定义(CRD)之类的资源。v1beta1 取代了之前的 v1alpha1 API 版本。
表 1 列出了方案中包含的配套基础设施组件。
此外,该方案还固定了组件版本,并记录了配置值、节点选择器、容忍度(tolerations)、校验和以及验证预期,以确保部署的可重复性。
在 Dynamo 1.4 中,前端、工作节点、可选的 Gateway API Inference Extension(GAIE)/ Endpoint Picker Plugin(EPP)组件,以及其他 Dynamo 服务通过 Kubernetes 资源相互发现。因此,AICR 的默认路径不再使用 NATS,dynamo-platform chart 也不再默认安装它。对于需要它的部署,NATS 仍可作为可选项使用。
智能体工作负载会反复扩展较长的 Token 前缀,包括系统提示、工具定义、对话历史和工具结果。如果某一轮对话到达的工作节点的 GPU 内存中没有该前缀,系统就会重新处理中间 Token,而不是复用缓存结果。Dynamo 会通过其前端路由器,或通过 Gateway API 层的 GAIE/EPP 集成,将请求路由到已经保存了相关 KV 块的工作节点。
Dynamo 还可以将提示处理(prefill)与 Token 生成(decode)分离,这种架构被称为分离式服务(disaggregated serving)。当出现 KV 缓存未命中时,提示的全部或部分内容必须由 prefill 池重新处理。随后,decode 工作节点接管逐 Token 生成,其在 GPU、内存、延迟和批处理方面具有不同的特性。缓存未命中率取决于工作负载:长时间运行的智能体会话与一次性聊天请求的表现不同。分离式服务使运营者能够针对特定的请求组合,独立扩展和调整 prefill 与 decode 的容量。
请求平面与 KV 缓存事件平面是分离的。在 Dynamo 1.4.2 中,AICR 默认的 Kubernetes 路径对请求使用 TCP,对 KV 缓存事件使用 ZMQ。每个 vLLM 工作引擎都会通过本地 ZMQ 发布者发出原始 KV 缓存事件,例如,通过以下 vLLM 配置:
--enable-prefix-caching --kv-transfer-config \ {"enable_kv_cache_events": true, "publisher": "zmq", "endpoint": "tcp://*:5557"}
随后,Dynamo 的工作节点运行时会订阅该本地 vLLM 事件源,对事件进行归一化处理,并将其重新发布到 Dynamo 事件平面上。无论是原生的 Dynamo 前端路由器,还是 GAIE/EPP 路径,都会利用这一由 Dynamo 管理的 KV 缓存状态来做出路由决策。
Kubernetes 上的 Dynamo 路由路径有哪些?
Dynamo 在 Kubernetes 上支持两种路由路径。第一种使用 Dynamo 前端路由器进行工作节点选择。第二种使用 Kubernetes Gateway API 实现方式进行入口接入,并使用 Dynamo EPP 进行端点选择。AICR 为这两种拓扑结构提供并验证 Dynamo 运行时。
路径一:Dynamo 前端路由器
默认路径是在 Kubernetes Service 后面暴露一个 Dynamo 前端。在 DYN_ROUTER_MODE=kv 模式下运行时,前端会对每个请求进行分词处理,基于前缀重叠度和当前负载对符合条件的工作节点进行评分,选择一个工作节点,并通过默认使用 TCP 的 Dynamo 请求平面分发请求。
当应用团队拥有专属于某个模型的端点,或现有的边缘代理只需要将流量转发到 Dynamo 前端 Service 时,这种路径就比较合适。这是部署和验证 Dynamo 图(graph)所需的最小拓扑结构,也是经过生产环境验证最充分的服务选项。它不需要路径二中所用的额外网关和 EPP 组件。
路径二:Gateway API Inference Extension 与 Dynamo EPP
这种路径将 Dynamo 与 Gateway API 及 Gateway API Inference Extension(GAIE)集成在一起。在 AICR 的示例中,agentgateway 将 HTTPRoute 解析到一个 InferencePool。Dynamo 操作器根据 DynamoGraphDeployment 创建该 InferencePool:其选择器(selector)用于识别符合条件的工作节点 Pod,而其 endpointPickerRef 则标识 Dynamo EPP Service。
网关通过 GAIE 的端点选择接口调用 Dynamo EPP。EPP 对请求进行分词,并使用 Dynamo 的 KV 路由器来选择端点。随后,它将所选结果和路由元数据返回给网关实现(即实际的 HTTP 代理)。在此模式下,每个可路由的工作节点 Pod 都包含一个 Dynamo 前端边车(sidecar),用于接收来自网关的请求,并将其转发给本地的工作节点容器。该前端以 --router-mode direct 模式运行,因此会直接应用 EPP 的选择结果,而不会重新路由。
当平台团队管理共享的 Kubernetes 入口,并需要通过 Gateway API 机制来配置模型端点的工作节点选择、超时、重试和回退时,这种路径就比较合适。需要注意的是,这两种路由方式都可以在 Gateway API HTTPRoute 之后运行,区别在于由哪个组件负责管理到工作节点的传输:是 Dynamo 前端,还是网关本身。
说明:本文介绍的是 Dynamo 与 GAIE 之间由操作器管理的 DynamoGraphDeployment 集成;而处于实验阶段的独立原生 vLLM 接入方式是另一种独立的集成方式。在 Dynamo 1.4 中,这种路径使用 GAIE 的 Go EPP 框架,并通过 CGO 嵌入 Dynamo 的 Rust KV 路由器,通过 eppConfig 进行配置。
展望:从 Dynamo 1.5 开始,原生的 Rust EPP 将取代 Go/CGO 桥接方案。它直接实现 GAIE 的轻量级端点选择器(Lightweight Endpoint Picker,ext_proc)接口,在进程内运行完整的 Dynamo 路由器,并使用 DYN_* 环境变量来取代 eppConfig 插件和调度配置文件。聚合式和分离式路由都将直接依据通过 Dynamo 发现机制注册的工作节点角色来处理。周边的 Kubernetes 拓扑结构保持不变。移除 Go 插件框架和 CGO 边界,还能降低每个请求的 EPP 开销。
客户端请求通过网关(如 agentgateway)进入,并匹配由 InferencePool 支持的 HTTPRoute。网关调用 Dynamo EPP,后者只执行具备 Token 感知能力的 KV 选择,并返回所选端点和路由元数据。随后,网关以直接模式将请求转发给所选工作节点的前端边车,由该边车通过 Dynamo 请求平面将其发送给 vLLM 工作节点。工作节点的 KV 缓存状态通过 Dynamo 事件平面传递给 EPP,而 Dynamo 操作器则根据 DynamoGraphDeployment 创建 EPP 和 InferencePool。
如何选择路径
路由路径的选择取决于应由网关还是 Dynamo 前端来处理向工作节点转发请求的工作,包括超时、重试和回退管理。表 2 比较了 Dynamo 前端路径与 Gateway API/EPP 路径。
这两种路径都利用工作节点发布的 KV 缓存事件,以实现精确的缓存感知放置。Dynamo 也可以配置为根据每个请求的发送目的地来预测 KV 缓存状态。但预测方式无法感知缓存驱逐(eviction)情况,因此路由器所掌握的视图可能会与每个工作节点实际保存的内容产生偏差,路由质量也可能因此下降,尤其是在内存压力较大时。本文中的 AICR 配置启用了实时事件机制,因此两种路径都基于工作节点上报的 KV 缓存状态进行路由。
AICR 方案流程是如何运作的
AICR 将运行时设置与应用部署分离开来。首先,它捕获现有的 Kubernetes 集群状态,并生成相匹配的 Dynamo 方案。随后,在安装应用的 DynamoGraphDeployment 并测试其推理端点之前,先渲染、部署并验证运行时捆绑包。
步骤一:对集群进行快照
快照会捕获 AICR 用于方案选择和验证所需的集群状态:
aicr snapshot \ --namespace aicr-validation \ --output snapshot.yaml
如果未指定任何放置标志,AICR 会自动以标记为 nvidia.com/gpu.present=true 的节点为目标,并容忍 GPU 节点的污点(taint)。在集群需要更特定放置方式时,可使用 --node-selector 和 --toleration 标志。
步骤二:生成 Dynamo 推理方案
AICR 利用快照来识别 Kubernetes 发行版、GPU 加速器以及 GPU 节点的操作系统。该命令会指定工作负载意图和平台:
aicr recipe \ --snapshot snapshot.yaml \ --intent inference \ --platform dynamo \ --output recipe.yaml
生成的方案记录了固定的组件版本、针对特定环境的配置、兼容性约束以及验证检查。对于适用于 NVIDIA GB200 NVL72 和 NVIDIA GB300 NVL72 系统的 Amazon EKS Dynamo 推理方案,AICR v1.0.0 选择了以下 Helm chart 版本:
AICR 团队已经在指定的平台和硬件上一起测试了这些组件版本。以下验证步骤用于确认集群是否满足所选方案的要求。
可选的离线检查
由于方案选择已经使用了 snapshot.yaml 中的集群信息,因此针对同一份快照再次验证生成的方案所带来的额外价值有限。离线验证的用途在于:在不连接 Kubernetes 的情况下,针对另一份已捕获的集群快照来测试某个方案。它只评估声明性约束,而行为性检查则会被标记为跳过。
aicr validate \ --recipe recipe.yaml \ --snapshot candidate-snapshot.yaml \ --no-cluster \ --output dry-run.json
步骤三:渲染运行时捆绑包
AICR 将方案渲染为可直接用于部署的 Helm values 和清单文件:
aicr bundle \ --recipe recipe.yaml \ --accelerated-node-selector nodeGroup=gpu-worker \ --accelerated-node-toleration dedicated=worker-workload:NoSchedule \ --accelerated-node-toleration dedicated=worker-workload:NoExecute \ --system-node-selector nodeGroup=system-worker \ --system-node-toleration dedicated=system-workload:NoSchedule \ --system-node-toleration dedicated=system-workload:NoExecute \ --set-json agentgateway:allowedSourceRanges='["<your-cidr>"]' \ --deployer helmfile \ --output bundle
这些放置标志反映的是本文所使用测试集群的情况。对于具有不同标签和污点的集群,可以调整或省略这些标志。如果集群中没有默认的 StorageClass,该命令还需要加上 --storage-class 参数。
步骤四:部署运行时
对于没有集群内 GitOps 控制器的本地部署场景,Helmfile 提供了一种部署选项。在本地可用 Helm 及 helm-diff 插件的情况下,以下命令可以在应用之前,先检查 AICR 生成的发布关系图:
helmfile -f bundle/helmfile.yaml diff helmfile -f bundle/helmfile.yaml apply
AICR 会在生成的 Helmfile 捆绑包中编码组件之间的依赖关系。Helmfile 会按顺序处理这些依赖层级,并在同一层级内并发应用相互独立的组件。重新运行 apply 命令,可使已安装的 Helm 发布版本与生成的配置保持一致。
如果没有 Helmfile 可用,也可以使用 AICR 的默认 Helm 部署器重新生成该捆绑包。其生成的 deploy.sh 脚本是一种轻量级的备用方案,适用于交互式试用:
aicr bundle \ --recipe recipe.yaml \ [... all the flags setting node selectors and tolerations ...] \ --set-json agentgateway:allowedSourceRanges='["<your-cidr>"]' \ --deployer helm \ --output bundle-helm chmod +x bundle-helm/deploy.sh ./bundle-helm/deploy.sh
在生产环境中,AICR 还可以通过 --deployer argocd、--deployer argocd-helm 以及 --deployer flux 等选项渲染出 GitOps 捆绑包。
步骤五:验证已安装的运行时
安装完成后,在安装应用工作负载之前,需要对实际集群进行部署验证和一致性验证。由于此处未提供快照,AICR 会在运行验证器 Job 之前先捕获当前的集群状态。
aicr validate \ --recipe recipe.yaml \ --node-selector nodeGroup=gpu-worker \ --toleration dedicated=worker-workload:NoSchedule \ --toleration dedicated=worker-workload:NoExecute \ --phase deployment \ --phase conformance \ --output report.json
只有在这些检查通过之后,才会安装应用的 DynamoGraphDeployment。性能验证是单独运行的,因为它会部署一个临时的服务工作负载,并占用正在测试的 GPU 资源。
AICR 验证会检查哪些内容?
AICR 会根据所选方案中编码的检查项和约束条件,对已安装的运行时进行验证。具体检查项会因方案而异。对于一个 Dynamo 推理方案,其部署验证和一致性验证通常涵盖以下内容:
这些检查用于确认,在部署应用之前,已安装的运行时是否满足所选方案的要求。
AICR 将版本化的运行时配置,与用于验证集群是否满足所选方案要求的检查机制结合在了一起。
开始使用
NVIDIA AI Cluster Runtime(AICR)与 NVIDIA Dynamo 都是 NVIDIA DSX AI Factory Platform 的开源组件。在 Kubernetes 上部署 Dynamo 的团队,可以利用 AICR 提供的方案和部署示例,来配置、部署和验证支撑其推理工作负载的基础设施。
通过 NVIDIA DSX AI Factory GitHub,还可以获取更多项目和社区资源。
相关讨论可在 NVIDIA DSX AI Factory Slack 社区中进行。在北美 KubeCon + CloudNativeCon 大会期间举办的 NVIDIA DSX OS AI Inference and Contributor Workshop,将提供有关 AICR 的实践体验。由于座位有限,需要提前注册。
NVIDIA 在 KubeCon 的 170 号展位将带来 Kubernetes 的深度技术解析与现场演示。
