Spaces:
Build error
Build error
File size: 3,034 Bytes
3b838d1 | 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 | import torch
from pinecone import Pinecone
from torchvision.transforms import Compose, Resize, ToTensor, Normalize
from PIL import Image
from transformers import CLIPProcessor, CLIPModel
# Initialize the Pinecone client
pc = Pinecone(
api_key="pcsk_6w79Cx_MfeLRKxmSKerQhKiyrjZieguMKdiSVV1M3no8fTzAygLT8Qpx8F7AS7iMSzUEX1",
environment="us-east-1" # Ensure this matches your region
)
# Connect to the existing index
index_name = "multimodal-search"
if index_name not in pc.list_indexes().names():
raise ValueError(f"Index {index_name} does not exist. Please create it in your Pinecone dashboard.")
index = pc.Index(index_name)
# Initialize CLIP model and processor
device = "cuda" if torch.cuda.is_available() else "cpu"
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device)
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
# Define global image transformation pipeline
transform = Compose([
Resize((224, 224)),
ToTensor(),
Normalize(mean=(0.481, 0.457, 0.408), std=(0.268, 0.261, 0.275)) # CLIP-specific normalization
])
def query_pinecone_with_filters(query, mode="text-to-image", top_k=5, filter_metadata=None):
"""
Perform text-to-image or image-to-image search with metadata filtering using Pinecone and CLIP.
Args:
query: String (for text-to-image) or file path to image (for image-to-image).
mode: "text-to-image" or "image-to-image".
top_k: Number of top results to retrieve.
filter_metadata: Dictionary of filters to apply on metadata (e.g., {"type": "image", "captions": "dog"}).
Returns:
List of matches with metadata.
"""
if mode == "text-to-image":
# Convert text query to embedding
text_inputs = processor(text=[query], return_tensors="pt", padding=True).to(device)
query_embedding = model.get_text_features(**text_inputs)
query_embedding = query_embedding / query_embedding.norm(dim=-1, keepdim=True) # Normalize
elif mode == "image-to-image":
# Convert image to embedding
query_image = Image.open(query).convert("RGB")
image_tensor = transform(query_image).unsqueeze(0).to(device)
query_embedding = model.get_image_features(image_tensor)
query_embedding = query_embedding / query_embedding.norm(dim=-1, keepdim=True) # Normalize
else:
raise ValueError("Invalid mode. Choose 'text-to-image' or 'image-to-image'.")
# Query Pinecone
query_vector = query_embedding.cpu().detach().numpy().flatten().tolist()
results = index.query(
vector=query_vector,
top_k=top_k,
include_metadata=True,
filter=filter_metadata
)
# Update image paths to use URLs
for match in results["matches"]:
image_filename = match["metadata"]["image_path"].split("\\")[-1] # Extract filename
match["metadata"]["image_path"] = f"https://Dev24910-VisionVerse-Search.hf.space/file/workspace/images/{image_filename}"
return results["matches"] |