flashstudio 0.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flashstudio might be problematic. Click here for more details.
- flashstudio/__init__.py +5 -0
- flashstudio/app.py +194 -0
- flashstudio/cli.py +18 -0
- flashstudio/components/__init__.py +0 -0
- flashstudio/components/project_manager.py +490 -0
- flashstudio/components/sidebar.py +87 -0
- flashstudio/components/styles.py +346 -0
- flashstudio/components/wizard.py +45 -0
- flashstudio/components/zone_drawer/__init__.py +177 -0
- flashstudio/constants.py +245 -0
- flashstudio/core/__init__.py +3 -0
- flashstudio/core/constants.py +3 -0
- flashstudio/launcher.py +288 -0
- flashstudio/pages/__init__.py +8 -0
- flashstudio/pages/dashboard/__init__.py +3 -0
- flashstudio/pages/dashboard/_common.py +10 -0
- flashstudio/pages/dashboard/overview/__init__.py +3 -0
- flashstudio/pages/dashboard/overview/metrics.py +33 -0
- flashstudio/pages/dashboard/overview/pipeline_status.py +35 -0
- flashstudio/pages/dashboard/overview/project_banner.py +23 -0
- flashstudio/pages/dashboard/overview/quick_actions.py +28 -0
- flashstudio/pages/dashboard/overview/recent_runs.py +99 -0
- flashstudio/pages/dashboard/overview/tab.py +35 -0
- flashstudio/pages/dashboard/page.py +17 -0
- flashstudio/pages/data/__init__.py +3 -0
- flashstudio/pages/data/_common.py +107 -0
- flashstudio/pages/data/download/__init__.py +3 -0
- flashstudio/pages/data/download/tab.py +75 -0
- flashstudio/pages/data/helpers.py +338 -0
- flashstudio/pages/data/page.py +50 -0
- flashstudio/pages/data/preview/__init__.py +3 -0
- flashstudio/pages/data/preview/tab.py +139 -0
- flashstudio/pages/data/upload/__init__.py +3 -0
- flashstudio/pages/data/upload/tab.py +156 -0
- flashstudio/pages/data/verify/__init__.py +3 -0
- flashstudio/pages/data/verify/tab.py +108 -0
- flashstudio/pages/export/__init__.py +3 -0
- flashstudio/pages/export/page.py +54 -0
- flashstudio/pages/export/weights/__init__.py +4 -0
- flashstudio/pages/export/weights/exporter.py +60 -0
- flashstudio/pages/export/weights/settings.py +86 -0
- flashstudio/pages/inference/__init__.py +3 -0
- flashstudio/pages/inference/_common.py +76 -0
- flashstudio/pages/inference/data/__init__.py +3 -0
- flashstudio/pages/inference/data/tab.py +121 -0
- flashstudio/pages/inference/model/__init__.py +3 -0
- flashstudio/pages/inference/model/tab.py +62 -0
- flashstudio/pages/inference/page.py +42 -0
- flashstudio/pages/inference/run/__init__.py +3 -0
- flashstudio/pages/inference/run/detection.py +133 -0
- flashstudio/pages/inference/run/tab.py +161 -0
- flashstudio/pages/inference/run/video.py +195 -0
- flashstudio/pages/inference/solution/__init__.py +3 -0
- flashstudio/pages/inference/solution/tab.py +121 -0
- flashstudio/pages/model/__init__.py +3 -0
- flashstudio/pages/model/_common.py +3 -0
- flashstudio/pages/model/advanced/__init__.py +3 -0
- flashstudio/pages/model/advanced/tab.py +54 -0
- flashstudio/pages/model/architecture/__init__.py +3 -0
- flashstudio/pages/model/architecture/tab.py +90 -0
- flashstudio/pages/model/augment/__init__.py +3 -0
- flashstudio/pages/model/augment/tab.py +18 -0
- flashstudio/pages/model/hyperparams/__init__.py +4 -0
- flashstudio/pages/model/hyperparams/tab.py +89 -0
- flashstudio/pages/model/page.py +30 -0
- flashstudio/pages/model/utils/__init__.py +3 -0
- flashstudio/pages/model/utils/config.py +27 -0
- flashstudio/pages/training/__init__.py +3 -0
- flashstudio/pages/training/_common.py +24 -0
- flashstudio/pages/training/launch/__init__.py +3 -0
- flashstudio/pages/training/launch/controls.py +84 -0
- flashstudio/pages/training/launch/dialogs.py +247 -0
- flashstudio/pages/training/launch/preflight.py +77 -0
- flashstudio/pages/training/launch/runner.py +440 -0
- flashstudio/pages/training/launch/tab.py +134 -0
- flashstudio/pages/training/monitor/__init__.py +3 -0
- flashstudio/pages/training/monitor/checkpoints.py +96 -0
- flashstudio/pages/training/monitor/curves.py +113 -0
- flashstudio/pages/training/monitor/dashboard.py +129 -0
- flashstudio/pages/training/monitor/gt_verification.py +122 -0
- flashstudio/pages/training/monitor/log_viewer.py +43 -0
- flashstudio/pages/training/monitor/parsers.py +253 -0
- flashstudio/pages/training/monitor/run_meta.py +165 -0
- flashstudio/pages/training/monitor/tab.py +142 -0
- flashstudio/pages/training/monitor/visualizations.py +52 -0
- flashstudio/pages/training/page.py +134 -0
- flashstudio/utils/__init__.py +152 -0
- flashstudio/utils/config.py +104 -0
- flashstudio/utils/device.py +67 -0
- flashstudio/utils/filesystem.py +67 -0
- flashstudio/utils/jobs.py +95 -0
- flashstudio/utils/training_hooks.py +266 -0
- flashstudio-0.0.1.dist-info/METADATA +107 -0
- flashstudio-0.0.1.dist-info/RECORD +97 -0
- flashstudio-0.0.1.dist-info/WHEEL +5 -0
- flashstudio-0.0.1.dist-info/entry_points.txt +2 -0
- flashstudio-0.0.1.dist-info/top_level.txt +1 -0
flashstudio/__init__.py
ADDED
flashstudio/app.py
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""FlashStudio — Main Streamlit Application."""
|
|
2
|
+
|
|
3
|
+
import streamlit as st
|
|
4
|
+
|
|
5
|
+
st.set_page_config(
|
|
6
|
+
page_title="FlashStudio",
|
|
7
|
+
page_icon="FS",
|
|
8
|
+
layout="wide",
|
|
9
|
+
initial_sidebar_state="expanded",
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from flashstudio.components.styles import inject_custom_css # noqa: E402
|
|
13
|
+
from flashstudio.components.sidebar import render_sidebar # noqa: E402
|
|
14
|
+
from flashstudio.components.wizard import render_step_indicator, render_navigation # noqa: E402
|
|
15
|
+
from flashstudio.components.project_manager import ( # noqa: E402
|
|
16
|
+
get_active_project, render_project_manager_page,
|
|
17
|
+
save_project_state, list_projects, create_project,
|
|
18
|
+
load_project_state,
|
|
19
|
+
)
|
|
20
|
+
from flashstudio.pages.dashboard import render_dashboard # noqa: E402
|
|
21
|
+
from flashstudio.pages.data import render_data_page # noqa: E402
|
|
22
|
+
from flashstudio.pages.model import render_model_page # noqa: E402
|
|
23
|
+
from flashstudio.pages.training import render_training_page # noqa: E402
|
|
24
|
+
from flashstudio.pages.export import render_export_page # noqa: E402
|
|
25
|
+
from flashstudio.pages.inference import render_inference_page # noqa: E402
|
|
26
|
+
|
|
27
|
+
STEPS = [
|
|
28
|
+
{"id": "dashboard", "label": "Dashboard", "icon": "1"},
|
|
29
|
+
{"id": "data", "label": "Data", "icon": "2"},
|
|
30
|
+
{"id": "model", "label": "Model", "icon": "3"},
|
|
31
|
+
{"id": "training", "label": "Training", "icon": "4"},
|
|
32
|
+
{"id": "export", "label": "Export", "icon": "5"},
|
|
33
|
+
{"id": "inference", "label": "Inference", "icon": "6"},
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
PAGE_RENDERERS = {
|
|
37
|
+
"dashboard": render_dashboard,
|
|
38
|
+
"data": render_data_page,
|
|
39
|
+
"model": render_model_page,
|
|
40
|
+
"training": render_training_page,
|
|
41
|
+
"export": render_export_page,
|
|
42
|
+
"inference": render_inference_page,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _ensure_config_in_session(project_id: str):
|
|
47
|
+
"""Re-seed any missing model config keys from saved project state.
|
|
48
|
+
|
|
49
|
+
Streamlit may clean up widget-owned session state keys when the widget is
|
|
50
|
+
not rendered (e.g. navigating away from the Model page). This ensures
|
|
51
|
+
critical config values like epochs, batch_size, lr etc. always remain
|
|
52
|
+
available in session state for other pages to read.
|
|
53
|
+
"""
|
|
54
|
+
import os
|
|
55
|
+
import json
|
|
56
|
+
from flashstudio.components.project_manager import get_project_dir
|
|
57
|
+
|
|
58
|
+
config_keys = [
|
|
59
|
+
"epochs", "batch_size", "lr", "img_size", "weight_decay",
|
|
60
|
+
"warmup_epochs", "patience", "num_workers", "grad_accum",
|
|
61
|
+
"val_interval", "lr_final_ratio", "optimizer",
|
|
62
|
+
"model_arch", "arch_family", "pico_backbone",
|
|
63
|
+
"amp", "grad_clip", "multiscale",
|
|
64
|
+
"aug_mosaic", "aug_mixup", "aug_copypaste",
|
|
65
|
+
"finetune_strategy", "pretrain_option", "custom_weights",
|
|
66
|
+
"lora_variant", "lora_rank", "lora_alpha", "lora_dropout", "lora_targets",
|
|
67
|
+
"activation_checkpointing", "activation_offloading", "optimizer_in_bwd",
|
|
68
|
+
"compile_model", "use_8bit_optimizer", "ddp", "chunked_loss", "chunk_size",
|
|
69
|
+
"save_dir", "save_best", "resume_training",
|
|
70
|
+
"num_classes", "class_names",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
missing = [k for k in config_keys if k not in st.session_state]
|
|
74
|
+
if not missing:
|
|
75
|
+
return
|
|
76
|
+
|
|
77
|
+
proj_dir = get_project_dir(project_id)
|
|
78
|
+
state_file = os.path.join(proj_dir, "session_state.json")
|
|
79
|
+
if not os.path.isfile(state_file):
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
with open(state_file, "r") as f:
|
|
84
|
+
saved = json.load(f)
|
|
85
|
+
except (json.JSONDecodeError, OSError):
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
for key in missing:
|
|
89
|
+
if key in saved:
|
|
90
|
+
st.session_state[key] = saved[key]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _init_config_mirror():
|
|
94
|
+
"""Build initial _config_mirror from loaded session state."""
|
|
95
|
+
mirror_keys = [
|
|
96
|
+
"epochs", "batch_size", "lr", "img_size", "weight_decay",
|
|
97
|
+
"warmup_epochs", "patience", "num_workers", "grad_accum",
|
|
98
|
+
"val_interval", "lr_final_ratio", "optimizer",
|
|
99
|
+
"model_arch", "arch_family", "pico_backbone",
|
|
100
|
+
"amp", "grad_clip", "multiscale",
|
|
101
|
+
"aug_mosaic", "aug_mixup", "aug_copypaste",
|
|
102
|
+
"finetune_strategy", "pretrain_option", "custom_weights",
|
|
103
|
+
"lora_variant", "lora_rank", "lora_alpha", "lora_dropout", "lora_targets",
|
|
104
|
+
"activation_checkpointing", "activation_offloading", "optimizer_in_bwd",
|
|
105
|
+
"compile_model", "use_8bit_optimizer", "ddp", "chunked_loss", "chunk_size",
|
|
106
|
+
"save_dir", "save_best", "resume_training",
|
|
107
|
+
]
|
|
108
|
+
mirror = {}
|
|
109
|
+
for k in mirror_keys:
|
|
110
|
+
if k in st.session_state:
|
|
111
|
+
mirror[k] = st.session_state[k]
|
|
112
|
+
if mirror:
|
|
113
|
+
st.session_state["_config_mirror"] = mirror
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def main():
|
|
117
|
+
import traceback as _tb
|
|
118
|
+
|
|
119
|
+
inject_custom_css()
|
|
120
|
+
|
|
121
|
+
if "current_step" not in st.session_state:
|
|
122
|
+
st.session_state["current_step"] = 0
|
|
123
|
+
|
|
124
|
+
# Project system — check if user has an active project
|
|
125
|
+
active_project = get_active_project()
|
|
126
|
+
|
|
127
|
+
if active_project is None and not list_projects():
|
|
128
|
+
# First time user — show project creation
|
|
129
|
+
_render_first_time_setup()
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
# Load project state once on initial page load
|
|
133
|
+
if active_project and not st.session_state.get("_project_state_loaded"):
|
|
134
|
+
load_project_state(active_project["id"])
|
|
135
|
+
st.session_state["_project_state_loaded"] = True
|
|
136
|
+
# Initialize config mirror from loaded project state
|
|
137
|
+
_init_config_mirror()
|
|
138
|
+
|
|
139
|
+
# Re-seed any config keys that Streamlit's widget lifecycle may have removed
|
|
140
|
+
if active_project:
|
|
141
|
+
_ensure_config_in_session(active_project["id"])
|
|
142
|
+
|
|
143
|
+
if st.session_state.get("show_project_manager"):
|
|
144
|
+
render_project_manager_page()
|
|
145
|
+
if st.button("← Back to Workspace", key="back_from_projects"):
|
|
146
|
+
st.session_state["show_project_manager"] = False
|
|
147
|
+
st.rerun()
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
render_sidebar()
|
|
151
|
+
render_step_indicator(STEPS, st.session_state["current_step"])
|
|
152
|
+
|
|
153
|
+
current = STEPS[st.session_state["current_step"]]
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
PAGE_RENDERERS[current["id"]]()
|
|
157
|
+
except Exception as _e:
|
|
158
|
+
st.error(f"Error: {_e}")
|
|
159
|
+
st.code(_tb.format_exc())
|
|
160
|
+
|
|
161
|
+
render_navigation(STEPS, st.session_state["current_step"])
|
|
162
|
+
|
|
163
|
+
# Auto-save project state on each page render
|
|
164
|
+
if active_project:
|
|
165
|
+
save_project_state()
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _render_first_time_setup():
|
|
169
|
+
"""Compact first-time project creation."""
|
|
170
|
+
st.markdown(
|
|
171
|
+
"<div style='text-align:center; padding:2rem 0 0.5rem;'>"
|
|
172
|
+
"<b style='font-size:2.5rem;'>FS</b><br>"
|
|
173
|
+
"<b style='font-size:1.3rem;'>Welcome to FlashStudio</b><br>"
|
|
174
|
+
"<span style='color:#6B7280;font-size:0.9rem;'>Create your first project to get started</span>"
|
|
175
|
+
"</div>",
|
|
176
|
+
unsafe_allow_html=True,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
with st.container(border=True):
|
|
180
|
+
col_form, col_info = st.columns([3, 2])
|
|
181
|
+
with col_form:
|
|
182
|
+
name = st.text_input("Project Name", placeholder="e.g. Traffic Detection", key="first_project_name")
|
|
183
|
+
desc = st.text_input("Description (optional)", placeholder="Detect vehicles in traffic footage", key="first_project_desc")
|
|
184
|
+
if st.button("Create and Start", type="primary", disabled=not name, use_container_width=True):
|
|
185
|
+
create_project(name, desc)
|
|
186
|
+
st.rerun()
|
|
187
|
+
with col_info:
|
|
188
|
+
st.markdown("#### What's a Project?")
|
|
189
|
+
for item in ["Dataset management", "Model configuration", "Training runs", "Model exports", "Inference pipeline"]:
|
|
190
|
+
st.markdown(f'<span style="font-size:0.88rem;color:#4B5563;">• {item}</span>', unsafe_allow_html=True)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
if __name__ == "__main__":
|
|
194
|
+
main()
|
flashstudio/cli.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""FlashStudio CLI entrypoint."""
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
parser = argparse.ArgumentParser(description="FlashStudio — Training & Inference UI for FlashDet")
|
|
8
|
+
parser.add_argument("--port", type=int, default=8501, help="Port to serve on")
|
|
9
|
+
parser.add_argument("--no-share", action="store_true", help="Disable ngrok sharing in Colab")
|
|
10
|
+
parser.add_argument("--ngrok-token", type=str, default=None, help="ngrok auth token")
|
|
11
|
+
args = parser.parse_args()
|
|
12
|
+
|
|
13
|
+
from flashstudio.launcher import launch
|
|
14
|
+
launch(port=args.port, share=not args.no_share, ngrok_token=args.ngrok_token)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
main()
|
|
File without changes
|