HAMi 完全指南:Kubernetes 异构 AI 计算虚拟化与 GPU 共享调度实战 HAMi 完全指南Kubernetes 异构 AI 计算虚拟化与 GPU 共享调度实战【免费下载链接】HAMiHeterogeneous GPU Sharing on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ha/HAMiHAMiHeterogeneous AI Computing Virtualization Middleware异构 AI 计算虚拟化中间件是运行在 Kubernetes 之上的开源 GPU 虚拟化与异构加速器调度方案帮助平台团队在同一套 Kubernetes 工作负载中共享昂贵的 GPU、NPU 等 AI 加速器并在不改动应用代码的前提下完成设备内存/算力隔离与设备感知调度。本文以 README_ja.md 为主线结合仓库内的 Helm Chart、示例工作负载与调度器源码系统讲解 HAMi 的架构原理、设备虚拟化资源模型、Helm 部署步骤、调度策略与可观测性能力读完即可上手部署并理解其调度评分机制。HAMi 是什么从 k8s-vGPU-scheduler 到 CNCF 孵化项目HAMi 全称Heterogeneous AI Computing Virtualization Middleware前身是k8s-vGPU-scheduler。它的核心定位是让平台团队能够在 Kubernetes 工作负载之间共享昂贵的 GPU 及其他 AI 加速器按需隔离设备内存与计算能力使用设备感知的调度策略如拓扑感知、binpack、spread完成 Pod 调度无需修改任何应用程序代码仍然沿用标准的 Kubernetes 资源请求requests与限制limits语义。HAMi 是 CNCF Incubating 项目并同时列入 CNCF Landscape 与 CNAI Landscape以上项目归属信息来自 README_ja.md 原文说明。项目由维护者与贡献者共同治理贡献与治理相关资料位于仓库内的 MAINTAINERS.md、AUTHORS.md 与 CONTRIBUTING.md。为什么需要 HAMiAI 基础设施团队面临的共性问题AI 基础设施团队在 Kubernetes 上管理加速器时通常会遇到一组高度相似的问题详见 README_ja.md 的「なぜ HAMi」一节整块 GPU 被分配给很小的作业造成资源浪费团队之间争抢稀缺设备不同加速器厂商暴露完全不同的运维模型NVIDIA 的 vGPU、Ascend 的 NPU、寒武纪的 MLU 等各有各的资源抽象调度器缺乏足够的设备上下文无法高效放置工作负载。针对这些问题HAMi 提供了一个 Kubernetes 原生的抽象层能力可归纳为六点能力说明设备共享Device Sharing按内存、核心数或设备数量分配物理加速器的一部分例如只申请一块物理 GPU 的 3 GiB 显存资源隔离Resource Isolation在设备后端支持的前提下强制每个工作负载的显存与算力上限设备感知调度Device-Aware Scheduling以拓扑感知、binpack、spread 及设备特有策略放置 Pod异构 AI 集群Heterogeneous AI Clusters在同一个调度与分配工作流中管理 NVIDIA GPU、NPU、HCU、MLU 等多种加速器应用零改造Zero Application Changes继续使用标准的 Kubernetes 资源 requests 与 limits生产级运维Production Operations提供指标、Dashboard、WebUI、Helm 安装与社区部署指导典型使用场景在共享的 Kubernetes AI 集群中提升 GPU 利用率在同一加速器池上运行多租户的 Notebook、训练与推理工作负载构建具备公平设备分配与配额控制的私有云 AI 平台运维横跨 NVIDIA、Ascend、Cambricon、Hygon、Iluvatar、MetaX、摩尔线程Moore Threads等多厂商的异构加速器集群将 HAMi 与 kube-scheduler、Volcano 等 Kubernetes 调度器组合服务批式 AI 工作负载。工作原理Webhook、调度器扩展器与设备插件的协作链路HAMi 由四类组件构成README_ja.md 的「仕組み」一节Mutating Webhook、调度器扩展器Scheduler Extender、设备插件Device Plugin以及设备特定的容器内虚拟化组件。一个 Pod 从提交到运行的完整链路如下Pod 提交 - HAMi Mutating Webhook注入资源与调度信息 - HAMi 调度器 filter / score / bind - 设备分配结果写入 Pod 注解 - 设备插件 Allocate() - 容器运行时环境 - HAMi 监控与指标采集这一设计在 Helm Chart 中也有直接印证charts/hami/templates/scheduler/configmap.yaml 会按 Kubernetes 版本生成不同的调度器配置——Kubernetes 1.22 使用KubeSchedulerConfiguration更早版本使用 legacyPolicy格式两者都把 HAMi 作为 extender 注册进去filterVerb: filter、bindVerb: bind、managedResources声明 HAMi 托管的资源而 charts/hami/templates/device-plugin/ 目录下的模板则负责部署设备插件 DaemonSet 与相关 RBAC。设备虚拟化细粒度的显存与算力资源模型HAMi 让工作负载只申请自己真正需要的加速器资源。以 NVIDIA 为例下面的 Pod 请求1 块物理 NVIDIA GPU 且每块 GPU 分配 3 GiB 显存resources: limits: nvidia.com/gpu: 1 nvidia.com/gpumem: 3000工作负载在容器内部看到的即是分配到的设备资源而调度、分配与隔离全部由 HAMi 协调完成。两个关键注意点官方文档明确说明安装 HAMi 后节点上注册的nvidia.com/gpu值默认是 vGPU 的数量在 Pod 中请求资源时nvidia.com/gpu指的是当前 Pod 需要的物理 GPU 数量。也就是说节点可分配容量以 vGPU 切片计数而 Pod 侧声明的是物理卡数量二者语义不同使用时务必区分。完整的示例工作负载仓库 examples/nvidia/default_use.yaml 给出了可直接提交的完整示例apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: containers: - name: ubuntu-container image: ubuntu:22.04 command: [bash, -c, sleep 86400] resources: limits: nvidia.com/gpu: 1 # Pod 需要的物理 GPU 数量 nvidia.com/gpumem: 3000 # 每块物理 GPU 分配给 Pod 的显存MB可选整数 nvidia.com/gpucores: 30 # 每块物理 GPU 分配给 Pod 的核心比例%可选整数资源名的灵活用法百分比与独占卡除了固定显存gpumem单位 MBHAMi 还支持按百分比申请显存。仓库 examples/nvidia/use_memory_fraction.yaml 演示了同时使用百分比显存与核心比例resources: limits: nvidia.com/gpu: 2 # 请求 2 块物理 GPU nvidia.com/gpumem-percentage: 50 # 每块物理 GPU 分配 50% 显存可选整数 nvidia.com/gpucores: 30 # 每块物理 GPU 分配 30% 核心可选整数若希望独占整卡将gpumem-percentage与gpucores均设为 100 即可参见 examples/nvidia/use_exclusive_card.yaml。资源名与底层配置上述资源名均来自 Helm 默认值charts/hami/values.yaml并支持通过 values 调整#Nvidia GPU Parameters resourceName: nvidia.com/gpu resourceMem: nvidia.com/gpumem resourceMemPercentage: nvidia.com/gpumem-percentage resourceCores: nvidia.com/gpucores resourcePriority: nvidia.com/priority同一份 values 文件还声明了其他加速器的资源名例如 MLUcambricon.com/vmlu等、Hygon HCUhygon.com/hcunum等、MetaX sGPUmetax-tech.com/sgpu等、Enflame DRS GCU、Kunlun XPU、Vastai 与 Biren这正是「异构 AI 集群」能力在配置层面的体现。支持的设备HAMi 支持 GPU、NPU、HCU、MLU、GCU、XPU 等多种异构加速器后端具体功能随厂商、型号、驱动与硬件代际而不同。从 charts/hami/values.yaml 的devices段可以看到当前仓库内已包含的厂商后端包括NVIDIA、AMD、AWS Neuron、Kunlun昆仑芯、Enflame燧原、摩尔线程、Vastai、Biren壁仞、Ascend昇腾默认关闭可通过ascend.enabled: true开启、Iluvatar天数智芯默认关闭等对应的实现代码位于 pkg/device/ 下按厂商划分的目录如nvidia/、ascend/、metax/、iluvatar/、enflame/等。各厂商的设备能力与支持矩阵以项目官方文档维护的最新支持矩阵为准原文提示参见 README_ja.md 的「サポートされているデバイス」一节。快速开始前提条件与 Helm 部署前提条件NVIDIA 设备插件路径NVIDIA 驱动 440nvidia-docker版本 2.0NVIDIA 已被配置为 containerd、Docker 或 CRI-O 的默认运行时Kubernetes 1.23glibc 2.17Linux 内核 3.10Helm 3.0安装步骤第 1 步给 GPU 节点打标签让 HAMi 能够管理这些节点kubectl label nodes node-name gpuon第 2 步添加 HAMi Helm 仓库并更新helm repo add hami-charts https://project-hami.github.io/HAMi/ helm repo update第 3 步安装 HAMi 到 kube-system 命名空间helm install hami hami-charts/hami -n kube-system第 4 步验证调度器与设备插件均已运行kubectl get pods -n kube-system当hami-device-plugin与hami-scheduler都处于Running状态后提交一个示例工作负载kubectl apply -f examples/nvidia/default_use.yaml常用安装参数说明基于 charts/hami/values.yaml部署时可重点关注以下参数schedulerName默认hami-schedulerHAMi 调度器名称scheduler.defaultSchedulerPolicy集群默认调度策略默认nodeSchedulerPolicy: binpack、gpuSchedulerPolicy: spread详见下一节scheduler.service.monitorPort默认31993监控指标端口scheduler.admissionWebhook.enabled默认true是否安装准入 Webhook若关闭则使用 HAMi 的 Pod 必须显式配置schedulerName等设备相关配置devicePlugin.deviceSplitCount默认10与devicePlugin.deviceMemoryScaling默认1控制单卡可切分的 vGPU 数量与显存缩放比例devicePlugin.migStrategy默认noneMIG 策略devicePlugin.nodeConfiguration.config按节点覆盖配置如operatingmode、devicesplitcount、filterdevices等优先级为externalConfigName config 默认配置各类加速器的资源名resourceName、mluResourceName、hcuResourceName等与devices.vendor.enabled开关。调度策略binpack、spread 与拓扑感知HAMi 为 AI 工作负载提供多种调度模式README_ja.md 的「スケジューリングポリシー」一节binpack把工作负载尽量打包到少数节点或设备上提升整合度与资源利用率spread把工作负载分散到不同节点或设备上降低资源竞争拓扑感知调度在支持的情况下根据 GPU 拓扑选择设备组合动态 MIG针对受支持的卡与模式动态创建并分配 NVIDIA MIG 实例。HAMi 与默认 Kubernetes 调度器路径兼容也可以与面向批式 AI 工作负载的 Volcano 组合使用。评分公式调度器如何做决策调度策略的详细设计记录在 docs/develop/scheduler-policy.md 中核心是两套评分公式。节点级策略Node-Scheduler-Policybinpack 与 spread 都使用同一公式score ((request used) / allocatable) * 10。区别在于选分方向binpack 选分数最高的节点越满越高分spread 选分数最低的节点越空闲越低分。该设计在源码 pkg/scheduler/policy/node_policy.go 的Less方法中得到印证spread策略按分数降序排序取大者即最空闲默认binpack按升序排序取小者即最满。设备级策略GPU-Scheduler-Policy同时考虑每张卡的算力与显存占用score ((request.core used.core) / allocatable.core (request.mem used.mem) / allocatable.mem) * 10同样binpack 选高分卡被占得越满越好spread 选低分卡。节点级打分还会叠加设备级分数见 pkg/scheduler/policy/node_policy.go 的OverrideScore与 node_policy.go 的ComputeDefaultScore从源码结构看实现 policy 无关打分的设备后端其分数在 spread 策略下会被取负以保持排序方向一致。用 Pod 注解覆盖默认策略用户可以通过 Pod 注解覆盖集群默认策略。仓库 examples/nvidia/specify_scheduling_policy.yaml 演示了用法apiVersion: v1 kind: Pod metadata: name: gpu-pod annotations: hami.io/node-scheduler-policy: spread # 尽量把 Pod 调度到不同的 GPU 节点 hami.io/gpu-scheduler-policy: binpack # 尽量把 Pod 调度到同一张 GPU 卡 spec: containers: - name: ubuntu-container image: ubuntu:18.04 command: [bash, -c, sleep 86400] resources: limits: nvidia.com/gpu: 1按 Pod 定制设备评分权重除策略外HAMi 还支持通过注解hami.io/device-scoring-weights调整设备评分中槽位slot、核心core、显存memory三者的相对权重详见 docs/develop/scheduler-policy.md 的「Per-Pod device scoring weights」一节metadata: annotations: hami.io/device-scoring-weights: slot1,core1,memory3对应评分公式为score 10 * ( slotWeight * predictedSlotUtilization coreWeight * predictedCoreUtilization memoryWeight * predictedMemoryUtilization )权重只影响设备利用率评分排序binpack 仍倾向高分设备spread 仍倾向低分设备容量、互斥、NUMA 与拓扑约束的优先级不受影响。注解缺省时三者默认均为1注解存在时须同时指定三个非负整数且至少一个为正启用准入 Webhook 时非法注解会在 Pod 创建时被拒绝调度器侧也有校验兜底。动态 MIG按需创建 MIG 切片对于支持 MIG 的 NVIDIA 卡HAMi 可动态创建与分配 MIG 实例。相关工作流的旧版设计基于knownMigGeometries记录于 docs/develop/dynamic-mig.md其中给出了设备 ConfigMaphami-scheduler-device的 MIG 模板示例如 A30 的1g.6gb/2g.12gb/4g.24gb、A100-40GB 的1g.5gb/2g.10gb/3g.20gb/7g.40gb等并说明任务提交后设备共享插件会遍历模板找到第一个可用的组合进行适配。当前实现已迁移为基于 NVML 的拓扑感知发现与migProfileAllowlist迁移与设计文档见 docs/develop/dynamic-mig-migration.md 与 docs/develop/mig-dynamic-deallocate.md。使用 MIG 时Pod 可以直接请求 MIG 设备资源例如 examples/nvidia/mig_example.yamlapiVersion: v1 kind: Pod metadata: name: gpu-pod spec: containers: - name: ubuntu-container image: ubuntu:18.04 command: [bash, -c, sleep 86400] resources: limits: nvidia.com/mig-3g.20gb: 1 # 请求 1 个 MIG 切片也可以保持与普通 vGPU 任务相同的写法只设nvidia.com/gpu与nvidia.com/gpumem由 HAMi 自动选择合适的 MIG 模板若希望任务强制使用某一种虚拟化方式可设置注解nvidia.com/vgpu-mode: mig详见 docs/develop/dynamic-mig.md 的示例。可观测性与 WebUIHAMi 会暴露集群加速器使用情况的指标。安装后可通过调度器监控端点访问http://scheduler-ip:monitor-port/metrics默认监控端口为31993可通过 Helm values 修改例如--set scheduler.service.monitorPortport该端口在 charts/hami/values.yaml 的scheduler.service段中定义monitorPort: 31993、monitorTargetPort: metrics指向调度器的metricsBindAddress默认:9395。HAMi 还提供HAMi-WebUI面向可视化集群与设备管理Grafana Dashboard 示例用于加速器监控可视化基准测试素材用于评估工作负载行为与调度效果位于仓库 benchmarks/ 目录包含 ai-benchmark 的 Dockerfile 与 run_bench.sh 等。此外指标采集与暴露的实现可进一步参考 pkg/metrics/metrics.go 与 cmd/vGPUmonitor/ 下的监控代码其中包含容器级指标、MIG 指标等测试用例如metrics_container_test.go、metrics_mig_test.go。生态集成项目集成内容vLLM在 GPU 显存上限下运行推理服务器让多个模型共享一张 GPUVolcano面向 GPU 工作负载的 Gang 调度与基于队列的批式调度Kueue通过 ResourceTransformation 将 HAMi 资源暴露给 Kueue实现批作业排队PrometheusHAMi 暴露容器级 GPU 指标显存使用量、利用率等Grafana提供用于可视化 HAMi GPU 指标的预构建 DashboardNVIDIA GPU Operator可与 GPU Operator 共存HAMi 负责调度、GPU Operator 负责驱动管理社区、路线图与贡献HAMi 由 MAINTAINERS.md 列出的维护者与 AUTHORS.md 列出的贡献者共同治理。如需参与代码、文档、测试或设备后端的改进请阅读 CONTRIBUTING.md。社区面向用户、贡献者、硬件厂商以及构建 Kubernetes 基础 AI 基础设施的平台团队开放官方文档、Discord/Slack 频道、邮件列表与中英文社区会议信息均可通过 README_ja.md 的「コミュニティ」一节获取。HAMi 曾在 KubeDay Japan 2024、KubeCon AI_dev 等大会发表相关演讲详见 README_ja.md 的「講演と参考資料」一节。许可证HAMi 采用 Apache License 2.0 许可详见 LICENSE。版权归 HAMi 贡献者所有HAMi 是 LF Projects, LLC 旗下系列项目。【免费下载链接】HAMiHeterogeneous GPU Sharing on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ha/HAMi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考