ArtShumov commited on
Commit
6566666
·
1 Parent(s): 17a1e39

fix(tagger): Moondream2 NL captions, tagger_mode names parity, remove Git LFS weights from cache

Browse files
Files changed (3) hide show
  1. app.py +45 -4
  2. data/session_history.json.bak +26 -26
  3. src/i18n.py +4 -5
app.py CHANGED
@@ -455,13 +455,39 @@ def on_artist_style_recommendations(style: str, lang: str):
455
  def _build_tagger_html(result: dict, lc: str) -> str:
456
  lines = []
457
  lines.append("<div class='whyx-tagger-panel'>")
458
- lines.append(f"<div class='whyx-tagger-panel-title'>{t('tagger_ratings', lc)}</div>")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  rating_colors = {"general": "#34D399", "sensitive": "#FBBF24", "questionable": "#F97316", "explicit": "#EF4444"}
460
  for name, score in result["ratings"].items():
461
  color = rating_colors.get(name, "var(--text-dim)")
462
  pct = int(score * 100)
463
  bar = "▰" * (pct // 10) + "▱" * (10 - pct // 10)
464
  lines.append(f"<div class='whyx-tagger-rating-row'><span class='whyx-tagger-rating-name' style='color:{color};'>{name}</span> <span class='whyx-tagger-rating-bar' style='color:{color};'>{bar}</span> <span class='whyx-tagger-rating-pct'>({score:.1%})</span></div>")
 
465
  if result["characters"]:
466
  lines.append(f"<div class='whyx-tagger-panel-title' style='margin-top:10px;'>{t('tagger_characters', lc)}</div>")
467
  lines.append("<div class='whyx-tagger-badges'>")
@@ -531,15 +557,30 @@ def on_tag_image(image, gen_threshold, char_threshold, fmt, lang, progress=gr.Pr
531
  html_out = _build_tagger_html(result, lc)
532
  general_names = list(result["general"].keys())[:60]
533
  char_names = list(result["characters"].keys())
534
- general_choices = [(n.replace("_", " "), n) for n in general_names]
 
 
 
 
 
 
 
 
 
 
535
  char_choices = [(n.replace("_", " "), n) for n in char_names]
 
536
  raw_caption = result["caption"]
 
 
 
537
  esc_taglist = result["taglist"]
538
  tags_box = esc_taglist if fmt == "prompt" else raw_caption
 
539
  return (
540
  gr.update(value=html_out),
541
  gr.update(visible=True),
542
- gr.update(choices=general_choices, value=general_names, visible=True),
543
  gr.update(choices=char_choices, value=char_names, visible=True),
544
  gr.update(value=tags_box, visible=True),
545
  gr.update(visible=True),
@@ -1605,7 +1646,7 @@ with gr.Blocks(**_blocks_kw) as demo:
1605
  (t("tagger_mode_eva", "en"), "wd:eva02"),
1606
  (t("tagger_mode_swinv2", "en"), "wd:swinv2"),
1607
  (t("tagger_mode_vit", "en"), "wd:vit"),
1608
- (t("tagger_mode_qwen_caption", "en"), "qwen"),
1609
  ],
1610
  value="ensemble",
1611
  label="",
 
455
  def _build_tagger_html(result: dict, lc: str) -> str:
456
  lines = []
457
  lines.append("<div class='whyx-tagger-panel'>")
458
+
459
+ # ---- Natural-language caption (Moondream) --------------------------------
460
+ nl_caption = (result.get("nl_caption") or "").strip()
461
+ if nl_caption:
462
+ lines.append(
463
+ f"<div class='whyx-tagger-panel-title'>🗣️ {t('tagger_nl_caption', lc)}</div>"
464
+ f"<div class='whyx-tagger-nl-caption'>{html.escape(nl_caption)}</div>"
465
+ )
466
+
467
+ # ---- Pose summary ---------------------------------------------------------
468
+ pose_tags = result.get("pose_tags") or []
469
+ people = int(result.get("people_count") or 0)
470
+ if pose_tags or people:
471
+ pose_label = t("tagger_pose_single" if people == 1 else "tagger_pose_many", lc).format(n=people)
472
+ lines.append(f"<div class='whyx-tagger-panel-title' style='margin-top:10px;'>🧍 {t('tagger_pose_label', lc)}</div>")
473
+ if people:
474
+ lines.append(f"<div class='whyx-tagger-pose-people'>{html.escape(pose_label)}</div>")
475
+ if pose_tags:
476
+ lines.append(
477
+ "<div class='whyx-tagger-pose-tags'>"
478
+ + ", ".join(html.escape(p) for p in pose_tags)
479
+ + "</div>"
480
+ )
481
+
482
+ # ---- Rating distribution ---------------------------------------------------
483
+ lines.append(f"<div class='whyx-tagger-panel-title' style='margin-top:10px;'>{t('tagger_ratings', lc)}</div>")
484
  rating_colors = {"general": "#34D399", "sensitive": "#FBBF24", "questionable": "#F97316", "explicit": "#EF4444"}
485
  for name, score in result["ratings"].items():
486
  color = rating_colors.get(name, "var(--text-dim)")
487
  pct = int(score * 100)
488
  bar = "▰" * (pct // 10) + "▱" * (10 - pct // 10)
489
  lines.append(f"<div class='whyx-tagger-rating-row'><span class='whyx-tagger-rating-name' style='color:{color};'>{name}</span> <span class='whyx-tagger-rating-bar' style='color:{color};'>{bar}</span> <span class='whyx-tagger-rating-pct'>({score:.1%})</span></div>")
490
+
491
  if result["characters"]:
492
  lines.append(f"<div class='whyx-tagger-panel-title' style='margin-top:10px;'>{t('tagger_characters', lc)}</div>")
493
  lines.append("<div class='whyx-tagger-badges'>")
 
557
  html_out = _build_tagger_html(result, lc)
558
  general_names = list(result["general"].keys())[:60]
559
  char_names = list(result["characters"].keys())
560
+
561
+ # Merge NL caption + pose tags into the tag chips so they can be
562
+ # picked up by the same apply/copy pipeline as booru tags.
563
+ extra_names: list[str] = []
564
+ if result.get("nl_caption"):
565
+ extra_names.append(result["nl_caption"].strip())
566
+ pose_tags = result.get("pose_tags") or []
567
+ extra_names.extend(pose_tags)
568
+
569
+ all_names = extra_names + general_names
570
+ general_choices = [(n, n) for n in all_names]
571
  char_choices = [(n.replace("_", " "), n) for n in char_names]
572
+
573
  raw_caption = result["caption"]
574
+ # Pose tags are folded into the caption list so the chips match the summary.
575
+ if pose_tags:
576
+ raw_caption = ", ".join([*pose_tags, raw_caption]) if raw_caption else ", ".join(pose_tags)
577
  esc_taglist = result["taglist"]
578
  tags_box = esc_taglist if fmt == "prompt" else raw_caption
579
+
580
  return (
581
  gr.update(value=html_out),
582
  gr.update(visible=True),
583
+ gr.update(choices=general_choices, value=all_names, visible=True),
584
  gr.update(choices=char_choices, value=char_names, visible=True),
585
  gr.update(value=tags_box, visible=True),
586
  gr.update(visible=True),
 
1646
  (t("tagger_mode_eva", "en"), "wd:eva02"),
1647
  (t("tagger_mode_swinv2", "en"), "wd:swinv2"),
1648
  (t("tagger_mode_vit", "en"), "wd:vit"),
1649
+ (t("tagger_mode_moondream_caption", "en"), "qwen"),
1650
  ],
1651
  value="ensemble",
1652
  label="",
data/session_history.json.bak CHANGED
@@ -1,4 +1,30 @@
1
  [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  {
3
  "id": "2dad208c",
4
  "timestamp": 1785821643.762218,
@@ -1272,31 +1298,5 @@
1272
  "categories": [],
1273
  "seed": null,
1274
  "liked_indices": []
1275
- },
1276
- {
1277
- "id": "6f987ee2",
1278
- "timestamp": 1784831437.9085064,
1279
- "prompt": "1girl, blue hair",
1280
- "model": "anima",
1281
- "rating": "pg",
1282
- "num_variations": 2,
1283
- "creativity": "medium",
1284
- "weight_mode": "off",
1285
- "results": [
1286
- "masterpiece, best quality, score_9, safe, 1girl, BREAK, instagram filter, high contrast, blue hair, frilled dress, high heels, detailed background, wizard tower, phoenix, shield, sword, global illumination, gothic lighting, silver aesthetic, cosmic dust, floating, foreground framing, radial composition, first person view, looking at viewer, epic composition, surprised pose, from side, intricate details, beautiful detailed",
1287
- "masterpiece, best quality, score_9, safe, 1girl, BREAK, affectionate gaze, blue hair, crying, hoodie, detailed background, bullet train, motorcycle, skyscraper, dragon, global illumination, moonlight beam, holographic display, silver aesthetic, lightning aura, layered composition, surprised pose, looking away, incredibly absurdres, intricate details, magazine quality",
1288
- "",
1289
- "",
1290
- "",
1291
- "",
1292
- "",
1293
- "",
1294
- "",
1295
- ""
1296
- ],
1297
- "neg_results": [],
1298
- "categories": [],
1299
- "seed": null,
1300
- "liked_indices": []
1301
  }
1302
  ]
 
1
  [
2
+ {
3
+ "id": "b5e660fd",
4
+ "timestamp": 1785823213.9892197,
5
+ "prompt": "1girl, blue hair",
6
+ "model": "anima",
7
+ "rating": "pg",
8
+ "num_variations": 2,
9
+ "creativity": "medium",
10
+ "weight_mode": "off",
11
+ "results": [
12
+ "masterpiece, best quality, score_7, safe, 1girl, BREAK, blue hair, feather wings, pastel colors, angel wings, surprised pose, cute pose, cinematic composition, circular composition, retro futuristic, rainbow, subsurface scattering, reflected moonlight, mysterious lighting, cloudy lighting, dreamy haze, glitch effect, beautiful detailed, beautiful detail",
13
+ "masterpiece, best quality, score_7, safe, 1girl, BREAK, blue hair, happy, gentle smile, from above, saturated matte, high contrast, vibrant, demon wings, profile view, detailed background, clock tower, mist, bioluminescent sea, underlit horror, moon light, silver aesthetic, blue tint, intricate details, beautiful detailed, beautiful detail",
14
+ "",
15
+ "",
16
+ "",
17
+ "",
18
+ "",
19
+ "",
20
+ "",
21
+ ""
22
+ ],
23
+ "neg_results": [],
24
+ "categories": [],
25
+ "seed": null,
26
+ "liked_indices": []
27
+ },
28
  {
29
  "id": "2dad208c",
30
  "timestamp": 1785821643.762218,
 
1298
  "categories": [],
1299
  "seed": null,
1300
  "liked_indices": []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1301
  }
1302
  ]
src/i18n.py CHANGED
@@ -329,14 +329,13 @@ L10N = {
329
  "tagger_mode_eva": "WD14 EVA02",
330
  "tagger_mode_swinv2": "WD14 SwinV2",
331
  # --- tagger / ensemble ---
332
- # --- tagger / ensemble ---
333
  "tagger_mode_vit": "WD14 ViT",
334
- "tagger_mode_qwen": "Qwen3-VL (NL caption)",
335
- "tagger_mode_qwen_desc": "Qwen3-VL (Natural-language caption)",
336
  "tagger_pose_label": "Pose",
337
  "tagger_pose_single": "{n} person detected",
338
  "tagger_pose_many": "{n} people detected",
339
  "tagger_caption_label": "Natural-language caption",
 
340
  "tagger_chips_label": "Detected tags (click to toggle)",
341
  "tagger_chars_label": "Detected characters",
342
  "tagger_tags_label": "Tags to use",
@@ -700,8 +699,8 @@ L10N = {
700
  "tagger_mode_eva": "WD14 EVA02",
701
  "tagger_mode_swinv2": "WD14 SwinV2",
702
  "tagger_mode_vit": "WD14 ViT",
703
- "tagger_mode_qwen": "Qwen3-VL (NL описание)",
704
- "tagger_mode_qwen_desc": "Qwen3-VL (Подробное описание изображения)",
705
  "tagger_pose_label": "Поза",
706
  "tagger_pose_single": "Обнаружен {n} человек",
707
  "tagger_pose_many": "Обнаружено {n} человек",
 
329
  "tagger_mode_eva": "WD14 EVA02",
330
  "tagger_mode_swinv2": "WD14 SwinV2",
331
  # --- tagger / ensemble ---
 
332
  "tagger_mode_vit": "WD14 ViT",
333
+ "tagger_mode_moondream_caption": "Moondream2 (detailed NL caption)",
 
334
  "tagger_pose_label": "Pose",
335
  "tagger_pose_single": "{n} person detected",
336
  "tagger_pose_many": "{n} people detected",
337
  "tagger_caption_label": "Natural-language caption",
338
+ "tagger_nl_caption": "🗣️ Natural-language caption",
339
  "tagger_chips_label": "Detected tags (click to toggle)",
340
  "tagger_chars_label": "Detected characters",
341
  "tagger_tags_label": "Tags to use",
 
699
  "tagger_mode_eva": "WD14 EVA02",
700
  "tagger_mode_swinv2": "WD14 SwinV2",
701
  "tagger_mode_vit": "WD14 ViT",
702
+ "tagger_mode_moondream_caption": "Moondream2 (подробное описание)",
703
+ "tagger_nl_caption": "🗣️ Описание сцены",
704
  "tagger_pose_label": "Поза",
705
  "tagger_pose_single": "Обнаружен {n} человек",
706
  "tagger_pose_many": "Обнаружено {n} человек",