Files
serverAppConfigs/serverAppConfigs-docs/LLM/frank-redo-2026-08-17.md
T
Frank 219a097b39 docs(vault): one page per endpoint, forever -- 45 era pages fold into three
Every payload swap a live endpoint has ever run is now one row in that
endpoint's Eras table, with its rollback path in the same row. No per-attempt
page, no per-swap ledger, nowhere else.

- Added: LLM/frank-archon.md (radiance, 2x R9700 TP=2), LLM/frank-dragoon.md
  (halogen flash-server, 19 eras), LLM/frank-zealot.md (llama.cpp PrismML fork
  on the 3090). Each carries Current shape, Eras, Laws, wire contract, files.
- Deleted: 45 per-payload runbooks -- the frank-dragoon line (11 including the
  pre-name halogen/kingjones/kairic/CIRU/eemin/agentionai/dflash2 pages and the
  benchmark page), the frank-zealot line (llama.cpp/vLLM/ik_llama/SGLang eras),
  the frank-archon line (vLLM/FreeToken/R9V/llama.cpp/radiance eras), plus
  frank-medium, frank-npu and the ubatch/PCIe one-offs that owned nothing.
- Rewired: every wikilink and markdown-path reference to a folded page points
  at the endpoint page instead; the three Research see-also lists and the
  ubatch sweep's runbook link included. No anchored links existed in the set.
- Regenerated both index pages as pure locators -- one row, one clause, no
  numbers -- so the docs_completeness locator law holds for all 153 pages.

tests/docs_completeness.bats green: index links every page, no unresolved
links. The pages moved to .AGENTTRASH/20261018-doc-dedupe/LLM/ (gitignored,
and git history holds every byte).
2026-10-19 00:49:03 -07:00

