Tolerate broken files per-item in video embedding - #1754
Conversation
Replace the `_VideoFileDataset` + `DataLoader` machinery in the perception encoder video path with a manual per-video batch loop, mirroring the structure of `embed_image_crops_batched`. With `num_workers=0` the DataLoader gave no async prefetch, only batching/collation, so nothing is lost; the manual loop is simpler and gives the (stacked) per-item broken-file PR a natural place to skip individual videos. - Extract frame sampling into a module-level `_load_video_frames` helper (the former `_VideoFileDataset._load_frames` + stack); it raises on an unusable video, preserving today's abort-on-broken behavior. - `embed_videos` buffers preprocessed videos and flushes batches via a new `_flush_video_batch` helper. Pure refactor: no behavior change. Return type stays NDArray and a broken video still aborts the run. The stacked follow-up adds per-item broken-file tolerance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply the per-item broken-file handling from the image and image-crop paths to the video path, on top of the manual-batch-loop refactor. - _load_video_frames returns None for an unreadable/undecodable video (caught (OSError, FFmpegError, IndexError, StopIteration) plus no-usable-duration) instead of raising, so a broken video skips itself rather than aborting the run. - embed_videos records each video once as BROKEN/ADDED in a FileOutcomeReport, returns an EmbeddingResult carrying kept_indices (input positions of the embedded videos), and raises AllInputFilesFailedError when every video is broken. - Propagate EmbeddingResult through the VideoEmbeddingGenerator protocol embed_videos and RandomEmbeddingGenerator. - embedding_manager.embed_videos filters sample IDs by kept_indices before storing, keeping sample IDs and embeddings in sync. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughVideo embedding APIs now return ChangesVideo embedding flow
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant EmbeddingManager
participant PerceptionEncoderEmbeddingGenerator
participant FileOutcomeReport
EmbeddingManager->>PerceptionEncoderEmbeddingGenerator: embed_videos(filepaths)
PerceptionEncoderEmbeddingGenerator->>FileOutcomeReport: track video load outcomes
FileOutcomeReport-->>PerceptionEncoderEmbeddingGenerator: successful indices and failures
PerceptionEncoderEmbeddingGenerator-->>EmbeddingManager: EmbeddingResult
EmbeddingManager->>EmbeddingManager: filter sample IDs using kept_indices
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
❌ Fast Track: checks did not pass
To run the guardrails locally, from Reflects |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0b9d976354
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Convert StopIteration on decode to the documented ValueError so embed_videos callers handle a single exception type for broken videos - Move _load_video_frames below the class per file-layout convention and document its arguments - Drop no-op non_blocking=True on the pageable-memory device transfer Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Apply the per-item broken-file handling from the image and image-crop paths to the video path, on top of the manual-batch-loop refactor. - _load_video_frames returns None for an unreadable/undecodable video (caught (OSError, FFmpegError, IndexError, StopIteration) plus no-usable-duration) instead of raising, so a broken video skips itself rather than aborting the run. - embed_videos records each video once as BROKEN/ADDED in a FileOutcomeReport, returns an EmbeddingResult carrying kept_indices (input positions of the embedded videos), and raises AllInputFilesFailedError when every video is broken. - Propagate EmbeddingResult through the VideoEmbeddingGenerator protocol embed_videos and RandomEmbeddingGenerator. - embedding_manager.embed_videos filters sample IDs by kept_indices before storing, keeping sample IDs and embeddings in sync. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0b9d976 to
2839aec
Compare
Route each per-video attempt through report.track(path=...) instead of the manual try/except + report.record pattern. _load_video_frames now raises the typed signals (MissingInputFileError proactively via fs.exists, otherwise BrokenInputFileError) that track records and suppresses, matching add_videos. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match the image/crop embedding paths so the end-of-run FileOutcomeReport summary reads "embedded=N" instead of "added=N". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
/review |
Replace the manual batch buffer/flush machinery in embed_videos with utils.batching.batched over a generator of preprocessed frame tensors, mirroring _encode_preprocessed_batches. Removes _flush_video_batch and the Any-typed progress_bar parameter. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mbedding-manual-loop' into HEAD # Conflicts: # lightly_studio/src/lightly_studio/dataset/perception_encoder_embedding_generator.py
Replace the manual batch buffer and _flush_video_batch with the base branch's batching.batched() generator approach. Broken-file tolerance is preserved by feeding batched() a generator that records missing/broken videos via report.track and yields only readable ones, appending their input positions to kept_indices. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-embedding-tolerate-broken-files-per-item-instead-of # Conflicts: # lightly_studio/src/lightly_studio/dataset/perception_encoder_embedding_generator.py
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ken-files-per-item-instead-of
Summary
Apply the per-item broken-file handling from the full-image (#1691) and crop (#1706) embedding paths to the video path.
_load_video_framesreturnsNonefor an unreadable/undecodable video — catching(OSError, FFmpegError, IndexError, StopIteration)plus the no-usable-duration case — instead of raising, so a broken video skips itself rather than aborting the run.embed_videosrecords each video once asBROKEN/ADDEDin aFileOutcomeReport, returns anEmbeddingResultcarryingkept_indices(input positions of the embedded videos), and raisesAllInputFilesFailedErrorwhen every video is broken.EmbeddingResultis propagated through theVideoEmbeddingGenerator.embed_videosprotocol method andRandomEmbeddingGenerator.embedding_manager.embed_videosfilters sample IDs bykept_indicesbefore storing, keeping sample IDs and embeddings in sync.kept_indicescomes out already sorted (videos are processed in input order, unlike the crop path which groups by filepath), so no post-sort is needed.Stacking
This PR is stacked on #1753 (the manual-batch-loop refactor), not
main. Its base isjonas-lig-10035-refactor-video-embedding-manual-loop. Rebase ontomainonce #1753 merges. Review #1753 first — this PR's diff is only the tolerance change.Testing
make static-checks— ruff + format + mypy clean.pytest tests/dataset/{test_perception_encoder_embedding_generator,test_embedding_manager,test_embedding_generator}.py— 41 passed.kept_indicesassertions, all-broken raisesAllInputFilesFailedError, and a manager stub-drop case asserting only kept sample IDs are stored; unwrapped.embeddingsin the existing video tests.🤖 Generated with Claude Code
Summary by CodeRabbit
kept_indicesmapping for successfully processed inputs.kept_indicesalignment, and raising an error when all inputs fail.