frank-default-large: re-enable --flash-attn on via QSA F32-mask patch

fa on aborted graph build: build_attn_qsa called ggml_fill on the
F16-converted kq mask (GGML_ASSERT F32 at ggml.c:5371). Patch mirrors the
MLA sparse path in llm_graph_context::build_attn (F32 base mask for the
top-k surgery, F16 cast only at the attention call, gated on
cparams.flash_attn). Vendored at scripts/patches/qwen4exp-qsa-f32-mask.patch
(sha256 f2f4a486...); the build-qwen38 binary on Dankclaw is rebuilt with
it and validated live at CTX_SIZE=32768 (health 200, real completion).
This commit is contained in:
Frank
2026-08-29 23:43:25 -07:00
parent 101b1f8be2
commit 7cb6eeb67a
5 changed files with 70 additions and 21 deletions
+8 -4
View File
@@ -298,9 +298,10 @@ slot (author quick-start; the fully GPU-resident 87 GiB model + f16 KV +
compute buffer OOMs the SVM pool beyond that — verified live: cudaMalloc
fails at 131072/262144), b 4096 / ub 4096, t 16 / tb 16, f16 KV cache,
`--fit off` (auto-fit segfaults on qwen4exp hyper-connection config),
`--flash-attn off` (required: fa on aborts graph build on the QSA indexer
path — F32 `ggml_fill` on the F16 kq mask, ggml.c:5371), and reasoning on (Sharp
template, budget -1, `--reasoning-format deepseek`; chat kwargs keep
`--flash-attn on` (restored 2026-08-29 via the QSA F32-mask patch,
`scripts/patches/qwen4exp-qsa-f32-mask.patch` — re-apply inside
`/home/dank/GitPackages/ROCmFPX` before any clean rebuild), and reasoning on
(Sharp template, budget -1, `--reasoning-format deepseek`; chat kwargs keep
`preserve_thinking` + `preserve_reasoning`). Env
`scripts/frank-default-large.env`, serve `scripts/serve-frank-large.sh`.
@@ -309,7 +310,10 @@ model (v2 joined PLE layout), replacing the kingjones STRIX and jcbtc CIRU v1.1
deployments. The own-matched MTP draft head does NOT load on build-qwen38 —
verified against the v2 main itself (`missing tensor blk.0.hc_attn_norm.weight`),
third confirmation (EasiiX Q8_0 + agentionai FAST vs STRIX_LEAN earlier). The
head stays on disk for a future compatible binary.
head stays on disk for a future compatible binary. Same day, `--flash-attn on`
was restored: the QSA F32-mask patch (vendored
`scripts/patches/qwen4exp-qsa-f32-mask.patch`) fixes the F16-kq_mask
`ggml_fill` abort; the rebuilt fork binary carries it, verified live at 32K.
Runbook:
[serverAppConfigs-docs/LLM/agentionai-fast-imatrix.md](serverAppConfigs-docs/LLM/agentionai-fast-imatrix.md).
+12 -8
View File
@@ -10,12 +10,16 @@
#
# Model: Qwen3.8-Flash-Next base (qwen4exp MoE: 512 experts / 10 used,
# 48 layers = 12 attention + 36 SSM, QSA indexer, hyper-connections, PLE
# KNOWN CONSTRAINTS on the charlie12345/ROCmFPX build-qwen38 runtime.
# 1. FA must stay OFF. --flash-attn on aborts graph build: the QSA
# indexer path calls ggml_fill on the F16-cast kq mask (ggml_fill
# asserts GGML_TYPE_F32 at ggml.c:5371). The v2 main loads and serves
# fine with --flash-attn off (verified live: model loaded, health 200,
# real completion).
# 1. Flash attention is ON. fa on used to abort graph build: the QSA
# indexer path called ggml_fill on the F16-cast kq mask (ggml_fill
# asserts GGML_TYPE_F32 at ggml.c:5371). Fixed in the fork source by
# the QSA F32-mask patch (scripts/patches/qwen4exp-qsa-f32-mask.patch,
# sha256 f2f4a486e21cfad80bfa42683281d18e1cba22fa43c5e0e2aa0cfdbe141e925f)
# and the rebuilt binary at LLAMA_BIN already carries the fix. A clean
# rebuild must re-apply: git apply scripts/patches/qwen4exp-qsa-f32-mask.patch
# inside /home/dank/GitPackages/ROCmFPX before make. Verified live:
# --flash-attn on + v2 main at CTX_SIZE=32768 loads, health 200, real
# completion.
# 2. The MTP draft head does NOT load on this binary. The qwen4exp loader
# requires blk.0.hc_attn_norm.weight per layer; the agentionai FAST
# head carries only blk.48 (verified 3x: EasiiX Q8_0 + FAST against
@@ -54,7 +58,7 @@ ALIAS=frank-default-large
BIND_ADDR=0.0.0.0
LISTEN_PORT=7770
# Serving: 131072-token context on ONE slot (parallel 1), batch 4096 /
# Serving: 32768-token context on ONE slot (parallel 1), batch 4096 /
# ubatch 4096, 16+16 threads, f16 KV, 16 context checkpoints, 8 GiB
# prompt cache. --fit off: auto-fit segfaults on this model's
# hyper-connection/indexer config; -ngl 999 puts every layer on the
@@ -81,7 +85,7 @@ SLOT_SAVE_PATH=/home/dank/serverAppConfigs/scripts/slot-state
SPLIT_MODE=none
FIT=off
NGL=999
FLASH_ATTN=off
FLASH_ATTN=on
# Sampling (card instruct table, non-thinking).
TEMPERATURE=0.7
@@ -0,0 +1,31 @@
--- a/src/models/qwen4exp.cpp
+++ b/src/models/qwen4exp.cpp
@@ -560,9 +565,13 @@ ggml_tensor * llama_model_qwen4exp::graph::build_attn_qsa(
ggml_build_forward_expand(gf, mctx_cur->cpy_k(ctx0, k_cur, k_idxs, il));
ggml_build_forward_expand(gf, mctx_cur->cpy_v(ctx0, v_cur, v_idxs, il));
}
- ggml_tensor * kq_mask = inp->get_kq_mask();
+ // get_kq_mask() returns the F16-converted mask when flash attention is
+ // on, but ggml_fill/set_rows require F32. Mirror the MLA sparse path
+ // (llm_graph_context::build_attn): run the top-k mask surgery on the F32
+ // base mask and cast to the attention type only at the end.
+ ggml_tensor * kq_mask = inp->self_kq_mask;
// prepare new kq mask - starts filled with -INFINITY
ggml_tensor * kq_mask_all = ggml_fill(ctx0, kq_mask, -INFINITY);
@@ -592,9 +601,12 @@ ggml_tensor * llama_model_qwen4exp::graph::build_attn_qsa(
ggml_tensor * q = q_cur;
ggml_tensor * k = mctx_cur->get_k(ctx0, il);
ggml_tensor * v = mctx_cur->get_v(ctx0, il);
- ggml_tensor * cur = build_attn_mha(q, k, v, nullptr, kq_mask_top_k, nullptr, nullptr, kq_scale, il);
+ // flash attention consumes an F16 mask; softmax consumes F32 as-is
+ ggml_tensor * kq_mask_attn = inp->cparams.flash_attn ? ggml_cast(ctx0, kq_mask_top_k, GGML_TYPE_F16) : kq_mask_top_k;
+
+ ggml_tensor * cur = build_attn_mha(q, k, v, nullptr, kq_mask_attn, nullptr, nullptr, kq_scale, il);
cb(cur, "kqv_out", il);
return cur;
}
+1 -1
View File
@@ -59,7 +59,7 @@ fi
: "${SPLIT_MODE:=none}"
: "${FIT:=off}"
: "${NGL:=999}"
: "${FLASH_ATTN:=off}"
: "${FLASH_ATTN:=on}"
: "${TEMPERATURE:=0.7}"
: "${TOP_K:=20}"
: "${TOP_P:=0.8}"
@@ -88,7 +88,7 @@ llama-server \
--mmproj mmproj-Qwen3.8-Flash-Next-f16.gguf \
--host 0.0.0.0 --port 7770 --jinja \
--device ROCm0 --gpu-layers 999 \
--split-mode none --fit off --flash-attn off \
--split-mode none --fit off --flash-attn on \
--ctx-size 32768 --parallel 1 \
--batch-size 4096 --ubatch-size 4096 \
--cache-type-k f16 --cache-type-v f16 \
@@ -114,11 +114,18 @@ Key choices and deviations from the CIRU deployment:
`GGML_QWEN4EXP_PLE_*` / `GGML_CUDA_Q41_MOE_FORCE_J` env knobs are CIRU-
runtime-only and are gone.
- **`--mmproj` active** — vision tower included (f16, lossless).
- **`--flash-attn off` is mandatory.** With fa on, the QSA indexer path
(layers with attention compression) calls `ggml_fill` on the F16-cast kq
mask and aborts graph build (`GGML_ASSERT(a->type == GGML_TYPE_F32)`,
ggml.c:5371, backtrace through `build_attn_qsa`). Verified live on this
v2 main — loads and serves fine with fa off.
- **`--flash-attn on` (restored 2026-08-29).** fa on previously aborted graph
build: the QSA indexer path (layers with attention compression) called
`ggml_fill` on the F16-cast kq mask (`GGML_ASSERT(a->type == GGML_TYPE_F32)`,
ggml.c:5371, backtrace through `build_attn_qsa`). Fixed in the fork source
by the QSA F32-mask patch — vendored at
`scripts/patches/qwen4exp-qsa-f32-mask.patch` (sha256
`f2f4a486e21cfad80bfa42683281d18e1cba22fa43c5e0e2aa0cfdbe141e925f`);
the binary at `build-qwen38/bin/llama-server` (rebuilt 2026-08-29) already
carries it. A clean rebuild must re-apply
`git apply scripts/patches/qwen4exp-qsa-f32-mask.patch` inside
`/home/dank/GitPackages/ROCmFPX` before `make`. Verified live at
CTX_SIZE=32768: model loads, health 200, real completion.
- Context capped at **32768 × 1 slot — the author's own quick-start**. This
model is fully GPU-resident (87.06 GiB): the PLE n-gram table sits inside
the GGUF as one tensor, unlike STRIX_LEAN which streamed it from RAM.
@@ -158,6 +165,8 @@ best: 32.4 t/s, 0.612 acceptance; adaptive p-split measured worse).
- Env: `scripts/frank-default-large.env`
- Serve: `scripts/serve-frank-large.sh`
- Chat template: `scripts/chat-template.jinja` (unchanged, Qwen-Sharp)
- Fork patch: `scripts/patches/qwen4exp-qsa-f32-mask.patch` (re-apply after
any clean fork rebuild — see Serving profile)
## Swap procedure
@@ -188,8 +197,9 @@ loading; `deploy.sh` waits up to 20 minutes (`LLM_WAIT`). Do not kill it.
requires a full per-layer `blk.<il>.hc_attn_norm.weight` set; every
Flash-Next-era head checked (EasiiX Q8_0, agentionai FAST, CIRU) carries
only `blk.48`. Spec decoding is ngram-mod only. See the MTP section.
4. **`--flash-attn off` is mandatory.** fa on aborts graph build on the QSA
indexer path (F32 `ggml_fill` on the F16 mask) — see Serving profile.
4. **`--flash-attn on` (restored 2026-08-29).** fa on aborts graph build
without the QSA F32-mask patch — see Serving profile (fix + sha256
vendored there).
5. **`SVM mapping failed` kernel spam** is a documented symptom, not root
cause — investigate before blaming memory pressure.