Download scripts/queue_after_tune.sh from Anonymous1611/Lattice_Spike: direct link, hf CLI and curl.
- Browser
- Download file 6.22 kB
-
https://huggingface.co/Anonymous1611/Lattice_Spike/resolve/main/scripts/queue_after_tune.sh
- Command line
-
hf download hf://Anonymous1611/Lattice_Spike/scripts/queue_after_tune.sh
-
curl -L -o queue_after_tune.sh https://huggingface.co/Anonymous1611/Lattice_Spike/resolve/main/scripts/queue_after_tune.sh
6.22 kB
| # Wait for the tune sweep to finish, then run the queued work unattended. | |
| # | |
| # The sweep holds the GPU for hours and the next two jobs both need it, so this | |
| # blocks until it is genuinely done rather than racing it. "Done" means no | |
| # LatticeSpike trainer is alive AND the tune session is gone -- either alone is | |
| # not enough, because the session outlives the last arm briefly while it writes | |
| # the summary table, and a trainer can be alive during a gap between waves. | |
| # | |
| # Steps run in order and a failure does not stop the rest: each is independently | |
| # useful, and losing the TriviaQA pilot should not cost the seed-44 run that | |
| # already succeeded. | |
| # | |
| # tmux new -s queue 'bash scripts/queue_after_tune.sh 2>&1 | tee outputs/queue.log' | |
| # | |
| # Skip individual steps: | |
| # SKIP_SEED44=1 bash scripts/queue_after_tune.sh | |
| # SKIP_TRIVIAQA=1 bash scripts/queue_after_tune.sh | |
| set -u -o pipefail | |
| REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"; cd "$REPO" | |
| PY="${PY:-$REPO/.venv/bin/python}" | |
| POLL="${POLL:-120}" | |
| WAIT_FOR="${WAIT_FOR:-tune}" | |
| PILOT_N="${PILOT_N:-200}" | |
| DATA="$HOME/datasets/hallucinations_custom/ragtruth_llama2_7b_chat.jsonl" | |
| SPLIT="$HOME/datasets/hallucinations_custom/ragtruth_llama2_7b_chat_split.json" | |
| SIGNALS="outputs/ragtruth_l2_7b_signals" | |
| say () { printf '\n=== %s %s\n' "$1" "$(date -Is)"; } | |
| # --- wait ------------------------------------------------------------------- | |
| say "waiting for the '$WAIT_FOR' session and all LatticeSpike trainers to exit" | |
| waited=0 | |
| while true; do | |
| session_alive=0; trainer_alive=0 | |
| tmux has-session -t "$WAIT_FOR" 2>/dev/null && session_alive=1 | |
| pgrep -f train_latticespike_llm_eval.py > /dev/null 2>&1 && trainer_alive=1 | |
| if (( session_alive == 0 && trainer_alive == 0 )); then | |
| break | |
| fi | |
| # Report every ~30 min so a long wait does not look like a hang. | |
| if (( waited % 900 == 0 )); then | |
| running=$(pgrep -cf train_latticespike_llm_eval.py 2>/dev/null || echo 0) | |
| printf ' [%s] session=%s trainers=%s (waited %dm)\n' \ | |
| "$(date +%H:%M)" "$session_alive" "$running" "$((waited / 60))" | |
| fi | |
| sleep "$POLL"; waited=$(( waited + POLL )) | |
| done | |
| say "clear after $((waited / 60))m -- starting queued work" | |
| # --- 1. the sweep's own ranked table ---------------------------------------- | |
| # The sweep prints this itself, but only if it exited cleanly; reprinting costs | |
| # nothing and means the queue log is self-contained. | |
| say "sweep results" | |
| if [[ -d outputs/rt_tune ]]; then | |
| "$PY" - outputs/rt_tune <<'PYEOF' || true | |
| import json, glob, os, sys | |
| root = sys.argv[1] | |
| rows = [] | |
| for f in sorted(glob.glob(os.path.join(root, "*", "summary.json"))): | |
| s = json.load(open(f)) | |
| rows.append(( | |
| (s.get("validation_eval") or {}).get("auprc", 0), | |
| (s.get("eval") or {}).get("auprc", 0), | |
| (s.get("eval") or {}).get("auroc", 0), | |
| (s.get("checkpoint_selection") or {}).get("best_epoch"), | |
| (s.get("training") or {}).get("epochs"), | |
| os.path.basename(os.path.dirname(f)), | |
| )) | |
| rows.sort(reverse=True) | |
| ctrl = next((r for r in rows if r[5] == "ctrl_s42"), None) | |
| base = ctrl[0] if ctrl else None | |
| print("%-12s%9s%9s%9s%9s%8s" % ("arm", "VAL AP", "dVAL", "TEST AP", "AUROC", "epoch")) | |
| print("-" * 56) | |
| for v, t, a, be, ep, n in rows: | |
| d = "--" if base is None else "%+.4f" % (v - base) | |
| print("%-12s%9.4f%9s%9.4f%9.4f%7s%s" % (n, v, d, t, a, be, "*" if be == ep else " ")) | |
| PYEOF | |
| fi | |
| # --- 2. seed 44 of the control ---------------------------------------------- | |
| # The two-seed spread is 0.0091 and our AP lead over the probe is 0.0074, so the | |
| # third seed is what decides whether that lead is a result. Runs on the current | |
| # config: if a sweep arm wins, the winner needs its own seeds regardless, and | |
| # this still stands as the control's third point. | |
| if [[ "${SKIP_SEED44:-0}" == "1" ]]; then | |
| say "seed 44 skipped" | |
| elif [[ -f outputs/rt_ctrl_s44/summary.json ]]; then | |
| say "seed 44 already done" | |
| else | |
| say "seed 44 (control config)" | |
| mkdir -p outputs/rt_ctrl_s44 | |
| "$PY" -u scripts/train_latticespike_llm_eval.py \ | |
| --input "$DATA" --split-summary "$SPLIT" \ | |
| --model NousResearch/Llama-2-7b-chat-hf --allow-unpinned-model \ | |
| --prompt-template raw --allow-unverified-replay --tie-box-token-emb \ | |
| --skip-extract \ | |
| --lam-contain 0 --lam-vol 0 --lam-recon 0 --lam-mrl 0 \ | |
| --rank-objective ap --lam-rank 12 --ap-tau 0.25 \ | |
| --epochs 10 --seed 44 \ | |
| --signals-dir "$SIGNALS" \ | |
| --out-dir outputs/rt_ctrl_s44 --summary outputs/rt_ctrl_s44/summary.json \ | |
| > outputs/rt_ctrl_s44/run.log 2>&1 \ | |
| && echo " seed 44 OK" \ | |
| || { echo " seed 44 FAILED"; tail -4 outputs/rt_ctrl_s44/run.log | sed 's/^/ /'; } | |
| # Three seeds is the point of this, so print the spread as soon as it exists. | |
| "$PY" - <<'PYEOF' || true | |
| import json, os | |
| paths = {"s42": "outputs/rt_tune/ctrl_s42/summary.json", | |
| "s43": "outputs/rt_tune/ctrl_s43/summary.json", | |
| "s44": "outputs/rt_ctrl_s44/summary.json"} | |
| ap = {} | |
| for k, p in paths.items(): | |
| if os.path.exists(p): | |
| ap[k] = (json.load(open(p)).get("eval") or {}).get("auprc") | |
| if len(ap) >= 2: | |
| vals = [v for v in ap.values() if v is not None] | |
| mean = sum(vals) / len(vals) | |
| var = sum((v - mean) ** 2 for v in vals) / (len(vals) - 1) if len(vals) > 1 else 0 | |
| print("\n control TEST AP: " + " ".join("%s=%.4f" % kv for kv in sorted(ap.items()))) | |
| print(" mean %.4f sd %.4f over %d seeds" % (mean, var ** 0.5, len(vals))) | |
| print(" marks to beat: probe 0.4075, lookback 0.4036") | |
| PYEOF | |
| fi | |
| # --- 3. TriviaQA pilot ------------------------------------------------------ | |
| # Deliberately a pilot. The 3-judge pass has never been timed here, and its | |
| # output decides whether the corpus is usable at all -- if prevalence comes back | |
| # near 0 or near 1 there is nothing to detect. Better to learn that from 200 | |
| # rows than from an overnight run on 3,000. | |
| if [[ "${SKIP_TRIVIAQA:-0}" == "1" ]]; then | |
| say "TriviaQA pilot skipped" | |
| else | |
| say "TriviaQA pilot (N=$PILOT_N)" | |
| MAX_ITEMS="$PILOT_N" bash scripts/run_triviaqa_pipeline.sh \ | |
| && echo " pilot OK" \ | |
| || echo " pilot FAILED -- likely missing judge models; see log above" | |
| fi | |
| say "queue finished" | |