Files
serverAppConfigs/serverAppConfigs-docs/LLM/frank-large-rocmfpx-q8agent-mtp.md
T
Frank b80886e318 docs: frank-large Q6 uncensored cutover + frank-small 2x200704 f16-KV reslice
- new active runbook frank-large-rocmfpx-q6agent-uncensored-mtp.md: the
  Q6_0_ROCMFPX_AGENT file (ftype 114, 339 type-102 + 159 type-103 tensors),
  27.6-28.1 t/s at 86.8% draft acceptance, the measured ngram-mod chain
  rejection (-15% prose: recurrent-state rollback disabled), the
  bench-window hardening laws
- frank-large-rocmfpx-q8agent-mtp.md retired; rollback section corrected
  (gufo payloads removed from disk 2026-10-03 - that rollback is now a
  re-download; the aligned Q8 file is the direct one, still on disk)
- frank-small-llama-mimo-q5km.md reshaped to 2 x 200704 with fully
  unquantized f16 KV: boot-pair table gains the measured row (20,530 used /
  4,046 free), 104.84 tok/s, slot-window contract at 200704, rollback to
  the 3x180224 + q8_0-V shape documented
- AGENTS.md: fleet table rows, both endpoint sections, the chain law
  extended with the recurrent-model measurement, the --parallel law with
  the reslice, runbook index (active + retired)
- LLM/index.md + root index entries updated
2026-10-03 08:01:44 -07:00

