# Vertex AI Custom Job — CXR-VLM EVALUATION on L4 # # Submit with: # gcloud ai custom-jobs create \ # --region=us-central1 \ # --display-name=cxr-vlm-eval-run1 \ # --config=scripts/vertex_eval_job.yaml # # Watch logs (streaming): # gcloud ai custom-jobs stream-logs --region=us-central1 # # This reuses the SAME Docker image you trained with — no rebuild needed. # Quota: uses CustomModelTrainingNvidiaL4Gpus (NOT global GPU quota), so it # works even when Workbench / Compute Engine GPU creation is blocked. # # Output: # - Predictions + metrics_summary.json land under # /workspace/results// inside the container # - With UPLOAD_RESULTS_TO_HF=1 they're also uploaded to # hieu3636/cxr-vlm-runs//results/ # (After the job ends the container is destroyed, so HF upload is what you'll # actually retrieve afterward.) # # Typical wall-clock on L4 for MIMIC-CXR_resized (10k test samples, all tasks): # ~1.5-2.5 hours total (3-5x faster than T4). workerPoolSpecs: - machineSpec: machineType: g2-standard-8 # 8 vCPU, 32GB RAM, 1×L4 24GB acceleratorType: NVIDIA_L4 acceleratorCount: 1 replicaCount: 1 diskSpec: bootDiskType: pd-ssd bootDiskSizeGb: 200 # enough for MIMIC-CXR_resized (~40GB extracted) + Vicuna cache containerSpec: imageUri: us-central1-docker.pkg.dev/cxr-vlm-thesis/cxr-vlm/cxr-vlm-env:cu128 # Same bootstrap pattern as the training job: pull code from HF Hub, # then exec the eval entrypoint. command: - bash - -c - | set -e echo "[bootstrap] downloading code from HF Hub …" python -c " from huggingface_hub import snapshot_download import os snapshot_download('hieu3636/cxr-vlm-code', repo_type='model', token=os.environ['HF_TOKEN'], local_dir='/workspace/code') " cd /workspace/code echo "[bootstrap] exec scripts/gcp_eval_entrypoint.py …" exec python scripts/gcp_eval_entrypoint.py env: # ── Required ──────────────────────────────────────────────────────────── - name: HF_TOKEN value: _tSxYqkUSvesmWQOtoyrNpsHmfZlNFVUDRb - name: DATASET_NAME value: MIMIC-CXR_resized # 'IU-Xray' | 'MIMIC-CXR' | 'MIMIC-CXR_resized' - name: RUN_ID value: MIMIC-CXR_resized_run_3 # which run on HF_RUNS_REPO to evaluate # ── Optional ──────────────────────────────────────────────────────────── - name: HF_RUNS_REPO value: hieu3636/cxr-vlm-runs - name: CKPT_PICK value: best # 'best' | 'last' # ── Which tasks to (re-)evaluate — per-task toggles like the notebook ── # Re-running a subset MERGES into the existing metrics_summary.json, so the # other tasks' numbers are preserved. Below: re-eval ONLY findings + # impression (VQA off). Flip EVAL_VQA to "1" to include VQA. - name: EVAL_FINDINGS value: "1" - name: EVAL_IMPRESSION value: "1" - name: EVAL_VQA value: "0" # - name: EVAL_REPORT # value: "0" # only for merged report_mode runs # Optional explicit override (e.g. "all" / "vqa"); blank → derive from EVAL_*. # - name: TASK # value: all - name: SPLIT value: test # PNU prompt-condition source. 'oracle' = GT chex_* labels from JSON; # 'predicted' = run the Stage-0 CheXpert classifier per image (realistic). - name: PNU_SOURCE value: predicted # 'oracle' | 'predicted' # Classifier checkpoint on HF_RUNS_REPO (only used when PNU_SOURCE=predicted). - name: CHEXPERT_CKPT_PATH value: chexpert_classifier/chexpert_mimic_resized.pt - name: MAX_NEW_TOKENS value: "300" - name: UPLOAD_RESULTS_TO_HF value: "1" # '0' to disable HF upload # Leave REPORT_MODE / IMAGE_MODE blank → use the run's saved snapshot. # Set explicitly only if you need to override (rare). # - name: REPORT_MODE # value: split_cascade # - name: IMAGE_MODE # value: all_views_split # Leave BATCH_SIZE blank → auto from GPU profile (L4 -> 4). # - name: BATCH_SIZE # value: "8" # LLM-as-judge for VQA (extra cost; needs OPENAI_API_KEY). # - name: LLM_JUDGE # value: "1" # - name: OPENAI_API_KEY # value: sk-... # - name: LLM_JUDGE_MODEL # value: gpt-4o-mini scheduling: # STANDARD on-demand. Eval is short (~2h) so spot interruption isn't worth # the risk — evaluate.py doesn't checkpoint mid-task. If preempted you'd # restart from the beginning. strategy: STANDARD # 6h ceiling. MIMIC-CXR_resized on L4 finishes in ~2h; raise this if # you're evaluating the full MIMIC-CXR with VQA. timeout: 21600s