feat(scripts): rebuild the frank-dragoon eval stage after a reboot

/tmp is tmpfs: the 2026-10-18 IOMMU reboot deleted /tmp/halogen-eval mid-A/B and
the off-arm numbers nearly went unreproducible. One command restores the corpus
(wikitext-2 raw test, blanks dropped, 2891 lines / 1287656 B -- the byte count is
the identity check because battery.py sizes haystacks in characters), the 512px
probe PNG, and battery.py itself; WARM=1 also pre-reads the 51.2 GB n-gram table
so a cold page cache cannot masquerade as a measured regression. Must run through
a login shell: uv lives in ~/.local/bin.
This commit is contained in:
Frank
2026-10-18 01:34:17 -07:00
parent 9d617ab010
commit 5ad28c19d8
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
# stage-frank-dragoon-eval.sh — rebuild the /tmp/halogen-eval staging dir that
# battery-frank-dragoon.py reads. /tmp is tmpfs, so EVERY REBOOT deletes the
# corpus and the probe image (learned the hard way on 2026-10-18, mid A/B).
#
# Run on Dankclaw through a login shell: uv lives in ~/.local/bin, which a
# bare `ssh host script` does not put on PATH.
# ssh dankclaw 'bash -lc "/home/dank/serverAppConfigs/scripts/stage-frank-dragoon-eval.sh"'
#
# The corpus is the wikitext-2 raw test split with blank lines removed and the
# rows joined by single newlines (2,891 lines). battery.py sizes its haystacks
# in CHARACTERS (CPT 4.33), so the byte count IS the identity check across two
# boots: 1287656 B. If that number changes, the two boots are not comparable.
set -euo pipefail
STAGE=/tmp/halogen-eval
mkdir -p "$STAGE"
cd "$STAGE"
if [ ! -s wikitext-2-raw-test.txt ]; then
uv run --quiet --with pyarrow python3 - <<'PY'
import pathlib, urllib.request
import pyarrow.parquet as pq
raw = pathlib.Path("test.parquet")
url = ("https://huggingface.co/datasets/wikitext/resolve/main/"
"wikitext-2-raw-v1/test-00000-of-00001.parquet")
if not raw.exists() or raw.stat().st_size < 1_000_000:
urllib.request.urlretrieve(url, raw)
lines = []
for text in pq.read_table(raw).column("text").to_pylist():
lines.extend(ln for ln in text.split("\n") if ln.strip())
out = pathlib.Path("wikitext-2-raw-test.txt")
out.write_text("\n".join(lines) + "\n")
print("lines", len(lines), "bytes", out.stat().st_size)
PY
fi
if [ ! -s red512.b64 ]; then
uv run --quiet python3 - <<'PY'
import base64, struct, zlib
def chunk(tag, data):
body = tag + data
return struct.pack(">I", len(data)) + body + struct.pack(">I", zlib.crc32(body) & 0xFFFFFFFF)
w = h = 512
rows = b"\x00" + b"\xdc\x32\x32" * w # filter 0 + solid color per pixel
png = (b"\x89PNG\r\n\x1a\n"
+ chunk(b"IHDR", struct.pack(">IIBBBBB", w, h, 8, 2, 0, 0, 0))
+ chunk(b"IDAT", zlib.compress(rows * h, 6))
+ chunk(b"IEND", b""))
open("red512.b64", "wb").write(base64.b64encode(png))
print("png bytes", len(png), "b64", len(base64.b64encode(png)))
PY
fi
# battery.py reads the corpus and the PNG at import time; ship it here so one
# command restores the whole stage.
cp -f "$(dirname "$(readlink -f "$0")")/battery-frank-dragoon.py" battery.py
chmod +x battery.py
# The 51.2 GB n-gram table is page cache (Pin::None). A reboot leaves it cold,
# and a cold table throttles prefill — warm it before any measurement.
if [ "${WARM:-0}" = 1 ]; then
time cat /home/dank/models/halogen-v2-abliterated/qwen38-flash-next-ngram.hgn >/dev/null
fi
ls -l "$STAGE" | sed -n '1,8p'