docs + guard: single 262k slot state, split-limits analysis, cache incident

- spec matrix + PP doc: production state = 1 slot @ 262144, split 0.53
  (34 blocks), KV 8192/8192, 3090 at 23460/24576. New 'Split limits
  (measured 2026-08-17)' section: 0.50/0.54/0.55 boundary data, the
  KV-per-device rounding rule (round(f x 66)), and why 35 blocks is
  unreachable (9-FA flip at f~0.538).
- PP doc: cache incident writeup - full Dankserver disk -> 0-byte cache
  entries -> corrupt weights -> degenerate output; fix + signature.
- deployment.md + AGENTS.md + index.md: numbers brought current.
- scripts/prune-rpc-cache.sh: cron guard capping the worker cache at
  40 GiB (oldest first) to prevent the disk-full recurrence.
This commit is contained in:
Frank
2026-08-17 01:24:06 -07:00
parent c85ff6c6fd
commit aa1941d592
6 changed files with 132 additions and 45 deletions
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env bash
# Bound the ggml-rpc worker tensor cache.
#
# The worker (frank-pp-worker on Dankserver) keys cache entries per
# session, so each model load writes a fresh full copy (~15 GB). Left
# unbounded, the directory filled the root disk to 100% on 2026-08-17;
# failed cache writes left 0-byte entries, and a later reload served
# corrupt weights -> degenerate model output (see the cache incident in
# docs/Pipeline Parallelism/Qwen3.8 PP Deployment.md).
#
# This script prunes the cache to a byte cap, oldest files first. Cache
# entries are derived data: safe to delete. Run from cron on Dankserver.
set -euo pipefail
CACHE_DIR=/home/dank/.cache/llama.cpp/rpc
MAX_BYTES=$((40 * 1024 * 1024 * 1024)) # 40 GiB
if [[ ! -d "$CACHE_DIR" ]]; then
exit 0
fi
total=$(du -sb "$CACHE_DIR" | cut -f1)
if (( total <= MAX_BYTES )); then
exit 0
fi
while (( total > MAX_BYTES )); do
oldest=$(ls -1t "$CACHE_DIR" | tail -1)
if [[ -z "$oldest" ]]; then
break
fi
rm -f -- "$CACHE_DIR/$oldest"
total=$(du -sb "$CACHE_DIR" | cut -f1)
done
echo "prune-rpc-cache: pruned to $(du -sh "$CACHE_DIR" | cut -f1)"