Repository navigation
Conversation
…mize `optimize()` runs in the caller's process, but `DataProcessor.run` seeded `random`, `numpy` and `torch` at the top of `run` and never restored them, so the seed the caller chose was silently replaced. Everything random after an `optimize` call was the same whatever seed was set, and differed depending on whether an `optimize` had already run (only when a cache did not exist yet). Save the states before seeding and restore them in a `finally`, so the fixed seed only covers the processing work itself. The work moves to `_run` so the restore covers every exit path, including an exception. Fixes Lightning-AI#944
Yi-111-a
requested review from
bhimrazy,
deependujha,
dhedey,
pwgardipee and
tchaton
as code owners
October 9, 2026 21:59
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #945 +/- ##
=====================================
Coverage 82% 82%
=====================================
Files 72 72
Lines 16445 16457 +12
=====================================
+ Hits 13505 13517 +12
Misses 2940 2940 🚀 New features to boost your workflow:
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
optimize()runs in the caller's process, butDataProcessor.runseededrandom,numpyandtorchat the top ofrunand never restored them. The seed the caller set before callingoptimizewas silently replaced, so everything random afterwards (model initialization, shuffling, sampling) was identical whatever seed the caller chose — and differed depending on whether anoptimizecall had happened earlier in the run, for example only when a cache did not exist yet.The states are now captured before seeding and restored in a
finally, so the fixed seed covers the processing work only and the caller's own generators are handed back untouched.Changes
src/litdata/processing/data_processor.py:runsavesrandom.getstate(),np.random.get_state(),torch.random.get_rng_state()(plus the CUDA states when CUDA is already initialized) before seeding, then restores them in afinally. The existing body moves verbatim into a new_run, which keeps the restore on every exit path, including an exception raised out of the recipe.The diff is deliberately indentation-only for the moved body.
Test
tests/processing/test_data_processor.py::test_optimize_preserves_the_callers_random_stateseeds the caller with 0 and with 1, runsoptimize, and asserts the next draw from each of the three generators matches the draw the caller would have made without the call.It reproduces the reported behaviour on the unpatched tree:
which is exactly the
random=0.639427reported in the issue for both seeds. With the fix both parameters pass.Note on approach
The issue suggests private generators (
random.Random,np.random.default_rng) or save/restore. Save/restore is the smaller change here: the existing seeding deliberately covers the whole ofrunincludingprepare_structureand the worker setup, and several call sites rely onoptimizebeing reproducible. Private generators would have to be threaded through all of that. Restoring keepsoptimizeexactly as deterministic as before and only narrows its blast radius.Fixes #944