multimodalart HF Staff commited on
Commit
d18d66f
·
verified ·
1 Parent(s): f2873a1

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +46 -13
app.py CHANGED
@@ -13,6 +13,8 @@ Three tokens, three jobs:
13
 
14
  from __future__ import annotations
15
 
 
 
16
  import gradio as gr
17
 
18
  import caption
@@ -20,6 +22,7 @@ import jobs
20
 
21
  MAX_IMAGES = 40
22
  MAX_LOG = 60_000
 
23
 
24
  LR_SCHEDULERS = ["constant", "cosine", "linear", "constant_with_warmup", "polynomial"]
25
  OPTIMIZERS = ["adamW", "prodigy"]
@@ -91,12 +94,34 @@ CAPTION_TIP = (
91
  "trigger token.\n"
92
  "- <b>✨ Auto-caption</b> fills these for you; edit anything you like. Blank captions fall "
93
  "back to the trigger.\n"
 
 
94
  "</details>"
95
  )
96
 
97
 
98
- def _paths(images) -> list[str]:
99
- return [p if isinstance(p, str) else getattr(p, "name", p) for p in (images or [])]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
 
102
  def _signin_state(profile: gr.OAuthProfile | None):
@@ -120,38 +145,46 @@ def on_concept_change(concept: str):
120
  )
121
 
122
 
123
- def load_captioning(images, trigger):
124
- """Reveal the captioning + training UI once images are uploaded; one row per image."""
125
- paths = _paths(images)
 
 
 
126
  n = len(paths)
127
  if n > MAX_IMAGES:
128
  raise gr.Error(f"For now, up to {MAX_IMAGES} images are supported (got {n}).")
129
  updates = [gr.update(visible=n > 0), gr.update(visible=n > 0)] # captioning_area, post_upload
130
  for i in range(MAX_IMAGES):
131
  visible = i < n
 
 
 
 
 
132
  updates.append(gr.update(visible=visible)) # row
133
  updates.append(gr.update(value=paths[i] if visible else None, visible=visible)) # image
134
- updates.append(gr.update(value=(trigger or "") if visible else None, visible=visible)) # cap
135
  return updates
136
 
137
 
138
- def ai_suggest_trigger(images, concept_type):
139
- paths = _paths(images)
140
  if not paths:
141
  raise gr.Error("Upload images first.")
142
  return caption.suggest_trigger(paths, concept_type)
143
 
144
 
145
- def ai_caption_all(images, concept_type, trigger):
146
- paths = _paths(images)
147
  if not paths:
148
  raise gr.Error("Upload images first.")
149
  caps = [caption.caption_one(p, concept_type, trigger) for p in paths]
150
  return [gr.update(value=caps[i]) if i < len(caps) else gr.update() for i in range(MAX_IMAGES)]
151
 
152
 
153
- def gather_dataset(images, *captions):
154
- paths = _paths(images)
155
  return [[img, (captions[i] if i < len(captions) else "")] for i, img in enumerate(paths)]
156
 
157
 
@@ -240,7 +273,7 @@ with gr.Blocks(title="Krea 2 LoRA Trainer") as demo:
240
  with gr.Row():
241
  images = gr.File(
242
  label="Upload your images (4–30 ideal)", file_count="multiple",
243
- file_types=["image"], interactive=True, scale=1,
244
  )
245
  with gr.Column(scale=3, visible=False) as captioning_area:
246
  gr.Markdown("## Trigger & captioning")
 
13
 
14
  from __future__ import annotations
15
 
16
+ import os
17
+
18
  import gradio as gr
19
 
20
  import caption
 
22
 
23
  MAX_IMAGES = 40
24
  MAX_LOG = 60_000
25
+ IMAGE_EXTS = (".png", ".jpg", ".jpeg", ".webp", ".bmp", ".gif", ".tiff", ".tif")
26
 
27
  LR_SCHEDULERS = ["constant", "cosine", "linear", "constant_with_warmup", "polynomial"]
