Files
serverAppConfigs/serverAppConfigs-docs/LLM/frank-zealot-llama-qwen35-9b-q6k-2x200704.md
T
Frank e7f0d93c86 docs(vault): fleet-wide fact re-verification pass (67 pages)
The docs-fact census wave re-read the live hosts and re-keyed every page
it could: runtime/payload identities, ports, sizes, ledger figures, unit
state, and the retirement banners that drifted as the fleet moved. The
wave was interrupted mid-run, so this commit carries only what passed the
integrity gates: every touched page parses (front matter or H1+status
convention intact, balanced fences, no truncated tables, trailing
newline), the docs_completeness and link-integrity seams are green, and
bats is 384/384.

Numbers that this session proved on live hosts are keyed to the measured
value, not the page's earlier claim.
2026-10-18 13:15:43 -07:00

168 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
type: reference
title: "frank-zealot on Dankclaw — llama.cpp, Qwen3.5-9B Q6_K, 2 x 200704, f16 KV (RETIRED, rollback target)"
description: "The frank-zealot runbook of 2026-10-07 → 2026-10-17 (RETIRED — rollback target) — llama.cpp master (CUDA sm_86) serving HauhauCS/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive at Q6_K on the RTX 3090: two conversations of 200,704 tokens with exact f16 KV, vision through the publisher's BF16 projector, MTP impossible (no tensors in the file), and the measured geometry that priced the shape."
tags:
- llm
- frank-zealot
- dankclaw
- llama-cpp
- gguf
- rtx3090
timestamp: 2026-10-07
---
# frank-zealot — llama.cpp Qwen3.5-9B Q6_K, 2 × 200,704, f16 KV
**RETIRED 2026-10-07 → 2026-10-17** (AGENTS.md Runbook Index), superseded by
[[frank-zealot-llama-prism-bonsai2-pq20]] (27B PQ2_0, 2 × 200,704 q8_0 KV, build
10754), itself retired 2026-10-17 → 10-18 and now the rollback target: :7771
today is llama.cpp PrismML build **10777** on
`Ternary-Bonsai-2-9B-PQ2_0-MTP-Q8_0.gguf`, 3 × 262,144 q8_0 KV, MTP off by
measurement (AGENTS.md Runbook Index active row; `scripts/frank-zealot.env`).
Transient 2026-10-18: :7771 is inside a bench window — the unit is `failed`
since 03:14 and a hand-booted process answers the port; restore with
`./scripts/deploy.sh dankclaw --service frank-zealot`.
This era is the rollback target: the payload is still on disk
(`stat -c %s /home/dank/models/Qwen35-9B-HauhauCS-Q6K/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive-Q6_K.gguf`
→ 7359259008, read 2026-10-18) with its master CUDA build. Same census: the
10754 rollback payload `Bonsai2-PQ2_0/Ternary-Bonsai-2-27B-PQ2_0.gguf` is
present at 7206168928 with its Q8_0 mmproj at 629246976, and
`Bonsai2-9B-MTP/Ternary-Bonsai-2-9B-PQ2_0-MTP-Q8_0.gguf` at 2675410720 —
nothing this era or its successors need has been purged. It replaced the
[[frank-zealot-llama-gemma4-q4km-200704]] era (Q4_K_M on ONE 200,704
slot). The swap is a capacity trade: the 9B dense-hybrid rung costs ~7 GiB of
weights where the 26B MoE cost ~16.6 GiB, and the freed room buys the second
conversation slot and unquantized KV back.
## Identity
| | |
|---|---|
| Host / device | Dankclaw (192.168.0.143), RTX 3090, 24,576 MiB |
| Endpoint | `http://192.168.0.143:7771` — served model id **`frank-zealot`** (`ALIAS` in the env; the SERVICE keeps the `frank-zealot` name), `/v1` OpenAI surface |
| Runtime | llama.cpp master (0.5.0-dev, commit `5fc4f3c`), CUDA sm_86 build `…/llama-master/build-cuda/bin/llama-server` — `--version` on the disk build reads `0.5.0-dev (build 1, commit 5fc4f3c)` (built 2026-10-01); its `CMakeCache.txt` says `GGML_CUDA_FA_ALL_QUANTS:BOOL=OFF` and that tree carries no CUDA-side guard for the option (`ggml/src/ggml-cuda/fattn.cu:438-449` dispatches Q4/Q5 KV unconditionally), so quantized KV never required it; `qwen35` is registered in the build's own `src/llama-arch.cpp` and `src/models/qwen35.cpp` exists at that commit |
| Unit | root systemd `frank-zealot.service` ([`scripts/frank-zealot.service`](../../scripts/frank-zealot.service)), `User=dank`, `Restart=on-failure`, `LimitMEMLOCK=infinity` |
| Serve script | [`scripts/serve-frank-zealot.sh`](../../scripts/serve-frank-zealot.sh), tunables [`scripts/frank-zealot.env`](../../scripts/frank-zealot.env) |
| Weights | `/home/dank/models/Qwen35-9B-HauhauCS-Q6K/Qwen3.5-9B-Uncensored-HauhauCS-Aggressive-Q6_K.gguf` — HauhauCS **Q6_K**, 7,359,259,008 B, sha256 `c0ba7beb68fd3fe47891bd549486d38dcf62d00817296ea314ad37017f5a4986` |
| Projector | `mmproj-Qwen3.5-9B-Uncensored-HauhauCS-Aggressive-BF16.gguf`, 921,704,448 B, sha256 `05f662501f8bd45607b079723a3e238a4e888fd085a10a53f4057a0e250f6934` — the model is natively multimodal and the Q6_K file carries no vision tensors, so this file IS the vision capability |
| Fetch | [`scripts/download-frank-zealot.sh`](../../scripts/download-frank-zealot.sh) — `-f`, byte-count + sha256 verified (the hashes are computed locally: the repo is Xet-backed, so the Hub publishes file OIDs, not file sha256), idempotent, `--verify-only` |
| Seam | `tests/frank_zealot_unit.bats` (argv assertions against a stub engine) |
## Payload geometry (read from the GGUF header, not the model card)
Range-read of the file's own metadata + tensor-info section:
|Key|Value|
|---|---|
|`general.architecture`|`qwen35` (dense hybrid: Gated DeltaNet + softmax attention)|
|`qwen35.block_count`|32, `full_attention_interval` 4 ⇒ **8 full-attention layers (3, 7, 11, …, 31) + 24 DeltaNet layers**|
|attention|16 heads, **4 KV heads**, `key_length` = `value_length` = 256|
|`qwen35.ssm.*`|`conv_kernel` 4, `state_size` 128, `group_count` 16, `time_step_rank` 32, `inner_size` 4096|
|context / vocab|262,144 native / 248,320|
|tensor types|Q6_K × 250 + F32 × 177 — standard types only, so the stock master build loads it (the ROCmFPX-style custom-quant lock-in does not apply)|
|MTP|**no `nextn`/`mtp` tensors exist** — in-file MTP is impossible; the card's "MTP support" line describes the base architecture, not this quantized export|
|chat template|supports `enable_thinking`, `tools`/`tool_call`, image/video content parts; it has **no `reasoning_effort` variable** (unused Jinja variables are ignored, so the harness's effort map is inert here, not an error source)|
## Shape
`--ctx-size 401408 --parallel 2` — llama.cpp divides the pool across slots,
so each conversation gets `n_ctx_slot = 200,704` (Frank's cap; the harness
`contextWindow` quotes the per-slot number). `--flash-attn on`,
**`--cache-type-k f16 --cache-type-v f16`** (exact KV), batch 4096 /
**ubatch 2048**, `--log-verbosity 4`, `--jinja --reasoning auto
--reasoning-format deepseek`, `--mmproj`, **speculative decoding OFF**
(`SPEC_TYPE=none` strips both spec flags — the file has no MTP tensors).
**KV rate law.** The pool scales with the 8 full-attention layers: 8 × 4 KV
heads × 256 dim = 8,192 elements/token per cache, so f16 K + f16 V bills
32,768 B/token = **32 KiB/token** → 12.25 GiB at the 401,408 pool. The 24
DeltaNet layers bill a fixed recurrent state **per slot**, not per token —
that is what makes two 200k slots affordable where the 26B MoE fit only one.
**Priced from boots, not formulas.** MiMo-V2.6-Distill-Qwen-9B (identical
qwen35 geometry, 7,793,710,624 B, same mmproj class) at 2 × 200,704 f16 K +
f16 V measured **21,276 used / 2,849 free** at ubatch 1024 and **21,846 /
2,279** at ubatch 2048 — see [[frank-zealot-llama-mimo-q6k-2x200704]].
This file is 415 MiB lighter in weights and its projector is 3 MiB heavier,
so the projection is ~21,430 used / ~2,700 free.
Ubatch 2048 is the measured CUDA optimum for this card and arch (+4.6 %
prefill at 8.9k depth, decode flat, cost 616 MiB); `1024` is the documented
fallback rung if a future shape lands under the 2 GiB floor.
## Measured boot (2026-10-07, deploy `ec6184d`)
`nvidia-smi`: **21,436 MiB used / 2,689 MiB free** — the MiMo-priced
projection (~21,430 / ~2,700) was within 11 MiB. Engine ledger
(`--log-verbosity 4`, `journalctl -u frank-zealot`):
|Line|Value|
|---|---|
|`llama_context`|`n_ctx = 401408`, `n_ctx_seq = 200704`, `kv_unified = false`|
|`llama_kv_cache`|`CUDA0 KV buffer size = 12544.00 MiB` — `size = 12544.00 MiB (200704 cells, 8 layers, 2/2 seqs), K (f16): 6272.00 MiB, V (f16): 6272.00 MiB`|
|`sched_reserve`|`CUDA0 compute buffer size = 1136.06 MiB`, `CUDA_Host compute buffer size = 848.07 MiB`|
|`clip_model_loader` (mmproj)|`model size: 878.99 MiB` + `reserve_compute_meta: CUDA0 248.10 MiB, CPU 24.93 MiB`|
|`srv load_model`|`n_slots = 2, n_ctx_slot = 200704`|
|`print_info`|`n_ctx_train = 262144`, `n_head_kv = 4`|
The `32 KiB/token` law is confirmed exactly: 401,408 × 32 KiB = 12,544 MiB,
which is what the engine printed. The `n_ctx_seq (200704) < n_ctx_train
(262144)` line is informational (a context **below** the trained window is
safe; the Gemma4 era's warning was the opposite case, a drafter running 53 %
**past** its window). Weights load in ~6 s from page cache; `/health` answers
`{"status":"ok"}` and `/v1/models` serves the alias `frank-zealot`.
**Wire rename (2026-10-09):** `ALIAS` moved `frank-secondary` → `frank-zealot`
(commit `7c77326`; the service-file rename to the `frank-zealot.*` names
followed 2026-10-10, commit `55f87fc`),
so the served id matches the harness model id and the family-facing name.
Consumers re-keyed in the same change: OpenWebUI (`model` row, `access_grant`
row, `openai.api_configs` index-2 `model_ids`) and `models.yml` (already
renamed 2026-10-08). llama.cpp does NOT validate the requested model name —
it answers and echoes the served alias — so a stale client keeps working;
the picker and any id-keyed grant is what breaks. See [[OpenWebUI]].
The deploy's Playwright gate passed (33 tests) and the fleet e2e set is
unchanged.
## Client contract
llama.cpp surface: model id `frank-zealot`, native tools via `--jinja`,
thinking in **`reasoning_content`**, vision via OpenAI `image_url` content
parts (probe with a ≥ 256 px image, or the Qwen-VL tower answers "video").
The publisher's recipe ships in `models.yml` `extraBody`: thinking mode
`temperature 0.6 / top_p 0.95 / top_k 20 / min_p 0` (non-thinking mode is
0.7/0.8/20/0). The card's advice "maintain at least 128K context to preserve
thinking" is satisfied by the 200,704 slot.
**Compaction hub**: `models.yml` routes `compactionModel` for all three
endpoints here — still true 2026-10-18 (`~/.omp/agent/models.yml:25,107,185` all name `llamacpp (dankclaw-3090)/frank-zealot`). With `--parallel 2` a compaction request no longer serializes
behind a live generation (the Gemma4 era's `--parallel 1` law), and the
200,704 slot still fits the worst-case compaction input (~133k tokens).
## Rollback
|Target|How|
|---|---|
|Gemma4-26B-A4B Q4_K_M, 1 × 200,704, f16 K + q8_0 V|revert the swap commit — payload stays at `/home/dank/models/Gemma4-26B-A4B/`; see [[frank-zealot-llama-gemma4-q4km-200704]]|
|MiMo-V2.6 Q6_K, 2 × 200,704, f16 KV|`MODEL_FILE=/home/dank/models/MiMo-Q6K/MiMo-V2.6-Distill-Qwen-9B-Q6_K.gguf` + its mmproj — measured 21,276/2,849 at ubatch 1024, 21,846/2,279 at 2048|
|Swift-1.5-27B IQ3_XXS 2 × 114,688 + MTP|payload on disk at `/home/dank/models/Swift15-UncIQ3XXS/`|
## When it misbehaves
Same decision tree as the predecessors: `No CUDA GPUs are available` ⇒
`nvidia-modprobe -u -c=0`; a 400 naming 200,704 ⇒ the conversation outgrew
one slot, not the pool; queue behind two long generations ⇒ the slot ceiling
is two, by contract; a boot that OOMs ⇒ read the verbosity-4 ledger in
`journalctl -u frank-zealot` (KV MiB, compute buffers) before touching
flags — the engine prints the exact figures the shape needs.
**`status=203/EXEC` boot loop**: the rewrite of `serve-frank-zealot.sh`
shipped without its `#!/usr/bin/env bash` line, and systemd failed the
`ExecStart` before the script ran — 10 s restarts, `Mem peak: 1.9M`, and
`nvidia-smi` flat at 1 MiB used (the GPU is never touched). Journal signature:
`Failed at step EXEC spawning /home/dank/…/serve-frank-zealot.sh`. A
shebang is not decoration on this host: every LLM serve script is a direct
`ExecStart`, so `head -1` is part of the deploy check (commit `ec6184d`).