Skip to content

Embed video frames during extraction when embed_frames is enabled.#1575

Open
horatiualmasan wants to merge 7 commits into
mainfrom
horatiu-lig-9970-support-calculating-embeddings-for-video-frames-python-api-2
Open

Embed video frames during extraction when embed_frames is enabled.#1575
horatiualmasan wants to merge 7 commits into
mainfrom
horatiu-lig-9970-support-calculating-embeddings-for-video-frames-python-api-2

Conversation

@horatiualmasan

@horatiualmasan horatiualmasan commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

What has changed and why?

Add embedding manager support for VIDEO_FRAME collections and wire frame embedding into the video ingest path via add_videos.

How has it been tested?

New tests

Did you update CHANGELOG.md?

  • Yes
  • Not needed (internal change)

Summary by CodeRabbit

  • New Features
    • Video frame import and annotation-based loading can now optionally generate and persist embeddings while decoding frames (with configurable embedding model selection).
    • Added in-memory PIL-image embedding support across embedding generators and manager, enabling embed-and-store workflows for frame images.
  • Bug Fixes
    • If embedding is enabled but a compatible embedding model isn’t available, embedding is skipped gracefully and a warning is logged.
    • Updated embedding routing so video-frame embeddings use the image embedding path.
  • Tests
    • Added coverage for embedding-enabled frame extraction to verify embeddings are created for each frame sample.

@horatiualmasan horatiualmasan requested a review from a team as a code owner July 6, 2026 09:24
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds optional embedding generation for extracted video frames. It extends embedding generators and the manager to handle in-memory PIL images, then wires embed_frames through video ingestion so decoded frames can be embedded and stored during extraction.

Changes

Frame embedding feature

Layer / File(s) Summary
Embedding generators for PIL images
lightly_studio/src/lightly_studio/dataset/embedding_generator.py, lightly_studio/src/lightly_studio/dataset/mobileclip_embedding_generator.py, lightly_studio/src/lightly_studio/dataset/perception_encoder_embedding_generator.py
Adds embed_pil_images to the shared protocol and implements it in RandomEmbeddingGenerator, MobileCLIPEmbeddingGenerator, and PerceptionEncoderEmbeddingGenerator.
EmbeddingManager PIL storage
lightly_studio/src/lightly_studio/dataset/embedding_manager.py, lightly_studio/tests/dataset/test_embedding_manager.py
Adds PIL image embedding/storage, centralizes image-model validation, maps VIDEO_FRAME to the image generator type, and updates the test stub.
Video frame embedding during extraction
lightly_studio/src/lightly_studio/core/video/add_videos.py, lightly_studio/tests/core/video/test_add_videos.py
Adds embed_frames plumbing, resolves a default frame embedding model, accumulates decoded frames as PIL images, flushes batches through embedding storage, and adds a test covering the embedded frame path.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant load_into_collection_from_paths
  participant _create_video_frame_samples
  participant _flush_frame_batch
  participant EmbeddingManager

  Caller->>load_into_collection_from_paths: embed_frames=True
  load_into_collection_from_paths->>EmbeddingManager: resolve default frame embedding model
  load_into_collection_from_paths->>_create_video_frame_samples: FrameExtractionContext(embed_frames, embedding_model_id)
  loop per decoded batch
    _create_video_frame_samples->>_create_video_frame_samples: collect RGB PIL frames
    _create_video_frame_samples->>_flush_frame_batch: flush(frame_sample_ids, pil_frames)
    _flush_frame_batch->>EmbeddingManager: embed_and_store_pil_images(...)
  end
Loading

Possibly related PRs

  • lightly-ai/lightly-studio#1452: Both PRs modify the video frame ingestion path in core/video/add_videos.py, especially _create_video_frame_samples, by changing which frame samples are created/processed.
  • lightly-ai/lightly-studio#1461: Both PRs change the shared image-embedding abstractions by extending EmbeddingGenerator and generator implementations with new embedding-entry methods.
  • lightly-ai/lightly-studio#1574: The new PIL embedding methods in this PR depend on the in-memory image embedding helper introduced there.

