Skip to content

fix: don't copy the driver environment into the caller's env_vars dict - #4274

Open
David-Wu1119 wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
David-Wu1119:fix/worker-group-env-vars-not-mutated
Open

David-Wu1119 wants to merge 1 commit into
NVIDIA-NeMo:mainfrom
David-Wu1119:fix/worker-group-env-vars-not-mutated

Conversation

@David-Wu1119

Copy link
Copy Markdown

What does this PR do ?

Stops RayWorkerGroup from writing the driver's environment into the env_vars dict it is given, which put every environment variable (tokens included) into each checkpoint's config.yaml.

_create_workers_from_bundle_indices merged os.environ into env_vars in place. That dict often belongs to the run config:

  • lm_policy.py passes config["dtensor_cfg"].get("env_vars", {}) unchanged (the Megatron path already copies it with dict(...)); lm_value.py and teacher_worker_group.py do the same.
  • PolicyConfig / DTensorConfig are TypedDicts stored as-is inside the pydantic MasterConfig, so master_config.policy[...]["env_vars"] is that same dict object (checked with pydantic 2.13.5).
  • GRPO saves master_config with each checkpoint (checkpointer.init_tmp_checkpoint(..., master_config) → yaml.safe_dump(run_config.model_dump(mode="json")) in utils/checkpoint.py).

So a run that sets, for example, policy.dtensor_cfg.env_vars: {NCCL_DEBUG: WARN} ends up with the whole driver environment (HF_TOKEN, WANDB_API_KEY, cloud credentials, ...) under that key in every checkpoint's config.yaml.

The change builds a new dict instead, env_vars = {**os.environ, **env_vars}, so caller values still take precedence and workers see exactly what they did before.

Issues

None filed.

Usage

No API change.

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

  • New test test_env_vars_argument_is_not_modified in tests/unit/distributed/test_worker_groups.py (CPU Ray cluster, like its neighbours). On main it fails with the dict holding the full environment; with this change it passes.
  • tests/unit/distributed/test_worker_groups.py on this branch: 29 passed, 1 skipped (local CPU Ray, Python 3.13, torch 2.11), including test_environment_variable_precedence_full.
  • ruff / ruff-format pass. pyrefly check nemo_rl/distributed/worker_groups.py reports the same 5 findings on main and on this branch. I couldn't run the uv-based hooks as configured, because Python 3.13.14 isn't available for macOS arm64 yet.

🤖 Generated with Claude Code

RayWorkerGroup._create_workers_from_bundle_indices merged os.environ into
the env_vars dict it was given. Policy and value workers pass the dict from
the run config (e.g. policy.dtensor_cfg.env_vars), and PolicyConfig is a
TypedDict stored as-is inside the pydantic MasterConfig, so after worker
creation the config held every driver environment variable. GRPO then
writes master_config.model_dump() to each checkpoint's config.yaml, which
put the whole environment, including tokens, into every checkpoint.

Build a new dict instead ({**os.environ, **env_vars}, caller values still
win) and add a test that the argument is left unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: David-Wu1119 <133224895+David-Wu1119@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 25, 2026 23:38
@copy-pr-bot

copy-pr-bot Bot commented Sep 25, 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@svcnvidia-nemo-ci svcnvidia-nemo-ci added the waiting-on-maintainers Waiting on maintainers to respond label Sep 28, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-request waiting-on-maintainers Waiting on maintainers to respond

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants