Repository navigation
npu forward: a pack with short-convolution layers is refused by name at load — LFM2.5 said ready and answered 500 to everything (Refs #1786) - #2158
Conversation
…at load (Refs #1786) FastFlowLM's LFM2.5-1.2B-NPU2 declares its hybrid through full_attn_idxs, not layer_types, so the unknown-layer-kind refusal could not see it. Its ten gated short-convolution layers were run as attention: the warm-up failed with 'MLP dequant : data_size 0 ...' and the serve said ready. model_shortconv_layers() counts them from what the loader already reads, and the forward's init refuses, naming the first. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
ready for review at cb440b0 |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
bong-water-water-bong
left a comment
There was a problem hiding this comment.
VERDICT at cb440b0: READY
Reviewed head cb440b0 (refs #1786, the LFM2.5 row). This is the first verdict.
-
git merge-treeonto main: no conflicts. CIbuildand CodeQL green. -
npu_forward_loader_test, built from this head: "all cases ok", rc 0. -
Mutants of
model_shortconv_layers()(npu/forward/include/model.h), each rebuilt and run:- never counting a layer: rc 1, "two of its first four layers are convolution layers, and the first is layer 1";
- reporting the last conv layer as the first: rc 1, the same arm.
I restored the file (git status clean).
-
npu/forward/src/q4nx_forward.cppat this head compiles clean (0 errors) as a single-file compile with the NPU build's flags. -
The detection is the loader's own definition. It counts layers whose
shortconv_in_proj_weighthas a shape, not aconfig.jsonkey, so it catches LFM2, whose hybrid is declared throughfull_attn_idxswith nolayer_typesand slipped past the existing layer-kind refusal. The refusal fails init, so the serve never announces itself ready for a model it would answer 500 to.
Note: every LFM2 container now stops at load on this route, including pk-lfm12, the pack #2149 discussed for q/k norm. That is the intended outcome: it was never actually served, only mis-served as attention. #2161 (the shortconv reference) is the path that would lift it.
Not re-run by me: the device rows (the 500 before; the load refusal in two tickets after).
|
VERDICT: READY at The defect is the worst kind and the fix is the right shape. Refusing by name, at load, with the count and the first path, is the correct alternative: That message answers the two questions an operator actually has — how much of this pack is unsupported and where is the first one — and Two asks:
Scope of my check: fresh configure (rc 0), built the loader test in a scratch dir, ran it (27 ok), and read the new helper plus the refusal text. No device and no LFM2 pack on this box: the "it ran them as attention" half is the PR's own observation. |
Refs #1786 (the
LFM2.5-1.2B-NPU2row). Backlog. I searched open issues and PRs forlfm2 shortconv forwardbefore writing this; nothing open covers it.The fault, on the NPU
FastFlowLM's
LFM2.5-1.2B-NPU2(model_typelfm2: sixteen layers, ten of them gated short convolutions, six attention) with a kernel set that has all four of its dense shapes,1bit serve --device npu, main before this change, onenpu-holdticket:The serve announces itself ready for a model it cannot run, holds the device, and answers every request with a 500 whose message blames a disagreement between the container and its config. There is none: the pack is fine. The forward has no short-convolution layer, runs those ten layers as attention, and trips over the first tensor it expects and the pack does not have.
Why the existing refusal did not catch it: the forward already refuses an unknown layer kind by name, but from
config.json'slayer_types. LFM2 declares its hybrid throughfull_attn_idxsand has nolayer_typeskey, so that check sees nothing.The fix
The loader already reads the short-convolution tensors (
model.h: "a layer IS a conv layer iffshortconv_in_proj_weightis present").model_shortconv_layers()counts such layers and names the first; the forward's init refuses when the count is not zero, in the wording of the existing layer-kind refusal.After, same pack and kernel set, binary from this branch, two tickets
Both runs the same. The serve does not come up, the device is released, and the message says what the pack has and what the forward lacks.
Tests
tests/npu_forward_loader_test.c(ctestnpu_forward_loader), 6 new checks on a container written by the test: a file withshortconv.*tensors loads; two of its first four layers are convolution layers and the first is layer 1; none among the layers before it; the count works without the index; an attention-only container has none; no model, none.all cases ok.The refusal line in
q4nx_forward.cppitself is only reachable with the NPU runtime, so its test is the device run above.tools/copyright.py --checkrc 0. Docs:docs/npu.md, a paragraph in the FastFlowLM rows section.Limits and one loose end
lfm2packs in the census, and is not attempted here.LFM2-1.2B-NPU2is on the box and has the same layer pattern by its config; I did not run it.🤖 Generated with Claude Code