Skip to content

feat(object-storage): auto-enable skip_listing for all storage types; adaptive validation interval#483

Merged
FileSystemGuy merged 1 commit into
mlcommons:mainfrom
russfellows:russfellows/skip-listing-object-storage
Jun 19, 2026
Merged

feat(object-storage): auto-enable skip_listing for all storage types; adaptive validation interval#483
FileSystemGuy merged 1 commit into
mlcommons:mainfrom
russfellows:russfellows/skip-listing-object-storage

Conversation

@russfellows

@russfellows russfellows commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

When running benchmarks with millions of files or objects, we can run out of memory due to listing and holding in memory the entire data set list. When number of files or objects exceeds 1M, this becomes especially problematic.

See issue #466

Addtionally, performing a "list" against S3-compatible object storage with large datasets (millions of files), DLIO must discover dataset files before training starts. The default mechanism — paginated list_objects_v2 — can take 12+ hours for a 50M-file dataset. The same problem exists for flat local-filesystem layouts where os.listdir() + sorted() materializes the entire file list on rank 0.

This PR makes mlp-storage automatically enable DLIO's skip_listing feature for all training benchmark runs (--file and --object), reducing cold-start time from hours to seconds and eliminating the per-rank OOM risk for large datasets.

Background: what is skip_listing?

skip_listing is implemented in mlcommons/DLIO_local_changes PR #27. When enabled, each MPI rank independently reconstructs its own file-URI shard from DLIO's standard naming convention — zero storage API calls, zero MPI communication, and no process ever holds the full file list in memory (each rank holds O(N/comm_size) entries only).

Does this affect benchmark scores?

No. File discovery runs inside DLIOBenchmark.initialize(), which completes before the scored benchmark window opens at stats.start_run(). AU and throughput scores are identical whether skip_listing is True or False.

Changes

mlpstorage_py/benchmarks/dlio.py

Two new methods on DLIOBenchmark:

_compute_validation_interval(num_files) — scales HEAD-check sampling geometrically with dataset size so startup time is bounded at any scale:

Train files Interval ~HEAD checks
< 10,000 1 every file
10,000 – 99,999 10 ~1,000
100,000 – 999,999 100 ~1,000
1,000,000 – 9,999,999 1,000 ~1,000
≥ 10,000,000 10,000 ~1,000–5,000

_apply_skip_listing_params() — injects dataset.skip_listing=True and dataset.listing_validation_interval=<adaptive> for all training runs. Called from TrainingBenchmark.__init__ after _apply_object_storage_params(). Both params respect --params overrides.

_apply_object_storage_params() no longer injects skip_listing (now handled by the new method for all storage types).

docs/OBJECT_STORAGE_GUIDE.md

Documents skip_listing, the adaptive validation interval, override examples, and scoring clarification.

Override examples

# Default: skip_listing=True, adaptive interval
uv run mlpstorage training run --object ...

# Externally generated dataset (non-standard naming):
uv run mlpstorage training run --object ... --params dataset.skip_listing=False

# Disable validation entirely (fastest startup, no safety net):
uv run mlpstorage training run --object ... --params dataset.listing_validation_interval=0

Depends on

mlcommons/DLIO_local_changes#27 — implements skip_listing in DLIO (required; pyproject.toml will be updated to pin the merged SHA once that PR lands).

… adaptive validation interval

- mlpstorage_py/benchmarks/dlio.py:
  - New _compute_validation_interval(num_files) static method: scales validation
    sampling geometrically with dataset size so startup HEAD-check time is
    bounded regardless of scale (exhaustive for <10K files; every 10,000th file
    for 10M+ files — ~1,000 checks at any scale).
  - New _apply_skip_listing_params() method: injects dataset.skip_listing=True
    and dataset.listing_validation_interval=<adaptive> for ALL training runs,
    both --file and --object. Each MPI rank reconstructs its own shard
    deterministically — no process ever holds the full file list in memory.
    Eliminates flat-file OOM for large local-filesystem datasets as well as
    the 12+ hour S3 listing problem (issue mlcommons#472). Respects --params overrides.
  - _apply_object_storage_params(): removed skip_listing injection (now handled
    by _apply_skip_listing_params). Object-storage-specific S3 credential and
    endpoint setup unchanged.

- docs/OBJECT_STORAGE_GUIDE.md: document skip_listing, adaptive validation
  interval, override examples, scoring clarification.

Relates-to: mlcommons/DLIO_local_changes#27
@russfellows russfellows requested a review from a team June 19, 2026 23:24
@github-actions

Copy link
Copy Markdown

MLCommons CLA bot All contributors have signed the MLCommons CLA ✍️ ✅

@FileSystemGuy

Copy link
Copy Markdown
Contributor

@russfellows I don't see skip_listing being set to true anywhere in DLIO_local_changes:PR#27

@russfellows

russfellows commented Jun 19, 2026 via email

Copy link
Copy Markdown
Contributor Author

@russfellows

russfellows commented Jun 19, 2026 via email

Copy link
Copy Markdown
Contributor Author

@FileSystemGuy FileSystemGuy merged commit 124613e into mlcommons:main Jun 19, 2026
3 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 19, 2026
@FileSystemGuy

Copy link
Copy Markdown
Contributor

@russfellows Now you're going to bump up the "pin" of the last commit for DLIO_local_changes and bump the version number in the pyproject.toml file and then regenerate the uv.lock file?

@russfellows

russfellows commented Jun 20, 2026 via email

Copy link
Copy Markdown
Contributor Author

@russfellows russfellows deleted the russfellows/skip-listing-object-storage branch June 20, 2026 00:53
@russfellows

russfellows commented Jun 20, 2026 via email

Copy link
Copy Markdown
Contributor Author

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants