HAMi-core 与 KAI Scheduler:GPU 共享从可分配走向可治理

GPU 共享正从软分配走向可治理,调度决策与运行时隔离开始能够对应。

GPU 共享要成为可治理的基础设施能力,缺的从来不是切分,而是调度决策与运行时隔离之间的可验证对应。

背景:算力治理这条线索的来处

今年以来,我一直线在关注一条主线:GPU 如何从独占的稀缺硬件,变成可治理的基础设施能力。这条线索已经走过几个维度。年初讨论GPU 的开放调度时,关注的是 DRA、CDI 这些标准与反锁定的结构性问题;之后从 HAMi v2.9 看到 Kubernetes 正在成为 GPU Control Plane,资源模型与控制面之争浮出水面;再往后是两条纵深:一条向观测,从 GPU 到 Token 的八层可观测性;一条向度量,GPU 利用率正在“失灵”与 Productive GPU-Hours。上个月写在 HAMi 晋升 CNCF Incubating 之后的那篇文章,讨论的则是共识:当技术路线不止一条,社区与生态如何做出选择。

把这些维度放在一起,会看到一个清晰的结构:调度解决怎么分,观测解决看得见,度量解决算得清,共识解决谁说了算。但还有一个维度始终悬着:执行。分配出去的资源,运行时凭什么不越界?治理若没有强制力,就只是建议。多租户不敢共享 GPU 的根源,正在于此。

HAMi-core 被 NVIDIA KAI Scheduler 采纳,恰好落在这个缺口上。这篇文章讨论的,就是执行这一环如何被补上,以及它对整条算力治理线索意味着什么。

把 GPU 当作一个分层栈来看

理解 GPU 治理,先把 GPU 从 Kubernetes 的视角拆成一个分层栈。一张 GPU 并不是一个单一资源,它至少跨越五层:调度与分配、Kubernetes 设备资源、容器设备注入、节点 GPU 软件、物理硬件。治理的本质,是让每一层都有清晰、唯一的归属。这套分层并不绑定某一家厂商:把 NVIDIA 换成昇腾或 AMD,结构不变,变的只是每一层的具体组件。

GPU 软件栈的五层结构,从调度分配到物理硬件逐层向下:

图 1: GPU 软件栈的五层结构
图 1: GPU 软件栈的五层结构

以最具代表性的 NVIDIA 生态为例,GPU Operator 覆盖的是中间三层,把一台带 GPU 的节点变成标准化的容器运行时节点;昇腾的 NPU 套件、AMD 的 GPU Operator 扮演的是同一层的角色。但这一层并不决定一个任务该进哪个队列、要不要 gang scheduling,也不负责运行时的显存拦截——NVIDIA 的 CUDA 层如此,昇腾的 CANN 层同理。把不同层混在一起讨论,是 GPU 治理最常见的认知错误。

长期缺的一环:运行时强制

在这个栈里,GPU 共享长期卡住的位置很明确:调度层能分配,设备资源层能声明,但没有任何东西在运行时强制执行这些分配。容器声明要多少显存,调度器据此记账,运行时却无法阻止容器越过声明,把整张卡的显存吃掉。

结果就是多租户不敢真正共享 GPU,昂贵的算力只能以独占方式消耗。这不是某一个调度器的缺陷,而是整条链路缺了“隔离执行”,以及与之配套的“可观测”。GPU 共享因此长期停在“能分配”,到不了“能治理”。

三类系统,三层归属

实践中最常被混淆的,是把 GPU Operator、KAI Scheduler、HAMi 当作三种同类产品。实际上它们的职责几乎不重叠,分别拥有栈的不同层次。下面以 NVIDIA 生态为例说明,这套归属关系换成昇腾、AMD 等其他厂商同样成立。