230 lines
10 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
description: "This page records the full redo of the inference fleet on 2026-08-17."
tags:
- llm
- frank
timestamp: 2026-09-03
---
# Frank Program Redo — 2026-08-17
This page records the full redo of the inference fleet on 2026-08-17.
The pipeline-parallel split and the FastFlowLM NPU endpoint were retired.
The old scripts moved to `old/scripts/` in this repository.
> **HISTORY — the topology below is two fleet generations dead.** Today the
> fleet is three endpoints: [[frank-archon]]
> (`192.168.0.235:7770`, radiance 1.0.13, 2×R9700 TP=2),
> [[frank-dragoon]] (`192.168.0.143:7770`, halogen
> flash-server 0.16.2 on the iGPU) and
> [[frank-zealot]] (`192.168.0.143:7771`, llama.cpp
> PrismML fork build 10754 on the RTX 3090 — the card that sat in Dankserver
> until 2026-09-15). No vLLM and no ROCm endpoint serves anything; there is no
> pipeline parallelism and no NPU endpoint.
## New Topology
| Service | Host | Runtime | Model | Port |
|---------|------|---------|-------|------|
| frank-dragoon | Dankserver | llama.cpp (patched FastMTP) | HauhauCS Qwen3.8-27B-Uncensored-Aggressive IQ4_XS | 7770 |
| frank-zealot | Dankclaw | vLLM ROCm | nameistoken Qwen3.6-35B-A3B Quark W8A8 INT8 | 52625 |
Names as the 2026-08-17 commit wrote them: `frank-default-large` on Dankserver
(`git show d9af7f1:scripts/frank-default-large.env:20,22` → `ALIAS=frank-default-large`,
`LISTEN_PORT=7770`) and `frank-default-small` on Dankclaw
(`git show d9af7f1:scripts/frank-default-small.env:16,18` → `ALIAS=frank-default-small`,
`LISTEN_PORT=52625`); the Protoss ids date from 2026-10-06 → 10-10.
The RTX 3090 runs the whole 27B model standalone. No RPC worker, no
tensor split, no NPU.
## Models
### frank-dragoon — HauhauCS/Qwen3.8-27B-Uncensored-HauhauCS-Aggressive-MTP-GGUF:IQ4_XS
- Base: Qwen3.8-27B (dense 27B, 64 layers: 48 GatedDeltaNet + 16
gated-attention, hidden 5120, 24 Q heads / 4 KV heads, head dim 256,
native 262144 ctx).
- Quant: IQ4_XS (4.60 BPW, 15.71 GB). Every GGUF in the repo preserves the
native embedded MTP/NextN head.
- FastMTP draft sidecar: `...FastMTP-32K.gguf` (903 MB). Requires the
patched llama.cpp build (commit `4df29be4f4c3673f428170fda944a5b19f743bb8`
+ `HauhauCS-FastMTP-llama.cpp.patch`). Without the patch, the draft load
fails with `expected 5120, 248320, got 5120, 32768`.
- Spec chain: FastMTP (`--spec-type draft-mtp`, `--spec-draft-n-max 2`,
`--spec-draft-ngl all`, `--spec-draft-p-min 0`) then ngram-mod fallback
(48/64/24).
### frank-zealot — nameistoken/Qwen3.6-35B-A3B-Quark-W8A8-INT8
- Base: Qwen3.6-35B-A3B (hybrid MoE, 256 experts top-8, ~3B active, 40
layers: 10 blocks of 3 DeltaNet + 1 Attention, native 262144 ctx).
- Quant: AMD Quark W8A8 INT8 (per-channel static weights, per-token
dynamic activations). MoE experts stored as per-expert nn.Linear
triplets that match vLLM's FusedMoE mapping exactly. Weights ~35 GB;
the vision tower, router, lm_head stay BF16.
- Served with vLLM ROCm, ngram speculative decoding, and tool calling.
- Swap history: the initial deployment used
`Avesed/Qwen3.6-35B-A3B-INT8-W8A8` (compressed-tensors INT8). Its tool
calls were malformed (the model emitted `<function=get_weather(city=...)>`
instead of the Qwen3 XML structure). The Quark quant follows the format
cleanly; swapped in the evening of 2026-08-17.
## Context Math (frank-dragoon, RTX 3090)
KV per token: 16 attention layers x 4 KV heads x 256 dim.
K q8_0 = 1088 B per layer (4 KV heads × 256 dim × 1.0625 B), V f16 = 2048 B per
layer, ×16 layers = 50176 B/token total.
Budget (MiB): 24576 total - 14982 weights - 861 draft - 1024 fixed
(CUDA context, compute graph, scratch, draft KV) - headroom.
| Context | KV (MiB) | Free after load |
|---------|----------|-----------------|
| 114688 (112K) | 5488 | 2221 (2.17 GiB) |
| 122880 (120K) | 5880 | 1829 (1.79 GiB) |
| 131072 (128K) | 6272 | 1437 (1.40 GiB) |
| 147456 (144K) | 7056 | 653 (0.64 GiB) |
Production choice: **131072 (128K)** — the maximum that keeps about
1.4 GiB headroom for checkpoints. Lower `CTX_SIZE` in
`scripts/frank-dragoon.env` to 122880 for ~1.8 GiB headroom.
## Install Runbook
### Dankserver (frank-dragoon)
1. Stop the old worker: `sudo systemctl stop frank-pp-worker`.
2. Download the model and draft to `/home/dank/models/hauhaucs-qwen38/`.
3. Build the patched llama.cpp:
```
git clone https://github.com/ggerganov/llama.cpp /home/dank/llama.cpp-fastmtp
cd /home/dank/llama.cpp-fastmtp
git checkout 4df29be4f4c3673f428170fda944a5b19f743bb8
curl -L -o HauhauCS-FastMTP-llama.cpp.patch <HF patch URL>
git apply HauhauCS-FastMTP-llama.cpp.patch
cmake -S . -B build -DGGML_CUDA=ON -DCMAKE_BUILD_TYPE=Release \
-DGGML_CUDA_FA=ON -DGGML_CUDA_FA_ALL_QUANTS=ON
cmake --build build --config Release -j$(nproc)
```
`GGML_CUDA_FA_ALL_QUANTS=ON` is mandatory. Without it, prefill collapses
~12x (the q8_0 KV + flash attention falls back to a slow path;
measured 95 t/s vs 1300+ t/s at 8K on the 3090).
4. Symlink the unit, reload, enable, restart:
```
sudo ln -sf /home/dank/vLLM/scripts/frank-dragoon.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable frank-dragoon
sudo systemctl restart frank-dragoon
```
5. Verify: `curl -sf http://127.0.0.1:7770/health` and a chat completion.
6. Confirm VRAM headroom with `nvidia-smi`.
### Dankclaw (frank-zealot)
1. Stop the old services: `sudo systemctl stop frank-dragoon
frank-zealot` (retired PP head and NPU endpoint).
2. Install uv and create the venv:
```
curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv --python /usr/bin/python3.12 /home/dank/vllm-venv
uv pip install --python /home/dank/vllm-venv vllm --torch-backend=auto
```
The resolver pulls the AMD ROCm wheel set (torch +
amd-torch-device-gfx1151 + the vllm rocm variant) from the AMD index.
3. Cache the model (default HF cache):
```
python3 -c "from huggingface_hub import snapshot_download; snapshot_download('Avesed/Qwen3.6-35B-A3B-INT8-W8A8')"
```
4. Install the ROCm wheel set and the flash-attention triton path:
```
uv pip install torch --torch-backend=auto
uv pip install "vllm==0.27.1+rocm723" --index-url https://wheels.vllm.ai/rocm/ \
--extra-index-url https://pypi.org/simple --index-strategy unsafe-best-match --no-build-isolation
cp -r <ciru-venv>/site-packages/flash_attn* <vllm-venv>/site-packages/
# add a flash_attn_2_cuda stub module (ROCm build has no compiled .so)
```
Set `FLASH_ATTENTION_TRITON_AMD_ENABLE=TRUE` (env file). Without it the
vision encoder falls back to torch SDPA and engine init OOMs.
5. Symlink the unit, reload, enable, restart:
```
sudo ln -sf /home/dank/vllmScripts/scripts/frank-zealot.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable frank-zealot
sudo systemctl restart frank-zealot
```
6. Verify: `curl -sf http://127.0.0.1:52625/health` and a chat completion.
## Fallback: vLLM source build for gfx1151
If the prebuilt ROCm vLLM wheel cannot run on gfx1151, build from source.
The retired CIRU package documents the proven recipe:
`/home/dank/ling3-ciru/Ling-3.0-Flash-CIRU-int4-Strix-native/scripts/build-vllm-gfx1151.sh`
(branch `ciru/ling3-gfx1151-rocm715`, index `https://rocm.nightlies.amd.com/whl-multi-arch/`).
The upstream starting point needed a five-line ROCm sampler fix to launch
on gfx1151; newer vLLM releases may already include it.
## Configuration
- `models.json` (pi): two providers — `llamacpp (dankserver)` at
http://192.168.0.235:7770/v1 and `vllm (dankclaw)` at
http://192.168.0.143:52625/v1. (The harness config today has three providers
and no vLLM: `~/.omp/agent/models.yml:14,94,173`.)
- HF token: `~/.cache/huggingface/token` on both machines (mode 600).
- OpenWebUI (sibling repo): retarget `OPENAI_API_BASE_URL` to the
Dankserver endpoint.
## Evening Session (2026-08-17): tool calling, model swap, batch 8192
Three changes landed after the initial deployment:
### 1. Tool calling on frank-zealot (HTTP 400 fix)
Clients (pi) send `tool_choice: "auto"`. vLLM rejects it with HTTP 400
unless the server enables tool calling. Fixes applied:
- `--enable-auto-tool-choice --tool-call-parser qwen3_xml` (the Avesed /
Quark chat template renders the Qwen3 XML tool format, and qwen3_xml
is the matching parser).
- Custom chat template `/home/dank/models/qwen36-chat_template-tools.jinja`:
derived from the repo's `chat_template.jinja` (the tokenizer_config.json
ships no template, so vLLM would use its built-in one, which does not
render the XML tool instructions). The custom template adds:
- a concrete WORKED EXAMPLE built from the actual tool schema
(name + parameter keys) — models follow concrete examples much
better than the generic placeholder;
- tool requests default to non-thinking (`enable_thinking` unset + tools
present -> empty think block). Qwen3 tool calls only work reliably
with thinking off; normal requests keep thinking.
Known pitfall: the earlier Avesed model still emitted malformed XML even
with the strong template (`<function=get_weather(city=...)>`); that was
model behavior, which motivated the swap.
### 2. Model swap: Avesed INT8 W8A8 -> Quark W8A8 INT8
`frank-zealot` now serves
`nameistoken/Qwen3.6-35B-A3B-Quark-W8A8-INT8` (AMD Quark 0.11.1, ~35 GB,
vLLM-native expert layout). The Avesed compressed-tensors quant's
Qwen3-XML tool fidelity was poor. Verified with the Quark model: plain
tool requests (no chat_template_kwargs) return clean
`tool_calls: [{"name": "get_weather", "arguments": {"city": "Paris"}}]`;
non-tool requests keep reasoning. The Avesed checkpoint stays in the HF
cache for rollback.
### 3. Batch 8192
`MAX_NUM_BATCHED_TOKENS` lowered from 16384 to 8192 (user request).
vLLM has no separate ubatch knob; the scheduler issues one batch per
step up to this token cap.
### 4. Prefix caching enabled
Added `--enable-prefix-caching`. The model is hybrid (GatedDeltaNet +
full attention); vLLM keeps prefix caching **opt-in** for hybrid models
(`default_prefix_caching = is_prefix_caching_supported and not
is_hybrid`), so it was off by default. Enabling it reuses the KV of
repeated prompt prefixes. Measured on a 2023-token prefix (2026-08-17
evening): 4.6s cold -> 1.1s cached (~4x TTFT), output unchanged. This is
the main TTFT lever for pi, which re-sends the same system prompt + tool
schema every turn. Toggled via `ENABLE_PREFIX_CACHING` in the env file.