AI 工厂是功率受限的系统,在完全优化时可提供最大价值。GPU 工作负载布局是一项关键优化。糟糕的工作负载放置分散了拓扑域,并迫使流量跨越共享链路,从而降低吞吐量,提高作业成本,并使 GPU 在等待数据而不推进工作负载的同时消耗调配的电力。
GPU 在训练和推理期间持续交换数据,因此分布式工作负载可从通信局部性中获益。NVIDIA NVLink 和 NVLink 交换机可在机架级 GPU 域内提供高带宽、多对多的纵向扩展连接,而 NVIDIA Spectrum-X 以太网则可跨系统和机架提供可预测、低延迟的横向扩展网络。
调度程序只有在获得这些 GPU 和结构关系的最新、准确视图的情况下才能高效地放置工作负载,而在集群变化时保持该视图是实际放置中断的地方。
NVIDIA Topograph 解决了这个问题。它会从NVIDIA DSX OS云 API 或本地网络系统中发现集群拓扑,将其规范化为通用模型,并以每个工作负载管理器所期望的格式发布:Kubernetes 节点标签、Slurm 拓扑配置或 Slinky ConfigMaps。在 NVIDIA DSX OS 集群编排层中,Topograph 可与动态资源分配 (DRA) 和 KAI Scheduler 配合使用,在 AI 工厂基础设施中实现拓扑感知型群组调度。
本文将介绍如何部署 Topograph,并使用它在 Kubernetes、Slurm 和 Slinky 上调度拓扑感知工作负载。
核心拓扑问题
Topograph 会映射集群硬件的连接方式,以便调度人员可以使用附近的资源。将网络视为道路系统:同一本地域中的 GPU 具有短的高带宽路径,而域之间的流量则通过更多共享链路和交换机。将紧密合的工作负载分散到远程域会增加争用和延迟,因此 Topograph 有助于将工作负载放置在最高效的位置,并避免这些瓶颈。
现代 NVIDIA Quantum InfiniBand 端口可实现高达 800 Gb/s 的速度,而 NVIDIA NVLink 通过专用的 NVIDIA NVLink Switch 结构,在其第五代产品 ( NVIDIA Blackwell,例如 GB200/ GB300) 中为每个 GPU 提供 1.8 TB/s 的双向带宽,在第六代产品 ( Vera Rubin) 中为每个 GPU 提供 3.6 TB/s 的双向带宽。这种无阻塞、多对多的设计为每个 GPU 提供了自己的通道,而不是在负载下共享带宽。具有当前视图的调度程序可以优先考虑最接近拓扑域中的 GPU。
Slurm 和 Kubernetes 均支持拓扑感知分配,但调度程序只能对其观察到的拓扑采取行动。Topograph 会根据请求和已观察到的集群更改重新生成该视图,因此调度程序基于当前数据而非手动维护的快照运行。
跨环境的通用模型
Topograph 是一个开源工具包,可识别集群的网络拓扑,使工作负载管理器能够做出拓扑感知型调度决策。它有两个概念:提供程序和引擎。提供商从云 API 或本地系统中发现拓扑,并将其标准化为标准模型。引擎会将该模型转换为 Slurm 配置、Kubernetes 标签、Slinky ConfigMaps、节点特征发现 (NFD) 资源或面向实例的拓扑 JSON。
与 Google Cloud、Lambda、Nebius、Nscale 和 OCI 集成工作的云提供商包括,还有更多的云和托管提供商正在开发中。
在本地使用时,请使用带有 InfiniBand 提供程序 的 ibnetdiscover,或使用适用于 Spectrum-X 或 多节点 NVLink (MNNVL) 域的 NetQ。提供程序接口是开放的,因此操作员可以为自己的环境添加一个,并将其贡献到上游。
环境和引擎支持
| 环境或提供商 | Kubernetes | Slurm | 图 | ||
| 节点标签 ( k8s) |
NFD 资源 ( nfd) |
Slinky ConfigMap ( Slinky) |
|||
| 云和托管提供商 | |||||
| Crusoe | 是 | 是 | 是 | 是 | 是 |
| Google Cloud | 是 | 是 | 是 | 是 | 是 |
| Lambda | 是 | 是 | 是 | 是 | 是 |
| Nebius | 是 | 是 | 是 | 是 | 是 |
| Nscale | 是 | 是 | 是 | 是 | 是 |
| Oracle 云基础设施 (OCI) | 是 | 是 | 是 | 是 | 是 |
| 本地部署模型 | |||||
| Kubernetes 中的 InfiniBand | 是 | 是 | 是 | 是 | 是 |
| bare metal 或 VM 上的 InfiniBand | 否 | 否 | 否 | 是 | 是 |
| 本地网络和拓扑 | |||||
| Spectrum-X 或 NetQ 管理的网络 | 是 | 是 | 是 | 是 | 是 |
| MNNVL NVLink 分区 (仅限 DRA 块拓扑) | 否 | 否 | 是 | 否 | 否 |
范围和解释。此矩阵反映了截至 2026 年 9 月 16 日的当前上游主线。它显示了支持的提供商到引擎的输出组合;要求可能会因地形图版本、环境和提供商配置而异。
- Crusoe 提供程序从 Crusoe Managed Kubernetes 节点中读取结构和加速器域标签;因此,Topograph 为此提供程序在 Kubernetes 中运行。
- Slurm 引擎可以在 Kubernetes 中运行,但其配置的
topology.conf输出路径需要一个可写卷。 - NFD 引擎需要 alpha NodeFeatureGroupAPI 特征门。Kubernetes 引擎会发布节点标签。
在集群变化时保持最新状态
五个组件可使视图保持最新状态:
- API 服务器:验证请求、聚合重复数据和调度发现
- Node Observer:观察已配置的 Kubernetes 节点或 Pod 更改和 API 就绪情况,然后通过重试请求再生
- 节点数据代理:收集每个节点的属性并将其存储为节点标注
- 提供程序:将云或网络数据转换为标准表示形式
- 引擎:以调度程序能够理解的格式编写表示

