Update app.py
Browse files
app.py
CHANGED
|
@@ -74,7 +74,6 @@ except Exception:
|
|
| 74 |
logging.exception("Bootstrap failed, UI will still load so you can see errors")
|
| 75 |
|
| 76 |
# === model choices (restricted to Supervisely RT-DETRv2) ======================
|
| 77 |
-
# Exact mapping to configs and reference COCO checkpoints you provided
|
| 78 |
MODEL_CHOICES = [
|
| 79 |
("rtdetrv2_s", "S (r18vd, 120e) β default"),
|
| 80 |
("rtdetrv2_m", "M (r34vd, 120e)"),
|
|
@@ -115,7 +114,7 @@ _ROBO_URL_RX = re.compile(r"""
|
|
| 115 |
|
|
| 116 |
(?P<ws2>[A-Za-z0-9\-_]+)/(?P<proj2>[A-Za-z0-9\-_]+)(?:/(?:v)?(?P<ver2>\d+))?
|
| 117 |
)$
|
| 118 |
-
""", re.
|
| 119 |
|
| 120 |
def parse_roboflow_url(s: str):
|
| 121 |
s = s.strip()
|
|
@@ -441,10 +440,7 @@ def _set_first_existing_key_deep(cfg: dict, keys: list, value):
|
|
| 441 |
|
| 442 |
def _install_supervisely_logger_shim():
|
| 443 |
"""
|
| 444 |
-
Create a
|
| 445 |
-
supervisely/nn/training/__init__.py -> exposes train_logger
|
| 446 |
-
Ensures 'from supervisely.nn.training import train_logger' works even if the
|
| 447 |
-
installed 'supervisely' no longer provides it.
|
| 448 |
"""
|
| 449 |
root = pathlib.Path(tempfile.gettempdir()) / "sly_shim_pkg"
|
| 450 |
pkg_training = root / "supervisely" / "nn" / "training"
|
|
@@ -456,7 +452,7 @@ def _install_supervisely_logger_shim():
|
|
| 456 |
if not init_file.exists():
|
| 457 |
init_file.write_text("")
|
| 458 |
|
| 459 |
-
#
|
| 460 |
(pkg_training / "__init__.py").write_text(textwrap.dedent("""
|
| 461 |
# Minimal shim for backward-compat with older RT-DETRv2 training code.
|
| 462 |
class _TrainLogger:
|
|
@@ -467,14 +463,9 @@ def _install_supervisely_logger_shim():
|
|
| 467 |
def log_image(self, *a, **k): pass
|
| 468 |
train_logger = _TrainLogger()
|
| 469 |
"""))
|
| 470 |
-
# Return path to prepend to PYTHONPATH
|
| 471 |
return str(root)
|
| 472 |
|
| 473 |
def _ensure_checkpoint(model_key: str, out_dir: str) -> str | None:
|
| 474 |
-
"""
|
| 475 |
-
Download the reference COCO checkpoint for the selected model if not present.
|
| 476 |
-
Returns local path (or None if not available).
|
| 477 |
-
"""
|
| 478 |
url = CKPT_URLS.get(model_key)
|
| 479 |
if not url:
|
| 480 |
return None
|
|
@@ -500,6 +491,29 @@ def _ensure_checkpoint(model_key: str, out_dir: str) -> str | None:
|
|
| 500 |
pass
|
| 501 |
return None
|
| 502 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 503 |
def patch_base_config(base_cfg_path, merged_dir, class_count, run_name,
|
| 504 |
epochs, batch, imgsz, lr, optimizer, pretrained_path: str | None):
|
| 505 |
if not base_cfg_path or not os.path.exists(base_cfg_path):
|
|
@@ -508,6 +522,9 @@ def patch_base_config(base_cfg_path, merged_dir, class_count, run_name,
|
|
| 508 |
with open(base_cfg_path, "r") as f:
|
| 509 |
cfg = yaml.safe_load(f)
|
| 510 |
|
|
|
|
|
|
|
|
|
|
| 511 |
ann_dir = os.path.join(merged_dir, "annotations")
|
| 512 |
paths = {
|
| 513 |
"train_json": os.path.abspath(os.path.join(ann_dir, "instances_train.json")),
|
|
@@ -970,7 +987,6 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="sky")) as app:
|
|
| 970 |
|
| 971 |
if __name__ == "__main__":
|
| 972 |
os.environ.setdefault("YOLO_CONFIG_DIR", "/tmp/Ultralytics") # silence stray warnings from other libs
|
| 973 |
-
# Log training script resolution at startup for quick troubleshooting
|
| 974 |
try:
|
| 975 |
ts = find_training_script(REPO_DIR)
|
| 976 |
logging.info(f"Startup check β training script at: {ts}")
|
|
|
|
| 74 |
logging.exception("Bootstrap failed, UI will still load so you can see errors")
|
| 75 |
|
| 76 |
# === model choices (restricted to Supervisely RT-DETRv2) ======================
|
|
|
|
| 77 |
MODEL_CHOICES = [
|
| 78 |
("rtdetrv2_s", "S (r18vd, 120e) β default"),
|
| 79 |
("rtdetrv2_m", "M (r34vd, 120e)"),
|
|
|
|
| 114 |
|
|
| 115 |
(?P<ws2>[A-Za-z0-9\-_]+)/(?P<proj2>[A-Za-z0-9\-_]+)(?:/(?:v)?(?P<ver2>\d+))?
|
| 116 |
)$
|
| 117 |
+
""", re.VERBOSE | re.IGNORECASE)
|
| 118 |
|
| 119 |
def parse_roboflow_url(s: str):
|
| 120 |
s = s.strip()
|
|
|
|
| 440 |
|
| 441 |
def _install_supervisely_logger_shim():
|
| 442 |
"""
|
| 443 |
+
Create a package shim so 'from supervisely.nn.training import train_logger' works.
|
|
|
|
|
|
|
|
|
|
| 444 |
"""
|
| 445 |
root = pathlib.Path(tempfile.gettempdir()) / "sly_shim_pkg"
|
| 446 |
pkg_training = root / "supervisely" / "nn" / "training"
|
|
|
|
| 452 |
if not init_file.exists():
|
| 453 |
init_file.write_text("")
|
| 454 |
|
| 455 |
+
# Expose train_logger from the package's __init__
|
| 456 |
(pkg_training / "__init__.py").write_text(textwrap.dedent("""
|
| 457 |
# Minimal shim for backward-compat with older RT-DETRv2 training code.
|
| 458 |
class _TrainLogger:
|
|
|
|
| 463 |
def log_image(self, *a, **k): pass
|
| 464 |
train_logger = _TrainLogger()
|
| 465 |
"""))
|
|
|
|
| 466 |
return str(root)
|
| 467 |
|
| 468 |
def _ensure_checkpoint(model_key: str, out_dir: str) -> str | None:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 469 |
url = CKPT_URLS.get(model_key)
|
| 470 |
if not url:
|
| 471 |
return None
|
|
|
|
| 491 |
pass
|
| 492 |
return None
|
| 493 |
|
| 494 |
+
def _absify_base_includes(cfg: dict, base_cfg_path: str):
|
| 495 |
+
"""
|
| 496 |
+
If the upstream template uses relative 'base' includes (e.g. '../dataset/coco_detection.yml'),
|
| 497 |
+
rewrite them to absolute paths so loading your generated config outside the repo tree works.
|
| 498 |
+
"""
|
| 499 |
+
if not isinstance(cfg, dict):
|
| 500 |
+
return
|
| 501 |
+
repo_base_dir = os.path.dirname(base_cfg_path)
|
| 502 |
+
for key in ("base", "_base_", "BASE", "BASE_YAML"):
|
| 503 |
+
if key in cfg:
|
| 504 |
+
val = cfg[key]
|
| 505 |
+
if isinstance(val, str):
|
| 506 |
+
if not os.path.isabs(val):
|
| 507 |
+
cfg[key] = os.path.abspath(os.path.join(repo_base_dir, val))
|
| 508 |
+
elif isinstance(val, list):
|
| 509 |
+
new_list = []
|
| 510 |
+
for item in val:
|
| 511 |
+
if isinstance(item, str) and not os.path.isabs(item):
|
| 512 |
+
new_list.append(os.path.abspath(os.path.join(repo_base_dir, item)))
|
| 513 |
+
else:
|
| 514 |
+
new_list.append(item)
|
| 515 |
+
cfg[key] = new_list
|
| 516 |
+
|
| 517 |
def patch_base_config(base_cfg_path, merged_dir, class_count, run_name,
|
| 518 |
epochs, batch, imgsz, lr, optimizer, pretrained_path: str | None):
|
| 519 |
if not base_cfg_path or not os.path.exists(base_cfg_path):
|
|
|
|
| 522 |
with open(base_cfg_path, "r") as f:
|
| 523 |
cfg = yaml.safe_load(f)
|
| 524 |
|
| 525 |
+
# <<< Fix: ensure 'base' includes are absolute, not relative to generated_configs >>>
|
| 526 |
+
_absify_base_includes(cfg, base_cfg_path)
|
| 527 |
+
|
| 528 |
ann_dir = os.path.join(merged_dir, "annotations")
|
| 529 |
paths = {
|
| 530 |
"train_json": os.path.abspath(os.path.join(ann_dir, "instances_train.json")),
|
|
|
|
| 987 |
|
| 988 |
if __name__ == "__main__":
|
| 989 |
os.environ.setdefault("YOLO_CONFIG_DIR", "/tmp/Ultralytics") # silence stray warnings from other libs
|
|
|
|
| 990 |
try:
|
| 991 |
ts = find_training_script(REPO_DIR)
|
| 992 |
logging.info(f"Startup check β training script at: {ts}")
|