网络/通讯

借助 NVIDIA Topograph 实现拓扑感知型工作负载调度

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 CloudLambdaNebiusNscaleOCI 集成工作的云提供商包括,还有更多的云和托管提供商正在开发中。

在本地使用时,请使用带有 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 块拓扑)
表 1. 按引擎划分的受支持的拓扑提供程序

范围和解释。此矩阵反映了截至 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 SchedulerKueue 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/treetopology/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 生态系统

标签