""" 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()