import spaces # must be imported before torch import html import json import sys import time from pathlib import Path import gradio as gr import torch from huggingface_hub import snapshot_download from PIL import Image MODEL_ID = "Cloudflare/clef" MODEL_PATH = Path(snapshot_download(MODEL_ID)) sys.path.insert(0, str(MODEL_PATH)) from joint_schema_model import ( # noqa: E402 ClefModel, JointSchemaHead, QUESTION_TYPES, collate_records, encode_record, systemone_answer, ) from safetensors.torch import load_file # noqa: E402 from transformers import AutoProcessor, Qwen3_5ForConditionalGeneration # noqa: E402 # Same as joint_schema_model.load_release_model, but loaded to CPU first and moved with # .to("cuda") so the ZeroGPU hijack can pack the weights (device_map would bypass it). backbone = Qwen3_5ForConditionalGeneration.from_pretrained(MODEL_PATH, dtype=torch.bfloat16) backbone.config.use_cache = False head = JointSchemaHead(**json.loads((MODEL_PATH / "joint_head_config.json").read_text())) head.load_state_dict(load_file(MODEL_PATH / "joint_head.safetensors"), strict=True) head = head.to(dtype=torch.bfloat16) model = ClefModel(backbone, head).eval().to("cuda") processor = AutoProcessor.from_pretrained(MODEL_PATH) MAX_IMAGE_SIDE = 1024 EX_SUPPORT_STATE = "Checkout has been failing for every customer for the last hour." EX_SUPPORT_Q = { "urgent": {"type": "noul", "instructions": "Is this support request urgent?"}, "team": { "type": "choice", "instructions": "Which team should handle this request?", "criteria": { "billing": "Payments, invoices, refunds", "technical": "Bugs, errors, outages", "sales": "Pricing, plans, new purchases", }, }, "severity": { "type": "score", "instructions": "How severe is the customer impact?", "criteria": ["No impact", "Minor", "Major", "Critical"], }, } EX_INVOICE_STATE = {"invoice": {"vendor": "Acme", "total": 1250.0, "currency": "USD", "status": "overdue"}} EX_INVOICE_Q = { "status": { "type": "choice", "instructions": "What is the invoice status?", "criteria": {"paid": "Invoice is paid.", "overdue": "Invoice is past due.", "draft": "Not sent."}, }, "large": {"type": "noul", "instructions": "Is the total above 1000 USD?"}, } EX_ROUTING_STATE = "Our checkout started returning errors and orders are blocked." EX_ROUTING_Q = { "department": { "type": "choice", "instructions": "Which team should handle the message?", "criteria": {"billing": "Payments or invoices", "technical": "Bugs or outages"}, }, "urgency": {"type": "score", "criteria": ["Can wait", "This week", "Today"]}, "outage": {"type": "noul", "instructions": "Is a service down?"}, } EX_FOOD_STATE = "A user uploaded this photo to a restaurant review listing." EX_FOOD_Q = { "category": { "type": "choice", "instructions": "What does the photo mainly show?", "criteria": { "food": "A dish or drink", "interior": "The inside of a venue", "people": "People or portraits", "other": "Anything else", }, }, "appetizing": { "type": "score", "instructions": "How appetizing is the photo?", "criteria": ["Unappetizing", "Neutral", "Appetizing", "Very appetizing"], }, "safe": {"type": "noul", "instructions": "Is the photo safe to publish on the listing?"}, } EX_ROOM_STATE = {"listing": {"type": "apartment rental", "claimed_style": "minimalist"}} EX_ROOM_Q = { "room": { "type": "choice", "instructions": "Which room is shown?", "criteria": { "living_room": "Living room or lounge", "kitchen": "Kitchen", "bedroom": "Bedroom", "bathroom": "Bathroom", }, }, "matches_style": {"type": "noul", "instructions": "Does the photo match the claimed style?"}, "clutter": { "type": "score", "instructions": "How cluttered is the room?", "criteria": ["Spotless", "Tidy", "Some clutter", "Very cluttered"], }, } def _dump(value) -> str: return value if isinstance(value, str) else json.dumps(value, indent=2, ensure_ascii=False) def _parse_state(state: str): text = (state or "").strip() if not text: raise gr.Error("Please provide a state (plain text or JSON).") try: return json.loads(text) except json.JSONDecodeError: return text def _parse_questions(questions: str) -> dict: try: parsed = json.loads(questions or "") except json.JSONDecodeError as error: raise gr.Error(f"Questions must be valid JSON: {error}") if not isinstance(parsed, dict) or not parsed: raise gr.Error("Questions must be a non-empty JSON object keyed by question ID.") for question_id, question in parsed.items(): if not isinstance(question, dict) or question.get("type") not in QUESTION_TYPES: raise gr.Error(f"{question_id}: type must be one of noul, choice, score.") if question["type"] == "choice" and not isinstance(question.get("criteria"), dict): raise gr.Error(f"{question_id}: choice criteria must be an object of option -> description.") if question["type"] == "score" and not isinstance(question.get("criteria"), list): raise gr.Error(f"{question_id}: score criteria must be a list of level descriptions.") if question["type"] != "noul" and not question.get("criteria"): raise gr.Error(f"{question_id}: criteria must not be empty.") return parsed def _prep_image(image: Image.Image) -> Image.Image: image = image.convert("RGB") scale = MAX_IMAGE_SIDE / max(image.size) if scale < 1: image = image.resize((round(image.width * scale), round(image.height * scale)), Image.LANCZOS) return image def _render(questions: dict, probs: dict, latency_ms: float, n_tokens: int) -> str: cards = [] for question_id, question in questions.items(): p = probs[question_id] if question["type"] == "noul": options = [("true", "true", p["true"]), ("false", "false", p["false"])] elif question["type"] == "choice": options = [(k, f"{k} — {v}" if v else k, p[str(k)]) for k, v in question["criteria"].items()] else: options = [(str(i), f"{i} — {v}", p[str(i)]) for i, v in enumerate(question["criteria"])] best = max(options, key=lambda o: o[2])[0] rows = [] for key, label, value in options: highlight = "clef-best" if key == best else "" rows.append( f'