Suggested reviewers: MalteEbner, JonasWurst, lukas-lightly

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly states the main change: embedding video frames during extraction when embed_frames is enabled.
Description check ✅ Passed The description includes the required sections and covers the main change and changelog choice, though testing is minimal.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch horatiu-lig-9970-support-calculating-embeddings-for-video-frames-python-api-2

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Base automatically changed from horatiu-lig-9970-support-calculating-embeddings-for-video-frames-python-api to main July 6, 2026 13:36

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lightly_studio/src/lightly_studio/core/video/add_videos.py (1)

227-227: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Handle embedding failures inside the per-video boundary.
FileOutcomeReport.track only suppresses the typed file-outcome signals; _flush_frame_batch can still raise RuntimeError or embedding-manager exceptions, which will escape load_into_collection_from_paths and stop the rest of the videos in the batch. Catch and log those here if best-effort ingest is intended.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lightly_studio/src/lightly_studio/core/video/add_videos.py` at line 227, The
per-video exception handling in load_into_collection_from_paths currently only
covers file/FFmpeg errors, so failures from _flush_frame_batch or
embedding-related RuntimeError paths can still abort the whole batch. Broaden
the try/except around the per-video processing block in add_videos.py to catch
and log those embedding/flush exceptions at the video boundary, using the
existing _flush_frame_batch and FileOutcomeReport.track flow so one bad video
does not stop later videos from being processed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@lightly_studio/src/lightly_studio/core/video/add_videos.py`:
- Line 227: The per-video exception handling in load_into_collection_from_paths
currently only covers file/FFmpeg errors, so failures from _flush_frame_batch or
embedding-related RuntimeError paths can still abort the whole batch. Broaden
the try/except around the per-video processing block in add_videos.py to catch
and log those embedding/flush exceptions at the video boundary, using the
existing _flush_frame_batch and FileOutcomeReport.track flow so one bad video
does not stop later videos from being processed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 066166dd-f002-46cc-aaac-35c8a9aed2d7

📥 Commits

Reviewing files that changed from the base of the PR and between 3b4e509 and 5192516.

📒 Files selected for processing (7)
  • lightly_studio/src/lightly_studio/core/video/add_videos.py
  • lightly_studio/src/lightly_studio/dataset/embedding_generator.py
  • lightly_studio/src/lightly_studio/dataset/embedding_manager.py
  • lightly_studio/src/lightly_studio/dataset/mobileclip_embedding_generator.py
  • lightly_studio/src/lightly_studio/dataset/perception_encoder_embedding_generator.py
  • lightly_studio/tests/core/video/test_add_videos.py
  • lightly_studio/tests/dataset/test_embedding_manager.py

@horatiualmasan

Copy link
Copy Markdown
Contributor Author

/review

@horatiualmasan horatiualmasan force-pushed the horatiu-lig-9970-support-calculating-embeddings-for-video-frames-python-api-2 branch from b8b01fa to 6852dff Compare July 9, 2026 09:07
@horatiualmasan horatiualmasan changed the base branch from main to horatiu-lig-10136-embeddings-for-video-frames-merge-prs July 9, 2026 09:08
Base automatically changed from horatiu-lig-10136-embeddings-for-video-frames-merge-prs to main July 9, 2026 11:53
Comment thread lightly_studio/src/lightly_studio/core/video/add_videos.py Outdated
"""
...

def embed_pil_images(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think it is quite convoluted now. Especially if you imagine users that need to implement this interface. we can go ahead for now, but should consider how to improve this. I.e. i would expect only one embed_images, not two.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we can address this after we refactor to move the embedding at index time, we could pass directly the in memory image and won't need the variant with file paths

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm make sure to create an issue

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also test mobileclip and perception encoder?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added tests

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.

2 participants