Skip to content

Save and resume

Capture loader.state_dict() after processing a batch, alongside your model, optimizer, and training RNG state. It records the global sample position delivered to the consumer, so prefetched batches do not advance the saved position.

Save and restore the state

This complete example saves the loader state as JSON, resumes in a fresh loader, and compares the remaining batches. In a training job, put this state in the same checkpoint as your model and optimizer after the training step completes.

Workers and prefetching are enabled to show that prepared batches do not move the saved position ahead of the consumer.

from pathlib import Path
from tempfile import TemporaryDirectory
import json

import torch

from guideloom import DocumentPickleFormat, DocumentStorage, StatefulDataLoader


def collate(samples):
    return list(samples)


with TemporaryDirectory() as directory:
    storage = DocumentStorage(Path(directory), DocumentPickleFormat())
    with storage.sync_writer() as writer:
        for value in range(12):
            writer.append(0, value)
    settings = dict(
        collate_fn=collate,
        device=torch.device("cpu"),
        local_batch_size=2,
        shuffle=True,
        shuffle_seed=42,
        num_workers=2,
        prefetch=2,
    )
    with StatefulDataLoader.from_storage(storage, **settings) as loader:
        iterator = iter(loader)
        first_batch = next(iterator)
        checkpoint = loader.state_dict()
        assert checkpoint["observation_offset"] == 2
        checkpoint_path = Path(directory) / "loader-state.json"
        checkpoint_path.write_text(json.dumps(checkpoint))
        expected_remaining = list(iterator)

    with StatefulDataLoader.from_storage(storage, **settings) as resumed:
        resumed.load_state_dict(json.loads(checkpoint_path.read_text()))
        assert list(resumed) == expected_remaining

Use a fresh loader for resumption. Closing an iterator resets that loader's sample position, so capture the state before closing it. load_state_dict also rejects restoration while the target loader has an active iterator.

What the checkpoint contains

A loader checkpoint contains epoch, observation_offset, shuffle, shuffle_seed, and drop_last. The offset advances by global_batch_size for each delivered batch, including padding in an incomplete final batch. The epoch and offset identify the position already delivered to the consumer across all ranks. It does not store prefetched samples, dataset files, model state, optimizer state, or random state used by transformations.

The loader warns when the saved shuffle/drop settings differ from its configuration. It does not record or validate a package version, dataset identity, dataset size, sequence length, batch size, or world size. Save these settings in your training application when you need to verify them on resumption.

Preserve sample order

The loader reconstructs its position from the epoch, global observation offset, shuffle seed, and dataset size. You can change the local batch size or world size when resuming: the remaining global sample order is preserved, with samples repartitioned across the new ranks and batches. Load the same checkpoint on every rank after all original ranks have completed the same number of steps. Individual ranks can receive different samples than they would have before the change.

For the same remaining sample order, preserve the dataset contents and ordering, storage format, dataset view and sequence length, shuffle, shuffle_seed, and drop_last. Use an explicit shuffle seed; None does not provide reproducible shuffled resumption. With drop_last=True, the new global batch size determines how many samples at the end of the remaining sequence are dropped. With drop_last=False, all remaining samples are delivered, and some ranks can receive an empty final batch.

Changes to worker count, prefetching, or device placement should not change sample ordering. Identical tensor values still depend on your transforms, RNG state, hardware, and dependency behavior. A loader checkpoint is not a snapshot of user code or dataset contents.

See compatibility for guarantees across package releases.