yousefabdelsalam's picture
Qwen3-VL-Embedding-2B server on ZeroGPU
38db1cd verified
|
Raw
History Blame Contribute Delete
1.93 kB

A newer version of the Gradio SDK is available: 6.26.0

Upgrade
metadata
title: VisualOps Qwen3-VL Embeddings
emoji: πŸ”
colorFrom: blue
colorTo: indigo
sdk: gradio
app_file: app.py
pinned: false
short_description: Qwen3-VL-Embedding-2B embeddings over a REST API

VisualOps Embedding Server (ZeroGPU)

Hosts Qwen/Qwen3-VL-Embedding-2B and serves the VisualOps embedding contract. It replaces the Modal deployment; app/embed_client.py needs no change, only a new EMBEDDING_SERVER_URL.

Contract

Method Path Body Returns
GET /health – status, model, backend, device, dtype, dimension, uptime
POST /embed {images: [b64], batch_size, dimension?} {embeddings, dimension, count, model, normalized, elapsed_ms}
POST /embed_text {texts: [str], is_query, batch_size, dimension?} same

Images are embedded directly β€” there is no captioning step. Text and images land in the same Qwen vector space, which is what makes cross-modal retrieval work.

Setup

  1. Create the Space with SDK = Gradio (ZeroGPU is compatible with the Gradio SDK only).
  2. In Settings β†’ Hardware, select ZeroGPU. Hosting requires a personal account in good standing (verified email, older than 30 days, max 2 Spaces) or PRO.
  3. Optional: set the Space secret EMBEDDING_SERVER_TOKEN to require Authorization: Bearer <token>. Leave unset to run open.

Notes

  • The model is placed on cuda at import, not inside the GPU function β€” ZeroGPU's documented rule, and far faster than transferring per call.
  • Only the forward pass is wrapped in @spaces.GPU; decoding and serialisation stay outside it, because daily quota is consumed by GPU-held time.
  • Startup fails loudly if the model does not report 2048 dimensions, since the FAISS manifest pins that width.
  • Daily GPU quota: 5 min (free), 40 min (PRO). A full index rebuild plus the 25-query evaluation must fit inside it.