perf(streaming): async S3 chunk prefetch, cache eviction, obstore downloads#852
Merged
Conversation
…loader spike - Use deque for upcoming_indexes (avoid O(n) pop(0) per sample). - Add LITDATA_TIMING counters + prefetch/thread microbenches. - Advisory cache-byte tracking for eviction; unify Parquet/Tokens/PyTree readiness waits; remove dead skip-deletion machinery (eager .cnt wins). - Experimental StreamingDataLoader(use_threading=True) spike inspired by FFCV's thread-based loader (no process IPC); not the default path. Co-authored-by: Cursor <cursoragent@cursor.com>
Fix prefetch matrix for num_workers=0, report item counts in the threaded vs process bench, and add a deque popleft microbench. Co-authored-by: Cursor <cursoragent@cursor.com>
Threaded StreamingDataLoader only helps when the GIL is disabled; reject use_threading=True on regular CPython so the experimental path is not enabled under GIL contention. Co-authored-by: Cursor <cursoragent@cursor.com>
Collaborator
Author
|
Follow-up: |
These were incorrectly removed as "dead code" in the next-opt spike. Eager .cnt refcounting does not replace the skip-deletion helpers / ChunksConfig.skip_chunk_indexes_deletion API; put them back. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep existing tests untouched. Add a dedicated threaded-loader suite for gates, coverage, determinism, resume counts, failures, and lifecycle. Fix per-worker prefetch so in-order round-robin cannot deadlock. Co-authored-by: Cursor <cursoragent@cursor.com>
Add a CIFAR-shaped three-way microbench so PR numbers include a non-LitData torch Dataset+DataLoader baseline alongside StreamingDataLoader modes. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep use_threading as the no-GIL in-process loader (no use_asyncio). Add an opt-in LITDATA_ASYNC_CHUNK_PREFETCH path that overlaps remote chunk downloads via asyncio.gather inside PrepareChunksThread only. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #852 +/- ##
====================================
- Coverage 81% 81% -0%
====================================
Files 54 56 +2
Lines 7923 8389 +466
====================================
+ Hits 6450 6794 +344
- Misses 1473 1595 +122 🚀 New features to boost your workflow:
|
…tion Make process+async the default remote path (opt out with LITDATA_ASYNC_CHUNK_PREFETCH=0), stream S3 chunks to disk, reuse the prepare-thread event loop, and floor max_pre_download to 4 for gather width. Enforce max_cache_size with shared chunk slots and size-first eviction so multi-worker prefetch cannot ignore the disk budget. Co-authored-by: Cursor <cursoragent@cursor.com>
for more information, see https://pre-commit.ci
Keep all streaming/S3 bench entrypoints in one folder and fix REPO_ROOT path depth after the move. Co-authored-by: Cursor <cursoragent@cursor.com>
Real-S3 ImageNet benches showed threaded workers ~2.3× slower than process workers under decode+transform load. Drop the API, threaded_loader module, and related tests/benches. Co-authored-by: Cursor <cursoragent@cursor.com>
for more information, see https://pre-commit.ci
Use obstore for S3 sync downloads with tunable stream chunk size, drain pending chunk deletes at END_TOKEN so tiny max_cache_size caches clear, and add obstore ImageNet/chunk-size bench helpers. Co-authored-by: Cursor <cursoragent@cursor.com>
for more information, see https://pre-commit.ci
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
for more information, see https://pre-commit.ci
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…exit Prevents leaked asyncio_N daemon threads from to_thread under async chunk prefetch, which tripped Windows session thread-police teardown. Co-authored-by: Cursor <cursoragent@cursor.com>
…lots Async floor raised max_pre_download to 4 while sub-10MB budgets skipped the cap, so reader eviction tests could briefly hold too many chunks. Co-authored-by: Cursor <cursoragent@cursor.com>
Floor the delete-when-processed prefetch cap at 2 and tear down the asyncio default executor without waiting so prepare-thread exit cannot hang. Co-authored-by: Cursor <cursoragent@cursor.com>
Decompression os.replace can briefly deny open() on Windows even after the file is size-ready; retry instead of failing the read. Co-authored-by: Cursor <cursoragent@cursor.com>
for more information, see https://pre-commit.ci
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
LITDATA_ASYNC_CHUNK_PREFETCH=0.adownload_file), reuse event loop, non-blocking batch drain, floormax_pre_downloadto 4 for gather width.LITDATA_OBSTORE_STREAM_MIN_CHUNK_MIB(default 8)..litdata_cache_slotsfor multi-worker budgets, force-redownload keeps slots; drain all pending deletes onEND_TOKENso tiny caches fully clear.ImageReadMode.RGB.use_threading(real S3 ~2.3× slower than process workers).scripts/bench/(includingbench_obstore_*.py,bench_s3_full_epochs.py).Real-S3 ImageNet (this Studio)
Dataset:
lightning_data_search, 48 workers, batch 256, wipe/cache/chunks,PYTHON_GIL=0, transformsRandomResizedCrop(224)+flip+fp16.max_pre=4)max_pre=8)Warm epoch ~12.2k is decode/transform-bound. Prefer
max_pre_download=4.Cache budget
Warn below 25GB. Slot gate only for realistic budgets (≥10MB + delete-when-processed). Real S3 check at 10GB / 48w: peak ~1.07× limit.
Obstore benches
Test plan
tests/streaming/test_cache_eviction.pytests/streaming/test_async_prefetch.pytests/streaming/test_next_streaming_optimizations.py