frank-large: swap to stock llama.cpp serving Qwen3.8-27B UD-Q8_K_XL with DFlash2

Replace the Kairic Edge ROCmFPX build with the unsloth b11030 stock
llama.cpp prebuilt (ROCm gfx1151) serving unsloth/Qwen3.8-27B-GGUF:
UD-Q8_K_XL (a 27B dense model, 31.5 GiB) with the z-lab DFlash2 Q4_K_M
drafter (depth 4) on the gfx1151 iGPU.

Serving shape: one 262,144-token conversation, q8_0 KV (the build lacks
fp8), text-only, greedy sampling, Qwen-Sharp v22.4.0 template.

- scripts/serve-frank-large.sh: stock llama.cpp + DFlash2 spec decode
- scripts/frank-large.env: new model/drafter/runtime, 262144 ctx / 1 slot
- scripts/download-frank-large.sh: per-file fetch, verify mode, idempotent
- scripts/frank-large.service: updated description
- scripts/deploy-remote.sh: updated pkill pattern + asset gates
- tests/frank_large_unit.bats: new model/runtime/spec assertions
- docs: new runbook (active), Kairic Edge runbook retired (rollback target)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
FrankandClaude committed 2026-09-21 21:50:36 -07:00
1 parent 43b8258061
commit 7689092db8
10 files changed
+414 -306

No files matched your search

