一页结论
HAMi 是面向 Kubernetes 的异构 AI 计算虚拟化中间件。它的价值不是“让一个 Pod 看见一张 GPU”这么简单,而是把 GPU、NPU、MLU、DCU 等异构加速器抽象成统一的可调度资源,并在 Pod 之间实现共享、隔离、拓扑感知和策略化调度。
如果用一句工程化语言概括:HAMi 在 Kubernetes 调度链路中插入了准入变更、调度扩展器、定制 device plugin 和容器内控制层,使用户仍然通过原生 Pod 资源声明表达需求,而平台可以在后台完成设备选择、份额切分、显存/算力限制和节点注解协议同步。
解决什么问题
- GPU/加速器利用率低:训练、推理、开发任务常常不需要独占整卡,HAMi 支持按显存和核心比例做部分分配。
- 异构设备 API 分裂:不同厂商的 GPU、NPU、MLU、DCU 暴露方式不同,HAMi 试图提供统一的 Kubernetes 入口。
- 调度只看数量不够:AI 设备调度需要考虑节点、卡、显存、核心、NUMA、拓扑和碎片化。
- 原生 Device Plugin 粒度粗:官方 device plugin 往往偏整卡分配;HAMi 使用定制插件和容器内控制层实现细粒度共享与隔离。
- 多租户缺少显存配额:HAMi 支持通过 Kubernetes ResourceQuota 管控 namespace 级 GPU 显存用量。
不是什么
- 不是只支持 NVIDIA 的 vGPU 项目。NVIDIA 是核心场景,但仓库已经覆盖多类异构设备。
- 不是模型推理框架,也不替代 vLLM、TensorRT、PyTorch 或推理网关。
- 不是完全透明的“装上就万无一失”的系统。它依赖定制 device plugin、节点标签、运行时配置、注解协议和各厂商隔离技术。
- 不是所有场景都适合共享。强隔离、安全合规、性能稳定性或大训练任务可能仍需要独占卡。
核心架构
HAMi 的架构可以按 Pod 生命周期理解:准入阶段识别资源,调度阶段选择节点与设备,绑定后由节点侧插件根据注解配置容器运行环境,最后由容器内控制机制执行显存/算力限制。
检查 Pod 是否声明 HAMi 支持的设备资源;如果识别到资源请求,则设置调度器名称,并补齐或校验资源字段。
对可共享设备实现 Filter 和 Score。Filter 找可用节点,Score 根据策略对节点和设备排序。
节点侧周期上报设备信息到 Node 注解,并在调度结果确定后为容器生成环境变量、挂载和设备可见性。
不同设备使用不同容器内限额机制。例如 NVIDIA 侧由 HAMi-Core 负责硬限制,其他厂商有各自控制库或插件。
资源声明模型
用户通常仍然用 Kubernetes Pod 的 resources.limits 声明资源。以 NVIDIA 为例,最常见的资源键包括:
| 资源键 | 含义 |
|---|---|
nvidia.com/gpu | 请求多少个物理 GPU 份额。安装后节点上注册值默认表示 vGPU 数量。 |
nvidia.com/gpumem | 每个请求 GPU 对应的显存,单位 MB 或 MiB 语义在文档中按场景表述。 |
nvidia.com/gpumem-percentage | 按百分比申请显存。 |
nvidia.com/gpucores | 申请 GPU 核心算力比例,范围通常按 0-100 表达。 |
nvidia.com/priority | 任务优先级资源名,可通过配置覆盖。 |
resources:
limits:
nvidia.com/gpu: 1
nvidia.com/gpumem: 3000
nvidia.com/gpucores: 30
Pod 注解能力
资源键表达“要多少”,注解表达“怎么调度、能用哪些卡、不能用哪些卡、使用哪种 vGPU 模式”。
| 注解 | 用途 |
|---|---|
nvidia.com/use-gpuuuid | 限制只能使用指定 GPU UUID。 |
nvidia.com/nouse-gpuuuid | 排除指定 GPU UUID。 |
nvidia.com/use-gputype | 限制可用 GPU 型号。 |
nvidia.com/nouse-gputype | 排除某些 GPU 型号。 |
hami.io/node-scheduler-policy | 覆盖节点层调度策略:binpack 或 spread。 |
hami.io/gpu-scheduler-policy | 设计文档中用于覆盖 GPU 层策略;正式文档提示 GPU 层主要通过全局配置。 |
nvidia.com/vgpu-mode | 指定 hami-core 或 mig。 |
调度逻辑:Filter 与 Score
HAMi 作为 scheduler extender 工作,核心接口是 Kubernetes 调度扩展器协议中的过滤和打分。过滤阶段判断节点是否有满足请求的设备组合;打分阶段对节点和卡进行排序。
默认策略
- 节点调度默认
binpack:倾向把任务放到已有负载的 GPU 节点上,减少节点碎片。 - GPU 调度默认
spread:在单节点内倾向分散到不同 GPU 上,降低单卡拥塞。 - Pod 可通过注解覆盖节点层策略;GPU 层策略在文档中更偏全局配置。
binpack 与 spread 的实际含义
| 层级 | binpack | spread |
|---|---|---|
| Node | 尽量填满同一 GPU 节点。 | 尽量分散到不同 GPU 节点。 |
| GPU | 尽量把份额放到已使用的同一张卡,减少碎片。 | 尽量把份额分散到不同卡,降低局部争用。 |
节点注解协议
HAMi 用 Node 注解作为调度器和 device plugin 的协议层。device plugin 需要周期性上报设备规格,调度器据此构建全局设备视图。
hami.io/node-handshake-{device-type}:握手状态和时间戳。hami.io/node-{device-type}-register:设备列表,包含 UUID、切分数量、显存、核心、类型、NUMA、健康状态等。- 如果节点长时间未注册,调度器会将对应设备视为不可用。
这个协议的优点是实现简单、贴近 Kubernetes 对象模型;代价是注解内容必须保持一致,时间戳、健康状态和插件上报逻辑会直接影响调度正确性。
Pod 调度结果协议
调度器把最终设备分配结果写回 Pod 注解,节点侧 device plugin 再据此完成容器设备暴露。
hami.io/devices-to-allocate:每个容器要分配的设备 UUID、设备类型、显存和核心。hami.io/device-node:调度目标节点。hami.io/device-schedule-time:调度时间。
这使调度决策成为 Kubernetes 对象的一部分,便于插件协作、监控和故障排查。
支持的设备生态
HAMi 的定位是异构 AI 设备池化,因此代码和文档都围绕多厂商设备扩展。仓库中可以看到 NVIDIA、Cambricon、Hygon、Iluvatar、Moore Threads、Ascend、MetaX、Enflame、Kunlun、VastAI、AWS Neuron、AMD 等设备包或示例。
| 设备/厂商 | 文档或代码线索 | 关注点 |
|---|---|---|
| NVIDIA GPU | pkg/device/nvidia、动态 MIG、HAMi-Core | vGPU、显存/核心限制、MIG、拓扑打分。 |
| Cambricon MLU | pkg/device/cambricon | 国产 AI 加速器共享与调度。 |
| Hygon DCU | pkg/device/hygon | DCU 资源声明与打分。 |
| Iluvatar / Mthreads / MetaX | 各自支持文档与设备包 | 多厂商 GPU 虚拟化资源模型。 |
| Ascend NPU | Ascend 支持文档与独立 device plugin 链接 | NPU 资源接入与 Volcano 场景。 |
| AWS Neuron / Kunlun / Enflame / VastAI | examples 与 pkg/device 下实现 | 将云端或国产异构设备纳入统一调度面。 |
动态 MIG
动态 MIG 是 HAMi 2.5 之后的重要能力:用户无需提前在节点上创建 MIG 实例,HAMi 可以根据任务需求创建实例、切换 MIG 模板,并把 MIG 与 hami-core 统一到同一资源池。
- 适用于 NVIDIA Blackwell、Hopper、Ampere 等支持 MIG 的设备。
- 节点需要配置
operatingmode: mig。 - Pod 仍可通过
nvidia.com/gpu和nvidia.com/gpumem申请资源。 - 如果未指定模式,任务可能被分配到 MIG 或 hami-core。
- 监控指标会暴露 HAMi 管理的 MIG 实例视图。
多租户配额
虚拟设备数量本身不能准确代表真实显存消耗,因此 HAMi 支持通过 Kubernetes ResourceQuota 对 namespace 级 GPU 显存做限制。
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
limits.nvidia.com/gpumem: 30000
这类能力适合平台团队限制团队/租户的显存总量,避免某个 namespace 因为大量小 vGPU 任务挤占整个集群。
安装与运维要点
| 事项 | 笔记 |
|---|---|
| 节点标记 | GPU 节点需要标记 gpu=on,否则不会被 HAMi 管理。 |
| 安装方式 | 官方推荐 Helm:添加 https://project-hami.github.io/HAMi/ chart repo 后安装到 kube-system。 |
| NVIDIA 前置条件 | 文档列出驱动、nvidia-docker、默认 runtime、Kubernetes 版本、glibc、内核和 Helm 要求。 |
| 配置入口 | 全局设备配置主要在 hami-scheduler-device ConfigMap;节点级插件行为在 hami-device-plugin ConfigMap。 |
| Webhook 过滤 | 支持 namespaceSelector 和 objectSelector;默认排除带 hami.io/webhook: ignore 标签的命名空间/Pod。 |
| TLS | 可使用 Helm job 生成自签证书,或启用 cert-manager。 |
| 监控 | 安装后自动启用 metrics,默认监控端口文档中给出为 31993,并提供 Grafana dashboard 示例。 |
Benchmark 解读
仓库 benchmark 文档使用 vLLM 对 Qwen3-8B 推理场景做对比,环境为 A100-SXM4-40GB 双卡。文档中的关键指标显示,新版本 HAMi 相比旧版本更接近原生 NVIDIA device plugin。
| 指标 | Native | v2.8.0 | v2.9.0 |
|---|---|---|---|
| TTFT p50 | 0.0621s | 0.0670s | 0.0629s |
| TTFT p95 | 0.0642s | 0.0713s | 0.0650s |
| 每 token 延迟均值 | 0.0285s | 0.0310s | 0.0291s |
这个 benchmark 的重点不是证明“虚拟化零损耗”,而是说明 HAMi 的共享/隔离机制可以在典型推理负载中做到接近原生的延迟表现。
代码结构速记
cmd/scheduler:调度器入口、metrics。cmd/vGPUmonitor:vGPU 监控组件。pkg/scheduler:调度主逻辑、节点管理、Webhook、路由、事件、打分。pkg/scheduler/policy:节点和 GPU 打分策略。pkg/device:设备抽象接口、Pod/Quota 管理、各设备实现。charts/hami:Helm Chart 和默认配置。examples:不同厂商设备的 Pod 示例。docs/develop:架构、协议、调度策略和路线图。
优点、代价与适用场景
| 维度 | 观察 |
|---|---|
| 优点 | 统一异构设备入口;减少整卡浪费;支持按显存/核心共享;可以策略化处理碎片;与 Kubernetes 原生 Pod、ResourceQuota、Webhook、Scheduler Extender 协同。 |
| 工程代价 | 部署链路更复杂;依赖定制 device plugin;不同厂商隔离能力不完全一致;节点注解协议和插件健康上报成为关键可靠性点。 |
| 适合 | AI 平台、多租户推理、开发/实验集群、资源利用率优化、国产异构设备混合集群。 |
| 谨慎使用 | 强隔离安全场景、极致稳定延迟任务、大规模分布式训练、已有复杂 NVIDIA 原生 MIG/DCGM 体系的集群。 |
我会继续追的点
- 各设备实现之间的隔离语义是否一致,尤其是“核心限制”和“显存限制”的硬度。
- 动态 MIG 在繁忙节点上的切换代价、失败恢复和与外部 NVIDIA 组件的兼容性。
- Scheduler extender 在大规模集群中的缓存一致性、leader election、节点锁和事件可观测性。
- ResourceQuota 对多容器、多设备、多 namespace 场景的边界行为。
- 和 Volcano、Kubeflow、KServe、Ray、vLLM 平台化栈的集成实践。
快速阅读路线
- README_cn.md:先理解定位、能力、安装和注意事项。
- docs/develop/design.md:看清组件分工。
- docs/develop/protocol.md:理解注解协议。
- docs/config_cn.md:掌握真实可调参数。
- dynamic-mig-support_cn.md:了解 MIG 方向。
- pkg/scheduler/webhook.go 与 score.go:从代码看准入和调度。
来源与版本信息
原始仓库:https://github.com/Project-HAMi/HAMi
本次阅读的浅克隆提交:b830c49843059652eccbe4979ed88902de6289df,提交时间 2026-05-08T02:02:05+00:00。
GitHub API 元数据读取时间:2026-05-08;latest release 为 v2.8.2,仓库内 VERSION 文件和 Helm chart 文档中仍可见 v2.8.0 相关默认值,实际部署前应以 release notes 和 chart 版本为准。