File size: 6,545 Bytes
2d5c26a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/usr/bin/env bash
# Run on the named Spark after source, isolated Python, data and artifacts arrive.
# Usage: bash scripts/start_spark_candidate.sh spark-a|spark-b /absolute/fresh/setup-dir
# This script never connects over SSH. Successful setup leaves a detached,
# train-only campaign; its status and stop/resume commands belong to that campaign.
set -euo pipefail

if [[ $# -ne 2 ]]; then
  echo 'Usage: start_spark_candidate.sh spark-a|spark-b /absolute/fresh/setup-dir' >&2
  exit 2
fi
SPARK_NAME="$1"
SETUP_DIR="$2"
case "$SPARK_NAME" in
  spark-a) EXPECTED_HOST=spark-d1b4; MODEL_NAME=Qwen3-4B-Instruct-2507-cdbee75f ;;
  spark-b) EXPECTED_HOST=spark-3e2a; MODEL_NAME=Qwen3.5-2B-15852e8c ;;
  *) echo 'Expected spark-a or spark-b.' >&2; exit 2 ;;
esac
case "$SETUP_DIR" in
  /*) ;;
  *) echo 'SETUP_DIR must be an absolute, fresh directory.' >&2; exit 2 ;;
esac
if [[ -e "$SETUP_DIR" || -L "$SETUP_DIR" ]]; then
  echo "Refusing an existing SETUP_DIR: $SETUP_DIR" >&2
  exit 2
fi
mkdir -p -- "$(dirname -- "$SETUP_DIR")"
mkdir -- "$SETUP_DIR"
SETUP_STAGE=initializing
finish() {
  local setup_exit=$?
  local setup_status=failed
  [[ $setup_exit -eq 0 ]] && setup_status=completed
  set +e
  printf '%s\n' "$setup_exit" > "$SETUP_DIR/exit_code"
  printf '{"stage":"%s","status":"%s","exit_code":%d,"finished_utc":"%s"}\n' \
    "$SETUP_STAGE" "$setup_status" "$setup_exit" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
    > "$SETUP_DIR/status.json"
  printf '%s %s exit_code=%s stage=%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
    "$setup_status" "$setup_exit" "$SETUP_STAGE" | tee -a "$SETUP_DIR/stages.log"
}
trap finish EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
stage() {
  SETUP_STAGE="$1"
  printf '%s\n' "$SETUP_STAGE" > "$SETUP_DIR/stage"
  printf '%s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$SETUP_STAGE" \
    | tee -a "$SETUP_DIR/stages.log"
}

cd "$(dirname "$0")/.."
stage preflight
[[ "$(hostname)" == "$EXPECTED_HOST" ]] || { echo "Expected host $EXPECTED_HOST" >&2; exit 2; }
printf '0\n' > /proc/self/oom_score_adj
export PYTHONUNBUFFERED=1 PYTHONNOUSERSITE=1 TOKENIZERS_PARALLELISM=false
export HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 HF_HUB_DISABLE_XET=1
export PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True
export OPENSYSONE_PYTHON=/home/andy/ai/envs/opensysone/bin/python
export OPENSYSONE_RUN_ROOT=/home/andy/ai/opensysone/runs
RUN_PYTHON="$OPENSYSONE_PYTHON"
MODEL_PATH="/home/andy/ai/models/opensysone/$MODEL_NAME"
MODEL_MANIFEST="/home/andy/ai/opensysone/bootstrap/$MODEL_NAME-files.json"
DATASET=/home/andy/ai/opensysone/data/public-decisions-v1-20260916
[[ -x "$RUN_PYTHON" && -d "$DATASET" && -f "$MODEL_MANIFEST" ]]
git rev-parse HEAD > "$SETUP_DIR/source_commit"
git status --porcelain > "$SETUP_DIR/source_status"

stage model_copy_verification
timeout --signal=TERM --kill-after=30s 5m "$RUN_PYTHON" - \
  "$MODEL_PATH" "$MODEL_MANIFEST" "$SETUP_DIR/model-copy-verified.json" <<'PY'
import hashlib, json, pathlib, sys
from datetime import datetime, timezone
model, manifest_path, output = map(pathlib.Path, sys.argv[1:])
manifest = json.loads(manifest_path.read_text())
if manifest['model'] != model.name or len(manifest['files']) != 13:
    raise ValueError('Unexpected model manifest identity or file count')
verified = {}
for name, expected in manifest['files'].items():
    relative = pathlib.Path(name)
    if relative.is_absolute() or '..' in relative.parts:
        raise ValueError('Model manifest path escapes model directory')
    path = model / relative
    if not path.is_file() or path.stat().st_size != expected['bytes']:
        raise ValueError(f'Missing or incomplete model file: {name}')
    digest = hashlib.sha256()
    with path.open('rb') as handle:
        for chunk in iter(lambda: handle.read(8 * 1024 * 1024), b''):
            digest.update(chunk)
    if digest.hexdigest() != expected['sha256']:
        raise ValueError(f'Model checksum mismatch: {name}')
    verified[name] = expected
proof = {'model': str(model), 'manifest': str(manifest_path),
         'manifest_sha256': hashlib.sha256(manifest_path.read_bytes()).hexdigest(),
         'files': verified, 'verified_utc': datetime.now(timezone.utc).isoformat()}
output.write_text(json.dumps(proof, indent=2) + '\n')
print(json.dumps({'event': 'model_copy_verified', 'model': str(model), 'files': len(verified)}))
PY

memory_preflight() {
  timeout 15s free -b
  timeout 15s nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv
}

if [[ "$SPARK_NAME" == spark-a ]]; then
  stage warm_start_pilot
  memory_preflight
  bash scripts/run_experiment.sh train \
    --warm-start /home/andy/ai/opensysone/runs/20260916T183823Z-train/artifacts/checkpoint.pt \
    --model "$MODEL_PATH" --dataset "$DATASET" --steps 8 --epochs 3 \
    --rank 8 --alpha 16 --lr 3e-5 --head-lr 3e-5 --seed 431 \
    --effective-batch 4 --branch-batch-size 1 --max-tokens 512 --two-pass \
    --schedule-steps 7500 --validation-per-family 128 \
    --eval-steps 500 --save-steps 250 --save-seconds 900 --patience 8
  IFS= read -r PILOT_RUN < "$OPENSYSONE_RUN_ROOT/LAST_EXPERIMENT_RUN"
  [[ -f "$PILOT_RUN/exit_code" && "$(cat "$PILOT_RUN/exit_code")" == 0 ]]
  PILOT="$PILOT_RUN/artifacts"
  REFERENCE="$PILOT/validation_step_000008_predictions.json"
else
  PILOT=/home/andy/ai/opensysone/runs/20260916T182352Z-train/artifacts
  REFERENCE="$PILOT/validation_step_000040_predictions.json"
fi
printf '%s\n' "$PILOT" > "$SETUP_DIR/pilot_path"
[[ -f "$PILOT/checkpoint.pt" && -f "$PILOT/best.pt" && -f "$REFERENCE" ]]

stage artifact_verification
memory_preflight
timeout --signal=TERM --kill-after=30s 15m "$RUN_PYTHON" scripts/verify_artifact.py \
  --checkpoint "$PILOT/checkpoint.pt" --reference "$REFERENCE" \
  --inference-max-tokens 1024 --output "$SETUP_DIR/verify"

stage campaign_launch
memory_preflight
timeout --signal=TERM --kill-after=30s 2m "$RUN_PYTHON" scripts/launch_24h.py \
  --pilot "$PILOT" --train-only --training-deadline 2026-09-17T16:00:00Z \
  --deadline 2026-09-17T18:16:10Z --inference-max-tokens 1024 \
  | tee "$SETUP_DIR/launcher.json"
cp -- "$OPENSYSONE_RUN_ROOT/LAST_CAMPAIGN" "$SETUP_DIR/campaign_path"
"$RUN_PYTHON" - "$SETUP_DIR" <<'PY'
import json, pathlib, sys
setup = pathlib.Path(sys.argv[1])
launched = json.loads((setup / 'launcher.json').read_text())
if launched['campaign'] != (setup / 'campaign_path').read_text().strip():
    raise RuntimeError('Campaign pointer differs from launcher result')
print(json.dumps({'event': 'train_only_campaign_launched', **launched}))
PY
stage campaign_running