HAMi(前身为 k8s-vGPU-scheduler)是一个面向 Kubernetes 的异构设备管理中间件。它可以管理不同类型的异构设备(如 GPU、NPU、MLU、DCU 等),实现异构设备在 Pod 之间的共享,并基于设备拓扑和调度策略做出更优的调度决策。
介绍
核心功能与优势包括:
- 设备虚拟化与共享: 这是 Hami-scheduler 最核心的功能。它允许将单个物理 GPU 虚拟化成多个 vGPU,并根据 Pod 的实际需求(如显存大小、计算核心比例)进行分配。这意味着多个 Pod 可以共享同一张物理 GPU,从而极大地提高了 GPU 的利用率,特别适用于推理服务、开发测试等对 GPU 资源需求不高的场景。
- 资源隔离: 在共享的同时,Hami-scheduler 也提供了硬性的资源隔离机制。它通过拦截 CUDA API 调用等技术手段,确保每个 Pod 只能使用其被分配的 vGPU 资源,避免了
邻居噪声
问题,即一个 Pod 的异常行为影响到共享同一物理设备的其他 Pod。
- 异构设备统一管理: Hami 意为
Heterogeneous AI Middleware
(异构 AI 中间件)。顾名思义,它不仅支持 NVIDIA 的 GPU,还致力于支持来自不同厂商的多种异构计算设备(如 NPU、MLU 等),提供一个统一的管理和调度界面。
- 灵活的调度策略: Hami-scheduler 提供了比默认调度器更丰富的调度策略,以应对复杂的 AI 工作负载场景。用户可以通过 Pod 的注解(Annotations)来指定调度策略,例如:
binpack
(装箱策略): 尽可能将 Pod 调度到已使用 GPU 的节点或已分配 vGPU 的物理 GPU 上,以整合资源,让部分 GPU 保持空闲以备大型任务使用。
spread
(分散策略): 尽可能将 Pod 分散到不同的节点或物理 GPU 上,以提高容灾能力和负载均衡。
- 无感知的应用体验: 对于应用开发者而言,使用 Hami-scheduler 管理的 vGPU 资源几乎是无感知的。开发者无需修改应用程序代码,只需在 Pod 的资源请求中声明所需的 vGPU 资源(如
hami.io/gpu-memory
),即可像使用普通 GPU 一样进行开发和部署。
Hami-scheduler 是如何工作的?
Hami-scheduler 并非完全取代了 Kubernetes 的默认调度器,而是以调度器扩展(Scheduler Extender) 的方式与之协同工作。其架构主要包含以下几个关键组件:
- Mutating Admission Webhook: 这是一个准入控制器。当一个 Pod 被创建时,该 Webhook 会进行拦截。它会检查 Pod 的资源请求中是否包含 Hami 定义的资源类型(如
hami.io/gpu-memory
)。如果包含,Webhook 会自动修改 Pod 的 YAML 文件,将其schedulerName
字段指定为hami-scheduler
,从而将这个 Pod 的调度权交给了 Hami。
- Hami-scheduler Extender: 这是调度的核心逻辑所在。当 Hami-scheduler 接手一个 Pod 的调度任务后,它会执行一系列的
过滤(Filter)
和评分(Score)
操作。它会根据节点上物理 GPU 的实际使用情况、vGPU 的分配情况以及 Pod 请求的资源量,计算出哪些节点是可行
的,并为这些可行节点打分,最终选择得分最高的节点进行绑定。
- Device Plugin: Hami 为每种支持的异构设备提供了设备插件。这些插件负责发现节点上的物理设备、上报设备信息(如总显存、健康状况)给 Kubernetes,并在 Pod 被调度到节点后,负责具体的资源分配和隔离操作。
简而言之,整个流程是:Webhook标记
需要特殊调度的 Pod -> Hami-scheduler决策
Pod 的最佳节点 -> Device Plugin 在节点上执行
资源的分配与隔离。
适用场景
Hami-scheduler 在众多场景下都能显著提升资源利用率和管理效率:
- AI 推理服务集群: 推理任务通常对 GPU 的计算核心需求不高,但对显存有一定要求。通过 vGPU 共享,可以在单张 GPU 卡上部署多个推理服务实例。
- 研发与测试环境: 在多用户、多任务的研发环境中,开发者可以申请小份额的 vGPU 进行代码调试和模型验证,避免了为每个开发者都分配一张完整 GPU 卡的巨大成本。
- 云计算平台: 云服务提供商可以利用 Hami-scheduler 提供更小颗粒度、更具成本效益的 GPU 云主机或容器服务,降低用户使用 AI 算力的门槛。
- 混合 AI 工作负载: 在同时存在模型训练和推理任务的集群中,Hami-scheduler 可以灵活调度,将需要整卡的训练任务与可以共享的推理任务进行合理地混合部署。
部署
- 通过添加标签
gpu = on
标签,标记 GPU 节点以与 HAMI 进行计划。没有此标签,节点将无法由 hami 调度程序管理
kubectl label nodes {nodeid} gpu=on
helm repo add hami-charts https://project-hami.github.io/HAMi/
# 或
wget xxx/hami.tar.gz
tar -xzf hami.tar.gz
helm install hami hami-charts/hami -n kube-system
# 查看
kubectl get pods -n kube-system
使用
Allocate device memory
resources:
limits:
nvidia.com/gpu: 1 # requesting 1 GPU
# nvidia.com/gpumem: 3000 # Each GPU contains 3000m device memory
nvidia.com/gpumem-percentage: 50 # Each GPU contains 50% device memory
limits:
nvidia.com/gpu: 1 # 请求1个vGPUs
nvidia.com/gpumem: 21000 # 每个vGPU申请21G显存 (可选,整数类型)
nvidia.com/gpucores: 30 # 每个vGPU的算力为30%实际显卡的算力核心 (可选,整数类型)
nvidia.com/gpu
: 请求的 vGPU 数量,例如 1
nvidia.com/gpucores
表示每张卡占用的 GPU 算力,值范围为 0-100;如果配置为 0,则认为不强制隔离;配置为 100,则认为独占整张卡
nvidia.com/gpumem
表示每张卡占用的 GPU 显存,值单位为 MB,最小值为 1,最大值为整卡的显存值
nvidia.com/gpumem-percentage
显存请求百分比,例如 50 表示请求 50% 的显存
nvidia.com/priority
优先级,0 表示高优先级,1 表示低优先级,默认为 1
其他