nielsr HF Staff commited on
Commit
8085243
·
verified ·
1 Parent(s): 0ebd454

Center app and add Qwen-branded visual examples

Browse files
Files changed (3) hide show
  1. README.md +1 -0
  2. app.py +71 -16
  3. assets/qwen-logo.svg +15 -0
README.md CHANGED
@@ -38,5 +38,6 @@ The app limits request concurrency, image size, queue depth, and per-session req
38
 
39
  - [Qwen 3.8 announcement](https://qwen.ai/blog?id=qwen3.8)
40
  - [OpenAI-compatible vision input format](https://developers.openai.com/api/docs/guides/images-vision#analyze-images)
 
41
 
42
  Qwen and DashScope are trademarks or services of their respective owners. This Space is not an official Qwen or Alibaba product.
 
38
 
39
  - [Qwen 3.8 announcement](https://qwen.ai/blog?id=qwen3.8)
40
  - [OpenAI-compatible vision input format](https://developers.openai.com/api/docs/guides/images-vision#analyze-images)
41
+ - [Qwen logo asset](https://logos-download.com/brands/qwen)
42
 
43
  Qwen and DashScope are trademarks or services of their respective owners. This Space is not an official Qwen or Alibaba product.
app.py CHANGED
@@ -22,6 +22,27 @@ MAX_IMAGES = 3
22
  MAX_IMAGE_BYTES = 15 * 1024 * 1024
23
  RATE_LIMIT_REQUESTS = 5
24
  RATE_LIMIT_WINDOW_SECONDS = 5 * 60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
  _requests_by_session: dict[str, deque[float]] = defaultdict(deque)
27
  _rate_limit_lock = Lock()
@@ -202,6 +223,11 @@ def clear_chat() -> tuple[list[Any], list[Any], dict[str, Any]]:
202
  return [], [], {"text": "", "files": []}
203
 
204
 
 
 
 
 
 
205
  def _draw_prompt_boxes(
206
  original_path: str,
207
  boxes: list[dict[str, Any]] | None,
@@ -408,13 +434,27 @@ For reference, the prompt boxes in normalized XYXY coordinates are: {_normalized
408
 
409
 
410
  CSS = """
411
- .gradio-container { max-width: 1080px !important; }
 
 
 
 
 
412
  #hero { text-align: center; margin: 0 auto 0.75rem; }
413
- #hero h1 { font-size: clamp(2rem, 5vw, 3.8rem); margin-bottom: 0.25rem; }
 
 
414
  #hero p { color: var(--body-text-color-subdued); font-size: 1.05rem; }
415
  #notice { border-left: 4px solid var(--color-accent); padding-left: 1rem; }
416
  #chat-shell { max-width: 840px; margin: 0 auto; width: 100%; }
417
  #box-shell { max-width: 960px; margin: 0 auto; width: 100%; }
 
 
 
 
 
 
 
418
  """
419
 
420
 
@@ -424,11 +464,13 @@ with gr.Blocks(title="Free Qwen 3.8 Max") as demo:
424
  box_annotations = gr.State([])
425
  pending_corner = gr.State(None)
426
 
427
- gr.Markdown(
428
- """
429
- # Free Qwen 3.8 Max 👀
430
-
431
- **100 million promotional tokens, shared with the community.** Ask anything or attach up to three images to test Qwen's visual understanding.
 
 
432
  """,
433
  elem_id="hero",
434
  )
@@ -458,15 +500,22 @@ with gr.Blocks(title="Free Qwen 3.8 Max") as demo:
458
  max_plain_text_length=8_000,
459
  )
460
 
461
- gr.Examples(
462
- examples=[
463
- [{"text": "Count each kind of shape. Explain how you avoided double-counting, then return a compact JSON summary.", "files": ["examples/crowded_shapes.png"]}],
464
- [{"text": "Read this receipt, independently recompute the subtotal and total, and flag any inconsistency.", "files": ["examples/mini_receipt.png"]}],
465
- [{"text": "Solve the visual logic puzzle. State the rule you infer and identify the missing tile.", "files": ["examples/logic_grid.png"]}],
466
- ],
467
- inputs=message,
468
- label="Try a visual challenge",
469
- example_labels=["Count crowded objects", "Audit a receipt", "Solve a visual pattern"],
 
 
 
 
 
 
 
470
  )
471
 
472
  with gr.Accordion("Generation settings", open=False):
@@ -547,6 +596,12 @@ with gr.Blocks(title="Free Qwen 3.8 Max") as demo:
547
  queue=False,
548
  api_name=False,
549
  )
 
 
 
 
 
 
550
  box_image.upload(
551
  load_box_image,
552
  inputs=box_image,
 
22
  MAX_IMAGE_BYTES = 15 * 1024 * 1024
23
  RATE_LIMIT_REQUESTS = 5
24
  RATE_LIMIT_WINDOW_SECONDS = 5 * 60
25
+ QWEN_LOGO_DATA_URL = "data:image/svg+xml;base64," + base64.b64encode(
26
+ (Path(__file__).parent / "assets" / "qwen-logo.svg").read_bytes()
27
+ ).decode("ascii")
28
+ EXAMPLES_DIR = Path(__file__).parent / "examples"
29
+ VISUAL_EXAMPLES = [
30
+ {
31
+ "title": "Count crowded objects",
32
+ "image": str(EXAMPLES_DIR / "crowded_shapes.png"),
33
+ "prompt": "Count each kind of shape. Explain how you avoided double-counting, then return a compact JSON summary.",
34
+ },
35
+ {
36
+ "title": "Audit a receipt",
37
+ "image": str(EXAMPLES_DIR / "mini_receipt.png"),
38
+ "prompt": "Read this receipt, independently recompute the subtotal and total, and flag any inconsistency.",
39
+ },
40
+ {
41
+ "title": "Solve a visual pattern",
42
+ "image": str(EXAMPLES_DIR / "logic_grid.png"),
43
+ "prompt": "Solve the visual logic puzzle. State the rule you infer and identify the missing tile.",
44
+ },
45
+ ]
46
 
47
  _requests_by_session: dict[str, deque[float]] = defaultdict(deque)
48
  _rate_limit_lock = Lock()
 
223
  return [], [], {"text": "", "files": []}
224
 
225
 
226
+ def load_visual_example(event: gr.SelectData) -> dict[str, Any]:
227
+ example = VISUAL_EXAMPLES[int(event.index)]
228
+ return {"text": example["prompt"], "files": [example["image"]]}
229
+
230
+
231
  def _draw_prompt_boxes(
232
  original_path: str,
233
  boxes: list[dict[str, Any]] | None,
 
434
 
435
 
436
  CSS = """
437
+ .gradio-container {
438
+ width: min(1080px, calc(100% - 32px)) !important;
439
+ max-width: 1080px !important;
440
+ margin-left: auto !important;
441
+ margin-right: auto !important;
442
+ }
443
  #hero { text-align: center; margin: 0 auto 0.75rem; }
444
+ #hero .hero-lockup { display: flex; align-items: center; justify-content: center; gap: 0.85rem; }
445
+ #hero img { width: clamp(54px, 8vw, 78px); height: auto; flex: 0 0 auto; }
446
+ #hero h1 { font-size: clamp(2rem, 5vw, 3.8rem); margin: 0; line-height: 1.05; }
447
  #hero p { color: var(--body-text-color-subdued); font-size: 1.05rem; }
448
  #notice { border-left: 4px solid var(--color-accent); padding-left: 1rem; }
449
  #chat-shell { max-width: 840px; margin: 0 auto; width: 100%; }
450
  #box-shell { max-width: 960px; margin: 0 auto; width: 100%; }
451
+ #examples-gallery { margin-top: 0.35rem; }
452
+ #example-prompts { color: var(--body-text-color-subdued); font-size: 0.92rem; }
453
+ @media (max-width: 560px) {
454
+ .gradio-container { width: calc(100% - 16px) !important; }
455
+ #hero .hero-lockup { gap: 0.4rem; }
456
+ #hero img { width: 48px; }
457
+ }
458
  """
459
 
460
 
 
464
  box_annotations = gr.State([])
465
  pending_corner = gr.State(None)
466
 
467
+ gr.HTML(
468
+ f"""
469
+ <div class="hero-lockup">
470
+ <img src="{QWEN_LOGO_DATA_URL}" alt="Qwen logo">
471
+ <h1>Free Qwen 3.8 Max</h1>
472
+ </div>
473
+ <p><strong>100 million promotional tokens, shared with the community.</strong> Ask anything or attach up to three images to test Qwen's visual understanding.</p>
474
  """,
475
  elem_id="hero",
476
  )
 
500
  max_plain_text_length=8_000,
501
  )
502
 
503
+ example_gallery = gr.Gallery(
504
+ value=[(example["image"], example["title"]) for example in VISUAL_EXAMPLES],
505
+ label="Try a visual challenge click a sample to load it",
506
+ columns=3,
507
+ rows=1,
508
+ height=255,
509
+ object_fit="contain",
510
+ allow_preview=False,
511
+ buttons=[],
512
+ elem_id="examples-gallery",
513
+ )
514
+ gr.Markdown(
515
+ """
516
+ **Sample prompts:** Count every shape without double-counting · Recompute the receipt total and flag errors · Infer the visual rule and solve the missing tile
517
+ """,
518
+ elem_id="example-prompts",
519
  )
520
 
521
  with gr.Accordion("Generation settings", open=False):
 
596
  queue=False,
597
  api_name=False,
598
  )
599
+ example_gallery.select(
600
+ load_visual_example,
601
+ outputs=message,
602
+ queue=False,
603
+ api_name=False,
604
+ )
605
  box_image.upload(
606
  load_box_image,
607
  inputs=box_image,
assets/qwen-logo.svg ADDED