File size: 2,029 Bytes
da0fb08
 
ec0ee7c
da0fb08
 
 
 
 
 
 
ec0ee7c
869bae6
da0fb08
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2d37781
da0fb08
 
 
 
 
2d37781
ec0ee7c
da0fb08
ec0ee7c
2d37781
 
ec0ee7c
2d37781
ec0ee7c
869bae6
ec0ee7c
 
 
 
 
 
2d37781
 
869bae6
 
ec0ee7c
2d37781
 
ec0ee7c
2d37781
 
 
ec0ee7c
 
 
2d37781
 
 
d9e5501
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""
Visual Search API - HuggingFace Space
Returns embedding vector for external Pinecone queries
"""

import os
import gradio as gr
import torch
import numpy as np
from PIL import Image
import json

# Model (loaded on first use)
model = None


def load_model():
    """Load Jina CLIP v2 model."""
    global model
    if model is None:
        print("Loading Jina CLIP v2...")
        from transformers import AutoModel
        model = AutoModel.from_pretrained(
            "jinaai/jina-clip-v2",
            trust_remote_code=True
        )
        model.eval()
        print("Model loaded!")
    return model


def get_embedding(image: Image.Image) -> list:
    """Generate 512-dim embedding for an image."""
    m = load_model()

    with torch.no_grad():
        emb = m.encode_image(image)
        if hasattr(emb, 'cpu'):
            emb = emb.cpu().numpy()
        emb = emb.flatten()
        emb = emb / np.linalg.norm(emb)
        if len(emb) > 512:
            emb = emb[:512]
        return emb.tolist()


def search(image):
    """Return embedding vector as JSON."""
    if image is None:
        return json.dumps({"error": "No image provided"})

    try:
        print("Generating embedding...")
        embedding = get_embedding(image)
        print(f"Embedding generated: {len(embedding)} dimensions")

        # Return embedding as JSON
        result = {
            "embedding": embedding,
            "dimensions": len(embedding)
        }
        return json.dumps(result, indent=2)

    except Exception as e:
        import traceback
        traceback.print_exc()
        return json.dumps({"error": str(e)})


# Gradio interface - returns embedding as JSON
demo = gr.Interface(
    fn=search,
    inputs=gr.Image(type="pil", label="Upload Image"),
    outputs=gr.Textbox(label="Embedding Vector (JSON)", lines=15),
    title="Visual Search - Embedding Generator",
    description="Upload an image to get its 512-dimensional CLIP embedding as JSON."
)

if __name__ == "__main__":
    demo.queue().launch()