rename frank-small → frank-secondary (Dankclaw llama.cpp :7771)

Cross-cutting rename of the current llama.cpp endpoint on the RTX 3090
(port 7771) from frank-small to frank-secondary:

- Service trio: scripts/{frank-small.env,frank-small.service,
  serve-frank-small.sh,download-frank-small.sh} → frank-secondary.*
- Test: tests/frank_small_unit.bats → tests/frank_secondary_unit.bats
- Runbooks: serverAppConfigs-docs/LLM/frank-small-*.md →
  frank-secondary-*.md (9 files); the FreeToken runbook stays
  freetoken-frank-small.md (it documents the retired CUDA-era service)
- Identifiers: FRANK_SMALL→FRANK_SECONDARY, llm_small→llm_secondary,
  LLM_SMALL_*→LLM_SECONDARY_*, deploy_llm_small→deploy_llm_secondary
- Historical references to the OLD frank-small (FreeToken/CUDA on the
  3090, and the Dankserver service that became frank-medium) are
  preserved verbatim — they describe what the service was called
  at the time.
This commit is contained in:
Frank committed 2026-10-06 15:37:13 -07:00
1 parent c71a3066c0
commit 87721ab0fe
87 files changed
+460 -460

No files matched your search

+1 -1
View File
@@ -70,7 +70,7 @@ load helpers
@test "remote runner has a handler per inference service" {
grep -q 'deploy_llm_large' "$REPO_ROOT/scripts/deploy-remote.sh"
grep -q 'deploy_llm_primary' "$REPO_ROOT/scripts/deploy-remote.sh"
grep -q 'deploy_llm_small' "$REPO_ROOT/scripts/deploy-remote.sh"
grep -q 'deploy_llm_secondary' "$REPO_ROOT/scripts/deploy-remote.sh"
}
@test "inference restarts are absent from the top-level dispatcher" {
+5 -5
View File
@@ -31,7 +31,7 @@ REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
@test "the retired ik chat template plans nothing, and its archive is still here" {
# scripts/chat-template.jinja existed only for the ik_llama.cpp runtime
# (retired 2026-09-16 in favour of halogen-flash-server again). The
# llama.cpp frank-small runtime serves the template the GGUF itself
# llama.cpp frank-secondary runtime serves the template the GGUF itself
# carries, which is the one with reasoning_effort, preserve_thinking and
# the tool-call grammar. Editing the archive must deploy nothing -- and the
# archive must still be present, so this cannot pass by the file having
@@ -84,15 +84,15 @@ REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
@test "the small endpoint is Dankclaw's again, and Dankserver's copy stays retired" {
run python3 "$PLANNER" --target dankclaw --paths \
scripts/frank-small.env scripts/frank-small.service scripts/serve-frank-small.sh
scripts/frank-secondary.env scripts/frank-secondary.service scripts/serve-frank-secondary.sh
[ "$status" -eq 0 ]
[ "$output" = "frank-small" ]
[ "$output" = "frank-secondary" ]
# frank-small runs on Dankclaw on the RTX 3090; the Dankserver endpoint of
# frank-secondary runs on Dankclaw on the RTX 3090; the Dankserver endpoint of
# that name was retired with the FreeToken runtime on 2026-09-15 and must
# not come back through a planner mapping.
run python3 "$PLANNER" --target dankserver --paths \
scripts/frank-small.env scripts/frank-small.service scripts/serve-frank-small.sh
scripts/frank-secondary.env scripts/frank-secondary.service scripts/serve-frank-secondary.sh
[ "$status" -eq 0 ]
[ -z "$output" ]
}
+3 -3
View File
@@ -142,7 +142,7 @@ good_env() {
# ~28 KiB/position (FLAGS.md). Against it: ~62 GiB resident weights,
# the arena scratch 3.8 + 8.4*(MAX_TOK/16384) GiB, the vision tower
# ~2 GiB pool charge, the 20 GiB host reserve and the host baseline
# + co-tenancy (frank-small, ComfyUI, Caddy/observability) ~15. The
# + co-tenancy (frank-secondary, ComfyUI, Caddy/observability) ~15. The
# box has 121 GiB unified. The n-gram table rides as mmap'd page
# cache beside the checkpoint and is not a pinned charge (the card's
# own quickstart arithmetic does not bill it).
@@ -320,8 +320,8 @@ $(cat "$TEST_TMP/serve.log")"
grep -qE 'podman pull' "$DEPLOYER"
}
@test "the stray sweep cannot take frank-small or the deployer down" {
# frank-small also listens on this host (7771, llama-server) and the
@test "the stray sweep cannot take frank-secondary or the deployer down" {
# frank-secondary also listens on this host (7771, llama-server) and the
# deployer's own command line contains "frank-large"; only the FULL
# container name matches a stray manual flash-server run and nothing
# else.
+1 -1
View File
@@ -44,7 +44,7 @@ TEMPLATE="$REPO_ROOT/scripts/qwen38-froggeric-v22.5.jinja"
}
@test "frank-primary unit is boot-persistent, self-healing and unprivileged" {
# Root unit parity with frank-large/frank-small: enable is the [Install]
# Root unit parity with frank-large/frank-secondary: enable is the [Install]
# section, the restart policy survives a crash, and the pinned host RAM
# (expert pools + PLE table + prefix host tier, ~132 GiB) needs an
# unbounded memlock (a root unit grants it via PID1; the dank session's
@@ -1,5 +1,5 @@
# Seam: the frank-small llama.cpp root unit on dankclaw.
# frank-small is the RTX 3090 endpoint; since 2026-10-06 (evening) it
# Seam: the frank-secondary llama.cpp root unit on dankclaw.
# frank-secondary is the RTX 3090 endpoint; since 2026-10-06 (evening) it
# serves ajgazin/Swift-1.5-Qwen3.8-27B-Uncensored-Dynamic-MTP-GGUF at
# RCO-IQ3_XXS (27B dense qwen3_5 hybrid) via a CUDA (sm_86) build of
# llama.cpp master: TWO 131,072-token conversations at Frank's 128k cap
@@ -13,9 +13,9 @@
load helpers
UNIT="$REPO_ROOT/scripts/frank-small.service"
SERVE="$REPO_ROOT/scripts/serve-frank-small.sh"
ENV_FILE="$REPO_ROOT/scripts/frank-small.env"
UNIT="$REPO_ROOT/scripts/frank-secondary.service"
SERVE="$REPO_ROOT/scripts/serve-frank-secondary.sh"
ENV_FILE="$REPO_ROOT/scripts/frank-secondary.env"
REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
ENV_LARGE="$REPO_ROOT/scripts/frank-large.env"
TARGET_STUB="Swift-1.5-Qwen3.8-27B-Uncensored-Dynamic-MTP-RCO-IQ3_XXS.gguf"
@@ -49,7 +49,7 @@ serve_argv() {
LLAMA_BIN=$RUNTIME_DIR/bin/llama-server
MODEL_FILE=$MODEL_DIR/$TARGET_STUB
MMPROJ_FILE=$MODEL_DIR/${mmproj##*/}
ALIAS=frank-small
ALIAS=frank-secondary
BIND_ADDR=0.0.0.0
LISTEN_PORT=7771
CTX_SIZE=$(sed -nE 's/^CTX_SIZE=([0-9]+)$/\1/p' "$ENV_FILE")
@@ -60,27 +60,27 @@ CACHE_TYPE_K=$(sed -nE 's/^CACHE_TYPE_K=(.+)$/\1/p' "$ENV_FILE")
CACHE_TYPE_V=$(sed -nE 's/^CACHE_TYPE_V=(.+)$/\1/p' "$ENV_FILE")
NGL=$(sed -nE 's/^NGL=([0-9]+)$/\1/p' "$ENV_FILE")
EOF
run env FRANK_SMALL_ENV_FILE="$envf" nvidia-modprobe=true bash "$SERVE"
run env FRANK_SECONDARY_ENV_FILE="$envf" nvidia-modprobe=true bash "$SERVE"
}
argv_value() {
grep -A1 -xF -- "$1" <<<"$output" | tail -1
}
@test "frank-small unit, serve script and env exist in scripts/" {
@test "frank-secondary unit, serve script and env exist in scripts/" {
[ -f "$UNIT" ]
[ -f "$SERVE" ]
[ -f "$ENV_FILE" ]
}
@test "frank-small is boot-persistent, self-healing and unprivileged" {
@test "frank-secondary is boot-persistent, self-healing and unprivileged" {
grep -q '^WantedBy=multi-user.target$' "$UNIT"
grep -q '^Restart=on-failure$' "$UNIT"
grep -q '^RestartSec=' "$UNIT"
grep -q '^User=dank$' "$UNIT"
grep -q '^LimitMEMLOCK=infinity$' "$UNIT"
grep -q '^ExecStart=/home/dank/serverAppConfigs/scripts/serve-frank-small.sh$' "$UNIT"
grep -q 'FRANK_SMALL_ENV_FILE=/home/dank/serverAppConfigs/scripts/frank-small.env' "$UNIT"
grep -q '^ExecStart=/home/dank/serverAppConfigs/scripts/serve-frank-secondary.sh$' "$UNIT"
grep -q 'FRANK_SECONDARY_ENV_FILE=/home/dank/serverAppConfigs/scripts/frank-secondary.env' "$UNIT"
}
@test "the shipped env points at the llama.cpp runtime and the Swift-1.5-27B Uncensored RCO-IQ3_XXS GGUF" {
@@ -95,7 +95,7 @@ argv_value() {
# would be gating on a file nobody reads — and a missing projector would
# ship a blind endpoint.
local env_v dep_v path pair
for pair in "MODEL_FILE LLM_SMALL_MODEL_FILE" "MMPROJ_FILE LLM_SMALL_MMPROJ"; do
for pair in "MODEL_FILE LLM_SECONDARY_MODEL_FILE" "MMPROJ_FILE LLM_SECONDARY_MMPROJ"; do
read -r env_v dep_v <<<"$pair"
path="$(sed -nE "s/^${env_v}=(.+)\$/\1/p" "$ENV_FILE" | tail -1)"
[ -n "$path" ]
@@ -106,7 +106,7 @@ argv_value() {
@test "the pool is exactly the native 262144 window, so each of the two conversations is 131072" {
serve_argv
[ "$status" -eq 0 ]
[ "$(argv_value --alias)" = "frank-small" ]
[ "$(argv_value --alias)" = "frank-secondary" ]
[ "$(argv_value --port)" = "7771" ]
[ "$(argv_value --host)" = "0.0.0.0" ]
[ "$(argv_value --model)" = "$MODEL_DIR/$TARGET_STUB" ]
@@ -212,7 +212,7 @@ argv_value() {
# The documented opt-out must reach the engine as ABSENCE of the flag,
# not as an argument pointing at an empty string.
sed -i 's|^MMPROJ_FILE=.*|MMPROJ_FILE=|' "$STAGE/test.env"
run env FRANK_SMALL_ENV_FILE="$STAGE/test.env" nvidia-modprobe=true bash "$SERVE"
run env FRANK_SECONDARY_ENV_FILE="$STAGE/test.env" nvidia-modprobe=true bash "$SERVE"
[ "$status" -eq 0 ]
! grep -qxF -- '--mmproj' <<<"$output"
}
@@ -232,27 +232,27 @@ argv_value() {
rm -f "$MODEL_DIR/$MM_STUB"
serve_argv
[ "$status" -ne 0 ]
[[ "$output" == *"frank-small: missing"* ]]
[[ "$output" == *"frank-secondary: missing"* ]]
rm -f "$RUNTIME_DIR/bin/llama-server"
serve_argv
[ "$status" -ne 0 ]
[[ "$output" == *"frank-small: missing"* ]]
[[ "$output" == *"frank-secondary: missing"* ]]
}
@test "the deploy handler gates on binary, GGUF and projector, then MainPID-hardens health" {
grep -q 'deploy_llm_small' "$REMOTE_DEPLOY"
grep -q 'LLM_SMALL_RUNTIME' "$REMOTE_DEPLOY"
grep -q 'LLM_SMALL_MODEL_FILE' "$REMOTE_DEPLOY"
grep -q 'LLM_SMALL_MMPROJ' "$REMOTE_DEPLOY"
grep -q 'relink_unit frank-small' "$REMOTE_DEPLOY"
grep -q 'systemctl enable frank-small.service' "$REMOTE_DEPLOY"
grep -q 'deploy_llm_secondary' "$REMOTE_DEPLOY"
grep -q 'LLM_SECONDARY_RUNTIME' "$REMOTE_DEPLOY"
grep -q 'LLM_SECONDARY_MODEL_FILE' "$REMOTE_DEPLOY"
grep -q 'LLM_SECONDARY_MMPROJ' "$REMOTE_DEPLOY"
grep -q 'relink_unit frank-secondary' "$REMOTE_DEPLOY"
grep -q 'systemctl enable frank-secondary.service' "$REMOTE_DEPLOY"
grep -q '127.0.0.1:7771/health' "$REMOTE_DEPLOY"
grep -q 'frank-small.service has no MainPID' "$REMOTE_DEPLOY"
grep -q 'frank-secondary.service has no MainPID' "$REMOTE_DEPLOY"
}
@test "the two endpoints keep separate ports and the large handler never pkills llama-server" {
# frank-large's gufo sweep must not take down frank-small, whose
# frank-large's gufo sweep must not take down frank-secondary, whose
# process is llama-server on the SAME host since this swap.
grep -q '^LISTEN_PORT=7771$' "$ENV_FILE"
local large
+2 -2
View File
@@ -72,8 +72,8 @@ by_probe = {s["probe"]: s["name"] for s in services}
primary = by_probe.get("192.168.0.235:7770")
assert primary == "frank-primary", f"Dankserver :7770 card is named {primary!r}"
# Dankclaw serves two endpoints on two ports: frank-large (unsloth llama.cpp
# on the iGPU, 7770) and frank-small (llama.cpp on the RTX 3090, 7771).
# on the iGPU, 7770) and frank-secondary (llama.cpp on the RTX 3090, 7771).
assert by_probe.get("127.0.0.1:7770") == "frank-large", by_probe.get("127.0.0.1:7770")
assert by_probe.get("127.0.0.1:7771") == "frank-small", by_probe.get("127.0.0.1:7771")
assert by_probe.get("127.0.0.1:7771") == "frank-secondary", by_probe.get("127.0.0.1:7771")
PY
}
+5 -5
View File
@@ -325,15 +325,15 @@ PAIRS
# container, and on this netavark host a container can only reach the
# host's LAN IP at a PUBLISHED port — a host-process bind like
# llama-server's 0.0.0.0:7770 is refused at 192.168.0.143:7770 while it
# answers at 169.254.1.2:7770 (why frank-small stayed red by construction
# answers at 169.254.1.2:7770 (why frank-secondary stayed red by construction
# for days until the 2026-09-20 /targets audit).
local cfg="$REPO_ROOT/shared/prometheus/prometheus.yml"
grep -q '"host.containers.internal:7771"' "$cfg" || { echo "frank-small not scraped"; return 1; }
grep -q '"host.containers.internal:7771"' "$cfg" || { echo "frank-secondary not scraped"; return 1; }
grep -q '"host.containers.internal:7770"' "$cfg" || { echo "frank-large not scraped"; return 1; }
! grep -q '"192.168.0.235:7770"' "$cfg"
grep -q '"host.containers.internal:7770,192.168.0.235:7770"' "$cfg" \
&& { echo "frank-primary folded into a Dankclaw gateway target"; return 1; }
for job in frank-small frank-large; do
for job in frank-secondary frank-large; do
grep -q "job_name: \"$job\"" "$cfg" || { echo "no scrape job for $job"; return 1; }
done
! grep -q 'job_name: "frank-primary"' "$cfg"
@@ -383,11 +383,11 @@ for want in ('job:llm_prefix_cache_reuse:rate5m',
# Every rule must be keyed to a series that actually exists. A rule naming a
# series nobody exports evaluates nothing forever and errors never — the
# failure this seam exists for. Since the 2026-09-26 cutover the only scraped
# LLM runtime is llama.cpp (frank-small, frank-large); the vllm: family left
# LLM runtime is llama.cpp (frank-secondary, frank-large); the vllm: family left
# with frank-medium's radiance runtime and must not survive in any expr.
exprs = [r.get('expr', '') for g in d['groups'] for r in g['rules']]
# llama.cpp families measured from /metrics on 2026-09-16 and 2026-09-20
# (frank-small, frank-large). Anything else is a guess.
# (frank-secondary, frank-large). Anything else is a guess.
live = {'llamacpp:prompt_tokens_total', 'llamacpp:prompt_tokens_cached_total',
'llamacpp:requests_deferred', 'llamacpp:requests_processing',
'llamacpp:spec_decode_num_drafts_total',