File size: 5,464 Bytes
da08b7d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | #!/bin/bash
#SBATCH --job-name=monitor_eval
#SBATCH --account=def-yalda
#SBATCH --time=12:00:00
#SBATCH --cpus-per-task=1
#SBATCH --mem=2G
#SBATCH --output=logs/monitor_eval_%j.out
#SBATCH --error=logs/monitor_eval_%j.err
# Autonomous monitor: Check eval job → parse results → trigger paper writing
# Runs on compute node, NOT login node
set -euo pipefail
EVAL_JOB_ID=14758888
PROJECT_DIR="/lustre09/project/6037638/knguy52/vla"
PYTHON="$PROJECT_DIR/.venv/bin/python"
cd "$PROJECT_DIR"
echo "=== Autonomous Evaluation Monitor Started ==="
echo "Watching job: $EVAL_JOB_ID"
echo "Start time: $(date)"
echo ""
# Function to check job status
check_job_status() {
sacct -j $1 --format=State --noheader -X 2>/dev/null | head -1 | awk '{print $1}'
}
# Function to check if all array tasks completed
check_array_complete() {
local job_id=$1
local states=$(sacct -j ${job_id} --format=State --noheader 2>/dev/null | grep -v "^$")
local total=$(echo "$states" | wc -l)
local completed=$(echo "$states" | grep -c "COMPLETED" || true)
if [ "$total" -gt 0 ] && [ "$completed" -eq "$total" ]; then
echo "COMPLETED"
elif echo "$states" | grep -q "FAILED\|CANCELLED\|TIMEOUT"; then
echo "FAILED"
else
echo "RUNNING"
fi
}
# Monitor loop
while true; do
STATUS=$(check_array_complete $EVAL_JOB_ID)
echo "[$(date +'%H:%M:%S')] Job status: $STATUS"
if [ "$STATUS" = "COMPLETED" ]; then
echo ""
echo "✅ Evaluation completed! Processing results..."
echo ""
# Parse results from all 3 seeds
$PYTHON << 'PYEOF'
import json
from pathlib import Path
results_dir = Path("/scratch/knguy52/dovla/experiments/h16_policy_runs")
seeds = [0, 1, 2]
all_results = []
for seed in seeds:
result_file = results_dir / f"seed_{seed}" / "online_rollout.json"
if result_file.exists():
with open(result_file) as f:
data = json.load(f)
all_results.append({
'seed': seed,
'policy_success': data.get('policy_rollout_success_rate', 0),
'per_task': data.get('per_task', {})
})
if not all_results:
print("❌ No results found!")
exit(1)
# Compute statistics
import statistics
success_rates = [r['policy_success'] for r in all_results]
mean_success = statistics.mean(success_rates)
std_success = statistics.stdev(success_rates) if len(success_rates) > 1 else 0
baseline = 0.2967
print("="*60)
print("📊 EVALUATION RESULTS")
print("="*60)
print(f"Policy Success Rate: {mean_success:.2%} ± {std_success:.2%}")
print(f"Baseline (h=4): {baseline:.2%}")
print(f"Absolute Gain: +{(mean_success - baseline):.2%}")
print(f"Relative Gain: {(mean_success / baseline):.2f}×")
print("")
# Per-task breakdown
print("Per-Task Breakdown:")
task_names = set()
for r in all_results:
task_names.update(r['per_task'].keys())
for task in sorted(task_names):
rates = [r['per_task'][task]['policy_rollout_success_rate']
for r in all_results if task in r['per_task']]
if rates:
mean_rate = statistics.mean(rates)
print(f" {task:25s} {mean_rate:6.2%}")
print("="*60)
# Save summary
summary = {
'mean_success_rate': mean_success,
'std_success_rate': std_success,
'baseline': baseline,
'absolute_gain': mean_success - baseline,
'relative_gain': mean_success / baseline,
'per_task_mean': {
task: statistics.mean([r['per_task'][task]['policy_rollout_success_rate']
for r in all_results if task in r['per_task']])
for task in task_names
},
'seeds': all_results
}
summary_path = Path("results/h16_evaluation_summary.json")
summary_path.parent.mkdir(parents=True, exist_ok=True)
with open(summary_path, 'w') as f:
json.dump(summary, f, indent=2)
print(f"Summary saved: {summary_path}")
# Trigger paper writing if results are good
if mean_success >= 0.55:
print("")
print("✅ Results meet A* threshold (≥55%)!")
print(" Triggering paper writing workflow...")
Path("results/.trigger_paper_writing").touch()
else:
print("")
print("⚠️ Results below target. Analysis needed.")
PYEOF
# Submit paper writing job if triggered
if [ -f "results/.trigger_paper_writing" ]; then
echo ""
echo "Submitting paper writing job..."
sbatch scripts/slurm/write_paper_draft.sbatch
fi
# Upload results to HF
echo ""
echo "Uploading results to HuggingFace..."
$PYTHON -c "
from huggingface_hub import upload_file
import sys
try:
upload_file(
path_or_fileobj='results/h16_evaluation_summary.json',
path_in_repo='results/h16_evaluation_summary.json',
repo_id='anhtld/vla',
commit_message='Add h=16 evaluation results (THE decisive number)'
)
print('✅ Results uploaded to HF')
except Exception as e:
print(f'⚠️ Upload failed: {e}', file=sys.stderr)
"
echo ""
echo "=== Monitor Complete ==="
exit 0
elif [ "$STATUS" = "FAILED" ]; then
echo ""
echo "❌ Evaluation failed. Checking logs..."
sacct -j $EVAL_JOB_ID --format=JobID,State,ExitCode,Reason
echo ""
echo "Check logs in: outputs/hpc/logs/eval_h16_rollout_${EVAL_JOB_ID}_*.{out,err}"
exit 1
fi
# Sleep 5 minutes before next check
sleep 300
done
|