flashstudio 0.1.3__tar.gz → 0.1.4__tar.gz
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-0.1.3 → flashstudio-0.1.4}/PKG-INFO +87 -19
- {flashstudio-0.1.3 → flashstudio-0.1.4}/README.md +84 -17
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/app.py +76 -5
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/components/project_manager.py +20 -10
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/components/sidebar.py +7 -6
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/components/styles.py +40 -3
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/constants.py +35 -1
- flashstudio-0.1.4/flashstudio/core/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/core/constants.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/__init__.py +8 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/_common.py +10 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/overview/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/overview/metrics.py +66 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/overview/pipeline_status.py +35 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/overview/project_banner.py +23 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/overview/quick_actions.py +28 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/overview/recent_runs.py +99 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/overview/tab.py +35 -0
- flashstudio-0.1.4/flashstudio/pages/dashboard/page.py +17 -0
- flashstudio-0.1.4/flashstudio/pages/data/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/data/_common.py +107 -0
- flashstudio-0.1.4/flashstudio/pages/data/download/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/data/download/tab.py +75 -0
- flashstudio-0.1.4/flashstudio/pages/data/helpers.py +290 -0
- flashstudio-0.1.4/flashstudio/pages/data/page.py +50 -0
- flashstudio-0.1.4/flashstudio/pages/data/preview/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/data/preview/tab.py +139 -0
- flashstudio-0.1.4/flashstudio/pages/data/upload/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/data/upload/tab.py +160 -0
- flashstudio-0.1.4/flashstudio/pages/data/verify/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/data/verify/tab.py +107 -0
- flashstudio-0.1.4/flashstudio/pages/export/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/export/page.py +54 -0
- flashstudio-0.1.4/flashstudio/pages/export/weights/__init__.py +4 -0
- flashstudio-0.1.4/flashstudio/pages/export/weights/exporter.py +60 -0
- flashstudio-0.1.4/flashstudio/pages/export/weights/settings.py +75 -0
- flashstudio-0.1.4/flashstudio/pages/inference/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/inference/_common.py +76 -0
- flashstudio-0.1.4/flashstudio/pages/inference/data/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/inference/data/tab.py +121 -0
- flashstudio-0.1.4/flashstudio/pages/inference/model/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/inference/model/tab.py +60 -0
- flashstudio-0.1.4/flashstudio/pages/inference/page.py +42 -0
- flashstudio-0.1.4/flashstudio/pages/inference/run/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/inference/run/detection.py +133 -0
- flashstudio-0.1.4/flashstudio/pages/inference/run/tab.py +159 -0
- flashstudio-0.1.4/flashstudio/pages/inference/run/video.py +195 -0
- flashstudio-0.1.4/flashstudio/pages/inference/solution/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/inference/solution/tab.py +121 -0
- flashstudio-0.1.4/flashstudio/pages/model/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/model/_common.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/model/advanced/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/model/advanced/tab.py +54 -0
- flashstudio-0.1.4/flashstudio/pages/model/architecture/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/model/architecture/tab.py +90 -0
- flashstudio-0.1.4/flashstudio/pages/model/augment/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/model/augment/tab.py +18 -0
- flashstudio-0.1.4/flashstudio/pages/model/hyperparams/__init__.py +4 -0
- flashstudio-0.1.4/flashstudio/pages/model/hyperparams/tab.py +89 -0
- flashstudio-0.1.4/flashstudio/pages/model/page.py +30 -0
- flashstudio-0.1.4/flashstudio/pages/model/utils/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/model/utils/config.py +27 -0
- flashstudio-0.1.4/flashstudio/pages/training/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/training/_common.py +24 -0
- flashstudio-0.1.4/flashstudio/pages/training/launch/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/training/launch/controls.py +84 -0
- flashstudio-0.1.4/flashstudio/pages/training/launch/dialogs.py +247 -0
- flashstudio-0.1.4/flashstudio/pages/training/launch/preflight.py +66 -0
- flashstudio-0.1.4/flashstudio/pages/training/launch/runner.py +429 -0
- flashstudio-0.1.4/flashstudio/pages/training/launch/tab.py +130 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/__init__.py +3 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/checkpoints.py +96 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/curves.py +113 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/dashboard.py +129 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/gt_verification.py +122 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/log_viewer.py +43 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/parsers.py +253 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/run_meta.py +165 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/tab.py +142 -0
- flashstudio-0.1.4/flashstudio/pages/training/monitor/visualizations.py +52 -0
- flashstudio-0.1.4/flashstudio/pages/training/page.py +128 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/utils/__init__.py +39 -1
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/utils/config.py +11 -4
- flashstudio-0.1.4/flashstudio/utils/training_hooks.py +266 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio.egg-info/PKG-INFO +87 -19
- flashstudio-0.1.4/flashstudio.egg-info/SOURCES.txt +106 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio.egg-info/requires.txt +1 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/pyproject.toml +16 -5
- flashstudio-0.1.4/tests/test_app.py +120 -0
- flashstudio-0.1.4/tests/test_cli.py +37 -0
- flashstudio-0.1.4/tests/test_constants.py +172 -0
- flashstudio-0.1.4/tests/test_launcher.py +60 -0
- flashstudio-0.1.4/tests/test_pipeline_flow.py +771 -0
- flashstudio-0.1.4/tests/test_save_dir_compat.py +685 -0
- flashstudio-0.1.3/flashstudio/pages/__init__.py +0 -0
- flashstudio-0.1.3/flashstudio/pages/dashboard.py +0 -251
- flashstudio-0.1.3/flashstudio/pages/data.py +0 -865
- flashstudio-0.1.3/flashstudio/pages/export.py +0 -160
- flashstudio-0.1.3/flashstudio/pages/inference.py +0 -850
- flashstudio-0.1.3/flashstudio/pages/model.py +0 -281
- flashstudio-0.1.3/flashstudio/pages/training.py +0 -2079
- flashstudio-0.1.3/flashstudio.egg-info/SOURCES.txt +0 -31
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/__init__.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/cli.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/components/__init__.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/components/wizard.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/components/zone_drawer/__init__.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/launcher.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/utils/device.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/utils/filesystem.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio/utils/jobs.py +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio.egg-info/dependency_links.txt +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio.egg-info/entry_points.txt +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/flashstudio.egg-info/top_level.txt +0 -0
- {flashstudio-0.1.3 → flashstudio-0.1.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flashstudio
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Interactive Training & Inference UI for FlashDet — runs on Google Colab
|
|
5
5
|
Author: Gaurav14cs17
|
|
6
6
|
License: Apache-2.0
|
|
@@ -12,7 +12,7 @@ Classifier: Intended Audience :: Science/Research
|
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
14
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
15
|
-
Requires-Python: >=3.
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
Requires-Dist: streamlit>=1.28.0
|
|
18
18
|
Requires-Dist: plotly>=5.0
|
|
@@ -33,6 +33,7 @@ Requires-Dist: pyngrok>=6.0; extra == "colab"
|
|
|
33
33
|
Provides-Extra: dev
|
|
34
34
|
Requires-Dist: ruff; extra == "dev"
|
|
35
35
|
Requires-Dist: pytest; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
36
37
|
|
|
37
38
|
<p align="center">
|
|
38
39
|
<img src="https://raw.githubusercontent.com/FlashVision/FlashStudio/main/assets/logo.png" width="200" alt="FlashStudio Logo">
|
|
@@ -237,26 +238,93 @@ Click the **Public URL** to open FlashStudio in a new tab.
|
|
|
237
238
|
```
|
|
238
239
|
FlashStudio/
|
|
239
240
|
├── flashstudio/
|
|
240
|
-
│ ├── __init__.py
|
|
241
|
-
│ ├── app.py
|
|
242
|
-
│ ├── launcher.py
|
|
243
|
-
│ ├── cli.py
|
|
244
|
-
│ ├──
|
|
245
|
-
│ │
|
|
246
|
-
│
|
|
247
|
-
│ │ ├──
|
|
248
|
-
│ │ ├──
|
|
249
|
-
│ │ ├──
|
|
250
|
-
│ │ └──
|
|
241
|
+
│ ├── __init__.py # Package init + launch() export
|
|
242
|
+
│ ├── app.py # Main Streamlit app (wizard flow)
|
|
243
|
+
│ ├── launcher.py # Colab/local launcher with ngrok
|
|
244
|
+
│ ├── cli.py # CLI entrypoint
|
|
245
|
+
│ ├── constants.py # Centralized constants (paths, defaults, models)
|
|
246
|
+
│ │
|
|
247
|
+
│ ├── pages/ # Each page is a sub-package
|
|
248
|
+
│ │ ├── dashboard/
|
|
249
|
+
│ │ │ ├── page.py # Main dashboard render
|
|
250
|
+
│ │ │ ├── pipeline_status.py # Pipeline status cards
|
|
251
|
+
│ │ │ └── recent_runs.py # Recent training runs table
|
|
252
|
+
│ │ ├── data/
|
|
253
|
+
│ │ │ ├── page.py # Main data page render
|
|
254
|
+
│ │ │ ├── upload.py # Upload tab (ZIP/TAR + class config)
|
|
255
|
+
│ │ │ ├── download.py # Download tab (quick start + registries)
|
|
256
|
+
│ │ │ ├── preview.py # Preview tab (image grid + annotations)
|
|
257
|
+
│ │ │ ├── verify.py # Verify tab (dataset validation)
|
|
258
|
+
│ │ │ └── helpers.py # Shared helpers (extract, detect, convert)
|
|
259
|
+
│ │ ├── model/
|
|
260
|
+
│ │ │ ├── page.py # Main model page render
|
|
261
|
+
│ │ │ ├── architecture.py # Architecture tab (FlashDet/YOLO selection)
|
|
262
|
+
│ │ │ ├── hyperparams.py # Hyperparameters tab
|
|
263
|
+
│ │ │ ├── augmentation.py # Augmentation tab
|
|
264
|
+
│ │ │ ├── advanced.py # Advanced tab (memory, distributed)
|
|
265
|
+
│ │ │ └── summary.py # Config summary bar + YAML save/load
|
|
266
|
+
│ │ ├── training/
|
|
267
|
+
│ │ │ ├── page.py # Main training page render
|
|
268
|
+
│ │ │ ├── _common.py # Shared utilities (_get_save_dir)
|
|
269
|
+
│ │ │ ├── launch/ # Launch sub-package
|
|
270
|
+
│ │ │ │ ├── tab.py # Launch tab entry point
|
|
271
|
+
│ │ │ │ ├── preflight.py # Pre-flight checks
|
|
272
|
+
│ │ │ │ ├── runner.py # FlashDet Trainer subprocess
|
|
273
|
+
│ │ │ │ ├── controls.py # Start/stop/pause/resume buttons
|
|
274
|
+
│ │ │ │ └── dialogs.py # Clean/resume/config dialogs
|
|
275
|
+
│ │ │ └── monitor/ # Monitor sub-package
|
|
276
|
+
│ │ │ ├── tab.py # Monitor tab entry point
|
|
277
|
+
│ │ │ ├── run_meta.py # Run metadata extraction
|
|
278
|
+
│ │ │ ├── parsers.py # CSV/log parsing
|
|
279
|
+
│ │ │ ├── dashboard.py # Run dashboard + metrics
|
|
280
|
+
│ │ │ ├── curves.py # Plotly training curves
|
|
281
|
+
│ │ │ ├── visualizations.py # Epoch visualizations
|
|
282
|
+
│ │ │ ├── gt_verification.py # Ground truth verification
|
|
283
|
+
│ │ │ ├── log_viewer.py # Full log viewer
|
|
284
|
+
│ │ │ └── checkpoints.py # File browser + checkpoints
|
|
285
|
+
│ │ ├── export/
|
|
286
|
+
│ │ │ └── page.py # Export page (ONNX/TorchScript)
|
|
287
|
+
│ │ └── inference/
|
|
288
|
+
│ │ ├── page.py # Main inference page render
|
|
289
|
+
│ │ ├── model_tab.py # Model selection tab
|
|
290
|
+
│ │ ├── data_tab.py # Data input tab (images/video/RTSP)
|
|
291
|
+
│ │ ├── solution_tab.py # Solution selection + zone drawing
|
|
292
|
+
│ │ ├── run_tab.py # Run tab + results display
|
|
293
|
+
│ │ ├── detection.py # Detection utilities (real + demo)
|
|
294
|
+
│ │ └── video.py # Video/image inference runners
|
|
295
|
+
│ │
|
|
251
296
|
│ ├── components/
|
|
252
|
-
│ │ ├── sidebar.py
|
|
253
|
-
│ │ ├── styles.py
|
|
254
|
-
│ │
|
|
297
|
+
│ │ ├── sidebar.py # Navigation sidebar
|
|
298
|
+
│ │ ├── styles.py # Custom CSS + UI helpers
|
|
299
|
+
│ │ ├── wizard.py # Step indicator + navigation
|
|
300
|
+
│ │ ├── project_manager.py # Project CRUD + state persistence
|
|
301
|
+
│ │ └── zone_drawer/ # Interactive canvas zone drawing
|
|
302
|
+
│ │
|
|
255
303
|
│ └── utils/
|
|
256
|
-
│
|
|
304
|
+
│ ├── __init__.py # Shared helpers (defaults, state, flash)
|
|
305
|
+
│ ├── device.py # GPU/environment detection
|
|
306
|
+
│ ├── jobs.py # Background process tracking
|
|
307
|
+
│ ├── filesystem.py # Directory size/listing utilities
|
|
308
|
+
│ ├── config.py # Training config build/save/load
|
|
309
|
+
│ └── training_hooks.py # FlashDet training callbacks
|
|
310
|
+
│
|
|
311
|
+
├── tests/ # Pytest test suite
|
|
312
|
+
│ ├── conftest.py # Shared fixtures
|
|
313
|
+
│ ├── test_constants.py # Constants validation
|
|
314
|
+
│ ├── test_cli.py # CLI tests
|
|
315
|
+
│ ├── test_utils/ # Utils sub-package tests
|
|
316
|
+
│ │ ├── test_init.py
|
|
317
|
+
│ │ ├── test_device.py
|
|
318
|
+
│ │ ├── test_filesystem.py
|
|
319
|
+
│ │ ├── test_config.py
|
|
320
|
+
│ │ └── test_jobs.py
|
|
321
|
+
│ ├── test_pages/ # Page logic tests
|
|
322
|
+
│ │ └── test_training_parsers.py
|
|
323
|
+
│ └── test_components/
|
|
324
|
+
│ └── test_project_manager.py
|
|
325
|
+
│
|
|
326
|
+
├── .github/workflows/ci.yml # GitHub Actions CI
|
|
257
327
|
├── notebooks/
|
|
258
|
-
│ ├── FlashStudio_Train.ipynb
|
|
259
|
-
│ └── FlashStudio_Inference.ipynb
|
|
260
328
|
├── .streamlit/config.toml
|
|
261
329
|
├── pyproject.toml
|
|
262
330
|
└── README.md
|
|
@@ -201,26 +201,93 @@ Click the **Public URL** to open FlashStudio in a new tab.
|
|
|
201
201
|
```
|
|
202
202
|
FlashStudio/
|
|
203
203
|
├── flashstudio/
|
|
204
|
-
│ ├── __init__.py
|
|
205
|
-
│ ├── app.py
|
|
206
|
-
│ ├── launcher.py
|
|
207
|
-
│ ├── cli.py
|
|
208
|
-
│ ├──
|
|
209
|
-
│ │
|
|
210
|
-
│
|
|
211
|
-
│ │ ├──
|
|
212
|
-
│ │ ├──
|
|
213
|
-
│ │ ├──
|
|
214
|
-
│ │ └──
|
|
204
|
+
│ ├── __init__.py # Package init + launch() export
|
|
205
|
+
│ ├── app.py # Main Streamlit app (wizard flow)
|
|
206
|
+
│ ├── launcher.py # Colab/local launcher with ngrok
|
|
207
|
+
│ ├── cli.py # CLI entrypoint
|
|
208
|
+
│ ├── constants.py # Centralized constants (paths, defaults, models)
|
|
209
|
+
│ │
|
|
210
|
+
│ ├── pages/ # Each page is a sub-package
|
|
211
|
+
│ │ ├── dashboard/
|
|
212
|
+
│ │ │ ├── page.py # Main dashboard render
|
|
213
|
+
│ │ │ ├── pipeline_status.py # Pipeline status cards
|
|
214
|
+
│ │ │ └── recent_runs.py # Recent training runs table
|
|
215
|
+
│ │ ├── data/
|
|
216
|
+
│ │ │ ├── page.py # Main data page render
|
|
217
|
+
│ │ │ ├── upload.py # Upload tab (ZIP/TAR + class config)
|
|
218
|
+
│ │ │ ├── download.py # Download tab (quick start + registries)
|
|
219
|
+
│ │ │ ├── preview.py # Preview tab (image grid + annotations)
|
|
220
|
+
│ │ │ ├── verify.py # Verify tab (dataset validation)
|
|
221
|
+
│ │ │ └── helpers.py # Shared helpers (extract, detect, convert)
|
|
222
|
+
│ │ ├── model/
|
|
223
|
+
│ │ │ ├── page.py # Main model page render
|
|
224
|
+
│ │ │ ├── architecture.py # Architecture tab (FlashDet/YOLO selection)
|
|
225
|
+
│ │ │ ├── hyperparams.py # Hyperparameters tab
|
|
226
|
+
│ │ │ ├── augmentation.py # Augmentation tab
|
|
227
|
+
│ │ │ ├── advanced.py # Advanced tab (memory, distributed)
|
|
228
|
+
│ │ │ └── summary.py # Config summary bar + YAML save/load
|
|
229
|
+
│ │ ├── training/
|
|
230
|
+
│ │ │ ├── page.py # Main training page render
|
|
231
|
+
│ │ │ ├── _common.py # Shared utilities (_get_save_dir)
|
|
232
|
+
│ │ │ ├── launch/ # Launch sub-package
|
|
233
|
+
│ │ │ │ ├── tab.py # Launch tab entry point
|
|
234
|
+
│ │ │ │ ├── preflight.py # Pre-flight checks
|
|
235
|
+
│ │ │ │ ├── runner.py # FlashDet Trainer subprocess
|
|
236
|
+
│ │ │ │ ├── controls.py # Start/stop/pause/resume buttons
|
|
237
|
+
│ │ │ │ └── dialogs.py # Clean/resume/config dialogs
|
|
238
|
+
│ │ │ └── monitor/ # Monitor sub-package
|
|
239
|
+
│ │ │ ├── tab.py # Monitor tab entry point
|
|
240
|
+
│ │ │ ├── run_meta.py # Run metadata extraction
|
|
241
|
+
│ │ │ ├── parsers.py # CSV/log parsing
|
|
242
|
+
│ │ │ ├── dashboard.py # Run dashboard + metrics
|
|
243
|
+
│ │ │ ├── curves.py # Plotly training curves
|
|
244
|
+
│ │ │ ├── visualizations.py # Epoch visualizations
|
|
245
|
+
│ │ │ ├── gt_verification.py # Ground truth verification
|
|
246
|
+
│ │ │ ├── log_viewer.py # Full log viewer
|
|
247
|
+
│ │ │ └── checkpoints.py # File browser + checkpoints
|
|
248
|
+
│ │ ├── export/
|
|
249
|
+
│ │ │ └── page.py # Export page (ONNX/TorchScript)
|
|
250
|
+
│ │ └── inference/
|
|
251
|
+
│ │ ├── page.py # Main inference page render
|
|
252
|
+
│ │ ├── model_tab.py # Model selection tab
|
|
253
|
+
│ │ ├── data_tab.py # Data input tab (images/video/RTSP)
|
|
254
|
+
│ │ ├── solution_tab.py # Solution selection + zone drawing
|
|
255
|
+
│ │ ├── run_tab.py # Run tab + results display
|
|
256
|
+
│ │ ├── detection.py # Detection utilities (real + demo)
|
|
257
|
+
│ │ └── video.py # Video/image inference runners
|
|
258
|
+
│ │
|
|
215
259
|
│ ├── components/
|
|
216
|
-
│ │ ├── sidebar.py
|
|
217
|
-
│ │ ├── styles.py
|
|
218
|
-
│ │
|
|
260
|
+
│ │ ├── sidebar.py # Navigation sidebar
|
|
261
|
+
│ │ ├── styles.py # Custom CSS + UI helpers
|
|
262
|
+
│ │ ├── wizard.py # Step indicator + navigation
|
|
263
|
+
│ │ ├── project_manager.py # Project CRUD + state persistence
|
|
264
|
+
│ │ └── zone_drawer/ # Interactive canvas zone drawing
|
|
265
|
+
│ │
|
|
219
266
|
│ └── utils/
|
|
220
|
-
│
|
|
267
|
+
│ ├── __init__.py # Shared helpers (defaults, state, flash)
|
|
268
|
+
│ ├── device.py # GPU/environment detection
|
|
269
|
+
│ ├── jobs.py # Background process tracking
|
|
270
|
+
│ ├── filesystem.py # Directory size/listing utilities
|
|
271
|
+
│ ├── config.py # Training config build/save/load
|
|
272
|
+
│ └── training_hooks.py # FlashDet training callbacks
|
|
273
|
+
│
|
|
274
|
+
├── tests/ # Pytest test suite
|
|
275
|
+
│ ├── conftest.py # Shared fixtures
|
|
276
|
+
│ ├── test_constants.py # Constants validation
|
|
277
|
+
│ ├── test_cli.py # CLI tests
|
|
278
|
+
│ ├── test_utils/ # Utils sub-package tests
|
|
279
|
+
│ │ ├── test_init.py
|
|
280
|
+
│ │ ├── test_device.py
|
|
281
|
+
│ │ ├── test_filesystem.py
|
|
282
|
+
│ │ ├── test_config.py
|
|
283
|
+
│ │ └── test_jobs.py
|
|
284
|
+
│ ├── test_pages/ # Page logic tests
|
|
285
|
+
│ │ └── test_training_parsers.py
|
|
286
|
+
│ └── test_components/
|
|
287
|
+
│ └── test_project_manager.py
|
|
288
|
+
│
|
|
289
|
+
├── .github/workflows/ci.yml # GitHub Actions CI
|
|
221
290
|
├── notebooks/
|
|
222
|
-
│ ├── FlashStudio_Train.ipynb
|
|
223
|
-
│ └── FlashStudio_Inference.ipynb
|
|
224
291
|
├── .streamlit/config.toml
|
|
225
292
|
├── pyproject.toml
|
|
226
293
|
└── README.md
|
|
@@ -43,6 +43,76 @@ PAGE_RENDERERS = {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
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
|
+
|
|
46
116
|
def main():
|
|
47
117
|
import traceback as _tb
|
|
48
118
|
|
|
@@ -51,11 +121,6 @@ def main():
|
|
|
51
121
|
if "current_step" not in st.session_state:
|
|
52
122
|
st.session_state["current_step"] = 0
|
|
53
123
|
|
|
54
|
-
# Ensure critical config values are always initialized
|
|
55
|
-
from flashstudio.utils import DEFAULTS
|
|
56
|
-
if not st.session_state.get("save_dir"):
|
|
57
|
-
st.session_state["save_dir"] = DEFAULTS["save_dir"]
|
|
58
|
-
|
|
59
124
|
# Project system — check if user has an active project
|
|
60
125
|
active_project = get_active_project()
|
|
61
126
|
|
|
@@ -68,6 +133,12 @@ def main():
|
|
|
68
133
|
if active_project and not st.session_state.get("_project_state_loaded"):
|
|
69
134
|
load_project_state(active_project["id"])
|
|
70
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"])
|
|
71
142
|
|
|
72
143
|
if st.session_state.get("show_project_manager"):
|
|
73
144
|
render_project_manager_page()
|
|
@@ -105,10 +105,12 @@ def create_project(name: str, description: str = "") -> dict:
|
|
|
105
105
|
|
|
106
106
|
def switch_project(project_id: str):
|
|
107
107
|
"""Switch active project and load its state."""
|
|
108
|
+
_clear_session_for_new_project()
|
|
108
109
|
index = _load_index()
|
|
109
110
|
index["active"] = project_id
|
|
110
111
|
_save_index(index)
|
|
111
112
|
load_project_state(project_id)
|
|
113
|
+
st.session_state["_project_state_loaded"] = True
|
|
112
114
|
|
|
113
115
|
|
|
114
116
|
def delete_project(project_id: str):
|
|
@@ -203,6 +205,8 @@ def load_project_state(project_id: str):
|
|
|
203
205
|
|
|
204
206
|
def duplicate_project(project_id: str, new_name: str) -> dict:
|
|
205
207
|
"""Duplicate an existing project with a new name."""
|
|
208
|
+
index = _load_index()
|
|
209
|
+
prev_active = index.get("active")
|
|
206
210
|
src_dir = get_project_dir(project_id)
|
|
207
211
|
new_project = create_project(new_name)
|
|
208
212
|
dst_dir = get_project_dir(new_project["id"])
|
|
@@ -220,12 +224,20 @@ def duplicate_project(project_id: str, new_name: str) -> dict:
|
|
|
220
224
|
if os.path.isfile(src_state):
|
|
221
225
|
shutil.copy2(src_state, os.path.join(dst_dir, "session_state.json"))
|
|
222
226
|
|
|
227
|
+
# Restore previously active project so duplication doesn't switch context
|
|
228
|
+
if prev_active and prev_active != new_project["id"]:
|
|
229
|
+
idx = _load_index()
|
|
230
|
+
idx["active"] = prev_active
|
|
231
|
+
_save_index(idx)
|
|
232
|
+
|
|
223
233
|
return new_project
|
|
224
234
|
|
|
225
235
|
|
|
226
236
|
def get_project_stats(project_id: str) -> dict:
|
|
227
237
|
"""Get statistics for a project."""
|
|
228
|
-
import re
|
|
238
|
+
import re
|
|
239
|
+
import csv
|
|
240
|
+
import glob
|
|
229
241
|
proj_dir = get_project_dir(project_id)
|
|
230
242
|
stats = {"runs": 0, "best_map": None, "total_size": "0 KB", "has_export": False}
|
|
231
243
|
|
|
@@ -257,7 +269,8 @@ def get_project_stats(project_id: str) -> dict:
|
|
|
257
269
|
except Exception:
|
|
258
270
|
pass
|
|
259
271
|
if best_map == 0:
|
|
260
|
-
|
|
272
|
+
from flashstudio.constants import TRAINING_LOG_GLOB
|
|
273
|
+
logs = glob.glob(os.path.join(rd, TRAINING_LOG_GLOB))
|
|
261
274
|
for lf in logs:
|
|
262
275
|
try:
|
|
263
276
|
with open(lf, "r", encoding="utf-8", errors="replace") as f:
|
|
@@ -298,7 +311,6 @@ def render_project_selector():
|
|
|
298
311
|
return False # No projects exist — show creation UI
|
|
299
312
|
|
|
300
313
|
# Quick selector
|
|
301
|
-
project_names = {p["id"]: p["name"] for p in projects}
|
|
302
314
|
active_idx = 0
|
|
303
315
|
for i, p in enumerate(projects):
|
|
304
316
|
if p["id"] == active_id:
|
|
@@ -324,8 +336,8 @@ def render_project_selector():
|
|
|
324
336
|
def render_project_manager_page():
|
|
325
337
|
"""Full project management page — create, switch, delete, manage projects."""
|
|
326
338
|
st.markdown(
|
|
327
|
-
"<div style='text-align:center; padding:
|
|
328
|
-
"<b style='font-size:1.
|
|
339
|
+
"<div style='text-align:center; padding:0.4rem 0;'>"
|
|
340
|
+
"<b style='font-size:1.2rem;'>Project Manager</b>"
|
|
329
341
|
"</div>",
|
|
330
342
|
unsafe_allow_html=True,
|
|
331
343
|
)
|
|
@@ -336,7 +348,7 @@ def render_project_manager_page():
|
|
|
336
348
|
|
|
337
349
|
# ─── Create New Project ───
|
|
338
350
|
with st.container(border=True):
|
|
339
|
-
st.markdown("
|
|
351
|
+
st.markdown("#### Create New Project")
|
|
340
352
|
col_name, col_desc, col_btn = st.columns([2, 3, 1])
|
|
341
353
|
with col_name:
|
|
342
354
|
new_name = st.text_input("Project Name", placeholder="e.g. PPE Detection v2",
|
|
@@ -349,7 +361,7 @@ def render_project_manager_page():
|
|
|
349
361
|
st.markdown("<div style='height:28px'></div>", unsafe_allow_html=True)
|
|
350
362
|
if st.button("Create", type="primary", key="create_project_btn",
|
|
351
363
|
use_container_width=True, disabled=not new_name):
|
|
352
|
-
|
|
364
|
+
create_project(new_name, new_desc)
|
|
353
365
|
st.success(f"Project **{new_name}** created!")
|
|
354
366
|
_clear_session_for_new_project()
|
|
355
367
|
st.rerun()
|
|
@@ -359,14 +371,12 @@ def render_project_manager_page():
|
|
|
359
371
|
st.info("No projects yet. Create your first project above to get started.")
|
|
360
372
|
return
|
|
361
373
|
|
|
362
|
-
st.markdown(f"
|
|
374
|
+
st.markdown(f"#### Your Projects ({len(projects)})")
|
|
363
375
|
|
|
364
376
|
for p in sorted(projects, key=lambda x: x.get("last_modified", ""), reverse=True):
|
|
365
377
|
is_active = p["id"] == active_id
|
|
366
|
-
proj_dir = get_project_dir(p["id"])
|
|
367
378
|
stats = get_project_stats(p["id"])
|
|
368
379
|
|
|
369
|
-
border_style = "border-left: 3px solid #7C3AED;" if is_active else ""
|
|
370
380
|
with st.container(border=True):
|
|
371
381
|
col_info, col_stats, col_actions = st.columns([3, 2, 2])
|
|
372
382
|
|
|
@@ -39,17 +39,17 @@ def render_sidebar():
|
|
|
39
39
|
logo_b64 = _get_logo_b64()
|
|
40
40
|
if logo_b64:
|
|
41
41
|
st.markdown(
|
|
42
|
-
f'<div style="display:flex;align-items:center;gap:0.
|
|
43
|
-
f'<img src="data:image/png;base64,{logo_b64}" style="width:
|
|
42
|
+
f'<div style="display:flex;flex-direction:column;align-items:center;gap:0.3rem;padding:0.6rem 0.2rem 0.5rem;">'
|
|
43
|
+
f'<img src="data:image/png;base64,{logo_b64}" style="width:56px;height:56px;">'
|
|
44
44
|
f'<b style="font-size:1.1rem;color:{COLOR_TEXT_PRIMARY};">FlashStudio</b>'
|
|
45
45
|
f'</div>',
|
|
46
46
|
unsafe_allow_html=True,
|
|
47
47
|
)
|
|
48
48
|
else:
|
|
49
49
|
st.markdown(
|
|
50
|
-
f'<div style="
|
|
50
|
+
f'<div style="display:flex;flex-direction:column;align-items:center;gap:0.2rem;padding:0.5rem 0 0.3rem;">'
|
|
51
51
|
f'<b style="font-size:1.5rem;">FS</b>'
|
|
52
|
-
f'<b style="font-size:1rem;color:{COLOR_TEXT_PRIMARY};
|
|
52
|
+
f'<b style="font-size:1rem;color:{COLOR_TEXT_PRIMARY};">FlashStudio</b>'
|
|
53
53
|
f'</div>',
|
|
54
54
|
unsafe_allow_html=True,
|
|
55
55
|
)
|
|
@@ -71,14 +71,15 @@ def render_sidebar():
|
|
|
71
71
|
st.divider()
|
|
72
72
|
|
|
73
73
|
gpu = get_gpu_info()
|
|
74
|
+
from flashstudio.constants import GPU_NAME_TRUNCATE, DATASET_NAME_TRUNCATE
|
|
74
75
|
train_status = st.session_state.get("training_status", "Idle")
|
|
75
76
|
status_color = COLOR_SUCCESS if train_status == "Complete" else (
|
|
76
77
|
COLOR_WARNING if train_status == "Running" else (
|
|
77
78
|
COLOR_ERROR if train_status == "Failed" else COLOR_TEXT_SECONDARY))
|
|
78
79
|
st.markdown(
|
|
79
80
|
f'<div style="font-size:0.75rem;color:{COLOR_TEXT_BODY};padding:0.1rem 0.5rem;line-height:1.9;">'
|
|
80
|
-
f'GPU: {gpu["name"][:
|
|
81
|
-
f'Data: {(st.session_state.get("dataset_name") or "—")[:
|
|
81
|
+
f'GPU: {gpu["name"][:GPU_NAME_TRUNCATE] if gpu["available"] else "CPU"}<br>'
|
|
82
|
+
f'Data: {(st.session_state.get("dataset_name") or "—")[:DATASET_NAME_TRUNCATE]}<br>'
|
|
82
83
|
f'Model: {st.session_state.get("model_arch", "Pico").replace("FlashDet-", "")}<br>'
|
|
83
84
|
f'Status: <span style="color:{status_color};font-weight:600;">{train_status[:12]}</span>'
|
|
84
85
|
f'</div>',
|
|
@@ -9,13 +9,33 @@ def inject_custom_css():
|
|
|
9
9
|
<style>
|
|
10
10
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
11
11
|
|
|
12
|
-
/* ═══════ GLOBAL ═══════ */
|
|
13
|
-
.stApp {
|
|
12
|
+
/* ═══════ GLOBAL — NO SCROLL ═══════ */
|
|
13
|
+
.stApp {
|
|
14
|
+
font-family: 'Inter', -apple-system, sans-serif;
|
|
15
|
+
overflow: hidden !important;
|
|
16
|
+
height: 100vh !important;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.main {
|
|
20
|
+
overflow: hidden !important;
|
|
21
|
+
height: 100vh !important;
|
|
22
|
+
}
|
|
14
23
|
|
|
15
24
|
.main .block-container {
|
|
16
25
|
padding: 0.8rem 1.5rem 0.5rem !important;
|
|
17
26
|
max-width: 1500px;
|
|
27
|
+
height: calc(100vh - 2rem) !important;
|
|
28
|
+
overflow: hidden !important;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Allow internal scroll on specific containers */
|
|
32
|
+
.scrollable-panel {
|
|
33
|
+
overflow-y: auto !important;
|
|
34
|
+
scrollbar-width: thin;
|
|
35
|
+
scrollbar-color: #D1D5DB transparent;
|
|
18
36
|
}
|
|
37
|
+
.scrollable-panel::-webkit-scrollbar { width: 4px; }
|
|
38
|
+
.scrollable-panel::-webkit-scrollbar-thumb { background: #D1D5DB; border-radius: 2px; }
|
|
19
39
|
|
|
20
40
|
.main .stMarkdown { margin-bottom: 0 !important; }
|
|
21
41
|
.main .element-container { margin-bottom: 0.15rem !important; }
|
|
@@ -152,6 +172,17 @@ def inject_custom_css():
|
|
|
152
172
|
border-bottom: 2px solid #7C3AED !important;
|
|
153
173
|
}
|
|
154
174
|
|
|
175
|
+
/* Tab content area: constrain height to prevent page scroll */
|
|
176
|
+
.stTabs [data-baseweb="tab-panel"] {
|
|
177
|
+
max-height: calc(100vh - 12rem) !important;
|
|
178
|
+
overflow-y: auto !important;
|
|
179
|
+
overflow-x: hidden !important;
|
|
180
|
+
scrollbar-width: thin;
|
|
181
|
+
scrollbar-color: #D1D5DB transparent;
|
|
182
|
+
}
|
|
183
|
+
.stTabs [data-baseweb="tab-panel"]::-webkit-scrollbar { width: 4px; }
|
|
184
|
+
.stTabs [data-baseweb="tab-panel"]::-webkit-scrollbar-thumb { background: #D1D5DB; border-radius: 2px; }
|
|
185
|
+
|
|
155
186
|
/* ═══════ FORM INPUTS ═══════ */
|
|
156
187
|
.main .stSelectbox > div > div,
|
|
157
188
|
.main .stTextInput > div > div > input,
|
|
@@ -296,9 +327,15 @@ def render_info_bar(items: dict):
|
|
|
296
327
|
|
|
297
328
|
|
|
298
329
|
def render_page_header(icon: str, title: str, subtitle: str = ""):
|
|
330
|
+
icon_html = f'<span style="margin-right:0.4rem;">{icon}</span>' if icon else ""
|
|
331
|
+
subtitle_html = (
|
|
332
|
+
f'<div style="font-size:0.82rem;color:#6B7280;margin-top:0.1rem;">{subtitle}</div>'
|
|
333
|
+
if subtitle else ""
|
|
334
|
+
)
|
|
299
335
|
st.markdown(
|
|
300
336
|
f'<div style="margin-bottom:0.4rem;">'
|
|
301
|
-
f'<span style="font-size:1.2rem;font-weight:700;color:#1A1A2E;">{title}</span>'
|
|
337
|
+
f'<span style="font-size:1.2rem;font-weight:700;color:#1A1A2E;">{icon_html}{title}</span>'
|
|
338
|
+
f'{subtitle_html}'
|
|
302
339
|
f'</div>',
|
|
303
340
|
unsafe_allow_html=True,
|
|
304
341
|
)
|
|
@@ -124,6 +124,13 @@ VIS_QUEUE_SIZE = 3
|
|
|
124
124
|
VIS_DIR_NAMES = ("visualizations", "plots", "vis")
|
|
125
125
|
VIS_SKIP_FILE = "latest_visualization.jpg"
|
|
126
126
|
GT_VERIFICATION_DIR = "gt_verification"
|
|
127
|
+
GT_REPORT_FILE = "verification_report.json"
|
|
128
|
+
GT_SUMMARY_FILE = "verification_summary.txt"
|
|
129
|
+
TRAINING_LOG_GLOB = "train_*.log"
|
|
130
|
+
ONNX_MODEL_FILE = "model.onnx"
|
|
131
|
+
ONNX_DATA_FILE = "model.onnx.data"
|
|
132
|
+
CONFIG_YAML_FILE = "config.yaml"
|
|
133
|
+
RESULTS_JSON_FILE = "results.json"
|
|
127
134
|
|
|
128
135
|
# ════════════════════════════════════════
|
|
129
136
|
# MODEL ARCHITECTURE
|
|
@@ -135,7 +142,16 @@ MODEL_SIZE_DEFAULT = "n"
|
|
|
135
142
|
|
|
136
143
|
ARCH_FAMILIES = ["FlashDet (recommended)", "YOLOv8", "YOLOv9", "YOLOv10", "YOLOv11", "YOLOX"]
|
|
137
144
|
OPTIMIZERS = ["AdamW", "SGD", "MuSGD"]
|
|
145
|
+
DEFAULT_OPTIMIZER = "AdamW"
|
|
138
146
|
LORA_VARIANTS = ["standard", "dora", "lora_plus", "adalora", "ortho", "lora_fa"]
|
|
147
|
+
LORA_RANK_DEFAULT = 8
|
|
148
|
+
LORA_ALPHA_DEFAULT = 16.0
|
|
149
|
+
LORA_DROPOUT_DEFAULT = 0.05
|
|
150
|
+
LORA_TARGETS_DEFAULT = ["backbone", "fpn"]
|
|
151
|
+
QLORA_DTYPE_DEFAULT = "int8"
|
|
152
|
+
CHUNKED_LOSS_CHUNK_SIZE = 1024
|
|
153
|
+
DEFAULT_FINETUNE_STRATEGY = "Full fine-tune"
|
|
154
|
+
DEFAULT_PRETRAIN_OPTION = "COCO pretrained"
|
|
139
155
|
|
|
140
156
|
FLASHDET_MODELS = {
|
|
141
157
|
"FlashDet-Pico": {"size": "p", "params": "~298K", "speed": "Ultra-fast", "backbone": "LiteBackbone(0.5x)", "neck": "PicoNeck(64ch)", "head": "E2EDualHead", "for": "Edge/Mobile"},
|
|
@@ -159,7 +175,25 @@ ZONE_DEFAULT_POLYGON = "100,100\n500,100\n500,400\n100,400"
|
|
|
159
175
|
# FONT
|
|
160
176
|
# ════════════════════════════════════════
|
|
161
177
|
|
|
162
|
-
|
|
178
|
+
def _resolve_font_path():
|
|
179
|
+
"""Find a usable TrueType font across platforms, with env override."""
|
|
180
|
+
env = os.environ.get("FLASHSTUDIO_FONT_PATH", "")
|
|
181
|
+
if env and os.path.isfile(env):
|
|
182
|
+
return env
|
|
183
|
+
candidates = [
|
|
184
|
+
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", # Debian/Ubuntu
|
|
185
|
+
"/usr/share/fonts/dejavu-sans-fonts/DejaVuSans-Bold.ttf", # Fedora/RHEL
|
|
186
|
+
"/usr/share/fonts/TTF/DejaVuSans-Bold.ttf", # Arch
|
|
187
|
+
"/System/Library/Fonts/Helvetica.ttc", # macOS
|
|
188
|
+
"C:\\Windows\\Fonts\\arial.ttf", # Windows
|
|
189
|
+
]
|
|
190
|
+
for c in candidates:
|
|
191
|
+
if os.path.isfile(c):
|
|
192
|
+
return c
|
|
193
|
+
return ""
|
|
194
|
+
|
|
195
|
+
FONT_PATH = _resolve_font_path()
|
|
196
|
+
FONT_PATH_LINUX = FONT_PATH # backward compat alias
|
|
163
197
|
FONT_SIZE_DEFAULT = 14
|
|
164
198
|
|
|
165
199
|
# ════════════════════════════════════════
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""FlashStudio pages package — each page is a sub-package."""
|
|
2
|
+
|
|
3
|
+
from flashstudio.pages.dashboard.page import render_dashboard # noqa: F401
|
|
4
|
+
from flashstudio.pages.data.page import render_data_page # noqa: F401
|
|
5
|
+
from flashstudio.pages.model.page import render_model_page # noqa: F401
|
|
6
|
+
from flashstudio.pages.training.page import render_training_page # noqa: F401
|
|
7
|
+
from flashstudio.pages.export.page import render_export_page # noqa: F401
|
|
8
|
+
from flashstudio.pages.inference.page import render_inference_page # noqa: F401
|