TensorCruncher's picture
Add cache redirect
0ea07d3 verified
Raw
History Blame Contribute Delete
3.37 kB
import os
# Redirect all Hugging Face / Torch caches to ephemeral storage
os.environ["HF_HOME"] = "/tmp/hf"
os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf"
os.environ["TORCH_HOME"] = "/tmp/torch"
os.environ["XDG_CACHE_HOME"] = "/tmp"
import gradio as gr
import torch
import open_clip
import faiss
import numpy as np
import json
from PIL import Image
from transformers import BlipProcessor, BlipForConditionalGeneration
with open("image_paths.json", "r") as f:
image_paths = json.load(f)
image_embeddings = np.load("image_embeddings.npy")
model, _, preprocess = open_clip.create_model_and_transforms('ViT-B-32', pretrained='laion2b_s34b_b79k')
tokenizer = open_clip.get_tokenizer('ViT-B-32')
d = image_embeddings.shape[1]
index = faiss.IndexFlatIP(d)
index.add(image_embeddings)
processor_cap = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
model_cap = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
def search_text(query, top_k=3):
with torch.no_grad():
tokenized = tokenizer([query])
text_embed = model.encode_text(tokenized)
text_embed = text_embed / text_embed.norm(dim=-1, keepdim=True)
text_np = text_embed.cpu().numpy()
_, I = index.search(text_np, top_k)
return [image_paths[i] for i in I[0]]
def search_image(image, top_k=3):
image_tensor = preprocess(image).unsqueeze(0)
with torch.no_grad():
image_embed = model.encode_image(image_tensor)
image_embed = image_embed / image_embed.norm(dim=-1, keepdim=True)
image_np = image_embed.cpu().numpy()
_, I = index.search(image_np, top_k)
return [image_paths[i] for i in I[0]]
def generate_captions(paths):
imgs = [Image.open(p).convert("RGB") for p in paths]
inputs = processor_cap(images=imgs, return_tensors="pt")
out = model_cap.generate(**inputs)
captions = [processor_cap.decode(out[i], skip_special_tokens=True) for i in range(len(imgs))]
return captions
def predict(input_text, input_image):
if input_text:
paths = search_text(input_text)
elif input_image:
paths = search_image(input_image)
else:
return None, None
captions = generate_captions(paths)
return [(Image.open(p), c) for p, c in zip(paths, captions)]
with gr.Blocks() as demo:
gr.Markdown("## Animal Image Search 🐈 🏞️ πŸ”Ž ")
gr.Markdown("Search database of 5400 animal images using text or image queries.")
gr.Markdown("Results come with automatic captions.")
gr.Markdown("For list of animal categories (90 animals x 60 images = 5400 images) visit [GitHub](https://github.com/TensorCruncher/animal-image-search/blob/main/animals.txt).")
gr.Markdown("Note: Make sure only one input field (text or image) is populated before searching")
with gr.Row():
text_input = gr.Textbox(label="Type your query")
image_input = gr.Image(type="pil", label="Or upload an image")
gr.Examples(
examples=[
"examples/sample1.jpg",
"examples/sample2.jpg",
"examples/sample3.jpg"
],
inputs=[image_input],
label="Choose a sample image"
)
output = gr.Gallery(label="Top Matches with Captions")
submit = gr.Button("Search", variant="primary")
submit.click(predict, inputs=[text_input, image_input], outputs=output)
demo.launch()