+42 -51
View File
@@ -1,34 +1,31 @@
#!/usr/bin/env bats
# Seam: the frank-large Kairic Edge root unit on dankclaw.
# Seam: the frank-large root unit on dankclaw.
#
# The 2026-09-21 cutover moved this service from the unsloth llama.cpp
# prebuilt (b11030-mix-5ff778e, ROCm gfx1151) serving
# unsloth/Qwen3.8-Flash-Next-GGUF:UD-IQ4_XS onto the Kairic Edge runtime
# (ciru-ai/ROCmFPX, branch kairic-edge-qwen38-27b-v1.2, commit 205a3e5)
# serving jcbtc/Qwen3.8-27B-IU4-Kairic-Edge, still as a ROOT unit: a
# source-built runtime has no container image to install and no generated
# The 2026-09-21 cutover moved this service from the Kairic Edge runtime
# (ciru-ai/ROCmFPX) serving jcbtc/Qwen3.8-27B-IU4-Kairic-Edge onto the
# stock llama.cpp prebuilt (unsloth b11030, ROCm gfx1151) serving
# unsloth/Qwen3.8-27B-GGUF:UD-Q8_K_XL with the DFlash2 drafter
# (z-lab/Qwen3.8-27B-DFlash2-GGUF:Q4_K_M), still as a ROOT unit: a
# prebuilt runtime has no container image to install and no generated
# unit to dodge. This seam pins what a flag list cannot show: the
# operator's one-stream / full-window shape, the payload the serve script
# refuses to start without, the MTP + n-gram spec wiring (DFlash is NOT
# available for this model), compatibility mode (the harness needs
# sampling/tools/reasoning, which fast-greedy rejects), a deploy handler
# that gates on the port, and the fact that the sweep for a stray
# benchmark run cannot take frank-small down with it.
# refuses to start without, the DFlash2 spec wiring, fp8 KV, greedy
# sampling, a deploy handler that gates on the port, and the fact that
# the sweep for a stray benchmark run cannot take frank-small down with
# it.
load helpers
ENV_FILE="$REPO_ROOT/scripts/frank-large.env"
UNIT="$REPO_ROOT/scripts/frank-large.service"
SERVE="$REPO_ROOT/scripts/serve-frank-large.sh"
FETCH="$REPO_ROOT/scripts/download-frank-large-kairic.sh"
BUILD="$REPO_ROOT/scripts/build-kairic-edge-gfx1151.sh"
FETCH="$REPO_ROOT/scripts/download-frank-large.sh"
REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
@test "the frank-large unit, env, serve and build files exist where the deployer installs them from" {
@test "the frank-large unit, env and serve files exist where the deployer installs them from" {
[ -f "$ENV_FILE" ]
[ -f "$UNIT" ]
[ -x "$SERVE" ]
[ -f "$BUILD" ]
}
@test "frank-large is boot-persistent, self-healing and unprivileged" {
@@ -44,7 +41,7 @@ REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
grep -q 'FRANK_LARGE_ENV_FILE=/home/dank/serverAppConfigs/scripts/frank-large.env' "$UNIT"
}
@test "the operator's shape is one stream of the full 262144 window with MTP depth 4" {
@test "the operator's shape is one stream of the full 262144 window with DFlash2 depth 4" {
local ctx slots
ctx="$(sed -nE 's/^CONTEXT_SIZE=([0-9]+)$/\1/p' "$ENV_FILE")"
slots="$(sed -nE 's/^PARALLEL_SLOTS=([0-9]+)$/\1/p' "$ENV_FILE")"
@@ -52,70 +49,64 @@ REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
[ "$ctx" -eq 262144 ]
# One stream.
[ "$slots" -eq 1 ]
# MTP depth 4 (the model's MTP layers) + n-gram drafting (24/64/64).
# DFlash2 depth 4 (the drafter's block-diffusion depth).
grep -q '^SPEC_DRAFT_N_MAX=4$' "$ENV_FILE"
}
@test "the harness needs compatibility mode (sampling, tools, reasoning)" {
# The fast-greedy path rejects sampling, penalties, probabilities,
# grammar-constrained tool calls, logit bias, LoRA and a reasoning
# budget. The harness needs all three, so COMPATIBILITY_MODE=1.
grep -q '^COMPATIBILITY_MODE=1$' "$ENV_FILE"
# The serve script enables the fastpath off in compatibility mode.
grep -q 'LLAMA_TARGET_GREEDY_ARGMAX_FASTPATH=0' "$SERVE"
}
@test "frank-large stays text-only" {
# The Kairic Edge model is text-only (no vision projector). The fleet's
# The new model is text-only (no vision projector). The fleet's
# image path is frank-small; models.yml declares frank-large text-only.
! grep -q -- '--mmproj' "$SERVE"
grep -q -- '--mmproj' "$REPO_ROOT/scripts/serve-frank-small.sh"
}
@test "the serve script pins the Kairic Edge runtime and refuses a missing build" {
grep -q 'ROCmFPX-kairic' "$SERVE"
@test "the serve script pins the stock llama.cpp runtime and refuses a missing binary" {
grep -q 'unsloth-llama-b11030' "$SERVE"
grep -q 'llama-server' "$SERVE"
# A missing runtime or payload is a deploy error with a pointer, not a
# restart loop.
grep -q 'Kairic Edge runtime not found' "$SERVE"
grep -q 'runtime not found' "$SERVE"
grep -q 'missing asset' "$SERVE"
# The Qwen3.8 template keeps prior thinking blocks across turns only
# when the kwarg is set.
grep -q 'preserve_thinking' "$SERVE"
# The chat template file is wired (not just the kwarg) — the 73k-token
# fallback incident (2026-09-21) was a missing --chat-template-file.
grep -q 'chat-template-file' "$SERVE"
}
@test "the serve script wires the MTP + n-gram spec method and the sidecars" {
# The Kairic Edge model uses native MTP depth 4 + n-gram drafting
# (24/64/64). DFlash is NOT available for this model (no DRAFT_DFLASH
# spec type in the Kairic Edge runtime).
grep -q -- '--spec-type draft-mtp' "$SERVE"
grep -q -- '--kairic-edge' "$SERVE"
@test "the serve script wires the DFlash2 spec method and the drafter" {
# The new model uses DFlash2 (block-diffusion drafter) at depth 4.
grep -q -- '--spec-type draft-dflash' "$SERVE"
grep -q -- '--model-draft' "$SERVE"
grep -q -- '--spec-draft-n-max' "$SERVE"
# The three PromptForge sidecars (FFN, GDN, GDN-Output) are wired via
# the PROMPTFORGE_* env block.
grep -q 'PROMPTFORGE_IU4_SIDECAR' "$SERVE"
grep -q 'PROMPTFORGE_GDN_SIDECAR' "$SERVE"
grep -q 'PROMPTFORGE_GDN_OUTPUT_SIDECAR' "$SERVE"
# The drafter runs on the iGPU (ROCm0).
grep -q -- '--spec-draft-device ROCm0' "$SERVE"
}
@test "the serve script uses q8_0 KV and greedy sampling" {
# q8_0 KV — the unsloth b11030 build does not support fp8 KV (allowed:
# f32/f16/bf16/q8_0/q4_0/q4_1/iq4_nl/q5_0/q5_1); q8_0 is the
# highest-precision 8-bit option and preserves the ~8 GiB footprint.
grep -q -- '--cache-type-k q8_0' "$SERVE"
grep -q -- '--cache-type-v q8_0' "$SERVE"
# Greedy sampling (DFlash2 needs greedy verification).
grep -q -- '--temp 0' "$SERVE"
}
@test "the payload is fetched resumably and verified against declared sizes + sha256" {
grep -q 'jcbtc/Qwen3.8-27B-IU4-Kairic-Edge' "$FETCH"
grep -q 'unsloth/Qwen3.8-27B-GGUF' "$FETCH"
grep -q 'z-lab/Qwen3.8-27B-DFlash2-GGUF' "$FETCH"
grep -q -- '-fL -C -' "$FETCH"
# Each file's local sha256 is compared to its declared oid and a
# mismatch fails the run.
grep -q 'SHA256 MISMATCH' "$FETCH"
}
@test "the build script pins the Kairic Edge commit and the CK patch" {
grep -q 'fdf4bb7fcc984811cef48ce817d89aac064b984a' "$BUILD"
grep -q 'composable-kernel-gfx1151-iu4.patch' "$BUILD"
grep -q 'gfx1151' "$BUILD"
}
@test "the fleet endpoint and alias survive the cutover" {
grep -q '^HOST=0.0.0.0$' "$ENV_FILE"
grep -q '^PORT=7770$' "$ENV_FILE"
grep -q '^MODEL_DIR=/home/dank/models/Qwen3.8-27B-IU4-Kairic-Edge$' "$ENV_FILE"
grep -q '^MODEL_DIR=/home/dank/models/Qwen3.8-27B-UD-Q8_K_XL$' "$ENV_FILE"
grep -q -- '--alias frank-large' "$SERVE"
}
@@ -138,7 +129,7 @@ REMOTE_DEPLOY="$REPO_ROOT/scripts/deploy-remote.sh"
# frank-small on this host is ALSO a llama-server. The sweep must match
# the model path, not the binary name, or a frank-large deploy restarts
# the 3090 endpoint.
grep -q "pkill -f 'Qwen3.8-27B-IU4-Kairic-Edge'" "$REMOTE_DEPLOY"
grep -q "pkill -f 'Qwen3.8-27B-UD-Q8_K_XL'" "$REMOTE_DEPLOY"
# ...and only inside the large handler: extract it and check there is no
# bare binary-name pkill in it.
local large