NVIDIA-NeMo / NVIDIA-NeMo/Run

JobGroup.SUPPORTED_EXECUTORS is closed to downstream Executor subclasses

Open
#537 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
258
Forks
113
Avg merge
1d 3h
Merged PRs (30d)
5

Description

Use case

nemo-skills' RayExecutor is a downstream Executor subclass that needs to be passable to JobGroup. Today JobGroup.__post_init__ (around nemo_run/run/job.py:265) asserts isinstance(self.executor, JobGroup.SUPPORTED_EXECUTORS) where SUPPORTED_EXECUTORS = [SlurmExecutor, DockerExecutor, LocalExecutor]. Any downstream package adding a new Executor type — Ray, Kubernetes, etc. — hits this assertion and cannot construct a JobGroup.

Why this matters now

nemo-skills now ships RayExecutor and uses JobGroup for multi-script eval-generation flows (vLLM + sandbox + client co-located). The Ray multi-script path is a separate architectural concern (single Ray submission = single container, vs. the heterogeneous group semantics JobGroup was designed for on Slurm) — but the immediate question is whether downstream Executor subclasses are even a supported extension point.

Current workaround

(Marking this clearly as workaround, not a proposed PR.) A downstream project patches the assertion at runtime via a class-name string sniff (`type(self.executor).name == "RayExecutor"`) to avoid a circular import. This sniff is intentionally narrow but a class-name string match is not idiomatic for upstream.

Proposed designs

Please indicate preference before we send a PR.

1. `SUPPORTED_EXECUTORS` extension hook

Downstream packages register their Executor subclass at import time:

```python
from nemo_run.run.job import JobGroup
JobGroup.SUPPORTED_EXECUTORS = (*JobGroup.SUPPORTED_EXECUTORS, RayExecutor)
```

  • Pro: explicit, discoverable.
  • Con: requires downstream packages to mutate a class attribute, which feels brittle.
2. Sentinel attribute on the Executor subclass

Downstream marks compatibility:

```python
class RayExecutor(Executor):
_jobgroup_compatible = True
```

…and `post_init` checks `getattr(executor, "_jobgroup_compatible", False)` in addition to `isinstance(SUPPORTED_EXECUTORS)`.

  • Pro: no mutation of upstream state.
  • Con: requires JobGroup to know about the sentinel.
3. `Executor.supports_job_group()` classmethod on the base

Defaults to `False`, overridable downstream. Same shape as option 2 but more discoverable in IDEs.

Note on JobGroup.launch path

Even with the assertion relaxed, `JobGroup.launch` calls `nemo_run.run.torchx_backend.launcher.launch(executor=...)` which routes through `EXECUTOR_MAPPING` in `torchx_backend/schedulers/api.py:30`. That mapping has no Ray entry, so `get_executor_str(RayExecutor)` raises `KeyError`. This means the assertion relax is necessary but not sufficient for Ray multi-script JobGroup to actually launch end-to-end. The pragmatic answer for the multi-script case is multi-pool architecture (pre-host components in separate Ray submissions; collapse multi-script to single-script), but the assertion remains too strict in principle for any downstream Executor subclass.

Reference

Prior PR #410 was the last touch on `nemo_run/run/job.py`. Searching closed issues for "Unsupported executor type" returned 0 hits, so this is a fresh report.

Ask

Which of the three designs (or a fourth) would you accept as a PR? Happy to send code once direction is confirmed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in nemo_run/run/job.py around JobGroup.post_init and trace the executor validation. Then inspect torchx_backend/schedulers/api.py and EXECUTOR_MAPPING to separate extension-point validation from launch support. Done means a maintainer-approved design is identified for downstream Executor subclasses, with the Ray launch limitation explicitly kept in scope or excluded.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.