Skip to content

add nomic-embed-vision-v1.5#651

Open
Dylancouzon wants to merge 1 commit into
mainfrom
add-nomic-embed-vision
Open

add nomic-embed-vision-v1.5#651
Dylancouzon wants to merge 1 commit into
mainfrom
add-nomic-embed-vision

Conversation

@Dylancouzon

Copy link
Copy Markdown

Do I fully know what I'm doing? Not really
Was AI involved? Absolutely
Did I do my best testing and verifying the contents? Yes sir

new: add nomic-embed-vision-v1.5

Adds nomic-ai/nomic-embed-vision-v1.5 and its quantized -Q variant to ImageEmbedding.

Both models use the same 768-dimensional embedding space as the existing nomic-embed-text-v1.5, enabling text-to-image and image-to-text search without extra alignment.

How

nomic-embed-vision-v1.5 returns last_hidden_state with shape [batch, 197, 768] instead of a pooled embedding. This PR adds a NomicVisionEmbedding subclass that takes the CLS token at index 0 and L2-normalizes it, matching the model's reference recipe.

This mirrors the existing text-side pooling override in PooledEmbedding. The base class and other image models are unchanged.

Canonical values

For fp32, canonical values were computed from the original HF Transformers model and match the ONNX path bit-for-bit (max abs diff 0.0):

from transformers import AutoImageProcessor, AutoModel
import torch, torch.nn.functional as F
from PIL import Image

proc = AutoImageProcessor.from_pretrained("nomic-ai/nomic-embed-vision-v1.5")
model = AutoModel.from_pretrained("nomic-ai/nomic-embed-vision-v1.5", trust_remote_code=True).eval()
inp = proc(Image.open("tests/misc/image.jpeg"), return_tensors="pt")
with torch.no_grad():
    emb = F.normalize(model(**inp).last_hidden_state[:, 0], p=2, dim=1)
print(emb[0, :10])  # canonical vector for nomic-embed-vision-v1.5

For -Q, there is no torch reference for the quantized graph, so the canonical value is the quantized ONNX output on linux/amd64 with cosine 0.995 to fp32. The test is skipped on macOS because ARM int8 kernels diverge, matching the existing handling for nomic-embed-text-v1.5-Q.

Models added:

  • nomic-embed-vision-v1.5: 768 dims, 0.37 GB, Apache-2.0
  • nomic-embed-vision-v1.5-Q: 768 dims, 0.1 GB, Apache-2.0

Checklist:

  • Have you followed the guidelines in our Contributing document?
  • Have you checked to ensure there aren't other open Pull Requests for the same update/change?

New Feature Submissions:

  • Does your submission pass the existing tests?
  • Have you added tests for your feature?
  • Have you installed pre-commit with pip3 install pre-commit and set up hooks with pre-commit install?

New models submission:

  • Have you added an explanation of why it's important to include this model?
  • Have you added tests for the new model? Were canonical values for tests computed via the original model?
  • Have you added the code snippet for how canonical values were computed?
  • Have you successfully ran tests with your changes locally?

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Nomic vision embedding model descriptors and ONNX-specific embedding classes. The new implementation reshapes model outputs, selects the CLS token, and normalizes the resulting vectors. ImageEmbedding registers the new backend, and image embedding tests add canonical vectors for standard and quantized Nomic models with a macOS-specific skip for the quantized variant.

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

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: adding nomic-embed-vision-v1.5 support.
Description check ✅ Passed The description is directly related to the PR and accurately explains the new image embedding support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 add-nomic-embed-vision

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.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
fastembed/image/image_embedding.py (1)

7-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Annotate mutable class attribute with ClassVar.

As hinted by Ruff (RUF012), EMBEDDINGS_REGISTRY is a class-level mutable list. Annotating it with typing.ClassVar is a best practice that signals it should not be overridden on instances.

♻️ Proposed refactor

Ensure ClassVar is imported at the top of the file:

from typing import ClassVar

Then update the attribute annotation:

 class ImageEmbedding(ImageEmbeddingBase):
-    EMBEDDINGS_REGISTRY: list[Type[ImageEmbeddingBase]] = [
+    EMBEDDINGS_REGISTRY: ClassVar[list[Type[ImageEmbeddingBase]]] = [
         OnnxImageEmbedding,
         NomicVisionEmbedding,
     ]
🤖 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 `@fastembed/image/image_embedding.py` around lines 7 - 15, Import ClassVar from
typing in the image embedding module and annotate
ImageEmbedding.EMBEDDINGS_REGISTRY as ClassVar containing the existing image
embedding class type, preserving the current registry contents.

Source: Linters/SAST tools

🤖 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 `@fastembed/image/image_embedding.py`:
- Around line 7-15: Import ClassVar from typing in the image embedding module
and annotate ImageEmbedding.EMBEDDINGS_REGISTRY as ClassVar containing the
existing image embedding class type, preserving the current registry contents.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 98523fe7-f0b8-4935-803c-b4c92da69c52

📥 Commits

Reviewing files that changed from the base of the PR and between 8a8ea4f and d4b9032.

📒 Files selected for processing (3)
  • fastembed/image/image_embedding.py
  • fastembed/image/onnx_embedding.py
  • tests/test_image_onnx_embeddings.py

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.

1 participant