Skip to content

Extract EmbeddingResult to a shared, path-agnostic module#1710

Open
JonasWurst wants to merge 1 commit into
mainfrom
jonas-lig-10034-extract-embedding-result
Open

Extract EmbeddingResult to a shared, path-agnostic module#1710
JonasWurst wants to merge 1 commit into
mainfrom
jonas-lig-10034-extract-embedding-result

Conversation

@JonasWurst

@JonasWurst JonasWurst commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Summary

Prefactor sliced out of #1706. Pure rename/move — no behavior change.

  • Rename ImageEmbeddingResultEmbeddingResult and move it out of image_embedding.py into its own dependency-free module dataset/embedding_result.py.
  • The type carries embeddings + kept_indices and is not image-specific. Giving it a neutral home lets the image, image-crop, and (future) video embedding paths reuse it without importing a path-specific module.
  • Only the image embedding path is touched here. The crop path still returns NDArray on main and adopts EmbeddingResult in the stacked crop PR (Tolerate broken files per-item in image crop embedding #1706).

Stacking

#1706 (crop broken-file handling) will be rebased to stack on top of this PR.

Testing

  • make static-checks — ruff + format + mypy clean.
  • pytest tests/dataset/{test_embedding_manager,test_mobileclip_embedding_generator,test_perception_encoder_embedding_generator,test_embedding_generator}.py — 46 passed.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements
    • Standardized embedding results across image, crop, and video workflows.
    • Embedding outputs now consistently include generated vectors and the source-item indices they correspond to.
    • Existing embedding behavior and filtering of unreadable inputs remain unchanged.
  • Examples & Tests
    • Updated custom embedding examples and validation coverage to use the standardized result format.

Rename ImageEmbeddingResult -> EmbeddingResult and move it out of
image_embedding.py into its own dependency-free module
(dataset/embedding_result.py). The type carries embeddings plus
kept_indices and is not image-specific; giving it a neutral home lets the
image, image-crop, and (future) video embedding paths reuse it without
importing a path-specific module.

Pure rename/move: no behavior change. All references and docstrings
updated. Only the image embedding path is touched here; the crop path
still returns NDArray on main and adopts EmbeddingResult in the stacked
crop PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JonasWurst
JonasWurst requested a review from a team as a code owner July 22, 2026 05:48
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f3c8344b-4a36-4dce-8586-a382efd69713

📥 Commits

Reviewing files that changed from the base of the PR and between 75bcf91 and d2f988d.

📒 Files selected for processing (7)
  • lightly_studio/src/lightly_studio/dataset/embedding_generator.py
  • lightly_studio/src/lightly_studio/dataset/embedding_result.py
  • lightly_studio/src/lightly_studio/dataset/image_embedding.py
  • lightly_studio/src/lightly_studio/dataset/mobileclip_embedding_generator.py
  • lightly_studio/src/lightly_studio/dataset/perception_encoder_embedding_generator.py
  • lightly_studio/src/lightly_studio/examples/example_custom_embedding_model.py
  • lightly_studio/tests/dataset/test_embedding_manager.py

📝 Walkthrough

Walkthrough

Adds a shared frozen EmbeddingResult dataclass and replaces ImageEmbeddingResult across batched image embedding functions, embedding generator implementations, the custom example, and embedding manager tests.

Changes

Embedding result standardization

Layer / File(s) Summary
Shared result and batched image embedding
lightly_studio/src/lightly_studio/dataset/embedding_result.py, lightly_studio/src/lightly_studio/dataset/image_embedding.py
Defines EmbeddingResult with embeddings and kept_indices, then uses it for empty and completed batched image embedding results.
Generator contract propagation
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
Updates generator protocols and implementations to return EmbeddingResult while preserving embedding generation behavior.
Downstream usage and validation
lightly_studio/src/lightly_studio/examples/example_custom_embedding_model.py, lightly_studio/tests/dataset/test_embedding_manager.py
Updates the custom generator example and test generator stubs to use and construct EmbeddingResult.

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

Possibly related PRs

Suggested reviewers: horatiualmasan

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 44.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: extracting EmbeddingResult into a shared module.
Description check ✅ Passed The description includes the change summary, motivation, stacking context, and testing, but it omits the changelog checkbox section.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jonas-lig-10034-extract-embedding-result

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.

@lightly-fast-track-bot

Copy link
Copy Markdown

❌ Fast Track: checks did not pass

Failed guardrails: backend/complexity (Guardrail threw: spawn uv ENOENT), backend/coverage (Guardrail threw: spawn uv ENOENT)

Guardrail Result Message
dummy Always passes.
frontend/complexity 0 file(s) checked.
backend/complexity Guardrail threw: spawn uv ENOENT
backend/coverage Guardrail threw: spawn uv ENOENT
diff-size PR adds 59 line(s) (limit: 215).
frontend/coverage 0 file(s) checked.

Reflects d2f988d.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2f988d9c4

ℹ️ 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".

Comment thread lightly_studio/src/lightly_studio/dataset/embedding_result.py
JonasWurst added a commit that referenced this pull request Jul 22, 2026
Apply the per-item broken-file handling from the full-image embedding path
(#1691) to the crop path, on top of the shared EmbeddingResult foundation
(#1710).

- embed_image_crops_batched catches (OSError, UnidentifiedImageError) per
  source file; a broken/undecodable file skips all of its crops instead of
  aborting the run, and is recorded once as BROKEN in a FileOutcomeReport.
  Returns an EmbeddingResult carrying kept_indices (input positions of the
  embedded crops) and raises AllInputFilesFailedError when every source file
  is broken.
- Propagate EmbeddingResult through the ImageEmbeddingGenerator protocol
  embed_image_crops and its implementations (mobileclip, perception_encoder,
  RandomEmbeddingGenerator, custom-model example).
- embedding_manager.embed_annotations filters annotation 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>
@JonasWurst

Copy link
Copy Markdown
Contributor Author

/review

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