客户端如何查询拓扑
API 服务器公开五个服务端点:
POST /v1/generate:提交异步请求并返回其 ID (使用 HTTP 202) 。GET /v1/topology?uid=<request-id>:处理时返回 HTTP 202,完成后返回 HTTP 200 及结果。POST /v1/lookup:返回同一请求体的缓存状态或结果,而无需再次提交。GET /healthz:是存活端点。GET /metrics:公开 Prometheus 指标。
需要聚合延迟;通常为 15 秒。重复相同的请求会重置追踪计时器并处理一次,从而减少集群事件突发期间的冗余工作。
对于不使用生产硬件的测试,仿真模型描述了节点和交换机层次结构。kwok-nodes 实用程序和 Kind/ KWOK 助手可将这些模型转换为虚拟 Kubernetes 节点。
在 Kubernetes 上解决此问题 (引擎:k8s)
默认的 Kubernetes 调度程序不会发现物理互连层次结构。Topograph 通过将提供商报告的拓扑发布为节点标签来解决这一差距,原生亲和性和拓扑感知型调度程序可以使用这些拓扑。
预备知识包括 Kubernetes 1.27 或更高版本、Helm 3.10+ 或 4.x、kubectl 权限以及受支持的提供程序。KAI Scheduler 或 Kueue TAS 是拓扑感知型群组调度的可选项。
使用 Helm 部署 Topograph
拓扑图以 Helm 图表 的形式分布:
helm repo add topograph https://dsx-ai-factory.github.io/topograph
helm repo update
helm install topograph topograph/topograph \
--namespace topograph \
--create-namespace \
--set engine.name=k8s \
--set provider.name=<provider>
将 <provider> 替换为与您的环境相匹配的值。
该资源库包含 charts/topograph 中的示例 Helm 值文件,该文件以 values.k8s 前缀和简短场景描述命名。每个模型都带有内联配置注释。
安装后,验证部署是否已成功完成:
helm test topograph --namespace topograph
捆绑的测试挂钩在集群内查询 /healthz 和 /metrics,并确认响应包含 topograph_version 指标。
确认 Pod 正在运行:
kubectl get pods -n topograph
验证节点上的拓扑标签
拓扑图表示具有可变深度标签系列的网络局部性,以及具有两层层次结构的加速器局部性:
fabric.topograph.run/tier-0 # switch closest to the node
fabric.topograph.run/tier-1 # next fabric tier outward
fabric.topograph.run/tier-<N> # additional discovered tiers
accelerator.topograph.run/domain # accelerator domain
accelerator.topograph.run/sub-domain # optional nested sub-domain
网络第 0 层是离计算节点最近的叶子交换机,层数向外增加。Topograph 仅编写已发现的拓扑结构中存在的层,没有固定的最大深度。运算符可以将 Kubernetes 引擎的 fabricLabels 数组和 acceleratorLabel 参数设置为使用自定义键;超出该数组的层不会被标记。子域密钥是固定的。
要验证是否已应用标签,请运行:
kubectl get nodes --show-labels | grep -E 'fabric\.topograph\.run|accelerator\.topograph\.run'
如果缺少标签,请检查 Topograph 日志:
kubectl logs -n topograph -l app.kubernetes.io/name=topograph
注意:地形图反映的是报告的拓扑而非预期拓扑。当生成运行时 (例如,在监视节点或 POD 更改后) ,标签会刷新。网络变更的可见性取决于提供程序及其触发事件。
公开 API
默认情况下,API 是 ClusterIP 服务。以上版本和命名空间的地址为:topograph.topograph.svc.cluster.local:49021。
对于本地调试:
kubectl -n topograph port-forward svc/topograph 49021:49021
curl http://localhost:49021/healthz
使用标准 Kubernetes 调度
拓扑标签可用作首选 Pod 亲和性中的 topologyKey 值:
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 90
podAffinityTerm:
labelSelector:
matchLabels:
app: myapp
topologyKey: fabric.topograph.run/tier-0
- weight: 70
podAffinityTerm:
labelSelector:
matchLabels:
app: myapp
topologyKey: fabric.topograph.run/tier-1
每个匹配项都有助于提高候选节点的分数,这非常有利于现有 app=myapp Pod 的 0 级域,同时也会奖励 1 级局部性。由于默认调度程序会单独放置 Pod,因此这不是全局最优分组放置的首选方案。
KAI Scheduler 和 Kueue 可以使用相同的节点标签来放置拓扑感知型集群。Kubernetes 1.36 还通过 KEP-5732 引入了 Alpha 拓扑感知型工作负载调度。上游测试版工作仍在进行中;请参阅增强追踪器,而不是取决于特定的未来版本。
使用 KAI Scheduler 进行拓扑感知型帮式调度
KAI Scheduler(由 NVIDIA 捐赠的 CNCF 沙盒项目)将节点标签整理成层次结构:
apiVersion: kai.scheduler/v1alpha1
kind: Topology
metadata:
name: cluster-topology
spec:
levels:
- nodeLabel: topology.kubernetes.io/zone
- nodeLabel: fabric.topograph.run/tier-1
- nodeLabel: fabric.topograph.run/tier-0
- nodeLabel: kubernetes.io/hostname
使用 kubectl apply -f cluster-topology.yaml 进行应用,然后标注多 Pod 作业:
apiVersion: batch/v1
kind: Job
metadata:
name: topology-aware-workers
annotations:
kai.scheduler/topology: cluster-topology
kai.scheduler/topology-required-placement: fabric.topograph.run/tier-1
kai.scheduler/topology-preferred-placement: fabric.topograph.run/tier-0
spec:
parallelism: 4
completions: 4
template:
metadata:
labels:
app: inference-worker
spec:
schedulerName: kai-scheduler
restartPolicy: Never
containers:
- name: worker
image: nvcr.io/nvidia/nemo:latest
resources:
limits:
nvidia.com/gpu: 1
所需的注释会将该帮保留在单个一级域内。首选标注要求 KAI 在可行的情况下将 Pod 集中到 0 级域中,但允许在所需边界内使用多个 0 级域。
有关更高级的拓扑感知调度示例,请参阅 Grove和 NVIDIA Dynamo文档。
Grove 提供 Kubernetes API 和 Operator,用于分层组调度、拓扑感知放置和协调扩展。Dynamo 是一个开源分布式推理服务框架,与用于 Kubernetes 工作负载编排的 Grove 集成。
通过 NFD 发布拓扑 (引擎:nfd)
Topograph 还为已使用 Node Feature Discovery 的用户提供支持。nfd 引擎为每个选定的拓扑节点发布一个 NodeFeature,并为每个不同的结构层、XCLR 域和 XCLR 子域值发布一个 NodeFeatureGroup。NFD 主节点会评估这些规格,并拥有每个组的 status.nodes 成员资格。
首先安装 nfd,并启用 Alpha NodeFeatureGroupAPI 功能门;默认关闭。然后选择运行 NFD 主节点的引擎和命名空间:
engine:
name: nfd
nfdNamespace: node-feature-discovery
当下游组件使用 NodeFeatureGroup 对象时,请使用此输出;它不能替代 Kubernetes topologyKey 标签。对于原生 Pod 亲和性、KAI Scheduler 或 Kueue TAS,请继续使用 engine: k8s。该图表将 NFD 权限范围扩展至 nfd 命名空间。调整后,引擎会删除过时的 Topograph 管理的对象,但会保留上次发布的拓扑 (如果一次生成未生成任何对象) 。
在 Slurm 上解决问题 (引擎:slurm)
Topograph 以树和块格式生成集群范围的配置,如下图 2 的上中心和下中心面板所示。Slurm 25.05 以YAML 格式引入了按分区配置,而 Topograph 也支持这种格式,如图所示。

