SynLayers commited on
Commit
0c5b5e2
·
verified ·
1 Parent(s): 946a25b

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +170 -0
app.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ import gradio as gr
8
+
9
+ CURRENT_FILE = Path(__file__).resolve()
10
+ PROJECT_ROOT = CURRENT_FILE.parents[1]
11
+ for candidate in (CURRENT_FILE.parent, CURRENT_FILE.parents[1]):
12
+ if (candidate / "infer").exists() and (candidate / "models").exists():
13
+ PROJECT_ROOT = candidate
14
+ break
15
+ if str(PROJECT_ROOT) not in sys.path:
16
+ sys.path.insert(0, str(PROJECT_ROOT))
17
+
18
+ from demo.real_world_pipeline import ( # noqa: E402
19
+ DEFAULT_BBOX_MODEL,
20
+ DEFAULT_REAL_CONFIG_PATH,
21
+ DEFAULT_RUN_NAME,
22
+ DEFAULT_WORK_DIR,
23
+ run_real_world_pipeline,
24
+ )
25
+
26
+ DEFAULT_EXAMPLE_DIR = Path(
27
+ os.environ.get(
28
+ "SYNLAYERS_EXAMPLE_DIR",
29
+ "/project/llmsvgen/share/data/kmw_layered_dataset/real_world_inference/layers_real_test_1024",
30
+ )
31
+ )
32
+
33
+
34
+ def list_example_images(limit: int = 6) -> list[list[str]]:
35
+ if not DEFAULT_EXAMPLE_DIR.exists():
36
+ return []
37
+
38
+ candidates = []
39
+ for ext in ("*.png", "*.jpg", "*.jpeg", "*.webp"):
40
+ candidates.extend(DEFAULT_EXAMPLE_DIR.glob(ext))
41
+ candidates = sorted(candidates)[:limit]
42
+ return [[str(path)] for path in candidates]
43
+
44
+
45
+ def build_gallery(result: dict) -> list[tuple[str, str]]:
46
+ gallery: list[tuple[str, str]] = []
47
+ if result.get("whole_image_rgba"):
48
+ gallery.append((result["whole_image_rgba"], "Whole RGBA"))
49
+ if result.get("background_rgba"):
50
+ gallery.append((result["background_rgba"], "Background RGBA"))
51
+ for idx, path in enumerate(result.get("layer_images", [])):
52
+ gallery.append((path, f"Layer {idx}"))
53
+ return gallery
54
+
55
+
56
+ def run_demo(
57
+ image_path: str,
58
+ sample_name: str,
59
+ max_new_tokens: int,
60
+ seed_value: float,
61
+ ):
62
+ if not image_path:
63
+ raise gr.Error("Please upload an input image first.")
64
+
65
+ seed = int(seed_value) if seed_value >= 0 else None
66
+
67
+ try:
68
+ result = run_real_world_pipeline(
69
+ image_path=image_path,
70
+ sample_name=sample_name or None,
71
+ work_dir=DEFAULT_WORK_DIR,
72
+ bbox_model=DEFAULT_BBOX_MODEL,
73
+ config_path=DEFAULT_REAL_CONFIG_PATH,
74
+ max_new_tokens=int(max_new_tokens),
75
+ seed=seed,
76
+ run_name=DEFAULT_RUN_NAME,
77
+ )
78
+ except Exception as exc:
79
+ raise gr.Error(str(exc)) from exc
80
+
81
+ return (
82
+ result["bbox_visualization"],
83
+ result["merged_image"],
84
+ result["bbox_record"].get("whole_caption", ""),
85
+ result["bbox_record"],
86
+ result["metadata"],
87
+ build_gallery(result),
88
+ result["archive_path"],
89
+ result["case_dir"],
90
+ )
91
+
92
+
93
+ with gr.Blocks(title="SynLayers Real-World Demo") as demo:
94
+ gr.Markdown(
95
+ """
96
+ # SynLayers Real-World Decomposition
97
+
98
+ Upload a single image and run the full pipeline in one step:
99
+ 1. fixed-prompt VLM whole-caption + bounding-box detection
100
+ 2. SynLayers real-image layer decomposition with the `step_120000` checkpoint
101
+
102
+ The app uses `demo/infer` for the VLM stage and `infer/infer.py` + `infer/infer.yaml`
103
+ for the decomposition stage.
104
+ """
105
+ )
106
+
107
+ with gr.Row():
108
+ with gr.Column(scale=1):
109
+ image_input = gr.Image(type="filepath", label="Input Image")
110
+ sample_name_input = gr.Textbox(
111
+ label="Optional Sample Name",
112
+ placeholder="Leave empty to use the uploaded filename",
113
+ )
114
+ max_new_tokens_input = gr.Slider(
115
+ minimum=128,
116
+ maximum=2048,
117
+ value=1024,
118
+ step=64,
119
+ label="VLM Max New Tokens",
120
+ )
121
+ seed_input = gr.Number(
122
+ value=42,
123
+ precision=0,
124
+ label="Seed (-1 keeps config default)",
125
+ )
126
+ run_button = gr.Button("Run Full Pipeline", variant="primary")
127
+
128
+ with gr.Column(scale=1):
129
+ bbox_vis_output = gr.Image(type="filepath", label="Detected Bounding Boxes")
130
+ merged_output = gr.Image(type="filepath", label="Merged Decomposition")
131
+
132
+ caption_output = gr.Textbox(label="Whole Caption", lines=6)
133
+ with gr.Row():
134
+ bbox_json_output = gr.JSON(label="BBox JSON")
135
+ meta_json_output = gr.JSON(label="Inference Metadata")
136
+ layer_gallery = gr.Gallery(label="Predicted Layers", columns=4, height="auto")
137
+ with gr.Row():
138
+ archive_output = gr.File(label="Download Result Bundle")
139
+ case_dir_output = gr.Textbox(label="Saved Case Directory")
140
+
141
+ examples = list_example_images()
142
+ if examples:
143
+ gr.Examples(examples=examples, inputs=[image_input], label="Example Images")
144
+
145
+ run_button.click(
146
+ fn=run_demo,
147
+ inputs=[
148
+ image_input,
149
+ sample_name_input,
150
+ max_new_tokens_input,
151
+ seed_input,
152
+ ],
153
+ outputs=[
154
+ bbox_vis_output,
155
+ merged_output,
156
+ caption_output,
157
+ bbox_json_output,
158
+ meta_json_output,
159
+ layer_gallery,
160
+ archive_output,
161
+ case_dir_output,
162
+ ],
163
+ )
164
+
165
+
166
+ if __name__ == "__main__":
167
+ demo.queue().launch(
168
+ server_name="0.0.0.0",
169
+ server_port=int(os.environ.get("PORT", "7860")),
170
+ )