Support New AI Frameworks Faster Using NVIDIA Workload Map NVIDIA released Workload Map, an open-source component of its DSX AI Factory Platform that provides a common description of Kubernetes workload structure so schedulers, controllers and platforms can interpret distributed workloads without per-framework adapter code. NVIDIA said the tool lets teams describe a distributed JobSet workload once and reuse that definition for workload inspection, gang scheduling and platform visibility, replacing the per-CRD adapters developers previously wrote for each new framework. The company cited a sample JobSet with one leader and two workers requesting four GPUs each, 12 GPUs total, as the kind of workload that otherwise requires JobSet-aware code because kubectl lists the resources separately. 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