convitom commited on
Commit ·
3f2d758
1
Parent(s): 5a3b157
scripts/gcp_finetune_vqa_entrypoint.py
CHANGED
|
@@ -103,6 +103,14 @@ CKPT_ROOT = WORK / "ckpt"
|
|
| 103 |
for d in (DATA_SRC, RUN_PULL_ROOT, CKPT_ROOT):
|
| 104 |
d.mkdir(parents=True, exist_ok=True)
|
| 105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
print(f"[gcp_finetune_vqa] PROJECT = {PROJECT}")
|
| 107 |
print(f"[gcp_finetune_vqa] WORK = {WORK}")
|
| 108 |
print(f"[gcp_finetune_vqa] DATASET_NAME = {DATASET_NAME}")
|
|
@@ -220,6 +228,14 @@ TGT_S1_DIR.mkdir(parents=True, exist_ok=True)
|
|
| 220 |
shutil.copy2(SRC_PROJ, TGT_S1_DIR / "stage1_final_projection.pt")
|
| 221 |
print(f"[gcp_finetune_vqa] seeded projection -> {TGT_S1_DIR / 'stage1_final_projection.pt'}")
|
| 222 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
tgt_lora = TGT_S1_DIR / "stage1_final_lora"
|
| 224 |
if tgt_lora.exists():
|
| 225 |
shutil.rmtree(tgt_lora)
|
|
|
|
| 103 |
for d in (DATA_SRC, RUN_PULL_ROOT, CKPT_ROOT):
|
| 104 |
d.mkdir(parents=True, exist_ok=True)
|
| 105 |
|
| 106 |
+
# Make project modules (utils.*, data.*, model.*) importable from this script
|
| 107 |
+
# itself. Python's sys.path includes the SCRIPT's dir (/workspace/code/scripts)
|
| 108 |
+
# but NOT the project root (/workspace/code) when invoked directly. The
|
| 109 |
+
# subprocess we spawn later uses `python -m training.train` which resolves
|
| 110 |
+
# modules relative to cwd, so it's fine — but the pre-flight VQA check below
|
| 111 |
+
# needs `from utils.dataset_resolver import ...` to work in-kernel.
|
| 112 |
+
sys.path.insert(0, str(PROJECT))
|
| 113 |
+
|
| 114 |
print(f"[gcp_finetune_vqa] PROJECT = {PROJECT}")
|
| 115 |
print(f"[gcp_finetune_vqa] WORK = {WORK}")
|
| 116 |
print(f"[gcp_finetune_vqa] DATASET_NAME = {DATASET_NAME}")
|
|
|
|
| 228 |
shutil.copy2(SRC_PROJ, TGT_S1_DIR / "stage1_final_projection.pt")
|
| 229 |
print(f"[gcp_finetune_vqa] seeded projection -> {TGT_S1_DIR / 'stage1_final_projection.pt'}")
|
| 230 |
|
| 231 |
+
# train.py:1043 gates on the LITERAL file `stage1_final.pt` existing (it then
|
| 232 |
+
# passes that path's stem to load_checkpoint, which derives the actual
|
| 233 |
+
# `*_projection.pt` + `*_lora/` paths from it). Without this sentinel the
|
| 234 |
+
# gate fails silently and Stage 2 starts with a RANDOM projection — defeats
|
| 235 |
+
# the entire seed step. The file's content is never read; it's a marker only.
|
| 236 |
+
(TGT_S1_DIR / "stage1_final.pt").touch()
|
| 237 |
+
print(f"[gcp_finetune_vqa] seeded sentinel -> {TGT_S1_DIR / 'stage1_final.pt'} (marker for train.py gate)")
|
| 238 |
+
|
| 239 |
tgt_lora = TGT_S1_DIR / "stage1_final_lora"
|
| 240 |
if tgt_lora.exists():
|
| 241 |
shutil.rmtree(tgt_lora)
|
scripts/vertex_finetune_vqa_job.yaml
CHANGED
|
@@ -52,7 +52,7 @@ workerPoolSpecs:
|
|
| 52 |
env:
|
| 53 |
# ── Required ────────────────────────────────────────────────────────────
|
| 54 |
- name: HF_TOKEN
|
| 55 |
-
value:
|
| 56 |
- name: DATASET_NAME
|
| 57 |
value: MIMIC-CXR_resized
|
| 58 |
- name: SOURCE_RUN_ID
|
|
@@ -85,3 +85,11 @@ scheduling:
|
|
| 85 |
# Stage 2 finetune (3 epochs, mixed batch ~80k samples) on L4 ≈ 3-4h.
|
| 86 |
# 6h ceiling leaves slack for data pull + builder.
|
| 87 |
timeout: 21600s
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
env:
|
| 53 |
# ── Required ────────────────────────────────────────────────────────────
|
| 54 |
- name: HF_TOKEN
|
| 55 |
+
value:
|
| 56 |
- name: DATASET_NAME
|
| 57 |
value: MIMIC-CXR_resized
|
| 58 |
- name: SOURCE_RUN_ID
|
|
|
|
| 85 |
# Stage 2 finetune (3 epochs, mixed batch ~80k samples) on L4 ≈ 3-4h.
|
| 86 |
# 6h ceiling leaves slack for data pull + builder.
|
| 87 |
timeout: 21600s
|
| 88 |
+
# Don't auto-retry on worker failure. When entrypoint asserts (bad path,
|
| 89 |
+
# missing source run, etc.) the retry just re-pulls 40GB tar shards and
|
| 90 |
+
# crashes the same way — wasteful. Set to 1 to fail fast.
|
| 91 |
+
restartJobOnWorkerRestart: false
|
| 92 |
+
# restartJobOnWorkerRestart is for preemption; for hard errors we want
|
| 93 |
+
# explicit no-retry which is the default (replicaCount=1, no replicas
|
| 94 |
+
# spec), but the explicit `disableRetries: true` makes intent clear.
|
| 95 |
+
disableRetries: true
|