Repository navigation
[Python] Decode LeRobot video payloads in parallel - #10703
XiaoHongbo-Hope wants to merge 5 commits into
Conversation
9ed3592 to
1cebeb2
Compare
1cebeb2 to
748ae57
Compare
JingsongLi
left a comment
There was a problem hiding this comment.
Two issues found during review; please see the inline comments.
| decode_pool=getattr(self, "_video_decode_pool", None), | ||
| decode_parallelism=getattr( | ||
| self, "_video_decode_parallelism", | ||
| CoreOptions.READ_VIDEO_DECODE_PARALLELISM.default_value())) |
There was a problem hiding this comment.
[P2] Honor the decode limit on the fallback path
The new option is passed only to the optimized window path. With two video cameras, no image_transforms, num_workers=0, and torch.get_num_threads() > 1, that path returns {}, and _decode_video_rows still decodes cameras concurrently. I reproduced read.video.decode-parallelism=1 yielding two simultaneous decoder calls through to_dataloader(batch_size=1, num_workers=0). This violates the documented serial setting. Please apply the same decode budget to the fallback path and add a regression test for this case.
| collator.close() | ||
|
|
||
| def test_video_windows_share_worker_pool_across_cameras(self): | ||
| import torch |
There was a problem hiding this comment.
[P2] Skip this test when the optional Torch dependency is missing
This unconditional import makes the new test fail with ModuleNotFoundError in environments without Torch. The python-tests dependency group does not include Torch, and the neighboring tests already skip when it is unavailable. Running this file without Torch gives 1 failed, 6 passed, 2 skipped. Please use the same missing-dependency skip guard here.
Purpose
Decode independent video payloads in parallel within LeRobot batches, preserving frame deduplication and output order.
read.video.decode-parallelismdefaults to16, shared across all cameras in each Dataset worker. Set it to1for serial decoding.image_transforms. Per-camera caches retain active decoders until tasks finish; worker-local pools are reused across batches and rebuilt after fork/spawn.Performance
Three-run medians on public LeRobot datasets, comparing shared-pool head
1b6f1b04eewith master8c09824c06:Samples/s; local warm-cache CPU decoding on 64 vCPUs, batch 32, 8 workers, 8-frame windows, uint8, exact TorchCodec 0.10, Native reads, no transforms/model. Each run warms 10 batches, then times 100 batches for ALOHA/Koch or 500 for PushT. Configurations 1/2/4 rotate order; master and 8 were measured afterward on the same machine.
A separate 4/8/16 comparison on the same decoder implementation rotated configurations across three seeds:
Local results and OSS ALOHA/PushT are three-run medians; OSS Koch has one diagnostic run per setting. Default 16 prioritizes throughput, with gains depending on the dataset. This also matches the 16-thread decode pool in the official lerobot-lancedb integration, shared across cameras within each Dataset worker. Local Koch uses 34.3 CPU cores and 10.55 GiB PSS at 16, versus 26.6 cores and 8.16 GiB at 4. Lower the option for resource-constrained workloads.
OSS first-batch waits at 4/8/16 are 37.3/38.5/35.2 s (ALOHA), 5.3/5.3/5.0 s (PushT), and 360.7/378.4/375.3 s (Koch). These measure the first
next()only, excluding Dataset/iterator construction. Log-reconstructed times including warmup are approximately 68.2/70.6/67.7 s for 3,520 ALOHA samples, 45.3/45.5/42.5 s for 16,320 PushT samples, and 756.2/747.3/732.2 s for 3,520 Koch samples; initial monitor startup lag is excluded. More threads do not resolve slow OSS video initialization.All comparisons force TorchCodec exact mode, not the default indexed/PyAV path; OSS/server caches are uncontrolled. The earlier ALOHA regression against master remains unresolved. These results do not establish a universally optimal default.
Tests
git diff --checkpassed.