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:
1 parent
c71a3066c0
commit
87721ab0fe
87 files changed
+460
-460
No files matched your search
@@ -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" {
|
||||
|
||||
@@ -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" ]
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
@@ -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',
|
||||
|
||||
Reference in new issue
Block a user