From 45c8463077838fc894f753ba5972e1a1105eb58f Mon Sep 17 00:00:00 2001 From: Nicki Skafte Date: Mon, 1 Dec 2025 14:36:50 +0100 Subject: [PATCH 1/3] add hash based mixing --- src/lightning/fabric/utilities/seed.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/lightning/fabric/utilities/seed.py b/src/lightning/fabric/utilities/seed.py index 841fa195696a2..21cb198b031dd 100644 --- a/src/lightning/fabric/utilities/seed.py +++ b/src/lightning/fabric/utilities/seed.py @@ -111,10 +111,19 @@ def pl_worker_init_function(worker_id: int, rank: Optional[int] = None) -> None: def _generate_seed_sequence(base_seed: int, worker_id: int, global_rank: int, count: int) -> list[int]: - """Generates a sequence of seeds from a base seed, worker id and rank using the linear congruential generator (LCG) - algorithm.""" + """Generates a sequence of seeds from a base seed, worker id and rank using hash-based mixing followed by the + linear congruential generator (LCG) algorithm.""" # Combine base seed, worker id and rank into a unique 64-bit number combined_seed = (base_seed << 32) | (worker_id << 16) | global_rank + + # Apply hash-based mixing (MurmurHash3 finalizer) to distribute bits uniformly + # This ensures that small base seeds don't result in zeros in lower bits + combined_seed ^= combined_seed >> 33 + combined_seed = (combined_seed * 0xFF51AFD7ED558CCD) & ((1 << 64) - 1) + combined_seed ^= combined_seed >> 33 + combined_seed = (combined_seed * 0xC4CEB9FE1A85EC53) & ((1 << 64) - 1) + combined_seed ^= combined_seed >> 33 + seeds = [] for _ in range(count): # x_(n+1) = (a * x_n + c) mod m. With c=1, m=2^64 and a is D. Knuth's constant From e31fbe9e1138c03e73542b2716713581f3937cdc Mon Sep 17 00:00:00 2001 From: Nicki Skafte Date: Mon, 1 Dec 2025 14:39:50 +0100 Subject: [PATCH 2/3] add testing --- tests/tests_fabric/utilities/test_seed.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/tests_fabric/utilities/test_seed.py b/tests/tests_fabric/utilities/test_seed.py index 81fde5aae3ef5..0cc56b59bae19 100644 --- a/tests/tests_fabric/utilities/test_seed.py +++ b/tests/tests_fabric/utilities/test_seed.py @@ -10,6 +10,7 @@ from lightning.fabric.utilities.seed import ( _collect_rng_states, + _generate_seed_sequence, _set_rng_states, pl_worker_init_function, reset_seed, @@ -153,3 +154,23 @@ def test_pl_worker_init_function(base_seed, num_workers, num_ranks): assert len(stdlib_rands) == num_ranks * num_workers assert len(numpy_rands) == num_ranks * num_workers assert len(torch_rands | stdlib_rands | numpy_rands) == 3 * num_workers * num_ranks + + +def test_generate_seed_sequence_no_collision(): + """Test that _generate_seed_sequence produces unique seeds for different base seeds.""" + base_seeds = [0, 1, 42, 123, 999, 12345] + generated_seeds = [] + random_outputs = [] + + for base_seed in base_seeds: + seed_everything(base_seed) + process_seed = torch.initial_seed() + generated_seed = _generate_seed_sequence(process_seed, worker_id=0, global_rank=0, count=1)[0] + generated_seeds.append(generated_seed) + torch.manual_seed(generated_seed) + random_outputs.append(tuple(torch.randn(10).tolist())) + + assert len(set(generated_seeds)) == len(generated_seeds), ( + "Generated seeds should be unique for different base seeds" + ) + assert len(set(random_outputs)) == len(random_outputs), "Random outputs should be unique for different base seeds" From d451ecaddad0da085ccb4232f3bdcc6f9c62f0e8 Mon Sep 17 00:00:00 2001 From: Nicki Skafte Date: Tue, 2 Dec 2025 09:15:38 +0100 Subject: [PATCH 3/3] changelog --- src/lightning/pytorch/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lightning/pytorch/CHANGELOG.md b/src/lightning/pytorch/CHANGELOG.md index 3558fe3cadc66..e5b61b4416627 100644 --- a/src/lightning/pytorch/CHANGELOG.md +++ b/src/lightning/pytorch/CHANGELOG.md @@ -20,6 +20,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). - +### Fixed + +- Fix `_generate_seed_sequence_sampling` function not producing unique seeds ([#21399](https://github.com/Lightning-AI/pytorch-lightning/pull/21399)) + ## [2.6.0] - 2025-11-28