Predefined Semantic Vocabulary layer with Cached AI Tags#1389
Conversation
Pulls Places365 + Open Images classes, applies COCO-80/person exclusion and dedupe, emits raw_candidates.json (838 entries). Downloads are cached and gitignored.
395 labels (194 scene / 139 object / 45 event / 17 attribute) with 1085 caption-shaped descriptions. Hand-pruned from the raw candidates plus hand-written events and attributes blocks.
Wikimedia Commons downloader for an 80-label stratified eval set, plus a calibration script scoring it through the production pipeline. Report recommends bucket thresholds, K=15 and a top-5 display cut.
Labels register in mappings (class_id >= 1000) and tags write to image_classes with scores, reusing the YOLO tag flow end to end. semantic_labels becomes a definition + embedding-cache table; scoring is invalidated by a content signature; the image_classes_display view caps chips at the top 5 semantic tags.
Startup, folder sync/AI-tagging, and semantic model install now run vocabulary sync, the label-embedding build, and the scoring sweep. All passes are self-gating no-ops when nothing is stale.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughAdds a curated 395-label semantic vocabulary, offline SIGLIP2 label and image scoring, cached embeddings and scoring signatures, database migration and display limits, calibration tooling, lifecycle integration, and tests. ChangesSemantic vocabulary and pre-scoring
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant ApplicationStartup
participant semantic_util_sync_vocabulary
participant semantic_util_build_label_embeddings
participant semantic_util_score_images
participant SQLite
ApplicationStartup->>semantic_util_sync_vocabulary: synchronize shipped vocabulary
ApplicationStartup->>semantic_util_build_label_embeddings: build cached label embeddings
semantic_util_build_label_embeddings->>SQLite: store label embeddings
ApplicationStartup->>semantic_util_score_images: score embedded images
semantic_util_score_images->>SQLite: write semantic scores and signatures
Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
backend/scripts/calibrate_semantic_vocabulary.py (1)
49-61: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAdd type hints to
build_label_matrix.As per path instructions, ensure proper use of type hints. While this is an offline script, annotating top-level functions improves readability and maintainability.
💡 Proposed refactor to add type annotations
-def build_label_matrix(labels, text_model, tokenize): +from typing import Any, Callable + +def build_label_matrix( + labels: list[dict], + text_model: Any, + tokenize: Callable[[str], tuple[np.ndarray, np.ndarray]], +) -> np.ndarray: """Ensembled label vectors: renormalized mean of description embeddings."""🤖 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 `@backend/scripts/calibrate_semantic_vocabulary.py` around lines 49 - 61, Add type annotations to the build_label_matrix function, including parameter types for labels, text_model, and tokenize, plus its NumPy array return type. Use appropriate existing or standard typing symbols and preserve the current embedding and normalization behavior.Source: Path instructions
backend/app/utils/semantic_labels.py (1)
8-20: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueAdd type hints to
_scoring_signature.The public DB functions in this cohort are fully typed, but this helper's parameters are untyped. Adding hints keeps the module consistent and documents the
meta/thresholds/label_matrixcontract the signature hashing depends on.As per path instructions ("Ensure proper use of type hints").
🤖 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 `@backend/app/utils/semantic_labels.py` around lines 8 - 20, Add complete type annotations to the _scoring_signature helper, including model_version, top_k, thresholds, meta, label_matrix, and its string return type. Use the existing project types or appropriate concrete types to document the meta tuple structure, threshold sequence, and NumPy label matrix contract without changing the hashing behavior.Source: Path instructions
🤖 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.
Nitpick comments:
In `@backend/app/utils/semantic_labels.py`:
- Around line 8-20: Add complete type annotations to the _scoring_signature
helper, including model_version, top_k, thresholds, meta, label_matrix, and its
string return type. Use the existing project types or appropriate concrete types
to document the meta tuple structure, threshold sequence, and NumPy label matrix
contract without changing the hashing behavior.
In `@backend/scripts/calibrate_semantic_vocabulary.py`:
- Around line 49-61: Add type annotations to the build_label_matrix function,
including parameter types for labels, text_model, and tokenize, plus its NumPy
array return type. Use appropriate existing or standard typing symbols and
preserve the current embedding and normalization behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: edf2b7e9-c44c-46bc-9390-c1344e9b5729
📒 Files selected for processing (21)
.gitignorebackend/app/config/settings.pybackend/app/data/semantic_vocabulary.jsonbackend/app/database/faces.pybackend/app/database/image_embeddings.pybackend/app/database/images.pybackend/app/database/semantic_labels.pybackend/app/routes/folders.pybackend/app/routes/models.pybackend/app/utils/semantic_labels.pybackend/main.pybackend/scripts/build_eval_set.pybackend/scripts/build_semantic_vocabulary.pybackend/scripts/calibrate_semantic_vocabulary.pybackend/scripts/reset_embeddings.pybackend/scripts/vocabulary/calibration_report.jsonbackend/scripts/vocabulary/eval_manifest.jsonbackend/scripts/vocabulary/raw_candidates.jsonbackend/tests/conftest.pybackend/tests/test_models.pybackend/tests/test_semantic_labels.py
Add type hints to _scoring_signature and build_label_matrix.
…y layer Curated vocabulary is now active: tag-flow reuse, new schema, scoring signature, display cut, reset script changes.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@docs/backend/backend_python/semantic-search.md`:
- Line 83: Update the vocabulary-section link target in the semantic-search
documentation to use the renderer-generated fragment for the referenced heading,
or add an explicit matching anchor when necessary. Preserve the link text and
ensure the internal link resolves correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 1008b000-eba8-4d3d-bede-72a0f49f225d
📒 Files selected for processing (2)
docs/backend/backend_python/database.mddocs/backend/backend_python/semantic-search.md
Anchor-friendly heading so the fragment resolves in both MkDocs and markdownlint.
Closes #1388
Summary
Adds a curated, precomputed vocabulary of semantic labels (beach, diwali, sunset, …) on top of the existing SigLIP2 embedding pipeline. Photos get searchable, browsable AI tags beyond YOLO's 80 classes, with common-word searches served from an instant SQL cache instead of a live matmul.
Design
Semantic labels reuse the existing YOLO tag flow instead of a parallel path:
mappingsrows atclass_id >= 1000(YOLO keeps 0–79); scoring writes plainimage_classesrows with a new nullablescorecolumn. Tag search, chips, and person-view tag lists work with zero consumer changes.semantic_labelsis a definition + cache table: per-label category, 2–4 caption-shaped descriptions (source of truth), and a cached label embedding (renormalized mean of description embeddings — attacks SigLIP2's bare-noun weakness text-side).image_classes_displayview caps chips at the top-5 semantic tags per image; search matching keeps the full stored set.Vocabulary
395 labels (194 scene / 139 object / 45 event / 17 attribute), derived from Places365 + Open Images, hand-pruned (COCO-80/person exclusion, synonym collapse, junk removal), plus hand-written events (incl. diwali, holi, ganesh chaturthi, durga puja, navratri, mehndi, eid) and attributes (sunset, night, selfie, …). 1,085 authored descriptions.
Calibration (measured, not guessed)
151-image stratified eval set (Wikimedia Commons, attribution recorded), scored through the production preprocessing pipeline:
Ensembled label scores sit ~2 orders of magnitude below the live-query path, so these floors are deliberately not
SIGLIP2_MATCH_THRESHOLD. Null-baseline contrast was evaluated and rejected (never beat absolute thresholds). Full report:backend/scripts/vocabulary/calibration_report.json.Migration
The old
semantic_labels/image_semantic_labelsshells shipped with no writers (guaranteed empty) → detected and drop-recreated. Populated tables get guarded ALTERs (image_classes.score,image_embeddings.scored_signature).Testing
beach__1→ coast, beach, island, ocean) andsearch?tag=beach/balloon/ case-insensitive queries hit the cache.Out of scope
EXIF write-back (later PR, reads the same rows with a stricter cut); score-ordered tag-search results.
AI Usage Disclosure:
We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact. AI slop is strongly discouraged and may lead to banning and blocking. Do not spam our repos with AI slop.
Check one of the checkboxes below:
I have used the following AI models and tools: Claude
Checklist
Summary by CodeRabbit