系统拥有的层次在 GPU 共享中的角色
GPU Operator节点 GPU 软件生命周期(Driver、Container Toolkit、CDI、DCGM让节点成为可用的 NVIDIA 容器运行时节点
KAI Scheduler调度策略、队列、公平性与共享记账决定 GPU 如何被分配与共享
HAMi Core运行时显存与算力隔离把“协同记账”变成“运行时强制”
表 1: GPU Operator、KAI Scheduler 与 HAMi Core 的职责归属

这里有一条容易被忽视的治理原则:一个节点必须有且只有一个设备资源所有者。真正的风险不是少装了组件,而是两个系统同时认为自己拥有同一层。例如 NVIDIA Device Plugin 与 HAMi Device Plugin 若在同一节点都注册 nvidia.com/gpu,就会直接冲突。把归属划清楚,这三类系统并不互斥,反而能构成一条边界清晰的 AI 基础设施栈。

调度与隔离开始能够对账

HAMi-core 进入 NVIDIA KAI Scheduler,补上的正是缺的那一环。这里有一个常被忽略的技术事实:KAI Scheduler 的 GPU 共享默认只做协同记账(cooperative accounting),官方明确说明它不会强制显存上限,也不隔离不同进程的显存使用。HAMi Core 的作用,就是把这种“协同记账”转变为运行时强制。

调度器负责分配决策,HAMi Core 在运行时拦截 CUDA 调用执行显存限制,二者第一次能够对应。这次集成,我曾在 HAMi 社区做过介绍;之后在 GKE 上做过验证,配额内的分配正常执行,越过配额的请求直接被拒,复现步骤也整理成了一份完整的实验。共享由此从基于信任的君子协定,转变为可验证的契约。

GPU 共享的四层验证:调度、设备分配、可见性都正确之后,隔离强制是最后一层:

图 2: GPU 共享的四层验证,隔离在最后一层
图 2: GPU 共享的四层验证,隔离在最后一层

验证“硬限制”,而不是只验证显示值

一个容易踩的坑:用 nvidia-smi(昇腾上是 npu-smi)看到容器只显示切分后的显存,就以为隔离成功了。可见性不等于强制。真正值得做的,是一个反向测试:让工作负载主动申请超过配额的显存,观察它是否被拒绝。只有分配失败(CUDA OOM),才能证明隔离在运行时真正生效。

这也是为什么我把这一层放进集群验收,而不是停留在一次性的可见性检查。调度正确、设备分配正确、可见性正确,都不等于强制正确;HAMi Core 补的恰恰是最后这一层。

软件隔离作为 GPU 治理层

更具结构意义的是 NVIDIA 的选择:KAI Scheduler(源自 Run:ai,现归 NVIDIA)没有自研隔离,而是直接采用 HAMi-core。这件事的意义不在于某个开源项目获得背书,而在于确认了一条路径:GPU 的隔离与治理可以作为独立的软件层存在,不必完全依赖 MIG、SR-IOV 这类硬件虚拟化。

对异构算力治理而言,这一点尤为关键。不同厂商的硬件虚拟化能力参差不齐,有的支持细粒度切分,有的几乎没有;一个统一的软件隔离层,是跨厂商治理得以成立的前提。从更长的演进看,资源面(Device Plugin、DRA)正与注入面(CDI)逐步分离,设备从一个简单的整数扩展资源,向带属性、可声明、可动态分配的模型演进。

资源面与注入面逐步分离,设备向带属性、可声明、可动态分配的模型演进:

图 3: 资源面与注入面的分离
图 3: 资源面与注入面的分离

这条方向,正是我在讨论 HAMi v2.9 时所提“GPU 控制面”的延续。

治理的下一站:可观测与异构统一

“可治理”不止于隔离。一项资源要能被治理,还需可观测、可运营,并能在异构环境里统一管理。这恰好是计划于 8 月 21 日发布的 HAMi 2.10 着力补齐的部分:

  • 昇腾软切分补齐了利用率、显存与 Prometheus 指标,使软切分资源从“可分配”走向“可观测、可运营”。
  • 同一集群可混合管理基于模板的硬切分与基于 HAMi-core 的软切分,向异构统一治理再进一步。
  • 异构设备扩展至 AMD MI300x 与壁仞(Biren),当前以调度层接入为主,完整虚拟化能力仍需后续验证。

这条主线本身也进入 2.10:通过独立的 KAI Resource Isolator,调度与隔离的分工被正式产品化。需要说明的是,相关隔离能力仍在完善,显存限制的真正生效、非 root 容器目录权限等问题发布前尚有 PR 待合并,因此现阶段宜表述为“快速成熟”,而非“已完整可用”。

综合来看,2.10 的重心是把 GPU 共享从“可用”,推向“可观测、可运营,并能在异构集群中统一治理”,这与前面讨论的治理闭环方向一致。

总结

回到这条线索的起点:今年从开放调度、控制面、可观测性到效率度量与社区共识,算力治理的各个维度被逐一讨论,唯独执行始终悬着。HAMi-core 进入 NVIDIA KAI Scheduler,补上的正是这一环:调度决策与运行时隔离,第一次能够可验证地对应。把 GPU 当作分层栈来看,治理就是让每一层有清晰归属:GPU Operator 管节点软件生命周期,KAI 管调度与共享记账,HAMi Core 管运行时强制。而软件隔离被主流调度器采纳,意味着 GPU 治理正从依赖硬件虚拟化,转向可跨厂商复用的软件层。隔离只是治理的起点,可观测与异构统一是下一步,HAMi 2.10 正沿这个方向推进。算力从稀缺硬件走向可治理的基础设施能力,这条路正在变得具体。

参考文献

宋净超(Jimmy Song)

宋净超(Jimmy Song)

专注于 AI 原生基础设施与云原生应用架构的研究与开源实践。

文章导航

评论区