安装 Topograph
Slurm 集群通常在 Linux 裸机服务器或虚拟机上运行,Topograph 通过本地包管理器安装。资源库包括 Debian 和 RPM 构建目标:
make deb # Debian / Ubuntu
make rpm # RHEL / Rocky / SUSE
软件包会在不启动服务的情况下安装服务,因此您可以查看和编辑配置文件 /etc/topograph/topograph-config.yaml
http:
port: 49021
provider: <provider>
engine: slurm
requestAggregationDelay: 15s
将 <provider> 替换为与您的环境相匹配的值。
更新配置后,启动服务并验证其是否正常运行:
sudo systemctl enable --now topograph.service
curl http://localhost:49021/healthz
生成 Slurm 拓扑配置
要启动发现,请将结果发布到 Topograph 的 /v1/generate 端点,该端点会重新生成 Slurm 拓扑配置。
提交请求并轮询其结果:
id=$(curl -s -X POST -H 'Content-Type: application/json' \
-d @payload.json http://localhost:49021/v1/generate)
curl -s "http://localhost:49021/v1/topology?uid=$id"
对于集群范围的树输出,请使用绝对路径:
{
"engine": {
"name": "slurm",
"params": {
"plugin": "topology/tree",
"topologyConfigPath": "/etc/slurm/topology.conf",
"reconfigure": true
}
}
}
使用 topology/block 和可选的 blockSizes 进行块输出。
可选 reconfigure 参数在文件写入后运行 scontrol reconfigure,默认为 false。如果省略了 topologyConfigPath,Topograph 将从结果端点返回生成的内容,而不是写入文件。
{
"engine": {
"name": "slurm",
"params": {
"topologies": {
"gpu-block": {
"partition": "gpu",
"plugin": "topology/block",
"blockSizes": [8, 16]
},
"cpu-tree": {
"partition": "cpu",
"plugin": "topology/tree"
},
"default": {
"plugin": "topology/flat",
"clusterDefault": true
}
},
"topologyConfigPath": "/etc/slurm/topology.yaml",
"reconfigure": true
}
}
}
要使用自动发现 Slurm 节点映射的提供程序进行节点状态驱动的刷新,请以 root 身份运行存储库的脚本:
scripts/create-topology-update-script.sh -p <provider> -c /etc/slurm/topology.conf
它注册永久 strigger,用于节点向上和向下转换。它不会检测到任意交换机重新布线或每次库存变化。
使用 Slinky 解决问题 (引擎:Slinky)
Slinky 由 SchedMD 开发,在 Kubernetes 上运行 Slurm。NVIDIA 于 2025 年 12 月收购了 SchedMD。Topograph Slinky 引擎将 Kubernetes 节点映射到 slurmd Pod,并将 Slurm 拓扑数据写入 ConfigMap。
Slinky 引擎支持集群范围的 topology/tree 和 topology/block 输出,以及用于特定分区配置的多拓扑 YAML。
将 Topograph 安装为 Helm 图表:
helm repo add topograph https://dsx-ai-factory.github.io/topograph
helm repo update
helm install topograph topograph/topograph \
--namespace topograph \
--create-namespace \
--values my-values.yaml
该存储库提供适用于树、块、每个分区和InfiniBand 块部署的现成 Helm 示例。
当选定的 slurmd Pod 发生变化时,Topograph 会重新生成并更新 ConfigMap。
dra 提供程序是适用于 MNNVL 系统的较窄 Slinky 块拓扑选项。重新生成拓扑配置时,它会读取现有的 nvidia.com/gpu.clique 标签。
对于动态 Slurm 节点,可选的 useDynamicNodes 模式还会使用当前的 Slurm 拓扑规范标记选定的 Kubernetes 节点。ConfigMap 更新和动态节点同步是截然不同的机制,因此请选择与已部署的 Slinky 配置相匹配的模式。
开始使用
随着网络拥塞,布局问题在规模和表面上变得更加复杂。Topograph 为调度程序提供了当前由提供商报告的物理网络地图,因此拓扑感知型决策在云和本地环境中保持一致,无需手动维护。
通过 KAI Scheduler、Kueue 和原生 Kubernetes,该地图提高了 AI 工厂的效率、每瓦 token 数和成本。
从 dsx-ai-factory/topograph GitHub 资源库 部署 Topograph,或详细了解 DSX OS 生态系统。