Skip to content

← Batching and the Data Path step 5 of 5

Medium Primitives

Shuffle the same way twice

Two ways to make a shuffle reproducible.

torch.manual_seed(0)
order = torch.randperm(n)                       # global state

g = torch.Generator().manual_seed(0)
order = torch.randperm(n, generator=g)          # explicit state

Both give the same permutation from a clean start. Only the second still does after somebody else draws a random number.

Why the global one breaks

manual_seed sets one process-wide stream, and everything draws from it: dropout, weight initialisation, augmentation, a library you imported. Insert one extra torch.rand anywhere earlier and every later draw shifts.

So a run is reproducible until you add a layer with dropout, and then it is not, and nothing about the change looks related. This is the single most common reason a “seeded” experiment does not reproduce.

An explicit Generator is a private stream. Nothing else touches it, so the shuffle is a function of its seed and nothing more.

In a DataLoader

DataLoader(ds, shuffle=True, generator=g, worker_init_fn=seed_worker)

Two separate problems: generator fixes the shuffle order, and worker_init_fn fixes each worker’s own stream, because workers are separate processes that inherit and then diverge. Setting only the first gives you a reproducible order over non-reproducible augmentation.

Reproducible is not the same as deterministic

Seeding fixes the random draws. It does not fix nondeterministic kernels: some backward passes use atomic adds whose order varies run to run, so results differ in the last bits regardless of seeding. torch.use_deterministic_algorithms(True) forces the deterministic variants where they exist and raises where they do not, which is the honest way to find out.

Your task

def shuffles(n: int, seed: int) -> dict

Produce a permutation of n items twice from the same seed, drawing an unrelated random number in between, and return both permutations plus whether they agree.

The interruption is the point: the starter’s two shuffles differ because of it.