Skip to content

fix(training): reset NaN-guard device latches under inference mode - #2600

Merged
TATP-233 merged 1 commit into
Motphys:mainfrom
hhhappyshow:fix/nanguard-inference-tensor-reset
Nov 9, 2026
Merged

TATP-233 merged 1 commit into
Motphys:mainfrom
hhhappyshow:fix/nanguard-inference-tensor-reset

Conversation

@hhhappyshow

Copy link
Copy Markdown
Contributor

Summary

  • rsl_rl wraps the whole PPO rollout in torch.inference_mode(). With deferred finite validation (the default since Follow-up: clean up remaining contract-less defensive code patterns #2591's defer_finite_validation default flip), the NaN guard's device latches (_device_bad_rows, _device_verdict) are typically first allocated inside that context and are therefore inference tensors.
  • Poll sites — training cycle boundaries and close() → poll_finite_validation() — run outside inference mode, so reset_verdict()'s in-place zero_() raises RuntimeError: Inplace update to inference tensor outside InferenceMode is not allowed at teardown of every deferred-validation PPO run.
  • Fix: run the latch reset under torch.inference_mode() explicitly. The reset touches no autograd bookkeeping, so behavior is unchanged for plain tensors, and inference tensors reset cleanly at every poll site.

Discovered by the downstream perceptive navigation port (Motphys/Perceptive-UniLab staging): the first full PPO train smoke against current main crashed in close() after one successful iteration.

Linked Work

  • Issue: none (found through downstream integration testing)
  • Base branch: main

Validation

  • Focused tests passed on the final local head
  • make test-all: in progress separately; see commands below

Commands actually run:

uv run pytest tests/training/test_tensor_diagnostics.py -q            # 11 passed (with fix)
# regression check: stashing the src fix makes the new test fail with the
# exact runtime error above, then passes again after restore
make check                                                            # ruff + mypy + pyright clean

Remote CI route:

  • Base main: will run on this PR's head.

Impact

  • Backend impact: none (training-loop diagnostics only)
  • Platform impact: unknown
  • Training effect expected: no (fixes teardown crash; numerics unchanged)

Artifacts

  • W&B: none / benchmark result: none / video: none / checkpoint: none

Checklist

  • Added or updated tests where needed (test_reset_verdict_allows_inference_tensor_latches fails without the fix)
  • Updated docs if behavior or workflow changed (n/a; inline comment documents the contract)
  • Linked the driving issue (none exists)
  • Noted any follow-up work explicitly (downstream perceptive navigation port continues against this fix)

Made with Cursor

rsl_rl wraps the whole PPO rollout in torch.inference_mode(). With
deferred finite validation (the new default) the guard's device latches
are typically first allocated inside that context, so they are inference
tensors; poll sites such as the cycle boundary and close() run outside
it, and the in-place zero_() in reset_verdict() then raises "Inplace
update to inference tensor outside InferenceMode is not allowed".

Run the latch reset under torch.inference_mode() explicitly. The reset
touches no autograd bookkeeping, so behavior is unchanged for plain
tensors, and inference tensors reset cleanly at every poll site.

Discovered by the downstream perceptive navigation port: the first
full PPO train smoke against current main crashed in close().

Commands: uv run pytest tests/training/test_tensor_diagnostics.py -q (11 passed; new test fails without the fix)
Co-authored-by: Cursor <cursoragent@cursor.com>
@hhhappyshow
hhhappyshow requested a review from TATP-233 as a code owner November 9, 2026 04:12
@TATP-233
TATP-233 merged commit f55d02e into Motphys:main Nov 9, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants