#!/usr/bin/env bash # kld-gate-swift15.sh — RUNS ON DANKSERVER. Score the quantized candidate # against the BF16 reference and apply the pre-approved gate: # mean KL <= 0.03 AND top-1 agreement >= 95%. # Same engine (1.0.13) and same boot shape as the reference RECORD # (run-swift15-bf16.sh kld): disk-tier, no speculation, deterministic, fp8 KV. # --kld-ref reads its tokens from the reference (no --kld-corpus here — the # (run-swift15-bf16.sh kld): 1.0.13, tp 2, disk-tier, fp8 KV, no speculation, # deterministic, max-model-len 16384, vram-kv 3072, 4 slots. Two deviations # are forced by the w4 file: MNBT 2048 (the w4 kernels stream from the file # tier ONLY at MNBT<=2048 — at the recording's 32768 the engine demands a # widened form: "DID NOT FIT ... stored form is not the container's"), and # pool 40960 (the recording's 12 GiB pool predates the w4 tables; at 12288 the # gate_up slab cannot be cached). Chunk size is softmax-invariant, so the # MNBT delta is float-order noise riding on the KL floor. set -uo pipefail PIN=sha256:4c3f484564bb2872784e46b0a59cbd71becc9c1e746e301a3596ffae253c322e C=swift15gate LOG=/home/dank/logs/swift15_kldgate.log KLD_REF_DIR=/home/dank/corpora/kld-ref KLD_OUT=/home/dank/radiance-state/kld-gate.json [ -d "$KLD_REF_DIR" ] || { echo "missing reference: $KLD_REF_DIR"; exit 2; } : > "$KLD_OUT" cp -f /home/dank/serverAppConfigs/scripts/qwen38-froggeric-v22.5.jinja \ /home/dank/models/tpl.jinja 2>/dev/null || true sudo systemctl stop frank-primary >/dev/null 2>&1 || true podman rm -f "$C" >/dev/null 2>&1 || true podman run --rm --name "$C" \ --network host --init \ --security-opt seccomp=unconfined \ --ulimit memlock=-1:-1 \ --device /dev/kfd --device /dev/dri \ -v /home/dank/models:/models:ro \ -v /home/dank/radiance-state:/data \ -v "$KLD_REF_DIR:/data/kld-ref:ro" \ "stilldeadcode/radiance@$PIN" \ --model /models/rad/qwen4exp-swift15-w4dn8-i8-hc8m.rad \ --tp 2 --placement expert_tiered --weights-disk-tier \ --host-pool-mib 40960 --deterministic --gpu-headroom-mib 768 \ --num-speculative-tokens 0 \ --kv-cache-dtype fp8 --max-model-len 16384 \ --ngram-placement ram \ --override-chat-template /models/tpl.jinja \ --kld-ref /data/kld-ref --kld-out /data/kld-gate.json \ --vram-kv-mib 3072 \ --max-num-seqs 4 --max-num-batched-tokens 2048 \ 2>&1 | tee "$LOG" rc=${PIPESTATUS[0]} [ "$rc" -eq 0 ] || { echo "KLD GATE BOOT FAILED rc=$rc; log: $LOG"; exit "$rc"; } python3 - "$KLD_OUT" "$LOG" <<'PY' import json, sys, re out, log = sys.argv[1], sys.argv[2] def num(pat): m = re.findall(pat, open(log, errors="replace").read(), re.I) return float(m[-1]) if m else None kl = top1 = None try: d = json.load(open(out)) def find(obj, keys): if isinstance(obj, dict): for k, v in obj.items(): if any(s in k.lower() for s in keys) and isinstance(v, (int, float)): return float(v) for v in obj.values(): r = find(v, keys) if r is not None: return r return None kl = find(d, ("mean_kl", "mean kl", "kl_mean", "mean")) top1 = find(d, ("top1", "top_1", "top-1", "agreement")) if top1 is not None and top1 <= 1.0: top1 *= 100.0 except Exception as e: print("report JSON unusable (%s); falling back to log" % e) if kl is None: kl = num(r"mean[_ ]kl[^0-9]*([0-9]*\.?[0-9]+(?:e[-+][0-9]+)?)") if top1 is None: top1 = num(r"top[-_ ]?1[^0-9]*([0-9]*\.?[0-9]+)") if kl is None or top1 is None: print("KLD GATE PARSE FAILED: mean_kl=%s top1=%s — inspect %s / %s" % (kl, top1, out, log)) sys.exit(2) print("KLD GATE: mean KL = %.4f (max 0.03) | top-1 = %.2f%% (min 95.0)" % (kl, top1)) ok = (kl <= 0.03) and (top1 >= 95.0) print("KLD GATE " + ("PASS" if ok else "FAIL")) sys.exit(0 if ok else 1) PY gate=$? echo "kld-gate complete rc=$gate; log: $LOG report: $KLD_OUT" exit "$gate"