Spaces:
Running on Zero
Running on Zero
| from typing import Any | |
| import gradio as gr | |
| import spaces | |
| from sentence_transformers import CrossEncoder | |
| MODEL_ID = "ramitha2002/genieai-product-reranker" | |
| # ZeroGPU requires CUDA placement at module level. | |
| model = CrossEncoder( | |
| MODEL_ID, | |
| device="cuda", | |
| max_length=384, | |
| ) | |
| def format_value(value: Any) -> str: | |
| if isinstance(value, list): | |
| return ", ".join(str(item) for item in value) | |
| return str(value) | |
| def build_product_text(product: dict[str, Any]) -> str: | |
| fields = [ | |
| ("Title", product.get("title") or product.get("name")), | |
| ("Description", product.get("description") or product.get("summary")), | |
| ("Features", product.get("features")), | |
| ("Brand", product.get("brand")), | |
| ("Color", product.get("color")), | |
| ("Category", product.get("category")), | |
| ] | |
| return "\n".join( | |
| f"{label}: {format_value(value)}" | |
| for label, value in fields | |
| if value is not None and value != "" | |
| ) | |
| def rerank( | |
| query: str, | |
| products: list[dict[str, Any]], | |
| top_n: int, | |
| ) -> dict[str, Any]: | |
| query = query.strip() | |
| if not query: | |
| raise gr.Error("Query is required.") | |
| if not isinstance(products, list) or not products: | |
| raise gr.Error("Products must be a non-empty JSON array.") | |
| if len(products) > 30: | |
| raise gr.Error("Maximum 30 products per request.") | |
| pairs = [ | |
| (query, build_product_text(product)) | |
| for product in products | |
| ] | |
| scores = model.predict( | |
| pairs, | |
| batch_size=min(16, len(pairs)), | |
| show_progress_bar=False, | |
| ) | |
| ranked = sorted( | |
| [ | |
| { | |
| **product, | |
| "rerankerScore": float(score), | |
| } | |
| for product, score in zip(products, scores) | |
| ], | |
| key=lambda product: product["rerankerScore"], | |
| reverse=True, | |
| ) | |
| return { | |
| "results": ranked[:max(1, min(int(top_n), len(ranked)))] | |
| } | |
| sample_products = [ | |
| { | |
| "id": "flowers-1", | |
| "name": "Pink Rose Bouquet", | |
| "description": "Fresh roses arranged for birthdays", | |
| "brand": "Bloom House", | |
| "color": "Pink" | |
| }, | |
| { | |
| "id": "mouse-1", | |
| "name": "Wireless Gaming Mouse", | |
| "description": "RGB computer mouse", | |
| "brand": "GamePoint", | |
| "color": "Black" | |
| } | |
| ] | |
| with gr.Blocks(title="GenieAI Product Reranker") as demo: | |
| gr.Markdown("# GenieAI Product Reranker") | |
| query_input = gr.Textbox( | |
| label="Search query", | |
| value="birthday flowers for mother", | |
| ) | |
| products_input = gr.JSON( | |
| label="Products", | |
| value=sample_products, | |
| ) | |
| top_n_input = gr.Slider( | |
| minimum=1, | |
| maximum=30, | |
| value=4, | |
| step=1, | |
| label="Number of results", | |
| ) | |
| rerank_button = gr.Button("Rerank", variant="primary") | |
| output = gr.JSON(label="Ranked products") | |
| rerank_button.click( | |
| fn=rerank, | |
| inputs=[query_input, products_input, top_n_input], | |
| outputs=output, | |
| api_name="rerank", | |
| ) | |
| demo.queue(default_concurrency_limit=2).launch() |