Add analysis scripts and experiment configurations for bridge attention and sensitivity studies

- Introduced `bridge_attention_ceiling_check.py` for variance decomposition analysis on bridge attention configurations.
- Added `bridge_attention_readout.py` to perform per-tower gate and contribution readouts, including AUC sanity checks.
- Created multiple JSON configuration files for backbone replication experiments, including anonymous CV variants and basic backbones.
- Implemented sensitivity experiments to evaluate the impact of axial length inclusion and EfficientNetV2-M performance at higher resolutions.
- Added a memory probe script to assess GPU memory usage during training with EfficientNetV2-M.
This commit is contained in:
rpotter6298
2026-07-03 08:51:44 +02:00
parent 3d954a4606
commit 708fbc70ce
52 changed files with 2223 additions and 218 deletions
+11 -3
View File
@@ -168,20 +168,28 @@ def _gpu_info() -> str:
# rsync helpers
# ──────────────────────────────────────────────────────────────
def _rsync(src: str, dst: str, delete: bool = False):
def _rsync(src: str, dst: str, delete: bool = False,
excludes: list[str] | None = None):
cmd = ["rsync", "-az", "--info=progress2"]
if delete:
cmd.append("--delete")
for pat in (excludes or []):
cmd.append(f"--exclude={pat}")
cmd += [src, dst]
subprocess.run(cmd, check=True)
def _sync_code(server_ssh: str, server_path: str, local_path: str):
"""Pull v4/ source from server → local (overwrites local changes)."""
"""Pull v4/ source from server → local (overwrites local changes).
results/ is excluded so the client never overwrites or deletes its own
per-job output directory, and so it never pulls down the full corpus of
historical results from the server.
"""
src = f"{server_ssh}:{server_path}/v4/"
dst = f"{local_path}/v4/"
Path(dst).mkdir(parents=True, exist_ok=True)
_rsync(src, dst, delete=True)
_rsync(src, dst, delete=True, excludes=["results/"])
def _upload_results(server_ssh: str, server_path: str, local_path: str,
Binary file not shown.
+26 -1
View File
@@ -413,8 +413,33 @@ def submit_job(job: JobSubmit):
)
if cur.rowcount == 0:
existing = conn.execute(
"SELECT job_id FROM jobs WHERE args=?", (args_json,)
"SELECT job_id, state FROM jobs WHERE args=?", (args_json,)
).fetchone()
# If the existing duplicate is a terminal failure, drop it and
# take the new submission — saves an explicit /jobs/clear round-
# trip when re-deploying after a fix.
if existing["state"] == "failed":
conn.execute(
"DELETE FROM jobs WHERE job_id=?", (existing["job_id"],)
)
conn.execute(
"INSERT INTO jobs "
"(job_id, run_name, module, args, output_dir, priority, created_at) "
"VALUES (?,?,?,?,?,?,?)",
(job_id, job.run_name, job.module, args_json,
job.output_dir, job.priority, _now()),
)
print(
f"[server] requeued failed {existing['job_id']}{job_id} "
f"({job.run_name})",
flush=True,
)
return {
"job_id": job_id,
"duplicate": False,
"requeued": True,
"previous_job_id": existing["job_id"],
}
job_id = existing["job_id"]
print(f"[server] duplicate ignored ({job.run_name}) → {job_id}", flush=True)
return {"job_id": job_id, "duplicate": True}