Spaces:
Running on Zero
Running on Zero
File size: 3,166 Bytes
6e15691 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 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 != ""
)
@spaces.GPU(duration=30)
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() |