#!/usr/bin/env bash # I/O honesty audit: prove the expert weights are read from the block device and # are NOT served from (or hidden in) the page cache. # # ./audit_io.sh [sdq-chat] [ram-budget-mb] [n-predict] # # Two runs with identical settings: # A) default pager uses O_DIRECT (bypasses the cache) # B) SDQ_NO_DIRECT_IO=1 + --no-fadvise control: buffered reads kept in cache # # If this measurement were blind, A and B would look the same. They do not: # B leaves gigabytes of the GGUF resident in the page cache, A does not. set -u MODEL="$(readlink -f "$1")" BIN="$(readlink -f "${2:-./llama.cpp/build/bin/sdq-chat}")" BUDGET="${3:-8192}" NPRED="${4:-32}" PROMPT="Explain in detail how paging mixture-of-experts weights from SSD works, \ and why the working set is much smaller than the weights." cd "$(dirname "$0")/.." SECOND="$(echo "$MODEL" | sed -E 's/-00001-of-/-00002-of-/')" IFS=',' read -r -a SHARDS <<< "$MODEL,$SECOND" if [ ! -x /tmp/pagecache_resident ]; then echo "building the mincore helper ..." g++ -O2 -o /tmp/pagecache_resident sdq-ling/pagecache_resident.cpp fi run() { local label="$1"; shift echo echo "================================================================" echo "[audit] $label" echo "================================================================" WATCH_INTERVAL=0.5 "$@" python3 sdq-ling/watch_io.py "$MODEL,$SECOND" \ "$BIN" -m "$MODEL" -p "$PROMPT" -n "$NPRED" -c 2048 -t 16 -b 128 \ --temp 0 --no-chat --no-interactive --ram-budget-mb "$BUDGET" \ 2>/dev/null | grep -E "^\[watch\]" grep -E "全程 SSD 實際讀取|O_DIRECT 讀取模型檔|O_DIRECT 不可用" /tmp/watch_stderr.log | tail -3 grep -E "^assistant:" /tmp/watch_stdout.log | head -1 } echo "[audit] model shards:" /tmp/pagecache_resident "${SHARDS[@]}" run "A) default (O_DIRECT)" env SDQ_RAM_BUDGET_MB="$BUDGET" echo echo "================================================================" echo "[audit] B) control: buffered reads + page cache kept" echo "================================================================" WATCH_INTERVAL=0.5 SDQ_NO_DIRECT_IO=1 python3 sdq-ling/watch_io.py "$MODEL,$SECOND" \ "$BIN" -m "$MODEL" -p "$PROMPT" -n "$NPRED" -c 2048 -t 16 -b 128 \ --temp 0 --no-chat --no-interactive --no-fadvise --ram-budget-mb "$BUDGET" \ 2>/dev/null | grep -E "^\[watch\]" grep -E "全程 SSD 實際讀取|O_DIRECT 不可用" /tmp/watch_stderr.log | tail -2