Skip to content

fix: honor NEMO_RL_PY_EXECUTABLES_SYSTEM for all actor environments - #4020

Merged
terrykong merged 3 commits into
mainfrom
yukih/honor-system-python
Sep 8, 2026
Merged

fix: honor NEMO_RL_PY_EXECUTABLES_SYSTEM for all actor environments#4020
terrykong merged 3 commits into
mainfrom
yukih/honor-system-python

Conversation

@yuki-97

@yuki-97 yuki-97 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

What does this PR do ?

Resolves NEMO_RL_PY_EXECUTABLES_SYSTEM inside PY_EXECUTABLES itself, so every consumer of a PY_EXECUTABLES.* constant honors the flag instead of each call site re-deriving it.

Before, the check was duplicated as seven ternaries in ray_actor_environment_registry.py and three more in nemo_rl/modelopt/registry.py, and any entry written as a plain PY_EXECUTABLES.X silently opted out. Seven actors were in that state: DTensorPolicyWorker, DTensorPolicyWorkerV2, DTensorValueWorkerV2, AsyncTrajectoryCollector, ReplayBuffer, SyncRolloutActor and NemoGym.

Changes:

  • PY_EXECUTABLES._resolve_system_overrides() rewrites every uv command constant to SYSTEM when the flag is set, and runs once at import.
  • The *_EXECUTABLE aliases in ray_actor_environment_registry.py are gone; every entry is now a PY_EXECUTABLES.* constant.
  • nemo_rl/modelopt/registry.py is deleted. Its three executables become PY_EXECUTABLES.MODELOPT_VLLM / MODELOPT_AUTOMODEL / MODELOPT_MCORE and its five actors move into ACTOR_ENVIRONMENT_REGISTRY.
  • docs/design-docs/uv.md documents the flag; dependency-management.md drops a snippet referencing the removed aliases.

Resolving at the PY_EXECUTABLES layer rather than at the registry also covers the runtime overrides that write into the registry after it is built, which a registry-level check cannot reach — single_controller_utils/setup.py:1030 (PY_EXECUTABLES.VLLM_GYM under token_capture.enabled) and research/template_project/single_update.py:60.

Issues

N/A

Usage

Set NEMO_RL_PY_EXECUTABLES_SYSTEM=1 when every actor's dependencies are already installed in the driver's interpreter, such as in a single-environment container image.

Before your PR is "Ready for review"

Pre checks:

  • Make sure you read and followed Contributor guidelines
  • Did you write any new necessary tests?
  • Did you run the unit tests and functional tests locally? Visit our Testing Guide for how to run tests
  • Did you add or update any necessary documentation? Visit our Document Development Guide for how to write, build and test the docs.

Additional Information

Overlaps with three open PRs that carry the same seven-actor behavior change: #3982 (alias-based), and #3947 / #4002 (which move the mapping into a separate actor-environments module). Worth deciding which lands first.

test_actor_registry_honors_system_flag in tests/unit/distributed/test_virtual_cluster.py covers both flag states through ACTOR_ENVIRONMENT_REGISTRY, in a subprocess so the flag is resolved at import time like it is in production.

@copy-pr-bot

copy-pr-bot Bot commented Sep 5, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the Documentation Improvements or additions to documentation label Sep 5, 2026
@yuki-97
yuki-97 force-pushed the yukih/honor-system-python branch 2 times, most recently from e5db960 to 46e5cdb Compare September 7, 2026 19:15

@yuki-97 yuki-97 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed by a team of specialized agents (RL/codebase, bug-finder, design, tests, devil's advocate). 3 inline comments below — one test gap worth acting on, plus two docs nits. No blockers.

The design call here is right. Resolving the flag at the PY_EXECUTABLES layer rather than in the registry is what makes "a plain PY_EXECUTABLES.X silently opts out" structurally impossible. Concretely, single_controller_utils/setup.py:1028 and research/template_project/single_update.py:60 write named constants into ACTOR_ENVIRONMENT_REGISTRY after it is built — no registry-layer check can reach those, which is why this isn't redundant with an alias-based approach. It also incidentally fixes trtllm_worker_async.py:68, where os.path.dirname(PY_EXECUTABLES.TRTLLM) was prepending the literal string uv run --locked --extra trtllm --directory /opt to PATH under the flag.

Verified clean: no remaining reference to the deleted nemo_rl/modelopt/registry.py or the *_EXECUTABLE aliases; all five ModelOpt FQNs byte-identical to the deleted file and resolving to real classes; 27 registry keys with no duplicates; the --extra modelopt --extra vllm|automodel|mcore combinations absent from the [tool.uv] conflicts table; pyrefly.toml removal correct; the new test's finally restore complete across both parametrizations.

Scope caveat: no tests were executed for this review (no uv/GPU available), and CI has not run on this PR yet — copy-pr-bot is still gating it. Conclusions come from reading the code plus standalone semantic models.

Generated by Claude Code

Comment thread tests/unit/distributed/test_virtual_cluster.py Outdated
Comment thread docs/design-docs/dependency-management.md Outdated
Comment thread nemo_rl/distributed/ray_actor_environment_registry.py
@yuki-97 yuki-97 added the CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version) label Sep 7, 2026
@yuki-97