28
  OPTIMIZERS = ["adamW", "prodigy"]
 
94
  "trigger token.\n"
95
  "- <b>✨ Auto-caption</b> fills these for you; edit anything you like. Blank captions fall "
96
  "back to the trigger.\n"
97
+ "- Already have captions? Upload a <code>.txt</code> next to each image with the same name "
98
+ "(e.g. <code>cat.jpg</code> + <code>cat.txt</code>) and they're filled in automatically.\n"
99
  "</details>"
100
  )
101
 
102
 
103
+ def _paths(files) -> list[str]:
104
+ return [p if isinstance(p, str) else getattr(p, "name", p) for p in (files or [])]
105
+
106
+
107
+ def _split_uploads(files):
108
+ """Split a mixed upload into image paths and a {basename: caption} map from .txt sidecars.
109
+
110
+ A .txt file whose name matches an image (e.g. cat.jpg + cat.txt) prefills that caption.
111
+ """
112
+ images, captions = [], {}
113
+ for p in _paths(files):
114
+ ext = os.path.splitext(p)[1].lower()
115
+ base = os.path.splitext(os.path.basename(p))[0]
116
+ if ext == ".txt":
117
+ try:
118
+ with open(p, encoding="utf-8") as f:
119
+ captions[base] = f.read().strip()
120
+ except Exception: # noqa: BLE001
121
+ pass
122
+ elif ext in IMAGE_EXTS:
123
+ images.append(p)
124
+ return images, captions
125
 
126
 
127
  def _signin_state(profile: gr.OAuthProfile | None):
 
145
  )
146
 
147
 
148
+ def load_captioning(files, trigger):
149
+ """Reveal the captioning + training UI once images are uploaded; one row per image.
150
+
151
+ If a matching `<name>.txt` sidecar was uploaded, its content prefills that image's caption.
152
+ """
153
+ paths, txt_caps = _split_uploads(files)
154
  n = len(paths)
155
  if n > MAX_IMAGES:
156
  raise gr.Error(f"For now, up to {MAX_IMAGES} images are supported (got {n}).")
157
  updates = [gr.update(visible=n > 0), gr.update(visible=n > 0)] # captioning_area, post_upload
158
  for i in range(MAX_IMAGES):
159
  visible = i < n
160
+ if visible:
161
+ base = os.path.splitext(os.path.basename(paths[i]))[0]
162
+ cap_val = txt_caps.get(base) or (trigger or "")
163
+ else:
164
+ cap_val = None
165
  updates.append(gr.update(visible=visible)) # row
166
  updates.append(gr.update(value=paths[i] if visible else None, visible=visible)) # image
167
+ updates.append(gr.update(value=cap_val, visible=visible)) # caption
168
  return updates
169
 
170
 
171
+ def ai_suggest_trigger(files, concept_type):
172
+ paths, _ = _split_uploads(files)
173
  if not paths:
174
  raise gr.Error("Upload images first.")
175
  return caption.suggest_trigger(paths, concept_type)
176
 
177
 
178
+ def ai_caption_all(files, concept_type, trigger):
179
+ paths, _ = _split_uploads(files)
180
  if not paths:
181
  raise gr.Error("Upload images first.")
182
  caps = [caption.caption_one(p, concept_type, trigger) for p in paths]
183
  return [gr.update(value=caps[i]) if i < len(caps) else gr.update() for i in range(MAX_IMAGES)]
184
 
185
 
186
+ def gather_dataset(files, *captions):
187
+ paths, _ = _split_uploads(files)
188
  return [[img, (captions[i] if i < len(captions) else "")] for i, img in enumerate(paths)]
189
 
190
 
 
273
  with gr.Row():
274
  images = gr.File(
275
  label="Upload your images (4–30 ideal)", file_count="multiple",
276
+ file_types=["image", ".txt"], interactive=True, scale=1,
277
  )
278
  with gr.Column(scale=3, visible=False) as captioning_area:
279
  gr.Markdown("## Trigger & captioning")