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.
9.2 KiB
type, title, description, tags, timestamp
| type | title | description | tags | timestamp | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| reference | frank-npu (retired) — FLM NPU endpoint on Dankclaw | The retired FastFlowLM endpoint on Dankclaw's XDNA2 NPU — what it served, why it died on 2026-09-11 with the amd_iommu=off decision, and where every dependent route went. |
|
2026-09-11 |
frank-npu — the retired FLM NPU endpoint
RETIRED 2026-09-11 by operator decision — and still retired: there is no NPU endpoint service on Dankclaw today. The IOMMU configuration it required has since been reversed twice — see dankclaw-iommu-translation-off: the live 2026-10-18 posture is
cat /proc/cmdline→… ro quiet splash iommu=pt …(noamd_iommutoken),amdxdnais bound and/dev/accel/accel0exists, so the hardware is reachable again — revival is tracked as Gitea issue #3. The service unit, env file and serve script are staged inserverAppConfigs/.AGENTTRASH/(suffixed.flm-npu), and the host unit is still masked (systemctl is-enabled frank-npu→masked, read 2026-10-18). Port 7771 belongs to frank-zealot-llama-prism-bonsai2-pq20 today.
The third inference endpoint on Dankclaw: a FastFlowLM (FLM) v1.0.1 server
(/usr/bin/flm, dpkg fastflowlm) on the XDNA2 NPU (50 TOPS), serving the
whole local model registry on port 7771 and routing per request by the exact
FLM registry tag. Its one capability the iGPU fleet lacked was sight — and
briefly sound: the Gemma4 E4B IT NPU2 pack carries both a vision and an
audio tower, which is why the service ran that pack rather than the
uncensored-but-text-only alternative.
This page is kept as the retirement record. The operational detail below was live-verified while the service ran and remains accurate about FLM's shape.
Why it is retired
The replacement large-model runtime is worth 13–16 % of prefill if the
kernel boots with amd_iommu=off instead of iommu=pt, measured by the
upstream project on this exact silicon. That single flag is the whole decision:
- With IOMMU off there is no PASID/SVA state, and the XDNA2 driver cannot hand
out
/dev/accel/accel0— every open fails witherr=-19("No such device"). That is precisely the failure the endpoint was rescued from on 2026-08-30, recorded in the next section. iommu=ptwas recorded here as "not a middle ground", on the theory that the passthrough domain still costs the vendor's prefill number. That claim is dead: the host flipped toiommu=pton 2026-10-18 and the local A/B on byte-identical traffic measured the cost at nothing (+2.0 % cold prefill, 1,616 t/s at 59k tokens). Identity mode does keep a 1:1 page walk plus ATS/PRI/PASID/GCR3 armed for the iGPU — worth 2–4 % on this silicon class, and AMD PerfOpt (Linux 7.4, merged 2026-09-24) removes it outright by enforcing only the IR/IW permission bits for the privileged iGPU — but nothing waits on that now.- The precondition is satisfied; the endpoint is still not deployed.
amdxdnabinds0000:c6:00.1(driver 0.7.0, firmwareamdnpu/17f0_11/npu_7.sbin), the NPU sits in IOMMU group 26identitywith PASID width 10,/dev/accel/accel0iscrw-rw---- root:render 261,0anddankis inrender— so a revival quadlet needsAddDevice=/dev/accel/accel0+GroupAdd=keep-groups, the ComfyUI/dev/kfdpattern. Re-read live 2026-10-18:lspci -k -s c6:00.1→Kernel driver in use: amdxdna;journalctl -k -b→Initialized amdxdna_accel_driver 0.7.0 for 0000:c6:00.1andLoad firmware amdnpu/17f0_11/npu_7.sbin;/sys/kernel/iommu_groups/26/type→identity;ls -l /dev/accel/accel0→crw-rw---- 1 root render 261, 0(created 2026-10-18 01:25);id -nG dankcontainsrender. Kernel versions to avoid: 6.18–6.18.7 disables SVA outright (unverified 2026-10-18 — upstream reports place the amdxdna/Strix-Halo breakage at 6.18.4+ and fixed by 6.19.2, not at a clean 6.18–6.18.7 window). Full census in dankclaw-iommu-translation-off § 2026-10-18 execution. - The operator took the vendor's prefill figure on the September evidence, so the NPU endpoint went — and it stays retired because nobody has asked for a model on it, not because the hardware is unreachable.
Consequences accepted at retirement: audio input left the fleet with no
replacement (halogen reads images only, no audio or video), and the surviving
image path is halogen's vision tower on frank-dragoon.
Where its routes went
| consumer | setting | now |
|---|---|---|
| Hermes | auxiliary.vision |
dankclaw-large / frank-dragoon (halogen vision tower) (unverified 2026-10-18: /opt/hermes is gone from Dankclaw, so the live config.yaml could not be read) |
| Hermes | auxiliary.title_generation |
dankserver-small / frank-zealot (unverified 2026-10-18: same) |
harness (~/.omp/agent/config.yml) |
modelRoles.vision |
moved again: llamacpp (dankclaw-3090)/frank-zealot:xhigh (config.yml:6) |
| harness | modelRoles.tiny |
llamacpp (dankclaw-3090)/frank-zealot:off (config.yml:10) |
| harness | modelRoles.task |
llamacpp (dankclaw-3090)/frank-zealot:off (config.yml:11) |
The flm (dankclaw-npu) provider block was removed from the harness model
config, and the dankclaw-npu provider from Hermes's live config.yaml.
What it was
| Field | Value |
|---|---|
| Runtime | FLM v1.0.1 (/usr/bin/flm, dpkg fastflowlm; dpkg -l fastflowlm on 2026-10-18 still reports fastflowlm 1.0.1) on the XDNA2 NPU |
| Service | frank-npu.service (systemd system unit, User=dank, Restart=on-failure, RestartSec=10, LimitMEMLOCK=infinity) |
| Files (archived) | scripts/frank-npu.env, scripts/serve-frank-npu.sh, scripts/frank-npu.service |
| Port | 7771 on 0.0.0.0 (that port is frank-zealot's today) |
| Power mode | FLM_PMODE=turbo — nothing else used the NPU, so the top power mode cost no neighbour anything |
| Context | FLM_CTX_LEN=131072 (128K, the verified maximum on this box) |
| Vision/audio | FLM_ASR=0; the E4B pack answers images through its own vision tower, and FLM_ASR=1 would have added Whisper-V3-Turbo-NPU2 (+0.62 GB) and /v1/audio/transcriptions |
The serve script exported FLM_CONFIG_PATH=/home/dank/.config/flm/model_list.json
and FLM_XCLBIN_PATH=/home/dank/.config/flm/xclbins, with kernels symlinked
from /opt/fastflowlm/share/flm/xclbins/ into the per-pack directories, so a
tag swap was an env-file edit rather than a script edit.
API contract (as it behaved)
- The endpoint served the whole local registry (36 tags at first deploy) on
one port;
/v1/modelslisted them all. Chat completions routed per request by the exact registry tag in themodelfield — never a service alias. - Unknown tags did not 404:
/v1/chat/completionsanswered HTTP 200 with a flat error body{"error":"Failed to load <tag> model!"}and nochoices. Status-code-only clients silently got an empty response. - Health was
GET /v1/version; FLM has no/healthroute. - The NPU is a single-lane device — generations serialized FIFO. It was a background/triage endpoint, not interactive multi-user chat.
The IOMMU/SVA root cause (first deploy crashed, fixed 2026-08-30)
First deploy crash-looped every 10 s with
Error: Open /dev/accel/accel0 failed (err=-19): No such device. The chain,
all live-verified on the host:
amdxdna_drm_openfailed SVA bind with ret -19 for every client — the XDNA2 driver cannot hand out the accel device without PASID/SVA.- SVA requires the AMD IOMMU to be enabled, and the kernel cmdline then
carried
iommu=off. With IOMMU off there are no IOMMU groups and no PASID state;PASIDCtl: Enable-was observed on0000:c5:00.1. - The fix was
iommu=pt: passthrough keeps the iGPU default domain identity-mapped (no DMA-translation overhead forfrank-dragoon) while enabling the IOMMU hardware and PASID that the driver's SVA bind needs. - Post-boot verification:
/sys/kernel/iommu_groups/populated (30 groups), zeroSVA bind device failedentries since boot,accel0recreated at boot, service active withNRestarts=0.
The same root cause explained the older
amdgpu 0000:c4:00.0: no vmid pasid mapping supported kernel line — a
consequence of IOMMU-off, not a GPU fault.
The standing rule this produced — "never set iommu=off on this host again" —
was superseded twice: amd_iommu=off was the intentional posture from
2026-10-16 to 2026-10-18, and the host has since flipped back to iommu=pt
(live cat /proc/cmdline, 2026-10-18: … ro quiet splash iommu=pt …). See
dankclaw-iommu-translation-off for the current posture and how to revert it.
Client wiring (historical)
The pi/harness model config registered this endpoint with the exact FLM
registry tag as the model id and baseUrl http://192.168.0.143:7771/v1.
Both that provider block and Hermes's dankclaw-npu provider were removed at
retirement; the routes are mapped in the table above.
Citations
- FastFlowLM — FLM runtime and NPU model packs
- dankclaw-iommu-translation-off — the decision that retired this endpoint
- halogen-flash-server — the surviving image-input path