233 lines
12 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-large on Dankclaw — ROCmFPX llama.cpp, Qwen3.8-27B Q8_0_ROCMFPX_AGENT + MTP (retired)"
description: "The retired frank-large runbook — the kingjones30/ROCmFPX llama.cpp fork (pinned commit, gfx1151) serving kingjones777's Q8_0_ROCMFPX_AGENT GGUF, a ftype-115 file no other loader can read, with the repo's own MTP-Q4_0 head, f16 KV, and the BF16 projector. Measured MTP-vs-none A/B, the client contract, and the rollback state as of 2026-10-03."
tags:
- llm
- frank-large
- dankclaw
- llama-cpp
- rocmfpx
- gfx1151
- gguf
- spec-decode
- mtp
timestamp: 2026-10-02
---
# frank-large — ROCmFPX Q8_0_ROCMFPX_AGENT + MTP (gfx1151, retired)
> **RETIRED 2026-10-03** — superseded by
> [[frank-large-rocmfpx-q6agent-uncensored-mtp]]: Frank swapped to the
> uncensored Q6_0_ROCMFPX_AGENT file (protected heads, one rung down), which
> measures **27.6–28.1 t/s** at a deeper prompt than this file's 17.0. This
> runbook stays live as the rollback reference and the trap catalogue; the
> payload it documents remains on disk at
> `/home/dank/models/kingjones-Qwen3.8-27B-ROCmFP4-STRIX-MTP/`.
>
> Cut over 2026-10-02 from [[frank-large-gufo-qwen38-27b]] (Q4_K_XL, ~15 t/s)
> on two requests from Frank: *highest quality that runs*, and *one full
> context*. It delivered 8.39 bpw weights — two quant rungs above what gufo
> could load — at 17.0 t/s, so quality was not bought with speed.
>
> The capability that forced this whole shape is a GGUF tensor type:
> **`GGML_TYPE_Q8_0_ROCMFPX` (103)**. It exists in exactly one loader on this
> host, so the runtime was decided by the file, not by preference.
## Identity
| | |
|---|---|
| Host / device | Dankclaw (192.168.0.143), Radeon 8060S iGPU `gfx1151`, ~114 GiB GTT aperture |
| Endpoint | `http://192.168.0.143:7770` — alias `frank-large`, `/v1` OpenAI surface |
| Runtime | **`kingjones30/ROCmFPX`** llama.cpp fork @ `36e9acd40e10a87cd3c3ef8ec734668757dc8520`, built by [`scripts/build-rocmfpx.sh`](../../scripts/build-rocmfpx.sh) → `/home/dank/GitPackages/kingjones-ROCmFPX/build/bin/llama-server` |
| Unit | root systemd `frank-large.service` ([`scripts/frank-large.service`](../../scripts/frank-large.service)), `User=dank`, `Restart=always` |
| Serve script | [`scripts/serve-frank-large.sh`](../../scripts/serve-frank-large.sh) (owns the argv), tunables [`scripts/frank-large.env`](../../scripts/frank-large.env) |
| Weights | `/home/dank/models/kingjones-Qwen3.8-27B-ROCmFP4-STRIX-MTP/Qwen3.8-27B-Q8_0_ROCMFPX_AGENT.gguf` — 28,214,425,952 B, sha256 `f3ef2bdbf56e244f…` |
| Draft | `…/mtp-Qwen3.8-27B-Q4_0.gguf` — 1,680,271,648 B, sha256 `051a1764cff8c4f3…` |
| Projector | `…/mmproj-Qwen3.8-27B-BF16.gguf` — 931,145,888 B, sha256 `de2a4986…` |
| Fetch | [`scripts/download-frank-large-kingjones.sh`](../../scripts/download-frank-large-kingjones.sh) (`-f`, byte-count + LFS sha256 verified, `--verify-only`, token never on the command line) |
| Seam | `tests/frank_large_unit.bats` (19 tests: payload gates, deployer/serve parity, spec block, KV dtype, sweep identity) |
## Why this file, and why only this runtime
`kingjones777/Qwen3.8-27B-ROCmFP4-STRIX-MTP-GGUF` ships several rungs. Parsed
headers of the two candidates:
| File | ftype | Tensor mix | Output-head tensors at plain Q8_0 | Card MTP acceptance |
|---|---|---|---|---|
| `Qwen3.8-27B-Q8_0_ROCMFPX_AGENT.gguf` | **115** | 353 F32 + 187 Q8_0 + **311 type-103** | **187** | 0.953 |
| `Qwen3.8-27B-Q8_0_ROCMFPX.gguf` | 111 | 2 Q8_0 + type-103 | 2 | 0.911 |
Two consequences, both measured off the header rather than guessed:
1. **Quality.** The AGENT routing variant keeps the output-head (and other
routing-sensitive) tensors at plain Q8_0 instead of folding them into the
ROCmFPX kernel layout — 187 vs 2 — so the logits the sampler reads are the
highest-precision tensors in the file. It is also the card's MTP-tuned
variant, so it is the *faster* drafter base at the same time.
2. **The runtime is forced.** Type 103 is a private extension: stock llama.cpp
and gufo both fail at load (`unknown tensor type`). Verified on the host
before deploying — the bake-off was not a horse race, it was a lock-in
check.
**The build identity matters as much as the fork.** The 2026-08-25 ROCmFPX
builds read this file and then died in `ggml_compute_forward_set_rows` — the
exact failure documented in [[kingjones-q8agent-rocmfpx]] when this payload was
first attempted on Dankclaw and routed to Dankserver as
[[frank-medium-rocmfpx]] instead. `scripts/build-rocmfpx.sh` therefore checks
the commit out **by SHA** and refuses to build anything else; the pin is
load-bearing, not tidiness.
## Shape and budget
One session, the model's full native window, unquantized KV:
| Dial | Value | Why |
|---|---|---|
| `--ctx-size` | 262,144 | "one full context" — the native window, no rope scaling |
| `--parallel` | 1 | one conversation, all memory to it |
| KV dtype | **f16** (both K and V) | ~64 KiB/token → ~16 GiB; free inside a 114 GiB aperture, so there is no reason to pay a quant |
| `--fit off` | on | the auto-fitter would silently resize the window we asked for |
| `--flash-attn on` | on | required for the long-window attention path to fit |
| `--direct-io` | on | bypasses page cache for the 26 GiB weight stream (mmap is disabled by it — deliberate) |
| `--ctx-checkpoints 16` | 16 | slot state for checkpoint/rollback |
| `--cache-ram 8192` + `--cache-idle-slots` | 8 GiB | prompt cache; verified a repeat pass over the same 6k prompt replays in **0.5 s** |
| `--jinja` | on | without it `chat_template_kwargs` are silently ignored |
| `--reasoning on --reasoning-format deepseek --reasoning-budget -1` | | thinking in its own channel, unbounded |
Measured steady state (production, one model copy resident):
`mem_info_gtt_used` **63.1 GiB** of the ~114 GiB aperture, `mem_info_vram_used`
0.17 / 2.0 GiB (the iGPU's dedicated carve-out is a stub; everything real lives
in GTT). llama-server RSS 2.1 GiB. Boot to `/health` 200: **16 s** — the fastest
endpoint bring-up in the fleet, because there is no engine compile step.
## Speculative decode — measured, not assumed
```
--spec-type draft-mtp --model-draft <mtp-Qwen3.8-27B-Q4_0.gguf>
--spec-draft-n-max 4 --spec-draft-n-min 0 --spec-draft-p-min 0.0
--spec-draft-device ROCm0 --spec-draft-ngl 99
```
MTP in llama.cpp is a property of the file, not of the flags: the head is a
trained tensor set (`nextn_predict_layers = 1` in this repo's head, arch
`qwen35`, 65 blocks) and the draft context runs on the main model's weights, so
there is no second 26 GiB copy in memory. See the fleet law in
`AGENTS.md → llama.cpp serving`.
**A/B, 2026-10-02** — same session, temp 0, 2,202-token prompt, 512 tokens,
`cache_prompt: false`, `frank-large.service` stopped for every scratch arm (the
benchmarking law), baseline arm stripped of `--model-draft` **and** every
`--spec-*` flag:
| Arm | Decode t/s (2 runs) | Prefill t/s | Draft acceptance |
|---|---|---|---|
| **MTP, n-max 4 (deployed)** | **17.00 / 17.14** | 350.6 / 324.9 | 0.462 (mean acceptance length ≈ 1.86) |
| no draft | 7.60 / 7.66 | 381.8 / 381.0 | — |
**+123 % decode for an 8–15 % prefill tax.** Notes that matter before someone
re-litigates this:
- Acceptance here (0.462) is nowhere near the card's 0.953. The card measures
its own short, repetitive text; this is a 2.2k-token prose prompt. Treat the
card's number as a file property, not a throughput promise.
- `n-max 4` is where the gain was measured; 2 and 8 are **unmeasured**. The
gufo-era law applies in spirit — never rank spec settings on a
self-predictable corpus.
- End-to-end on the chat path is slower than the `/completion` number because
thinking tokens are included: a 2,253-token chat prompt generating 512
tokens took 43.8 s wall (11.7 t/s end-to-end) — that is the cost of an
unbounded reasoning budget, not a regression in decoding.
## Client contract (live-verified 2026-10-02)
| Behavior | Observation |
|---|---|
| Model id | `/v1/models` → `frank-large` |
| Tools | native: `get_weather` → `{"city": "Seattle"}` in `tool_calls` |
| Thinking | in **`reasoning_content`** (llama.cpp field — *not* vLLM's `reasoning`); `models.yml` sets `reasoningContentField` accordingly |
| `reasoning_effort` | accepts **only** `xhigh`, `medium`, `low`; anything else is HTTP 500 (the template raises, it does not clamp). `models.yml` folds `high`/`max` → `xhigh` |
| Sampling | server defaults = the card's thinking recipe (temp 1.0, top_p 0.95, top_k 20, min_p 0, presence 0), mirrored in the harness `extraBody` |
| Vision | the BF16 projector loads (`loaded multimodal model`); a red square answers **`Red`** (`usage: 75 prompt / 71 cached`) |
| Prompt cache | second pass over the same 6k prompt: 0.5 s wall |
Three traps, all hit for real:
1. **`content: null` when reasoning eats the budget.** With
`--reasoning-parser`-style separation, a request whose `max_tokens` is
consumed entirely by thinking returns `message.content = None`. A bench
client that indexes `content` crashes *after* measuring and loses the
numbers — fall back to `reasoning_content`, or size the budget (200 was
enough for the vision probe).
2. **`MTP boundary missing for seq_id=… ; resyncing after a non-token step`**
appears in the log under draft resets. Self-recovering; not an outage signal.
3. **Never `pkill -f llama-server` on Dankclaw** — frank-small is also a
`llama-server`. The sweep key here is the payload name:
`pkill -f 'Qwen3.8-27B-Q8_0_ROCMFPX_AGENT'`.
## Operations
```bash
# deploy (planner selects this endpoint only via its own unit/env/serve trio)
./scripts/deploy.sh dankclaw --service frank-large
# status / logs / cause of a crash loop
systemctl status frank-large
journalctl -u frank-large -n 200 --no-pager
# rebuild the pinned fork (only when deliberately moving the pin)
scripts/build-rocmfpx.sh
# re-verify the payload without re-downloading
scripts/download-frank-large-kingjones.sh --verify-only
```
`serve-frank-large.sh` refuses to start — before touching the port — unless the
fork binary, the weights, the MTP head and (unless `FRANK_LARGE_MMPROJ=""`) the
projector all exist; `scripts/deploy-remote.sh` mirrors the same predicate so a
broken payload never stops the running unit. Caller environment **overrides**
`frank-large.env`, and defaults use `:=` so an explicitly empty value surfaces
as the error it reads as.
## Rollback (as of retirement, 2026-10-03)
**Primary rollback: the ALIGNED Q8 file itself is the previous shape's
payload and remains on disk** at
`/home/dank/models/kingjones-Qwen3.8-27B-ROCmFP4-STRIX-MTP/` — revert the
2026-10-03 swap commit (unit/env/serve trio) or repoint
`FRANK_LARGE_MODEL_FILE`/`LLM_LARGE_MODEL_FILE`, verify with
`scripts/download-frank-large-kingjones.sh --verify-only`, redeploy.
git tag **`frank-large-gufo-q4kxl-20261001`** (gufo v0.1.1, Q4_K_XL +
DFlash2) is now a **re-download** rollback: the gufo payloads
`/home/dank/models/Qwen3.8-27B-UD-Q4_K_XL/` (16.35 GiB) and
`/home/dank/models/Qwen3.8-27B-UD-Q8_K_XL/` (incl. the DFlash2 drafter) were
removed from disk on 2026-10-03 with Frank's explicit approval to free space.
`scripts/build-gufo.sh` remains on disk; re-fetch per
[[frank-large-gufo-qwen38-27b]].
The one-day vLLM MiMo era's payloads (MiMo-V2.6 BF16 18 GiB,
Qwen3.5-9B MTP source 19 GiB, both DFlash draft dirs) were staged to
`/home/dank/.AGENTTRASH/20261002-retired-llm-payloads/` on 2026-10-02 —
recoverable until the trash is purged, and never part of a rollback plan.
## When it misbehaves
- **`unknown tensor type` / ftype 115 refused** — something moved off the
ROCmFPX binary. Check `readlink -f $(systemctl show frank-large -p ExecStart)`
and the fork commit; this file cannot run on stock llama.cpp or gufo.
- **SIGSEGV in `ggml_compute_forward_set_rows` during load** — a fork build
older than the `36e9acd` pin; rebuild with `scripts/build-rocmfpx.sh`.
History: [[kingjones-q8agent-rocmfpx]].
- **Slow decode with no log error** — check whether the draft is engaged
(`/metrics`, `draft_n` / `draft_n_accepted`; a zero draft count means the head
did not load), and check GTT pressure with
`cat /sys/class/drm/card1/device/mem_info_gtt_used` — a second resident copy
of this model (an orphaned scratch server) drives the whole host into
eviction and halves the rate silently.
- **`500` naming Jinja** — a `chat_template_kwargs` field reached a server
without `--jinja`.
- **HTTP 500 naming the template on the first request of a role** — an
unmapped `reasoning_effort`; fix the fold in `models.yml`, not the model.