Design + what exists so far · updated as build proceeds

Architecture

Design in one paragraph

llama.cpp built from current source with two backends — Vulkan (RADV) and HIP (ROCm gfx1151) — benchmarked head-to-head, winner per workload serves. Model weights live on the dedicated 2TB NVMe (/srv/llm/models). Multiple models serve side-by-side where memory allows (Qwen3.8-27B at 19 GB + DeepSeek-V4-Flash at 103 GB ≈ 121 GB co-resident; the 27B + a smaller endpoint otherwise), coordinated by llama-swap — the same tier/eviction design proven on our ashborn-prime node. One OpenAI-compatible endpoint (:8080) fronts everything; a small embeddings model gets a dedicated endpoint; the CPU reranker pattern carries over verbatim. Everything runs as user wg via systemd user units — the dan setup account was removed 2026-09-11.

Why two backends

Strix Halo tuning (AMD playbook findings)

LeverSettingStatus
GPU-accessible memoryamdgpu.gttsize=126976 ttm.pages_limit=32505856 (124 GiB pair) — default ~50% cap is what breaks 100 GB modelsactive
BIOS UMA Frame Buffer512 MB, explicitly not AUTO (AUTO fights the GTT strategy; capacity-only, no speed effect)done — set to 512M 2026-09-09
BIOS version3.06 (Jul 2026) available via fwupd — fixes a UMA-cap bug, slow-GRUB bug, real CVEs; downgrade supporteddone — 03.06 flashed 2026-09-09
HIP build-DGGML_HIP_NO_VMM=ON is mandatory on gfx1151 (VMM crashes) — already in our builddone
Runtime load--no-mmap -fa 1; --load-mode dio for fast loads (93 GB in ~33 s); MTP draft = biggest throughput lever (+74–106% measured)A/B at benchmark time
Backend lanesVulkan for decode/interactive, ROCm for prefill/concurrencybenchmark decides

Rejected with evidence (don't re-add): amd_iommu=off (+5–12% prefill but breaks the NPU), xnack=1, vm_update_mode, gartsize=131072, GGML_CUDA_ENABLE_UNIFIED_MEMORY (CUDA-only knob), TDP/TDC/EDC chasing (box already sustains 120 W; decode is bandwidth-bound). Contested (bench before believing): rocWMMA flash-attn flag, ttm.page_pool_size, vm.compaction_proactiveness=20. Full report: research/amd-ai-playbook-strix-halo.md.

Layout on disk

/srv/llm/                     (owned by wg — survives dan-account removal)
├── src/
│   ├── llama.cpp/            production tree — build-vulkan/ + build-hip/ (serving lane)
│   ├── llama.cpp-fp4/        pinned-branch build (d3ca537 + qwen4exp patches) for Flash-Next FP4
│   └── llama.cpp-glm/        PR-branch build for GLM-5.3-Flash (agent experiment)
├── bench/                    benchmark scripts  ·  logs/  →  all run outputs
├── venv/                     Python 3.14 + huggingface_hub CLI (model pulls)
└── models/                   weights, one directory per model (2TB NVMe):
    Qwen3.8-27B (main+mmproj+MTP) · Flash-Next IQ1_S set · Flash-Next ROCmFP4 ·
    GLM-5.3-Flash IQ2_XS · Llama-3.3-70B · Qwen3-Embedding · bge-reranker (4 quants)

The OS keeps its own 1TB NVMe; wiping/replacing models never touches it.

Carried over from ashborn-prime (proven config)

Endpoints (live)

EndpointPurposeStatus
:8081 /v1THE GATEWAY — endpoint of record for clients: OpenAI-compatible chat/completions with memory (mem0+Qdrant) injection, tracing (Phoenix), server-side persona; streams byte-for-bytelive 2026-09-11
:8080 /v1Raw llama-swap lane (admin/benchmark): 7 model ids — qwen38-27b, flashnext-iq1s, flashnext-fp4, glm53-flash, dsv4-flash, llama-3.3-70b, embedlive
:18190 /v1/rerankCPU reranker (BGE-Reranker-v2-M3 Q8_0)live
:9621LightRAG (grounding; separate service — gateway proxying is a roadmap follow-up). Bound to 127.0.0.1, exposed to the tailnet via tailscale serve --tcp 9621live
:8188ComfyUI (mediagen). Bound to 127.0.0.1, exposed to the tailnet via tailscale serve --tcp 8188live
:6006Phoenix tracing UI (OTLP ingest from the gateway) — localhost-only, not tailnet-exposedlive
tailnet :22SSH admin (wg — key auth; the dan account was removed 2026-09-11)live
Firewall scope8080/8081/18190 reachable from tailnet CGNAT range (100.64.0.0/10) only; LAN rules for the owner's static-IP network are a handback item (Roadmap 5.3); public blocked. HTTPS via tailscale servelive
AuthAPI key required on all inference endpoints (llama-server --api-key per entry). Two independent keys are live (2026-09-12, gateway patched for multi-key): builder key in /srv/llm/secrets/api-key, owner key in /srv/llm/secrets/api-key-2 — both work on every endpoint; issued out-of-bandlive

Agent integration (Hermes profile template, model ids, client examples): Hermes Integration →

OpenWebUI is NOT installed on this box by design — the owner sets it up on his own machine after handback (guide: OpenWebUI →, with <BOX-IP> placeholders).

Ownership & service model