Skip to content

Streaming reads for cloud LeRobot-v3 & Zarr (inspect + ingest)#35

Merged
arpitg1304 merged 2 commits into
mainfrom
feat/streaming-reads-lerobot-zarr
Jul 20, 2026
Merged

Streaming reads for cloud LeRobot-v3 & Zarr (inspect + ingest)#35
arpitg1304 merged 2 commits into
mainfrom
feat/streaming-reads-lerobot-zarr

Conversation

@arpitg1304

@arpitg1304 arpitg1304 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

What

Streaming reads for cloud datasets — forge inspect and forge ingest on s3:// / gs:// LeRobot-v3 and Zarr now read over the network with range requests instead of downloading the whole dataset.

forge inspect s3://…/droid_100     # 464 MB dataset → ~3 KB fetched (info.json), ~0.3s
forge ingest  s3://…/droid_100 -c ./cat   # register + quality-score → ~3 MB fetched (proprio only, no video), ~0.5s

Both produce identical results to the local read — same DatasetInfo, same 100 episodes, same quality scores (avg 8.26). This is the credibility gate for the pretraining-scale story: point Forge at a huge cloud corpus and register + score it without pulling the videos.

How

  • forge/io/source.pyDataSource: a dataset root (local or fsspec-remote) exposing the metadata + column reads streaming needs (json, parquet footer/schema, parquet columns, exists, glob) as range requests for remote sources.
  • Inspect: lerobot-v3 _inspect_remote reads only meta/info.json (episode/frame counts, fps, robot, per-camera dims, schema — so the mp4 probe is skipped); zarr opens the store natively over fsspec.
  • Ingest: lerobot-v3 _read_episodes_remote yields proprio-only Episodes from parquet column reads (observation.state/action/timestamp) — never touching the videos — so content-hash + the proprio quality metrics run streamed. Zarr streams via its native fsspec store. catalog/ingest.py streams remote streamable formats instead of localizing.
  • registry: detect_format keeps remote URIs as strings so non-streamable readers safely return False; STREAMABLE_FORMATS = {lerobot-v3, zarr}.

Idempotency across paths

Streamed episodes deliberately leave state_dim/action_dim None (like the local reader) so an episode's content hash is identical whether streamed or downloaded. Verified: 100/100 hashes match between the two paths, and streaming into a download-built catalog skips all 100. Cross-path re-ingest stays a no-op.

Scope

Streamed: inspect (metadata) and ingest (register + proprio quality). Still download-to-temp: forge inspect --deep, embeddings and video quality (they need frames), and non-streamable formats (HDF5, rosbag, video seeking). See the roadmap.

Testing (rigorous)

tests/test_streaming.py:

  • Correctness over memory:// for inspect and ingest (right output, and an assertion that no temp download happened).
  • moto-S3 byte-budget assertions: inspect fetches < 1 MB and ingest fetches < 2 MB, each with a large fake video payload sitting next to the real data — so "it actually streamed" is a hard, reproducible test. Verified end-to-end against local MinIO. No regressions.

🤖 Generated with Claude Code

arpitg1304 and others added 2 commits July 19, 2026 21:48
… inspect)

`forge inspect s3://…` / `gs://…` now reads metadata over the network with range
requests instead of downloading the whole dataset. Inspecting a 464 MB cloud
LeRobot-v3 dataset fetches ~3 KB (its info.json) in ~0.3s — a ~150,000x
reduction in bytes moved — and returns the identical DatasetInfo.

- forge/io/source.py: `DataSource` — a dataset root (local or fsspec-remote)
  with the small metadata reads streaming inspection needs (json, parquet
  footer/schema, exists, glob), fetched as range requests for remote sources.
- lerobot-v3 reader: `_inspect_remote` reads only meta/info.json (which carries
  episode/frame counts, fps, robot, per-camera dims, and the action/observation
  schema, so the mp4 probe is skipped). Local inspect path is untouched;
  info.json→DatasetInfo mapping factored into `_populate_from_info` and shared.
- zarr reader: opens the store natively over fsspec (`zarr.open("s3://…")`
  range-reads chunks); can_read checks markers remotely.
- registry: `detect_format` keeps remote URIs as strings (non-streamable readers
  safely return False, so only streamable formats match without a download);
  `STREAMABLE_FORMATS = {lerobot-v3, zarr}`.
- CLI: `forge inspect` streams remote streamable formats; falls back to download
  for `--deep`, `--generate-config`, or other formats/commands.

Tests (tests/test_streaming.py): correctness over memory:// (right DatasetInfo,
no temp download) for both formats, plus a moto-S3 byte-budget assertion proving
inspect fetches < 1 MB even next to an 8 MB payload. Existing cloud-inspect test
updated (inspect now streams, `--deep` still downloads). No other tests change.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Extend streaming from inspect to the ingest/scoring path: `forge ingest s3://…`
registers and quality-scores episodes by reading only the proprio parquet
columns (state/action/timestamp) via range reads — never the videos. Ingesting a
464 MB cloud LeRobot-v3 dataset streams ~3 MB (vs 464 MB), in ~0.5s, producing
identical episodes and quality scores.

- lerobot-v3 reader: `_read_episodes_remote` yields proprio-only Episodes from
  parquet column reads (observation.state/action/timestamp), plus streamed tasks
  + episode metadata for language. state_dim/action_dim are left None to match
  the local reader so an episode's content_hash is identical whether streamed or
  downloaded — cross-path re-ingest stays idempotent (verified: 100/100 hashes
  match; streaming into a download-built catalog skips all 100). Zarr streams via
  its native fsspec store (already wired).
- catalog/ingest.py: `_resolve_for_ingest` streams remote streamable formats
  instead of localizing; other sources unchanged. Embeddings/video quality still
  download frames.

Tests: streaming ingest over memory:// (registers + scores, no temp download)
and a moto byte-budget assertion (ingest reads < 2 MB with an 8 MB video payload
alongside). No regressions.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@arpitg1304 arpitg1304 changed the title Streaming metadata reads for cloud LeRobot-v3 & Zarr (forge inspect) Streaming reads for cloud LeRobot-v3 & Zarr (inspect + ingest) Jul 20, 2026
@arpitg1304
arpitg1304 merged commit ec7695a into main Jul 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant