Files
command-center/agent/managed-skills/halogen-flash-server-ops/SKILL.md
T

3.7 KiB

name, description
name description
halogen-flash-server-ops Operate the frank-large halogen-flash-server deployment on Dankclaw (model swaps, restarts, memory sizing, health and client verification, rollback) — use for anything touching frank-large after the 2026-09-11 runtime swap

halogen-flash-server ops (frank-large, Dankclaw)

frank-large is a rootless Quadlet container since 2026-09-11: dankclaw/frank-large/quadlet/frank-large.container in the serverAppConfigs repo, installed to ~/.config/containers/systemd/, generated unit frank-large.service in the user manager. Full runbook: serverAppConfigs-docs/LLM/halogen-flash-server.md.

Never use sudo systemctl on it

It is a user unit. sudo systemctl stop frank-large does nothing useful.

systemctl --user status frank-large.service
podman logs frank-large | head -40        # version banner + memory ledger
curl -s http://127.0.0.1:7770/health      # 200 only after the engine PONGs
curl -s http://127.0.0.1:7770/v1/models   # must list frank-large

Deploy / change flags

  1. Edit the .container file in the repo (all tunables are inline Environment= lines).
  2. ./tests/run.sh (the quadlet seam covers GPU devices, memlock, ipc/seccomp, the single published port, writable weights mount).
  3. Commit, push, then ./scripts/deploy.sh dankclaw --service frank-large.

The handler retires the old root unit (moving its symlink to the home trash), pulls and re-tags the image to the localhost/ alias, installs the unit, restarts it, and gates on the download when the checkpoint is absent. Never systemctl --user enable a generated unit.

Sizing a swap

Read the startup ledger before and after any change: it prints the locked weights, the KV pool it chose, the working set, the BIOS iGPU carve-out, and the corrected free-memory figure. free, MemAvailable and every monitor built on them overstate free memory by the size of the model (~68 GiB) because the kernel counts the locked weights as reclaimable page cache.

  • KV is ~7.2 GiB per 262,144 positions; the prefill arena is 16.7 GiB at HALOGEN_MAX_TOK=32768.
  • The device budget stops near 47 GiB with the weights pinned, and lower on a machine carrying more besides this server. HALOGEN_KV_POOL_FIT=1 lowers the pool to fit and prints what it chose; a refused start needs a smaller HALOGEN_KV_POOL_POSITIONS (HALOGEN_KV_SLOTS will not help — slots share one pool).
  • Long prompts crawling with the disk busy = file cache, not memory: lower the pool or raise HALOGEN_HOST_RESERVE_GIB.

Client contract traps

  • No server-side sampler defaults: a request without temperature decodes GREEDY.
  • The per-request budget defaults to 8192 and includes thinking; a reasoning model plus a small budget returns EMPTY content with finish_reason: "length". Cap is 65536 (a 400 above it), and max_tokens/max_completion_tokens/max_output_tokens must agree.
  • response_format is a 400 ("no constrained decoding") — as it is on FreeToken/frank-small. Any caller that needs structured output or a tiny budget needs a different backend.
  • A request reserves prompt + max_tokens positions against the pool; larger requests queue and then fail with 503 engine_busy after 3600 s.

Verification after any change

Run a real completion (never just /health), a vision probe if the tower is enabled (image content part with a data: URL; http(s) URLs are refused), then one call from the client that consumes it. Rollback: the llama.cpp era is in .AGENTTRASH/ (.llama.cpp), the STRIX payload and ROCmFPX build stay on disk — but remove the Quadlet from ~/.config/containers/systemd/ before restoring the root unit, or both claim port 7770.