GPU 显存共享实战:用 HAMi 把一张卡分给多个任务
【免费下载链接】HAMiHeterogeneous GPU Sharing on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ha/HAMi
你的训练任务只要 3GB 显存,Pod 却必须申请整张卡,剩下的显存只能闲置。如果你要管理这样的集群,可以看看 HAMi:一个 CNCF 孵化项目,在 Kubernetes 上做 GPU 显存共享与异构计算调度,让任务按需申请显存和算力,应用侧不用改一行代码。
💡 它帮你解决什么
一句话:把昂贵的加速器当成"资源池",按显存、算力、卡数切分,再让调度器知道每张卡的状态。具体就三点:
- 按份共享:申请 1 张物理卡的同时,用
nvidia.com/gpumem限定这张卡上最多能用多少 MB 显存,用nvidia.com/gpucores限定算力百分比。像合租一间房,一张卡能住多户。 - 零应用改动:沿用标准 Kubernetes 资源请求/限制写法,应用代码对 HAMi 无感知。
- 设备感知的调度:提供 binpack、spread、拓扑感知、动态 MIG 等放置模式,还能把不同厂商的设备放进同一套调度流程。
知道它干什么之后,接下来看怎么装。
🚀 三步把 HAMi 跑起来
环境前置条件
以 NVIDIA 卡为例:驱动不低于 440,Kubernetes 不低于 1.23,Helm 大于 3.0,容器运行时把 nvidia 配成默认。其他厂商的卡有不同的后端要求,装之前先翻一下仓库里对应的 chart 说明。
然后按顺序做三件事:
- 给节点打标签:
kubectl label nodes <node-name> gpu=on - 安装核心组件:
helm install hami ./charts/hami -n kube-system(chart 就在仓库的charts/hami/目录,clone 下来直接用) - 验证并跑样例:
kubectl get pods -n kube-system确认hami-scheduler、hami-device-plugin都是 Running,再kubectl apply -f examples/nvidia/default_use.yaml
Pod 跑起来、容器内能看到被限定的卡,链路就算通了。样例文件在 examples/nvidia/default_use.yaml。
⚙️ 核心机制怎么工作
不必背组件清单,记住"一条流水线、一个关键参数"就够了。
流水线:Pod 提交后先被 Mutating Webhook(K8s 的准入控制器,能在对象入库前改它)标记,接着 HAMi 调度器依次做 filter、score、bind 三步,决定放在哪个节点、用哪张卡,把分配结果写进 Pod 注解;节点上的设备插件随后调用 Allocate() 往容器里注入对应的设备和环境变量,最后监控组件开始采集用量。整条数据流如下图所示:
关键参数是显存怎么"切"。Pod 里这段配置:
resources: limits: nvidia.com/gpu: 1 # 需要 1 张物理卡 nvidia.com/gpumem: 3000 # 这张卡上最多用 3000MB 显存容器里的 CUDA 申请显存时不会越过这个上限。注意一个容易踩的点:安装后节点注册的nvidia.com/gpu值默认是 vGPU(虚拟卡)数量,Pod 申请时它指物理卡数。
弄懂原理后,看看它到底能把利用率拉高多少。
📊 一张表看懂
共享前后差多少
经典场景:用户 A 每张卡要 10G 显存、用 2 张,用户 B 每张要 20G、也用 2 张。
| 指标 | 不用 HAMi | 用 HAMi |
|---|---|---|
| 占用的物理卡 | 4 | 2 |
| 利用率 | 50% | 100% |
| 每张卡承载的任务 | 1 | 2 个以上 |
共享后两张卡被填满,另外两张空出来留给新任务:
支持哪些设备
官方文档列了 NVIDIA、华为昇腾、寒武纪、海光、天数智芯、昆仑芯、沐曦、摩尔线程等;examples/目录里还有 AWS Neuron、壁仞、燧原、VastAI 的样例配置。不同厂商能力有差异(有的只支持显存上限、不支持算力上限),落地前建议对照 pkg/device/ 下的后端目录确认。
| 类别 | 示例 |
|---|---|
| GPU | NVIDIA、AMD、摩尔线程、天数智芯、沐曦、壁仞 |
| NPU | 华为昇腾 |
| 其他加速器 | 寒武纪 MLU、海光 DCU、昆仑芯、燧原、AWS Neuron |
设备能用了,下一步是挑一套适合自己的调度策略。
🎯 调度策略怎么选
默认策略是 binpack,也可以按 Pod 用注解覆盖。按场景挑:
| 你的情况 | 建议 |
|---|---|
| 卡池紧张,希望集中放置 | 保持默认 binpack,把任务塞进尽量少的节点和卡,留出整卡给大任务 |
| 想分散放置、减少互相干扰 | 节点级用 spread:hami.io/node-scheduler-policy: "spread" |
| 单节点多卡,想控制选哪张卡 | 卡级策略:hami.io/gpu-scheduler-policy: "binpack" |
| 支持的 NVIDIA 卡,要硬性分区 | 动态 MIG,由 HAMi 按需创建、复用和回收 MIG 实例 |
两条注解合起来就是这样:
annotations: hami.io/node-scheduler-policy: "spread" hami.io/gpu-scheduler-policy: "binpack"策略实现都在 pkg/scheduler/policy/。要用动态 MIG 的话,先读 docs/develop/dynamic-mig-lifecycle.md:它要求 HAMi 是该卡上唯一创建/销毁 MIG 的控制器,和别的 MIG 控制器并存是不支持的。
策略选好了,跑起来之后怎么用得上、查得到呢?
📈 看得见、查得动
装完监控默认就开着。调度器暴露/metrics端点,默认端口 31993,接上 Prometheus 再配 Grafana 就能看;项目还配套一个 WebUI,用来浏览资源总览和设备分布。
遇到"不工作"的情况,先按这张表自查:
| 现象 | 先查哪里 |
|---|---|
hami-device-plugin起不来 | 节点有没有gpu=on标签、nvidia 默认运行时是否配好、Pod 事件日志 |
| Pod 一直 Pending | 调度器和 webhook 是否都 Running;申请的显存是否超过单卡总量 |
| 显存上限像没生效 | 该设备后端是否支持显存限制;用 metrics 端点核对实际用量 |
工具链都齐了,最后说说它到底适合什么人。
🧭 适合谁,边界在哪
HAMi 比较契合这三类场景:
- 共享型 AI 集群:多租户的 Notebook、推理、轻训练混跑在同一个卡池里;
- 异构混合集群:不同厂商的加速器走一套统一调度入口;
- 要可观测的平台:分配了多少、用了多少,都能查得到。
两个边界要注意:
- 隔离能力取决于设备后端。部分厂商只有显存上限、没有算力上限,效果因卡型和驱动版本而异;
- 动态 MIG 只覆盖受支持的 NVIDIA 卡,且该卡上的 MIG 生命周期必须完全由 HAMi 接管。
如果你的场景只是单机单卡跑一个大作业,就没必要引入这套东西了。
一句话收尾:HAMi 把"整卡独占"变成"显存级共享",顺手把不同加速器的调度入口也统一了。想读源码或动手试:git clone https://gitcode.com/GitHub_Trending/ha/HAMi。
【免费下载链接】HAMiHeterogeneous GPU Sharing on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ha/HAMi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考