Row: BACKEND-ROCM
Measured on strix:gpu0 (gfx1151, ROCm 7.2.4), loading GLM-5.3 UD-IQ1_S
through vllm-cli --device auto with VT_CPU_MOE=1, on a build of
row/BACKEND-ROCM-IQ-EXPERT-RESIDENCY (#2562). VT_MLA_FUSED_NORM_ROPE was
not set. The load completes -- 1809 tensors, [vt load] weights 1372.153 s,
the engine sizes its KV cache -- and the FIRST forward throws:
engine-fatal: EngineCore busy loop threw: MLA block: the split A-projection path
needs vt::FusedNormRope to read the merged [kv_lora_rank + qk_rope_head_dim] row,
because a BLOCK-QUANTIZED kv_a_proj_with_mqa (q8_0) has no row slice — a quant
block spans whole rows and vt::SizeOf refuses a per-element size for it. This is
reachable only with VT_MLA_FUSED_NORM_ROPE=0 on a keep-quant MLA checkpoint;
unset it, or load this model with an expanded residency
The message's own diagnosis is wrong, and this run is the counterexample
src/vllm/model_executor/layers/attention/mla_attention.cpp:550-551:
const bool fused_nr = R > 0 && !has_k_rope_norm && MlaFusedNormRopeEnabled() &&
vt::OpRegistered(vt::OpId::kFusedNormRope, d.q.device.type);
There are FOUR ways for fused_nr to be false, and the comment above the throw
(:628-631) accounts for one of them:
vt::FusedNormRope is registered on CPU (cpu_ops.cpp) and CUDA
(cuda_ops.cu) and is default-ON, so the only way here on a keep-quant
checkpoint is VT_MLA_FUSED_NORM_ROPE=0.
It enumerates the backends that HAVE the op and forgets the ones that do not.
ROCm registers no kFusedNormRope (it is one of the eight MLA/DSA ops
.agents/specs/rocm-glm53-dsa.md W1.3 records as missing), so the fourth term is
false on this board with every environment variable unset.
And vt::OpRegistered cannot see the reference tier. It is deliberately a
native-only probe (src/vt/op_provider.cpp:788-806), which is right for its own
contract and is exactly what makes this branch wrong here: on an integrated
host-addressable board the portable CPU tier WOULD have served kFusedNormRope
(docs/ROCM.md:53-58), and RocmBackend::FlushPending() was overridden under
#2498 precisely so a host reference kernel reads drained device memory. The
branch never asks. It asks whether a NATIVE kernel exists, and takes a fallback
that this checkpoint's block-quantized kv_a_proj_with_mqa cannot survive.
Why it matters now
This is the last thing between GLM-5.3 non-flash and a token on strix:gpu0.
With #2516 and #2517 fixed (#2562) the load completes and the forward is reached;
reference-tier distinct=0 at the throw, and the three ops selected before it
are all device=5 selected=vt-native, so nothing had fallen back yet.
Three candidate repairs, none of them taken here
- Port
kFusedNormRope to ROCm. One kernel of the eight
.agents/specs/rocm-glm53-dsa.md owes, and the one with a CUDA sibling to
mirror. Smallest and most vLLM-shaped.
- Let
fused_nr consider the reference tier on a backend whose device
memory is host-addressable. One predicate, but it changes what "available"
means at a shared seam and needs its own before/after.
- Teach the split path to slice a block-quantized merged row. Largest, and
it fixes a fallback nobody wants to take.
At minimum the comment and the message must stop naming one cause when there are
two, because the next reader will look for an environment variable that is not
set.
Row:
BACKEND-ROCMMeasured on
strix:gpu0(gfx1151, ROCm 7.2.4), loading GLM-5.3UD-IQ1_Sthrough
vllm-cli --device autowithVT_CPU_MOE=1, on a build ofrow/BACKEND-ROCM-IQ-EXPERT-RESIDENCY(#2562).VT_MLA_FUSED_NORM_ROPEwasnot set. The load completes -- 1809 tensors,
[vt load] weights 1372.153 s,the engine sizes its KV cache -- and the FIRST forward throws:
The message's own diagnosis is wrong, and this run is the counterexample
src/vllm/model_executor/layers/attention/mla_attention.cpp:550-551:There are FOUR ways for
fused_nrto be false, and the comment above the throw(
:628-631) accounts for one of them:It enumerates the backends that HAVE the op and forgets the ones that do not.
ROCm registers no
kFusedNormRope(it is one of the eight MLA/DSA ops.agents/specs/rocm-glm53-dsa.mdW1.3 records as missing), so the fourth term isfalse on this board with every environment variable unset.
And
vt::OpRegisteredcannot see the reference tier. It is deliberately anative-only probe (
src/vt/op_provider.cpp:788-806), which is right for its owncontract and is exactly what makes this branch wrong here: on an integrated
host-addressable board the portable CPU tier WOULD have served
kFusedNormRope(
docs/ROCM.md:53-58), andRocmBackend::FlushPending()was overridden under#2498 precisely so a host reference kernel reads drained device memory. The
branch never asks. It asks whether a NATIVE kernel exists, and takes a fallback
that this checkpoint's block-quantized
kv_a_proj_with_mqacannot survive.Why it matters now
This is the last thing between GLM-5.3 non-flash and a token on
strix:gpu0.With #2516 and #2517 fixed (#2562) the load completes and the forward is reached;
reference-tier distinct=0at the throw, and the three ops selected before itare all
device=5 selected=vt-native, so nothing had fallen back yet.Three candidate repairs, none of them taken here
kFusedNormRopeto ROCm. One kernel of the eight.agents/specs/rocm-glm53-dsa.mdowes, and the one with a CUDA sibling tomirror. Smallest and most vLLM-shaped.
fused_nrconsider the reference tier on a backend whose devicememory is host-addressable. One predicate, but it changes what "available"
means at a shared seam and needs its own before/after.
it fixes a fallback nobody wants to take.
At minimum the comment and the message must stop naming one cause when there are
two, because the next reader will look for an environment variable that is not
set.