bidbrain / scripts /bench_when_ready.sh
atharvgaur18's picture
Upload folder using huggingface_hub (part 2)
5528e15 verified
Raw History Blame Contribute Delete
5.6 kB
#!/bin/bash
# Waits for the Sharanga vLLM job, tunnels it to localhost:8011, then runs the whole benchmark matrix.
#
# setsid nohup scripts/bench_when_ready.sh > /dev/null 2>&1 & # progress: data/eval/bench_runner.log
#
# Safe to re-run after any interruption: eval.run skips questions it already answered, the GraphRAG-SDK
# ingest is skipped once its graph exists, and every completion is cached. Stop it with
# pkill -f bench_when_ready.sh; pkill -f "socat TCP-LISTEN:8011"
set -u
ROOT=$(cd "$(dirname "$0")/.." && pwd)
LOG=$ROOT/data/eval/bench_runner.log
JOBS=${JOBS:-"399564 399236"} # our pending vLLM jobs (H100 fp8, H200 bf16); first one up wins
REMOTE=/scratch/pabitra/bidbrain
PY=$ROOT/backend/.venv/bin/python
SDK_PY=$ROOT/backend/.venv-sdk/bin/python
SETS=${SETS:-"S21 Q333 ABS TND"}
SYSTEMS=${SYSTEMS:-"bidbrain text2cypher vector_rag"}
WORKERS=${WORKERS:-16}
mkdir -p "$ROOT/data/eval"
cd "$ROOT/backend" || exit 1
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; }
remote() { ssh -o BatchMode=yes -o ConnectTimeout=20 sharanga "$@" 2>/dev/null; }
# ------------------------------------------------------------------ 1. wait for a server that passed its tool-call gate
log "waiting for one of jobs: $JOBS"
while :; do
ready=$(remote "for j in $JOBS; do
st=\$(squeue -h -j \$j -o %T 2>/dev/null)
[ \"\$st\" = RUNNING ] && [ -f $REMOTE/serve_ready_\$j.txt ] && { echo \$j \$(cat $REMOTE/serve_ready_\$j.txt); break; }
done")
if [ -n "$ready" ]; then break; fi
sleep 300
done
read -r JOB NODE PORT _ <<< "$ready"
log "server ready: job $JOB on $NODE:$PORT"
for j in $JOBS; do
[ "$j" != "$JOB" ] && remote "scancel $j" && log "cancelled the other pending job $j"
done
# ------------------------------------------------------------------ 2. relay localhost:8011 to the GPU node
# Sharanga's login node refuses TCP forwarding (ssh -L / -J: "administratively prohibited") but allows
# commands, so each local connection is piped through `nc` on the login node over one multiplexed ssh.
MUX=/tmp/bidbrain-sharanga-mux
SHORT=${NODE%%.*}
if ! curl -sf -m 15 http://localhost:8011/v1/models -o /dev/null; then
ssh -o BatchMode=yes -o ControlMaster=auto -o ControlPath=$MUX -o ControlPersist=yes -q sharanga true
setsid socat TCP-LISTEN:8011,bind=127.0.0.1,fork,reuseaddr \
EXEC:"ssh -o BatchMode=yes -o ControlMaster=auto -o ControlPath=$MUX -o ControlPersist=yes -q sharanga nc $SHORT $PORT" \
> /dev/null 2>&1 < /dev/null &
sleep 2
fi
for i in $(seq 1 30); do
curl -sf -m 15 http://localhost:8011/v1/models -o /dev/null && break
sleep 5
done
curl -sf -m 15 http://localhost:8011/v1/models -o /dev/null || { log "relay to $SHORT:$PORT never came up"; exit 1; }
log "relay up: localhost:8011 -> $SHORT:$PORT"
export LLM_PROVIDERS=vllm VLLM_BASE_URL=http://localhost:8011/v1 LLM_MAX_WAIT=300
# a fresh completion cache per run: a cached answer from an earlier run (or another quantisation served under the
# same model name) must never stand in for a re-run
export LLM_CACHE_PATH=${LLM_CACHE_PATH:-$ROOT/data/llm_cache_final.sqlite}
# ------------------------------------------------------------------ 3. smoke test before spending hours
"$PY" -m eval.run --selfcheck >> "$LOG" 2>&1 || { log "scorer self-check failed; stopping"; exit 1; }
"$PY" -m eval.run --system bidbrain --set S21 --limit 3 --workers 3 >> "$LOG" 2>&1
ok=$("$PY" -c "
import json; rs=[json.loads(l) for l in open('$ROOT/data/eval/results/bidbrain__S21.jsonl')]
print(sum(1 for r in rs if not r.get('error')))" 2>/dev/null || echo 0)
if [ "${ok:-0}" -lt 2 ]; then
log "smoke test failed ($ok of 3 answered without error); see the log above. Stopping."
exit 1
fi
log "smoke test passed ($ok/3)"
# ------------------------------------------------------------------ 4. the matrix (S21 first everywhere = early sanity)
for set in $SETS; do
for sys in $SYSTEMS; do
log "run $sys on $set"
"$PY" -m eval.run --system "$sys" --set "$set" --workers "$WORKERS" >> "$LOG" 2>&1 || log " $sys/$set exited non-zero"
"$PY" -m eval.run --summarize > /dev/null 2>&1
done
done
# ------------------------------------------------------------------ 5. GraphRAG-SDK baseline (needs its own venv)
if [ -x "$SDK_PY" ]; then
# re-ingest unless a previous ingest finished (an interrupted one leaves finalized=false)
if ! "$PY" -c "import json,sys; d=json.load(open('$ROOT/data/eval/results/graphrag_sdk_ingest.json')); sys.exit(0 if d.get('finalized') else 1)" 2>/dev/null; then
docker exec bidbrain-falkordb redis-cli GRAPH.DELETE grsdk_bidbrain > /dev/null 2>&1
log "GraphRAG-SDK ingest (auto schema over the corpus)"
"$SDK_PY" -m eval.baselines.graphrag_sdk ingest >> "$LOG" 2>&1 || log " ingest exited non-zero"
fi
for set in $SETS; do
log "run graphrag_sdk on $set"
"$SDK_PY" -m eval.baselines.graphrag_sdk run --set "$set" >> "$LOG" 2>&1 || log " graphrag_sdk/$set exited non-zero"
"$PY" -m eval.run --summarize > /dev/null 2>&1
done
else
log "no $SDK_PY; GraphRAG-SDK baseline skipped"
fi
# ------------------------------------------------------------------ 6. LLM-read gradings (after the eval, so the eval
# graph is the deterministic one); the loader picks them up on the next build
if [ ! -f "$ROOT/data/llm_gradings.json" ]; then
log "LLM grading extraction"
"$PY" -m bidbrain.ingest.llm_grading >> "$LOG" 2>&1 || log " llm_grading exited non-zero"
fi
"$PY" -m eval.run --summarize >> "$LOG" 2>&1
log "benchmark finished; summary in data/eval/qa_summary.json"