HAMi × 沐曦 MetaX sGPU 共享、三档 QoS、拓扑智能调度与 WebUI 全面适配
近日,密瓜智能团队与沐曦 MetaX 团队紧密合作,基于曦云C系列产品,在 HAMi v2.7.0 版本中联合推出了统一调度方案。该方案通过深度整合,实现了 sGPU 共享、三档 QoS、拓扑智能调度与 WebUI 全面适配,旨在大幅提升大规模 AI 训练与推理场景下的资源利用率与任务执行效率,为构建国产自主可控的 AI 算力底座提供了坚实支持。
一、 核心特性总览
-
GPU 共享 (sGPU) 与资源隔离: 允许多个容器任务共享同一张物理 GPU 卡,并通过精确限制每个任务的显存(如 4G)与计算核心比例(vcore, 如 60%)来实现资源隔离,从而显著提高资源利用率。
-
sGPU 拓扑感知调度: (v2.7.0 新增) 针对单机多卡的场景,调度器能动态感知 GPU 间的连接拓扑(如 MetaXLink、PCIe Switch),并为多卡 sGPU 任务优先选择通信带宽最高的 GPU 组合,提升训练性能。
-
服务质量 ( QoS ) 策略: (v2.7.0 新增) 支持为 sGPU 任务设置不同的资源服务等级,如 BestEffort (尽力而为)、FixedShare (固定份额) 和 BurstShare (突发份额),以满足不同业务场景的需求。
-
健康检查与监控: (v2.7.0 新增) 提供设备健康状态检查,在 HAMi-WebUI 中打通沐曦监控全链路,使得异构指标在界面中更直观呈现,可视化地展示整个集群的资源分配和使用情况。
-
GPU 拓扑感知调度: 基于DevicePlugin 的预先打分,为多卡 GPU 任务优先选择通信带宽最高的 GPU 组合,支持
binpack和spread等调度策略,实现更精细化的资源布局。
二、sGPU 拓扑感知调度:智能寻优
metax-tech.com/sgpu 资源,同时不指定 vcore(使其默认为 100)来触发。其核心目标是确保任务在高速互联的 GPU "群组"内部执行,从而最大化通信效率。
阶段一:节点内设备选择 - “规则至上”的确定性决策
-
输入: 节点上所有满足 Pod 资源请求(如显存、算力)的候选 GPU 列表。
-
分组: 算法首先将这些候选 GPU 按照它们的 linkZone ID (高速互联域标识) 进行分组。
-
决策树: 算法开始按以下优先级顺序进行决策:
-
第一优先级 (最优解:域内满足): 算法会检查是否存在任何一个 linkZone 分组,其内部的 GPU 数量足以满足任务的全部需求。
-
第二优先级 (次优解:跨域组合): 算法会创建一个新的空列表,然后逐个遍历所有 linkZone 分组,将里面的 GPU 全部添加到这个新列表中,直到列表中的 GPU 总数满足任务需求。
-
第三优先级 (保底解:补充无互联信息设备): 如果遍历完所有 linkZone 分组后,列表中的 GPU 数量仍然不够,算法最后会用那些没有 linkZone 信息的 GPU 来补足剩余的数量。
-
pkg/device/metax/sdevice.go 中的 prioritizeExclusiveDevices 函数实现。
linkZone 满足的设备组合。
// File: pkg/device/metax/sdevice.go
func prioritizeExclusiveDevices(candidateDevices device.ContainerDevices, require int) device.ContainerDevices {
// ... (代码将所有候选 GPU 按 linkZone 进行分组) ...
// linkDevices: 存储了所有带 linkZone 的设备组
// otherDevices: 存储了所有不带 linkZone 的设备
// 1. pickup devices within MetaLink (第一优先级)
for _, devices := range linkDevices {
if len(devices) >= require {
klog.V(5).Infof("prioritize exclusive devices: best result, within metalink")
return devices[0:require] // 找到一个linkZone能满足所有需求,直接返回,这是最优解
}
}
prioritizeDevices := device.ContainerDevices{}
// 2. pickup devices cross MetaLink (第二优先级)
// ... (如果单个 linkZone 不够,则开始跨 linkZone 凑齐设备) ...
// 3. if not satisfied, pick up devices no MetaLink (第三优先级)
// ... (用 otherDevices 里的设备进行补充) ...
return ...
}
C(n, k) 种组合进行暴力评分的巨大开销。它基于一个核心共识:域内通信的性能远高于跨域通信。因此,一旦找到满足条件的“最优解”(第一优先级),任何其他组合方案都无需再被考虑,从而极大地提升了调度效率。
阶段二:节点间评分决策 - “深谋远虑”的量化评估
pkg/device/metax/sdevice.go 中的 scoreExclusiveDevices 函数实现:
// File: pkg/device/metax/sdevice.go
func scoreExclusiveDevices(podDevices device.PodSingleDevice, previous []*device.DeviceUsage) int {
// ... (代码构建 allocatedDevices, availableDevices, restDevices 列表) ...
// 计算三个核心分数
availableScore := availableDevices.Score() // 分配前总分
allocatedScore := allocatedDevices.Score() // 分配组合得分
restScore := restDevices.Score() // 剩余设备得分
// 计算拓扑损失分
lossScore := availableScore - allocatedScore - restScore
// 计算最终得分,放大 allocatedScore 的权重
result := 10*allocatedScore - lossScore
klog.V(5).Infof("calcScore result[%d] >>> availableScore[%d], allocatedScore[%d], restScore[%d], lossScore[%d]",
result, availableScore, allocatedScore, restScore, lossScore)
return result
}
-
allocatedScore (分配质量分): 这个分数衡量的是第一阶段选出的那个 GPU 组合本身的内部连接紧密程度。组合内处于相同 linkZone 的设备对越多,这个分数就越高。10 * allocatedScore 表明调度器极度重视为当前任务分配一个高质量的组合。权重乘以 10,使其在最终得分中占据主导地位。
-
lossScore (拓扑损失分 / 碎片化惩罚): 这是一个非常关键的“远见”指标。它衡量的是:“为了完成本次分配,我们对节点上剩余的、未被分配的 GPU 的拓扑完整性造成了多大的破坏?”
-
计算方式:lossScore = (分配前总分) - (分配组合得分) - (剩余设备得分)
-
这意味着调度器会惩罚那些会导致节点拓扑资源“碎片化”的分配行为,在分配质量分相同的时候会起作用,保护了集群为未来的大型任务保留优质、完整拓扑资源的能力。
-
三、 服务质量(QoS)策略:“同类聚合”的隔离实现
-
BestEffort (尽力而为): 默认策略。资源尽力分配,不限制算力,追求最大化的资源利用率。
-
FixedShare (固定份额): 严格保证任务分配到的算力 (vcore) 和显存 (vmemory)固定配额,性能稳定,不受其他任务干扰。
-
BurstShare (突发份额): 有固定资源配额,但在 GPU 空闲时允许被 sGPU 使用,适合有突发负载的业务。
设计考量
核心原理与代码实现
checkDeviceQos 函数,我们可以将其总结为一句话:
-
如果第一个 Pod 是 FixedShare,这张卡就变成了“FixedShare 专用卡”。
-
如果第一个 Pod 是 BestEffort,这张卡就变成了“BestEffort 专用卡”。
-
检查 GPU 是否空闲: 如果 GPU 完全空闲,允许任何 QoS 任务入驻,并由该任务设定卡的 QoS 模式。
-
检查 QoS 是否匹配: 如果 GPU 已被占用,则新任务的 QoS 注解 必须严格等于卡上现有任务的 QoS 模式,否则调度将被拒绝。
-
独占任务例外: 请求 100% 算力的任务,因不涉及共享,不受此规则限制。
// file: pkg/device/metax/sdevice.go
// func: checkDeviceQos (simplified logic)
func (sdev *MetaxSDevices) checkDeviceQos(reqQos string, usage device.DeviceUsage, request device.ContainerDeviceRequest) bool {
if usage.Used == 0 { // 空闲卡
return true
}
if request.Coresreq == 100 { // 独占卡
return true
}
// ... 获取 devQos ...
if devQos == "" || reqQos == devQos { // 核心匹配规则
return true
} else {
return false
}
}
FixedShare专用卡,另一些则成为 BestEffort 专用卡,从而实现了优雅而高效的资源隔离。
四、WebUI 支持
五、 GPU 拓扑感知调度:Binpack 与 Spread
metax-tech.com/gpu 资源时,HAMi 的 binpack 和 spread 策略会通过一种被动的、读取静态分数的方式来影响调度决策。
-
spread模式: 调度器会读取metax-tech.com/gpu.topology.scores(MetaxAnnotationScore) 的注解值。为了配合 HAMi 框架“分数越低,越靠前”的spread逻辑,这里需要做反转处理 (分数 = 2000 - score)。这意味着,一个节点的预计算score越高,其在 HAMi 的最终得分反而越低,从而排名靠前,越倾向于被调度,进而选择最优拓扑。 -
binpack模式: 调度器会读取节点上metax-tech.com/gpu.topology.losses(MetaxAnnotationLoss) 的注解值。这个loss值越低,代表资源“损失”越小,节点得分就越高 (分数 = 2000 - loss),从而被优先选择,进而保障剩余资源的拓扑尽可能完整。
pkg/device/metax/device.go:
// File: pkg/device/metax/device.go
func (dev *MetaxDevices) ScoreNode(...) float32 {
res := float32(0)
if policy == string(util.NodeSchedulerPolicyBinpack) {
lossAnno, ok := node.Annotations[MetaxAnnotationLoss]
if ok {
loss := parseMetaxAnnos(lossAnno, sum)
res = 2000 - loss
}
} else if policy == string(util.NodeSchedulerPolicySpread) {
scoreAnno, ok := node.Annotations[MetaxAnnotationScore]
if ok {
score := parseMetaxAnnos(scoreAnno, sum)
res = 2000 - score
}
}
return res
}
MetaXLink 优先级高于 PCIe Switch,包含两层含义:
两卡之间同时存在 MetaXLink 连接以及 PCIe Switch 连接时,认定为 MetaXLink 连接; 服务器剩余 GPU 资源中 MetaXLink 互联资源与 PCIe Switch 互联资源均能满足作业请求时,分 配 MetaXLink 互联资源。
-
当任务使用
node-scheduler-policy=spread,分配 GPU 资源尽可能位于相同 MetaXLink 或 PCIe Switch 下,如下图所示:
-
当使用
node-scheduler-policy=binpack,分配 GPU 资源后,以尽量减少对 MetaXLink 拓扑的破坏,保障剩余资源尽可能完整,如下图所示:
六、 使用方式
GPU 拓扑感知调度
hami.io/node-scheduler-policy 注解控制 binpack 或 spread 行为。
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod2
annotations:
# binpack 策略: 针对 'gpu' 资源,调度器将读取节点注解 'metax-tech.com/gpu.topology.losses' 的值。
# 评分按 `2000 - loss` 计算,因此 loss 值越低的节点得分越高,会被优先选择,进而保障剩余资源的拓扑尽可能完整。
hami.io/node-scheduler-policy: "binpack"
spec:
containers:
- name: ubuntu-container
resources:
limits:
metax-tech.com/gpu: 2
---
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod3
annotations:
# spread 策略: 针对 'gpu' 资源,调度器将读取节点注解 'metax-tech.com/gpu.topology.scores' 的值。
# 评分按 `2000 - score` 计算。这会配合 HAMi 框架的 spread 逻辑,优先选择得分较低(即 score 注解值较高)的最优拓扑节点。
hami.io/node-scheduler-policy: "spread"
spec:
# ...
sGPU 拓扑感知调度
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod1
annotations:
metax-tech.com/sgpu-topology-aware: "true" # 开启拓扑感知调度
spec:
containers:
- name: ubuntu-container
resources:
limits:
# 请求 4 张完整的 GPU。因未指定 vcore,默认为100,从而触发独占模式与拓扑感知
metax-tech.com/sgpu: 4
# ...
sGPU 共享与 QoS 策略
metax-tech.com/sgpu-qos-policy 注解指定 QoS。
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
annotations:
metax-tech.com/sgpu-qos-policy: "fixed-share" # 或 "best-effort", "burst-share"
spec:
containers:
- name: ubuntu-container
resources:
limits:
metax-tech.com/sgpu: 1
metax-tech.com/vcore: 60
metax-tech.com/vmemory: 4
七、 总结
-
说明文档: MetaX GPU 支持说明
-
使用样例: MetaX GPU 样例
-
相关 PRs:
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
SofaRPC v5.14.0 发布,蚂蚁金服开源 Java RPC 框架
SOFARPC 是一个高可扩展性、高性能、生产级的 Java RPC 框架。SofaRPC v5.14.0 现已发布,此版本带来了对 sofa-rpc 框架的增强和一些错误修复(需要 JDK8 版本支持)。具体更新内容如下: Feature 优化动态配置,集成Zookeeper和Nacos,支持接口级动态配置#1430 支持自定义 UserThreadPool 接口方法#1500 支持自定义 triple header size 并修改默认最大标题大小为 64 KB#1509#1510 Fix 修复 hessian 反序列化支持 sofa.serialize.dynamic.load.enable#1463 修复 FailFastCluster 跟踪日志中的异常状态代码映射#1504 修复 sharedChannel 并发销毁问题#1513 Chore chore(deps):在 /bom 中将 org.apache.cxf:cxf-core 从 3.5.8 升级到 3.5.11#1497 更新 nexusUrl#1515#1516#1518 更新说明:https://github.c...
-
下一篇
DBeaver 25.2.3 发布
DBeaver 是一个免费开源的通用数据库工具,适用于开发人员和数据库管理员。DBeaver 25.2.3 已发布,具体更新内容如下: AI 助手: 添加了在“偏好设置”中测试 AI 配置的功能 修复了 AI 命令中的错误,该错误导致查询包含尾部分隔符时出现错误 Data Editor: 由于与“Advanced Copy”快捷键冲突,删除了“Select Row Count”(Ctrl+Alt+Shift+C)的默认快捷键 修复了 boolean inline editor 在没有主键的表中为只读的问题 Metadata Editor: 更新了对象注释编辑的用户界面 删除了视图 DDL 中重复的对象名称注释 Navigator: 添加了不区分大小写的字母排序选项 修复了断开连接后树形结构不一致的问题 修复了某些驱动程序(Databricks、Sybase 和其他驱动程序)中表列表读取的问题 Connectivity: 修复了无法在连接设置中删除 SSH 跳转服务器的问题 网络配置文件设置现在可以在“偏好设置”中更轻松地找到 General: 修复了无法将结果集获取大小设置为 0 的问...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL数据库在高并发下的优化方案
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- 设置Eclipse缩进为4个空格,增强代码规范
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- SpringBoot2整合Redis,开启缓存,提高访问速度

微信收款码
支付宝收款码