You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: add KubeflowExecutor for Kubernetes Training Operator (TrainJob CRD) (#462)
* feat: add KubeflowExecutor for Kubeflow Training Operator on Kubernetes
Introduces KubeflowExecutor and a matching TorchX scheduler to deploy
distributed TrainJobs (Kubeflow Training Operator v2) on any Kubernetes
cluster via run.run() / run.Experiment.
- KubeflowExecutor builds and submits TrainJob CRDs via the K8s API
(local kubeconfig with in-cluster fallback)
- macro_values() maps to PET_* env vars injected by Training Operator
- Inline scripts are chmod'd 755 and served via a data-mover pod syncing
into <workdir_pvc_path>/<username>/code; a /nemo_run symlink is created
for compatibility with hardcoded script paths
- fetch_logs streams kubectl logs per-replica and retries until the job
reaches a terminal state; --max-log-requests=num_nodes handles large jobs
- describe() exposes all replicas so log threads cover every rank
- Documentation added to docs/guides/execution.md
---------
Signed-off-by: oliver könig <okoenig@nvidia.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
For a complete end-to-end example using DGX Cloud with NeMo, refer to the [NVIDIA DGX Cloud NeMo End-to-End Workflow Example](https://docs.nvidia.com/dgx-cloud/run-ai/latest/nemo-e2e-example.html).
295
296
297
+
#### KubeflowExecutor
298
+
299
+
The `KubeflowExecutor` integrates with the [Kubeflow Training Operator](https://github.com/kubeflow/training-operator) to run distributed training jobs on any Kubernetes cluster. It submits CRDs directly via the Kubernetes API — no `kubectl` required.
300
+
301
+
Two job kinds are supported via the `job_kind` parameter:
302
+
303
+
-**`"PyTorchJob"`** (default) — Training Operator v1 (`kubeflow.org/v1`)
304
+
-**`"TrainJob"`** — Training Operator v2 (`trainer.kubeflow.org/v1alpha1`)
305
+
306
+
Kubernetes configuration is loaded automatically: local kubeconfig is tried first, falling back to in-cluster config when running inside a pod.
307
+
308
+
Here's an example configuration:
309
+
310
+
```python
311
+
# PyTorchJob (default)
312
+
executor = run.KubeflowExecutor(
313
+
namespace="runai-nemo-ci",
314
+
image="nvcr.io/nvidia/nemo:26.02",
315
+
num_nodes=3, # total pods: 1 Master + (num_nodes-1) Workers
316
+
gpus_per_node=8, # also sets nproc_per_node unless overridden explicitly
runtime_ref="torch-distributed", # name of the ClusterTrainingRuntime
331
+
namespace="runai-nemo-ci",
332
+
image="nvcr.io/nvidia/nemo:26.02",
333
+
num_nodes=3,
334
+
gpus_per_node=8,
335
+
)
336
+
```
337
+
338
+
`cancel(wait=True)` polls until both the CR and all associated pods are fully terminated before returning.
339
+
340
+
##### Limitations
341
+
342
+
Attributes like `resourceClaims` are not [supported](https://github.com/kubeflow/trainer/issues/3264) and must be injected in different ways, like by Mutating Webhooks.
343
+
296
344
#### LeptonExecutor
297
345
298
346
The `LeptonExecutor` integrates with an NVIDIA DGX Cloud Lepton cluster's Python SDK to launch distributed jobs. It uses API calls behind the Lepton SDK to authenticate, identify the target node group and resource shapes, and submit the job specification which will be launched as a batch job on the cluster.
0 commit comments