Summary
Unlike most GPU-ineligible architectures (e.g. Phi's LayerNorm gap, #3075), which fall
back to CPU inference with a warning, Qwen3.5/Qwen3.8-architecture GGUFs (hybrid Gated
DeltaNet / SSM layers, general.architecture = qwen35) are refused completely —
there is no CPU inference path at all today. Confirmed with two different downloads:
apr chat ~/Downloads/Qwen3.8-27B-UD-IQ2_XXS.gguf
apr chat ~/Downloads/Qwen3.5-4B-UD-Q4_K_XL.gguf
Both fail identically, even without --gpu:
[GGUF model parse failed: Format error: Architecture 'qwen35' uses SSM/Gated Delta Net
layers which are not yet supported for inference. Use a standard transformer model
(e.g., Qwen2.5, LLaMA, Mistral) or wait for SSM support in a future release., will use CPU]
You: hey
Assistant: [Error: Failed to create GGUF model: Format error: Architecture 'qwen35' ...]
The chat loop even prints "will use CPU" in the CUDA-init warning line, but then the
CPU load of the same GGUF fails with the exact same error — because the refusal is in
the shared GGUF transformer constructor (QuantizedGGUFTransformer::from_gguf), which
both the CPU and GPU code paths call. There is no degraded-but-working CPU mode; the
model simply cannot be loaded by this binary in any form.
Root cause
crates/aprender-serve/src/gguf/transformer.rs::unsupported_architecture_reason is
called unconditionally inside QuantizedGGUFTransformer::from_gguf (GH-704), before
backend selection, and returns Err(FormatError) whenever any tensor name contains
ssm_/ssm.. This is upstream of the CPU/GPU fork — it blocks both.
Ask
- Implement a scalar/SIMD CPU Gated DeltaNet (linear attention) forward pass for
GGUF-loaded hybrid layers — recurrent state + short causal conv1d + gated delta rule,
per Qwen3.5/Qwen3-Next's architecture — analogous to what
crates/aprender-serve/src/gpu/scheduler/linear_attn.rs already sketches for the GPU
scheduler (SafeTensors path), but for the GGUF QuantizedGGUFTransformer CPU path.
- Until CPU inference exists, consider narrowing the current blanket refusal message so
it doesn't imply CPU already works ("will use CPU" in the CLI's CUDA-fallback log line
is actively misleading for this architecture — see below) — or explicitly state in
the error that neither backend supports it yet, to save users a round trip.
- Once a real CPU path lands, extend
apr qa/apr validate to report this
architecture's status accurately (load-time capability, not just a runtime crash).
Secondary bug: misleading CLI message
The chat CLI's own log line claims a fallback that doesn't exist:
[GGUF model parse failed: ... will use CPU]
printed by crates/apr-cli/src/commands/chat_load_tokenizers.rs:166
(format!("[GGUF CUDA init failed: {}, will use CPU]", e)). That code path assumes any
GGUF parse failure on the GPU attempt is recoverable by retrying on CPU — true for the
Phi LayerNorm case (#3075), false here, since the same parse failure happens on the
CPU retry too. Worth a small fix regardless of when the real SSM CPU path lands: don't
print "will use CPU" when the failure reason is architecture-unsupported rather than
GPU-capability-specific, since the retry is guaranteed to fail with the identical message.
Evidence
crates/aprender-serve/src/gguf/transformer.rs:73-86,158-167 (refusal call site,
upstream of backend selection)
crates/apr-cli/src/commands/chat_load_tokenizers.rs:166 (misleading "will use CPU" log line)
- Repro commands above, no
--gpu flag, same host
Related
Summary
Unlike most GPU-ineligible architectures (e.g. Phi's LayerNorm gap, #3075), which fall
back to CPU inference with a warning, Qwen3.5/Qwen3.8-architecture GGUFs (hybrid Gated
DeltaNet / SSM layers,
general.architecture = qwen35) are refused completely —there is no CPU inference path at all today. Confirmed with two different downloads:
Both fail identically, even without
--gpu:The chat loop even prints "will use CPU" in the CUDA-init warning line, but then the
CPU load of the same GGUF fails with the exact same error — because the refusal is in
the shared GGUF transformer constructor (
QuantizedGGUFTransformer::from_gguf), whichboth the CPU and GPU code paths call. There is no degraded-but-working CPU mode; the
model simply cannot be loaded by this binary in any form.
Root cause
crates/aprender-serve/src/gguf/transformer.rs::unsupported_architecture_reasoniscalled unconditionally inside
QuantizedGGUFTransformer::from_gguf(GH-704), beforebackend selection, and returns
Err(FormatError)whenever any tensor name containsssm_/ssm.. This is upstream of the CPU/GPU fork — it blocks both.Ask
GGUF-loaded hybrid layers — recurrent state + short causal conv1d + gated delta rule,
per Qwen3.5/Qwen3-Next's architecture — analogous to what
crates/aprender-serve/src/gpu/scheduler/linear_attn.rsalready sketches for the GPUscheduler (SafeTensors path), but for the GGUF
QuantizedGGUFTransformerCPU path.it doesn't imply CPU already works ("will use CPU" in the CLI's CUDA-fallback log line
is actively misleading for this architecture — see below) — or explicitly state in
the error that neither backend supports it yet, to save users a round trip.
apr qa/apr validateto report thisarchitecture's status accurately (load-time capability, not just a runtime crash).
Secondary bug: misleading CLI message
The chat CLI's own log line claims a fallback that doesn't exist:
printed by
crates/apr-cli/src/commands/chat_load_tokenizers.rs:166(
format!("[GGUF CUDA init failed: {}, will use CPU]", e)). That code path assumes anyGGUF parse failure on the GPU attempt is recoverable by retrying on CPU — true for the
Phi LayerNorm case (#3075), false here, since the same parse failure happens on the
CPU retry too. Worth a small fix regardless of when the real SSM CPU path lands: don't
print "will use CPU" when the failure reason is architecture-unsupported rather than
GPU-capability-specific, since the retry is guaranteed to fail with the identical message.
Evidence
crates/aprender-serve/src/gguf/transformer.rs:73-86,158-167(refusal call site,upstream of backend selection)
crates/apr-cli/src/commands/chat_load_tokenizers.rs:166(misleading "will use CPU" log line)--gpuflag, same hostRelated
qwen35