RoboCorpse's picture
feat: add CLIP zero-shot demo
a584900
Raw
History Blame Contribute Delete
3.04 kB
"""
Interactive CLIP zero-shot classifier.
Run:
pip install -r requirements.txt
python app.py
"""
from __future__ import annotations
import gradio as gr
import torch
from PIL import Image
from transformers import CLIPModel, CLIPProcessor
MODEL_ID = "openai/clip-vit-base-patch32"
DEFAULT_LABELS = "apple\nbanana\norange\nstrawberry\nwatermelon"
device = "cuda" if torch.cuda.is_available() else "cpu"
processor = CLIPProcessor.from_pretrained(MODEL_ID)
model = CLIPModel.from_pretrained(MODEL_ID).to(device)
model.eval()
def parse_labels(text: str) -> list[str]:
labels = [line.strip() for line in text.replace(",", "\n").splitlines() if line.strip()]
if not labels:
raise gr.Error("Add at least one label (one per line or comma-separated).")
return labels
def classify(image: Image.Image | None, labels_text: str) -> dict[str, float]:
if image is None:
raise gr.Error("Upload an image first.")
labels = parse_labels(labels_text)
inputs = processor(
text=labels,
images=image.convert("RGB"),
return_tensors="pt",
padding=True,
).to(device)
with torch.no_grad():
probs = model(**inputs).logits_per_image.softmax(dim=1)[0]
return {label: float(score) for label, score in zip(labels, probs, strict=True)}
def build_ui() -> gr.Blocks:
with gr.Blocks(title="CLIP Zero-Shot Classifier") as demo:
gr.Markdown(
f"""
# CLIP Zero-Shot Image Classifier
Upload an image and enter candidate labels — no training required.
Model: [{MODEL_ID}](https://huggingface.co/{MODEL_ID}) · Device: **{device}**
"""
)
with gr.Row():
with gr.Column():
image_input = gr.Image(type="pil", label="Image")
labels_input = gr.Textbox(
label="Candidate labels",
placeholder="One label per line",
lines=6,
value=DEFAULT_LABELS,
)
classify_btn = gr.Button("Classify", variant="primary")
with gr.Column():
output = gr.Label(label="Predictions", num_top_classes=10)
classify_btn.click(
fn=classify,
inputs=[image_input, labels_input],
outputs=output,
)
gr.Examples(
examples=[
[
"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/parrots.png",
"animals\nhumans\nlandscape\nvehicles",
],
[
"https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/hub/parrots.png",
DEFAULT_LABELS,
],
],
inputs=[image_input, labels_input],
outputs=output,
fn=classify,
cache_examples=False,
)
return demo
if __name__ == "__main__":
build_ui().launch()