frank-large -> CIRU v4.4.1 Orca (new runbook), frank-medium -> the deployed
orcarouter Q8_0 / DFlash2 Q4_K_M / balanced 32:33 / 327680 state. The d374ab9
frank-medium deploy updated only scripts/tests and left AGENTS.md, the runbook
and both indexes on the predecessor (ajgazin Swift UD-Q8_K_XL, 35:30, 393216).
- AGENTS.md: frank-large section (CIRU Orca, root unit, runtime gate, PLE, MTP)
+ frank-medium section and topology row to the deployed shape
- new runbook frank-large-ciru-orca.md
- frank-medium runbook header/intro: orcarouter Q8_0 swap, 32:33, 327680;
predecessor kept as calibration history
- LLM index.md: intro + mermaid (halogen->CIRU, GSQ-RCO->Gemma4, Swift->orcarouter),
add ciru-orca, retire halogen
- top-level index.md: add ciru-orca link (docs-index seam), retire halogen,
fix frank-medium entry
220 lines
11 KiB
Markdown
220 lines
11 KiB
Markdown
---
|
|
type: reference
|
|
title: CIRU v4.4.1 Orca on Dankclaw (frank-large)
|
|
description: The active frank-large runbook — CIRU v4.4.1 (QSA window hotfix) serving jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca on the Dankclaw Strix Halo iGPU: the private host build, the runtime gate, the payload, the deployed config, MTP and PLE, the client contract, and the failure modes worth knowing.
|
|
tags:
|
|
- llm
|
|
- ciru
|
|
- dankclaw
|
|
- frank-large
|
|
- strix-halo
|
|
- gfx1151
|
|
- qwen4exp
|
|
- rocm
|
|
- mtp
|
|
timestamp: 2026-09-19
|
|
---
|
|
|
|
# CIRU v4.4.1 Orca on Dankclaw (frank-large)
|
|
|
|
> **ACTIVE since 2026-09-19.** It replaced halogen-flash-server (see
|
|
> [[halogen-flash-server]], the current rollback), which had replaced
|
|
> ik_llama.cpp (see [[frank-large-ik-uncensored]]). Deployed as a **root
|
|
> systemd unit** (`scripts/frank-large.service`, `User=dank`), port 7770, on the
|
|
> same gfx1151 iGPU the halogen quadlet used. The RTX 3090 it does not touch
|
|
> belongs to [[frank-small-gemma4-12b]].
|
|
|
|
CIRU is a llama.cpp fork tuned for the Qwen3.8-Flash-Next ("qwen4exp")
|
|
architecture on AMD gfx1151 (Strix Halo). v4.4.1 carries a **QSA window
|
|
hotfix** that is what makes vision and the MTP drafter work on this build; the
|
|
pre-applied hotfix source ships in the model repo under
|
|
`runtime/v4.4.1/qsa-window-hotfix/`. Like every other fleet endpoint it is a
|
|
llama.cpp runtime — `llama-bench` is its own harness.
|
|
|
|
## Shape
|
|
|
|
One root unit, one process, one published port:
|
|
|
|
| half | port | reachable |
|
|
|---|---|---|
|
|
| llama-server (OpenAI front-end + engine, single process) | 7770 | published as host **7770** |
|
|
|
|
Unlike the halogen predecessor (two ports: an unauthenticated engine on 8730
|
|
and an OpenAI front-end on 8731), CIRU is a single `llama-server` process —
|
|
there is no separate engine port to keep private.
|
|
|
|
`/v1/models` reports the loaded model name, **`Qwen3.8-Flash-CIRU-STRIX-Orca`**
|
|
(the launcher sets no `--alias`). The endpoint serves **whatever model name a
|
|
request names** — llama.cpp does not reject an unknown id — so the harness's
|
|
`frank-large` label in `models.yml` works without a rename.
|
|
|
|
## Runtime
|
|
|
|
A **private host build**, not a container image. The v4.4.1 source with the QSA
|
|
window hotfix, built on the host against the private ROCm SDK that
|
|
`scripts/ciru/setup-linux-amd.sh` installs into the checkout's own venv:
|
|
|
|
| path | what |
|
|
|---|---|
|
|
| `/home/dank/GitPackages/ciru-runtime-v4.4.1-qsa-hotfix/` | the checkout (source + build + venv) |
|
|
| `build-gfx1151-sdk/bin/llama-server` | the built binary |
|
|
| `.venv-rocm/` | the private ROCm SDK venv (~5.7 GB); the binary resolves its libs through RUNPATH |
|
|
| `scripts/ciru/run-orca-server.sh` | the launcher (`exec`'d by the serve script) |
|
|
| `profiles/strix-halo-production.env` | the 36-variable kernel bundle + PLE pager defaults, sourced by the launcher AFTER `frank-large.env` (every line is `${VAR:-default}`, so a value set in `frank-large.env` wins) |
|
|
|
|
### The runtime gate
|
|
|
|
`run-orca-server.sh` sources `run-server.sh`, which **exits 2** unless
|
|
`${repo_root}/runtime/hip/lib/libamdhip64.so` and `runtime/rocr/lib/
|
|
libhsa-runtime64.so` exist (unversioned, no suffix). It prepends both to
|
|
`LD_LIBRARY_PATH` and `ldd`-checks that the built `libllama-common.so` carries
|
|
the "Qwen4Exp MTP image position" marker and the HIP lib carries the
|
|
`flash_attn_index_mask_clear/set/empty` symbols before exec.
|
|
|
|
The build links the venv through RUNPATH, so those two files are an existence
|
|
gate, not a real dependency. `serve-frank-large.sh` satisfies the gate
|
|
idempotently: it finds the venv's unversioned devel symlinks
|
|
(`.venv-rocm/lib/python*/site-packages/_rocm_sdk_devel/lib/`) and `ln -sfn`-s
|
|
both into `runtime/{hip,rocr}/lib/`. **The first deploy of this endpoint failed
|
|
exactly here** — the build linked the venv but `runtime/` did not exist, so the
|
|
launcher exited 2 and the unit crash-looped until the serve script created the
|
|
symlinks.
|
|
|
|
## Payload
|
|
|
|
`scripts/download-frank-large-orca.sh` assembles `jcbtc/Qwen3.8-Flash-CIRU-
|
|
STRIX-Orca` (HuggingFace, public and ungated) into
|
|
`/home/dank/models/Qwen3.8-Flash-CIRU-STRIX-Orca/`, sha256-verified. The
|
|
launcher refuses to start without the main GGUF, the MTP head and the PLE
|
|
sidecar:
|
|
|
|
| file | bytes | role |
|
|
|---|---|---|
|
|
| `Qwen3.8-Flash-CIRU-STRIX-Orca.gguf` | 79,397,818,912 | the main model (Orca variant) |
|
|
| `mtp/Qwen3.8-Flash-CIRU-STRIX-Orca-MTP-Q8_0.gguf` | 4,135,893,440 | the MTP drafter head |
|
|
| `ple/ple.payload.bin` | 52,429,053,952 | the per-layer-embedding (PLE) payload — mmap'd and paged, not resident |
|
|
| `ple/ple.manifest.json` | — | PLE manifest |
|
|
| `ple/ple.scale.bf16` | — | PLE scale |
|
|
| `vision/mmproj-Qwen3.8-Flash-Orca-F16.mmproj` | 904,004,320 | the F16 vision projector (on disk, `ENABLE_VISION=0`) |
|
|
|
|
The main GGUF ships as **transport parts** that the download script assembles
|
|
and verifies; the PLE is the large one (52.4 GB) and is paged by the engine's
|
|
own workers, not held in RAM.
|
|
|
|
## Deployed config
|
|
|
|
Tunables live in `scripts/frank-large.env`; the launcher owns the flag list
|
|
(`-sm none` one iGPU no split, `-ngl all`, f16 KV, flash attention,
|
|
cont-batching, the PLE sidecar, the MTP drafter, the production kernel-bundle
|
|
profile). The departures worth naming:
|
|
|
|
| flag | value | why |
|
|
|---|---|---|
|
|
| `CONTEXT_SIZE` | `262144` | the model's FULL trained window (the operator's "full context" call); the GGUF carries no rope scaling |
|
|
| `PARALLEL_SLOTS` | `1` | one stream — and the MTP drafter **requires exactly one slot** in this runtime, so the operator's ask and the drafter's constraint are the same number |
|
|
| `ENABLE_MTP` | `1` | the MTP drafter, depth 4 (the Orca variant's own `mtp_depth_default`) |
|
|
| `ENABLE_VISION` | `0` | text-only for now; the F16 projector is on disk, one flip to enable. The fleet's image path is [[frank-small-gemma4-12b]] either way |
|
|
| `PLE_CACHE_MIB` | `4096` | the PLE pager's hot window kept resident; the vendor production-profile default. The 52.4 GB payload is mmap'd and paged around it |
|
|
| `HOST` | `0.0.0.0` | the launcher consumes it for `--host`; the value doubles as a JIT-cache directory name, which is why `0.0.0.0` is safe (HIP reads `HOST` bare — see the AGENTS.md note) |
|
|
|
|
`TEMP`, `HOST` and `GPU_MAX_HEAP_SIZE` are the three names to avoid for any
|
|
new tunable: HIP reads them bare.
|
|
|
|
## MTP
|
|
|
|
The Multi-Token Prediction drafter is a **separate Q8_0 head** (not inside the
|
|
main GGUF), loaded by the launcher. It requires exactly one slot, which is why
|
|
`PARALLEL_SLOTS=1`. Depth 4 is the Orca variant's default.
|
|
|
|
Verified at deploy (2026-09-19): the per-task `draft acceptance = 0.65625
|
|
(21/32), mean len = 3.62` — the drafter is engaged and accepting, not silently
|
|
standing down.
|
|
|
|
## PLE
|
|
|
|
The per-layer-embedding payload (52.4 GB) is the Qwen3.8-Flash-Next
|
|
architecture's signature: token embeddings live outside the main weight set and
|
|
are paged on demand by the engine's own workers (`GGML_QWEN4EXP_PLE_WORKERS=16`,
|
|
`GGML_QWEN4EXP_PLE_IO_WORKERS=32` in the production profile). `PLE_CACHE_MIB=4096`
|
|
is the hot window kept resident; the rest is mmap'd file cache. **Do not treat
|
|
the 52.4 GB as resident memory** — `free` and the dashboards will not show it
|
|
pinned, and that is correct.
|
|
|
|
## Client contract
|
|
|
|
The differences from a stock llama.cpp endpoint that bite:
|
|
|
|
- **`reasoning_content`** carries the reasoning trace (the standard OpenAI
|
|
field). The serve script passes `--chat-template-kwargs
|
|
'{"preserve_thinking":true}'` so prior thinking blocks are kept across turns;
|
|
a request-level `chat_template_kwargs` still wins.
|
|
- **`reasoning_effort` is gated.** Qwen3.8's template accepts only
|
|
`xhigh`, `medium`, `low` and **500s on anything else** (not a clamp). The
|
|
harness folds every level onto that set in `models.yml`
|
|
(`reasoningEffortMap`: minimal/low→low, medium→medium, high/max→xhigh) —
|
|
subagents run at `high`, which is why the map exists.
|
|
- **Text only.** `ENABLE_VISION=0`, so image content parts are refused. The
|
|
fleet's image path is [[frank-small-gemma4-12b]].
|
|
- **Sampling.** The server has no sampler defaults of its own; the harness
|
|
applies the per-model recipe from `models.yml` (temp 1.0 / top_p 0.95 / top_k
|
|
20 / min_p 0.0). A client that stays silent gets the launcher's default.
|
|
- **`tools` works** — the launcher passes `--jinja`, and the Qwen3.8 template
|
|
supplies the tool-call grammar. Verified at deploy: a tool call returns
|
|
`tool_calls`.
|
|
|
|
## Deploy and operate
|
|
|
|
```bash
|
|
./scripts/deploy.sh dankclaw --service frank-large
|
|
```
|
|
|
|
The handler pulls the checkout (ff-only), (re)links the unit, and gates on
|
|
`/health`. First boot is the slow one (model load ~46 s + graph capture); a
|
|
warm restart is fast.
|
|
|
|
```bash
|
|
sudo systemctl status frank-large # the root unit
|
|
sudo journalctl -u frank-large -n 60 # startup account: runtime check, model load, "listening on http://0.0.0.0:7770", MTP draft loaded
|
|
curl -s http://127.0.0.1:7770/health # ok
|
|
curl -s http://127.0.0.1:7770/v1/models # Qwen3.8-Flash-CIRU-STRIX-Orca
|
|
```
|
|
|
|
**Stop and mask before any GPU experiment** (the AGENTS.md bench protocol):
|
|
`sudo systemctl stop frank-large && sudo systemctl mask frank-large`. The
|
|
frank-large serve process is a `llama-server` **and so is frank-small on the
|
|
same host** — never `pkill -x llama-server`. If you must kill by pattern, use
|
|
`pkill -f 'Qwen3.8-Flash-CIRU-STRIX-Orca'` (the model path is unique to this
|
|
endpoint and does not appear in the deploying shell's own command line).
|
|
|
|
## Troubleshooting
|
|
|
|
| symptom | cause |
|
|
|---|---|
|
|
| launcher exits 2: "The v4.4 HIP/ROCr runtime is missing" | `runtime/{hip,rocr}/lib/*.so` absent — the serve script's `ln -sfn` did not run, or the venv was moved. Re-run the serve script or rebuild: `bash $RUNTIME_DIR/scripts/ciru/setup-linux-amd.sh --install-host-deps` |
|
|
| "missing SDK venv runtime under .../.venv-rocm" | the venv's unversioned devel symlinks are gone — rebuild the runtime |
|
|
| "missing target model / missing payload" | a download did not finish — re-run `scripts/download-frank-large-orca.sh` |
|
|
| loads, `/health` ok, first completion slow (~45-60 s) | the PLE pager pulling the hot window in from file cache — not a crash, do not restart over it |
|
|
| a subagent 500s naming `reasoning_effort` | the Qwen3.8 template gate — the harness `reasoningEffortMap` must fold the level onto {xhigh, medium, low} |
|
|
| `free` / dashboards do not show 52 GB pinned | correct — the PLE is mmap'd file cache, not resident; only `PLE_CACHE_MIB` is hot |
|
|
|
|
Retrieval: this is a **root** unit, so `journalctl -u frank-large` is the
|
|
durable record (no `--user`, no `sudo` needed for the journal once the unit is
|
|
readable). There is no container log — there is no container.
|
|
|
|
## Rollback
|
|
|
|
The predecessor is intact: the halogen payload stays at
|
|
`/home/dank/models/halogen` (retired, not deleted), and the halogen quadlet is
|
|
archived under `.AGENTTRASH/`. Rolling back is a `git revert` of this change set
|
|
plus a deploy — **but the root unit and the halogen quadlet both claim port
|
|
7770**, so the handler's port-free gate covers that race. See
|
|
[[halogen-flash-server]].
|
|
|
|
The `amd_iommu=off` kernel argument is separate and reverts on its own — see
|
|
[[dankclaw-iommu-translation-off]].
|
|
|
|
## Citations
|
|
|
|
- [jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca](https://huggingface.co/jcbtc/Qwen3.8-Flash-CIRU-STRIX-Orca) — weights, MTP head, PLE payload, and the v4.4.1 QSA window-hotfix source tarball
|
|
- [CIRU runtime v4.4.1](https://github.com/ciru) — `scripts/ciru/run-server.sh` (runtime gate), `profiles/strix-halo-production.env` (kernel bundle), `docs/BUILD_LINUX.md`
|