# Support New AI Frameworks Faster Using NVIDIA Workload Map

> Source: <https://developer.nvidia.com/blog/support-new-ai-frameworks-faster-using-nvidia-workload-map/>
> Published: 2026-11-02 16:00:00+00:00

[NVIDIA DSX AI Factory Platform](https://www.nvidia.com/en-us/data-center/products/dsx/) brings together technologies to help the ecosystem design, build, and operate more efficient AI factories, including open source, modular software components built to support multi-tenant operations and scaling.

Operating an AI factory requires a shared understanding of distributed workloads: their components, pod templates, replica counts, and status. On Kubernetes, each framework encodes that information differently. JobSet, LeaderWorkerSet, and other custom resources often require separate adapters before a tool can interpret and manage them.

[NVIDIA Workload Map](https://github.com/dsx-ai-factory/workload-map) provides a common description of Kubernetes workload structure that users can reuse across frameworks. As part of the NVIDIA DSX AI Factory Platform, Workload Map enables integrated schedulers, controllers, and platforms to interpret supported workload types without maintaining separate framework-specific parsing code.

This post shows how to describe a distributed JobSet workload once, then reuse that definition for workload inspection, gang scheduling, and platform visibility.

## **Why every workload type needs its own adapter**

On Kubernetes, a real workload is rarely a single pod. A distributed training job or a multi-node inference server is a small tree of resources: groups of pods, each with a role, a replica count, a pod template, and a status that depends on the workload type.

Teams building schedulers, controllers, dashboards, or cost tools that must work across these workloads encounter this immediately. The [NVIDIA Run:ai](https://docs.nvidia.com/run-ai/) team faced the same challenge while creating its platform. For each new custom resource definition (CRD), developers answer the same questions in code:

- What’s the structure of the workload type?
- How is the resource’s status interpreted as a phase?
- How is the pod spec changed without breaking the workload?

A developer answers those questions once per workload type and produces a per-CRD adapter. Each new framework a customer brings requires another adapter. That makes adapter development a roadmap item per framework, not a one-time cost, which is why support for a new workload type so often waits for a release.

The following manifest shows a distributed training job as a user submits it: a JobSet with a leader Job and two worker Jobs, each with a pod requesting four GPUs.

```
apiVersion: jobset.x-k8s.io/v1alpha2
kind: JobSet
metadata:
  name: demo
spec:
  replicatedJobs:
    - name: leader
      replicas: 1
      template:
        spec:
          parallelism: 1
          completions: 1

          template:
            spec:
              containers:
                - name: leader
                  image: ghcr.io/example/trainer:latest
                  resources:
                    limits:
                      nvidia.com/gpu: 4
    - name: worker
      replicas: 2
      template:
        spec:
          parallelism: 1
          completions: 1

          template:
            spec:
              containers:
                - name: worker
                  image: ghcr.io/example/trainer:latest
                  resources:
                    limits:
                      nvidia.com/gpu: 4
```

The manifest describes one leader, two workers, and a total request of 12 GPUs. Interpreting that structure requires JobSet-aware code; `kubectl` lists the resources separately.

*Figure 1.* *kubectl* *lists the demo JobSet, its three Jobs, and their pods as separate resource entries*

``` bash
$ kubectl get jobset,jobs,pods
NAME                      TERMINALSTATE   RESTARTS   COMPLETED   SUSPENDED   AGE
jobset.jobset.x-k8s.io/demo               0                                  3m46s

NAME                      STATUS   COMPLETIONS   DURATION   AGE
job.batch/demo-leader-0   Running  0/1           3m46s     3m46s
job.batch/demo-worker-0   Running  0/1           3m46s     3m46s
job.batch/demo-worker-1   Running  0/1           3m46s     3m46s

NAME                          READY   STATUS    RESTARTS   AGE
pod/demo-leader-0-0-ksb4l     1/1     Running   0          3m47s
pod/demo-worker-0-0-qv955     1/1     Running   0          3m47s
pod/demo-worker-1-0-5smfn     1/1     Running   0          3m47s
```

Owner references connect the Jobs to their JobSet, but a platform still needs a definition to interpret their roles and aggregate resource requests.

Without a shared workload description, users must reconstruct the workload and total its GPU requests themselves.

## **A common description of Kubernetes workload structure**

Workload Map (formerly Karta; the CRD’s resource kind remains Karta) ships as a Kubernetes CRD plus a Go library that interprets workload definitions. Each definition specifies where to find pod templates, replica counts, and status fields for its workload type.

Workload Map supplies a shared structural view to scheduling and platform consumers. [KAI Scheduler](https://github.com/kai-scheduler/KAI-Scheduler) uses its definitions to interpret pod grouping and gang-scheduling instructions, while [NVIDIA Run:ai](https://github.com/dsx-ai-factory/run-ai) uses them for workload management and visibility. Each consumer acts on the same description, reducing the need for separate framework-specific parsers.

The Go library resolves a live object into a uniform structural view. With a workload definition in hand, a consumer can:

- Extract pod templates, replica counts, status, and metadata.
- Update pod specs, labels, and annotations across every instance.
- Understand the workload hierarchy, for example, a JobSet’s replicated Jobs and their pods.

Workload Map includes a [catalog](https://github.com/dsx-ai-factory/workload-map/tree/main/docs/catalog) of prebuilt, tested definitions for JobSet, PyTorchJob, RayCluster, RayJob, RayService, KServe, Knative, MPIJob, NVIDIA NIM, LeaderWorkerSet, Milvus, [Grove PodCliqueSet](https://github.com/ai-dynamo/grove), and [NVIDIA Dynamo](https://github.com/ai-dynamo/dynamo). Additional workload types can be added by writing a YAML definition that describes their structure and status.

The key is that workload knowledge moves out of compiled adapters and into data developers can write, review, and apply to a cluster like any other manifest. The rest of this post describes the JobSet example, then shows how the same definition supports workload inspection, gang scheduling, and platform visibility.

## **Writing a workload definition for JobSet**

A workload definition, expressed as a Workload Map resource, describes that shape. The following excerpt shows key parts of the JobSet definition. The full version ships in the [repository](https://github.com/dsx-ai-factory/workload-map/blob/main/docs/catalog/jobset-x-k8s-io-jobset-v1alpha2.yaml).

The root component defines the workload’s own kind and how its status is read.

```
apiVersion: run.ai/v1alpha1
kind: Karta
spec:
  structureDefinition:
    rootComponent:
      name: jobset
      kind:
        group: jobset.x-k8s.io
        version: v1alpha2
        kind: JobSet
      statusDefinition:
        conditionsDefinition:
          path: .status.conditions
        statusMappings:
          running:
          - byExpression:
              expression: "(.status.replicatedJobsStatus // []) | any(.ready > 0 and .active > 0) and all(.failed == 0)"
              expectedResult: "true"
          completed:
          - byConditions:
            - type: Completed
              status: "True"
          failed:
          - byConditions:
            - type: Failed
              status: "True"
```

`statusMappings` is the translation layer. JobSet does not report a plain “Running” condition, so the definition derives it with a `jq` expression over `replicatedJobsStatus` (any Job ready and active, none failed) and maps the native Completed and Failed conditions onto the shared vocabulary a consumer already uses. When a RayJob or a LeaderWorkerSet is described, its very different status maps to the same categories.

The next excerpt defines the child component: the structure inside the workload.

```
    childComponents:
    - name: replicatedjob
      kind: { group: batch, version: v1, kind: Job }
      ownerRef: jobset
      specDefinition:
        podTemplateSpecPath: .spec.replicatedJobs[].template.spec.template
      scaleDefinition:
        replicasPath: .spec.replicatedJobs[] | .replicas * .template.spec.parallelism
      instanceIdPath: .spec.replicatedJobs[].name
```

A JobSet declares its roles as a list, so `.spec.replicatedJobs` holds one entry per role. The `[]` in these paths means “for each entry in that list,” and each entry is what Workload Map calls an instance. `podTemplateSpecPath` points to each Job’s pod template. `scaleDefinition` uses `jq`: the number of pods per replicated Job equals `replicas` times `parallelism`, which is why the example manifest sets `parallelism` explicitly. `instanceIdPath` takes each instance’s name from `.spec.replicatedJobs[].name`, which is how “leader” and “worker” show up as distinct roles instead of three anonymous Jobs.

The framework-specific structure is now captured in one reusable definition. The next section shows how different consumers use it.

## **Using one description across tools**

The same JobSet definition supports three workflows: inspecting workloads, scheduling them together, and managing them as one workload.

### **Inspecting workloads with the Workload Map CLI**

The [Workload Map CLI](https://github.com/dsx-ai-factory/workload-map/blob/main/docs/CLI%20Guide.md) reads workloads from a cluster and renders them through their workload definitions. For the demo JobSet, the CLI loads the JobSet description, resolves the live object and its pods, and prints the tree. The CLI uses a kubeconfig to access the cluster and includes built-in workload definitions. This inspection workflow does not require installing Workload Map into the cluster.

The following commands install the CLI with Homebrew on macOS or Linux and confirm that the executable is on the `PATH`.

```
brew tap dsx-ai-factory/kli https://github.com/dsx-ai-factory/workload-map
brew install dsx-ai-factory/kli/kli
kli --version
```

With the demo JobSet running in the current Kubernetes context, the following command inspects it. The `<namespace>` placeholder must be replaced with the namespace containing the workload.

```
kli describe jobset/demo -n <namespace>
JobSet/demo   namespace: default   definition: jobset-x-k8s-io-jobset-v1alpha2 (catalog)   age: 20s

`-- replicatedjob                   3/3 ready   gpu: 12   runai-cluster-worker-0-0
    |-- leader                      1/1 ready   gpu: 4    runai-cluster-worker-0-0
    |   `-- demo-leader-0-0-ck6kg   Running     gpu: 4    runai-cluster-worker-0-0
    `-- worker                      2/2 ready   gpu: 8    runai-cluster-worker-0-0
        |-- demo-worker-0-0-j9pdc   Running     gpu: 4    runai-cluster-worker-0-0
        `-- demo-worker-1-0-rrsxz   Running     gpu: 4    runai-cluster-worker-0-0

Phase: Running

Resources:
COMPONENT   REPLICAS   GPU   CPU   MEMORY
leader      1          4     0     0
worker      2          8     0     0
TOTAL       3          12    0     0
```

The output identifies the leader and worker roles and shows a total request of 12 GPUs for the example workload.

*Figure 4. An earlier Karta CLI view resolves the JobSet into leader and worker roles, showing readiness, GPU totals, and node placement*

``` bash
$ karta workload tree demo
JobSet/demo [Running]
└─ replicatedjob  (3/3 replicas)  3/3 ready  gpu: 12  runai-cluster-worker-0-2,runai-cluster-worker-0-5,runai-cluster-worker-0-7
   ├─ leader  (1/1 replicas)  1/1 ready  gpu: 4  runai-cluster-worker-0-7
   │  └─ Pod/demo-leader-0-0-ksb4l  Running  gpu: 4  runai-cluster-worker-0-7
   └─ worker  (2/2 replicas)  2/2 ready  gpu: 8  runai-cluster-worker-0-2,runai-cluster-worker-0-5
      ├─ Pod/demo-worker-0-0-qv955  Running  gpu: 4  runai-cluster-worker-0-5
      └─ Pod/demo-worker-1-0-5smfn  Running  gpu: 4  runai-cluster-worker-0-2

$ karta workload list
NAMESPACE   NAME  KIND    PHASE    COMPONENTS           GPU  AGE
karta-demo  demo  JobSet  Running  leader(1), worker(2)  12   3m
```

The definition supplies the JobSet-specific structure, so the CLI can inspect the workload without a dedicated parser.

### **Enabling gang scheduling with KAI Scheduler**

For consumers that schedule workloads, a definition can also include optional gang-scheduling instructions.

```
  optimizationInstructions:
    gangScheduling:
      podGroup:
        name: job
        subGroups:
        - componentName: replicatedjob
```

The definition supplies grouping information; KAI Scheduler enforces gang admission and makes placement decisions. KAI Scheduler uses Workload Map as a fallback in its pod grouper for workload types without a native plugin. A matching definition provides the structure and grouping information without requiring a new framework-specific plugin, while native plugins retain precedence.

### **Managing the same workload in NVIDIA Run:ai**

In [NVIDIA Run:ai](https://www.nvidia.com/en-us/software/run-ai/), a single API call registers the workload type using the same catalog definition with no additional code. The platform then uses that description to manage the JobSet as one workload.

The CLI, KAI Scheduler, and NVIDIA Run:ai use the same definition for different purposes: inspection, scheduling, and platform visibility. For another supported workload type, the corresponding catalog definition supplies its structure through the same interface.

## **Workload Map adoption across schedulers and platforms**

NVIDIA Workload Map is available under the [Apache 2.0 license](https://github.com/dsx-ai-factory/workload-map/blob/main/LICENSE) and is used in production within NVIDIA Run:ai. Its declarative definitions support workload visibility, status interpretation, submission, and mutation across supported Kubernetes workload types.

Adoption also extends to multi-cluster scheduling. [Elotl’s Nova](https://www.elotl.co/blog/nova-multi-cluster-scheduling-of-k8s-workload-frameworks-facilitated-by-runai-karta) uses Workload Map to interpret workload structure and resource requirements when selecting a cluster for distributed workloads. By using prebuilt definitions, Nova reduces the need to maintain framework-specific parsing logic, demonstrating how the same workload-description model can support different scheduling and platform consumers.

## **Getting started**

[NVIDIA Workload Map](https://github.com/dsx-ai-factory/workload-map) is an open source component available through the [NVIDIA DSX AI Factory GitHub organization](https://github.com/dsx-ai-factory). If you are running AI workloads on Kubernetes and need a consistent way to interpret their structure across frameworks, Workload Map helps close the gap.

Start with the [workload catalog](https://github.com/dsx-ai-factory/workload-map/tree/main/docs/catalog) to find a definition for a framework you already use, or adapt one to support a custom workload type. Join the conversation on the NVIDIA DSX AI Factory Slack workspace using [the Slack invitation link](https://inviter.co/dsx-ai-factory). We can’t wait to see what you build.
