Make training shuffle a train-only option; migrate config and use samplers for ordering#923
Conversation
There was a problem hiding this comment.
Pull request overview
This PR moves dataloader sample-order control from the global data_loader.shuffle option to a train-only train.shuffle setting, keeping non-training verbs deterministic while preserving a migration path for older configs.
Changes:
- Adds
train.shuffleto the default config and migrates deprecateddata_loader.shuffleto it. - Updates
dist_data_loaderto use explicit subset samplers instead of forwardingshuffleto PyTorch. - Adjusts train/infer/test behavior and expands tests/documentation around shuffle semantics.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/hyrax/pytorch_ignite.py |
Adds shuffle-aware sampler selection and ignores legacy dataloader shuffle kwargs. |
src/hyrax/verbs/train.py |
Reads train.shuffle and applies it only to training dataloaders. |
src/hyrax/verbs/infer.py |
Removes mutation of legacy dataloader shuffle config for inference. |
src/hyrax/verbs/test.py |
Removes mutation of legacy dataloader shuffle config for testing. |
src/hyrax/hyrax_default_config.toml |
Moves the default shuffle option from [data_loader] to [train]. |
src/hyrax/config_migrations/migrations/002_move_data_loader_shuffle_to_train.py |
Adds config migration for data_loader.shuffle to train.shuffle. |
specs/train_shuffle_config.md |
Documents train-only shuffle behavior and migration guidance. |
tests/hyrax/test_config_migrations.py |
Adds migration and deprecated nested-key warning coverage. |
tests/hyrax/test_config_utils.py |
Verifies default shuffle config placement. |
tests/hyrax/test_infer.py |
Confirms inference ordering is unaffected by train.shuffle. |
tests/hyrax/test_split_fraction_integration.py |
Adds sampler-selection and legacy shuffle tests. |
tests/hyrax/test_train.py |
Updates training split-fraction test wording for sampler behavior. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #923 +/- ##
==========================================
+ Coverage 67.64% 67.72% +0.08%
==========================================
Files 69 70 +1
Lines 6802 6805 +3
==========================================
+ Hits 4601 4609 +8
+ Misses 2201 2196 -5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| # Note that when sampler=None, a default sampler is used. The default config | ||
| # defines shuffle=False, which should prevent any shuffling of of the data. | ||
| # We expect that this will be the primary use case when running inference. | ||
| return idist.auto_dataloader(dataset, sampler=sampler, **loader_kwargs), indexes |
There was a problem hiding this comment.
On second thought, removing this comment seems okay.
drewoldag
left a comment
There was a problem hiding this comment.
This looks good. A few comments, but nothing overly pressing. Remove the warning, move or maybe remove one of the tests.
Otherwise good to go.
|
|
||
| ```toml | ||
| [train] | ||
| shuffle = false |
There was a problem hiding this comment.
As discussed, the config migration will move the shuffle key and value, which will lead to correct reproducibility of previous runs, but the default value in hyrax_default_config.toml will become true.
| @@ -158,6 +158,7 @@ def dist_data_loader( | |||
| dataset: Dataset, | |||
| config: dict, | |||
| split: Union[str, list[str], bool] = False, | |||
There was a problem hiding this comment.
FWIW - I think we might be close to being able to remove this argument. It is only non-False in a couple of legacy call points in train.
| "Hyrax controls dataloader ordering with explicit samplers; use config['train']['shuffle'] " | ||
| "to control training sample shuffling." | ||
| ) | ||
| warnings.warn(msg, UserWarning, stacklevel=2) |
| logger.warning(msg) | ||
| data_loader_kwargs.pop("shuffle") | ||
|
|
||
| # TODO: Actually DataProvider.collate. Callsites and parameter signature above have not been updated. |
There was a problem hiding this comment.
Outside of the scope of this PR, but I think this comment can be removed.
| def test_default_shuffle_config_is_train_only(): | ||
| """Default shuffle config lives under train and is absent from data_loader.""" | ||
| import hyrax | ||
|
|
||
| config = hyrax.Hyrax().config | ||
|
|
||
| assert config["train"]["shuffle"] is True | ||
| assert "shuffle" not in config["data_loader"] |
There was a problem hiding this comment.
This test shouldn't be in here. Not sure that it's really necessary, but if we keep it, I think it should be in test_config_migrations.py.
This test suite is for the config_utils.py functionality, no for verifying the contents of the config dictionary.
There was a problem hiding this comment.
I'm going with removal.
| """ | ||
| h, dataset = loopback_hyrax | ||
| h.config["data_loader"]["shuffle"] = shuffle | ||
| h.config["train"]["shuffle"] = train_shuffle |
There was a problem hiding this comment.
Yes, I like this very much!
|
Agree with the overall design choice here. Deferring to drew for the actual review |
Co-authored-by: Drew Oldag <47493171+drewoldag@users.noreply.github.com> Co-authored-by: Michael Tauraso <mtauraso@users.noreply.github.com>
|
@copilot Can you change the failing tests so they don't look for the warning that I specifically removed. kthx |
Agent-Logs-Url: https://github.com/lincc-frameworks/hyrax/sessions/a471d1fb-1c54-43e9-9671-5f2df78b7c25 Co-authored-by: mtauraso <31012+mtauraso@users.noreply.github.com>
Updated in 4683548: I removed the two |
Motivation
shufflethrough PyTorchDataLoaderkwargs to avoid sampler vs shuffle conflicts and to support explicit subset samplers whensplit_indicesare used.data_loader.shuffleentries are preserved and emit deprecation warnings.Description
specs/train_shuffle_config.mddescribing thattrain.shuffleis train-only and how it differs fromsetup_dataset(..., shuffle=...).src/hyrax/config_migrations/migrations/002_move_data_loader_shuffle_to_train.pyto renamedata_loader.shuffle→train.shuffle.src/hyrax/hyrax_default_config.tomlto includetrain.shuffle = trueand removedata_loader.shuffle.dist_data_loaderinsrc/hyrax/pytorch_ignite.pyto accept ashuffleparameter, to warn and ignore legacydata_loader.shuffle, to build deterministictorch.Generatorseeding, and to create explicitSubsetRandomSamplerorSubsetSequentialSamplervia amake_samplerhelper instead of passingshuffleintoDataLoader.trainverb to readconfig['train']['shuffle']and only apply shuffling to thetrainsplit; keep validation and test splits deterministic.config['data_loader']['shuffle']forinferandtest.train,infer, and legacy multi-split paths (tests undertests/hyrax/*).Testing
pytestfocused on config migrations, dataloader split/sampler behavior, infer/train/test integration, and config utils; all modified and added tests passed.tests/hyrax/test_config_migrations.py,tests/hyrax/test_config_utils.py,tests/hyrax/test_infer.py,tests/hyrax/test_split_fraction_integration.py, andtests/hyrax/test_train.pyand they succeeded under the CI test run.data_loaderkeys (e.g.batch_size) while movingshuffletotrain.shuffleand that legacydata_loader.shuffleemits aUserWarning/DeprecationWarningas appropriate.Codex Task