yuki-97 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 6e1e16d

@yuki-97
yuki-97 marked this pull request as ready for review September 7, 2026 19:41
@yuki-97
yuki-97 requested review from a team as code owners September 7, 2026 19:41

@terrykong terrykong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice change — two things I liked, one thing to watch on the rebase, and a scheduling question for whoever merges these.

This needs a rebase, and the rebase is the risky part. Main has rewritten the same block since you branched. Git will show you a conflict only in the alias block you delete, and will quietly auto-merge the dict body to your version — which drops the nemo_gym extra from the two vLLM workers. The comment on ray_actor_environment_registry.py has the details and a one-command check to run after rebasing.

Resolving the flag inside PY_EXECUTABLES is the right place for it, not just the shorter one. Some code reads PY_EXECUTABLES.X without going through the registry at all — trtllm_worker_async.py reads PY_EXECUTABLES.TRTLLM directly — so a fix inside get_actor_python_env() would have missed those.

Folding nemo_rl/modelopt/registry.py into the one registry also removes a backwards import. The deleted file had to import git_root back out of virtual_cluster, and the registry imported the modelopt module at the bottom of the file. After this PR nemo_rl/distributed/ has no import edge into nemo_rl.modelopt, because the entries are plain strings. Central registration is what dynamo, nemo_gym, trtllm and sglang already do; modelopt was the only one off on its own.

Overlapping PRs — a scheduling question, not a complaint. What this PR does that the others do not is cover every actor environment in one place: jepio's PR (#3982) is the same fix by a different author, but its own description says ModelOpt keeps its separate handling of the flag, so #4020 is a superset. tdene's PR (#3947) and #4002 (mine) touch the same mapping from the dependency side. Two open PRs rewriting the same block will conflict, so someone has to pick which lands first.

Lint note: the pinned ruff 0.9.9 reports the four changed Python files clean, formatting included. That is a single-machine result rather than a CI claim — pre-commit needs the Automodel submodule, which was not checked out here.

Generated by Claude Code

Comment thread nemo_rl/distributed/ray_actor_environment_registry.py Outdated
Comment thread nemo_rl/distributed/virtual_cluster.py
Comment thread tests/unit/distributed/test_virtual_cluster.py
Comment thread docs/design-docs/uv.md Outdated
yuki-97 and others added 3 commits September 7, 2026 19:42
Signed-off-by: Yuki Huang <yukih@nvidia.com>
Co-authored-by: Jeremi Piotrowski <jpiotrowski@nvidia.com>
…T_REGISTRY, fix stale SGLANG_EXECUTABLE and registry line references

Signed-off-by: Yuki Huang <yukih@nvidia.com>
…ert PY_EXECUTABLES directly in the system-flag probe, clarify NEMO_RL_PY_EXECUTABLES_SYSTEM scope in uv.md

Signed-off-by: Yuki Huang <yukih@nvidia.com>
@yuki-97
yuki-97 force-pushed the yukih/honor-system-python branch from 6e1e16d to 4926437 Compare September 8, 2026 02:50
@yuki-97

yuki-97 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

/ok to test 4926437

@terrykong
terrykong merged commit 85ec451 into main Sep 8, 2026
85 of 86 checks passed
@terrykong
terrykong deleted the yukih/honor-system-python branch September 8, 2026 04:46
terrykong added a commit that referenced this pull request Sep 8, 2026
#4020 moved the flag into PY_EXECUTABLES._resolve_system_overrides and says
callers should not check it themselves. That rewrite only touches the class
attributes, so uv_py_executable -- which builds a fresh string -- was not
covered, and this branch had to keep its own USE_SYSTEM_EXECUTABLE check.

Put the check in uv_py_executable instead and drop the one in the registry, so
the flag is handled in one place. Verified: with the flag set, all 28 actors
resolve to the driver interpreter.

Signed-off-by: Terry Kong <terryk@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI:Lfast Runs a fast test suite and re-use nightly `main` container (but sync dependencies to PRs version) Documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants