Repository navigation
[IE] Mark constant 2-bit weights for the DynDeq -> FakeQuantize bridge in multi-row graphs - #390
ryugyosoft-max wants to merge 2 commits into
Conversation
…multi-row graphs finishDynamicDequantizeRewrite() leaves a 2-bit DynamicDequantize unmarked outside the KV-cached (one-row) pattern, so constant 2-bit weights of a multi-row (prefill) MatMul / FullyConnected are dequantized by the DynamicDequantize SW kernel, which returns zeros for them on NPU4000 / NPU5010 (openvinotoolkit/openvino#39010). Marked, they take the FakeQuantize -> group unroll -> palletized path of the one-row graphs (weights still stored as 2 bits). The weights-as-inputs (block argument) prefill pattern is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
U2WeightsConstPrefillPatternToDynamicDequantize now expects vpux.weights_import_dyn_dequant; the new I2WeightsConstPrefillPatternToDynamicDequantize covers signed 2-bit weights without a zero point. DontBlockArgPrefillPatternToDynamicDequantize is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
I read openvinotoolkit/openvino#39010 and I'd like to proceed with internal testig with your changes. Just curious: how it was discovered? User-scenario I mean. Thank you for your PR! |
|
Thanks for picking it up! Some background: the existing LLM stacks for NPUs tend to lag behind the newest models, so I have been writing my own
A big goal is Ternary Bonsai 2 (4B / 9B / 27B, ternary weights stored as u2 with a scale per group of 128). I think On AMD we program the NPU at a low level, so the Bonsai port went smoothly. On Intel the model has to go through the How it showed up: token-by-token decoding (one-row graphs) was fine, but when we added a prompt (prefill) graph that For now onw ships its own compiler build with this fix for NPU 4000+, so having it upstream would let the 2-bit models |
|
Thank you for sharing detailed info. Could you please share a more details there? Kindly appreciated. |
|
Sure. Each of the other problems has its own report with measurements, reproducers or profiles, and a reference patch Weights twice in memory (a 1-token decode graph and a 64-token prefill graph over the same weights)
Slow compiles on Panther Lake (Bonsai 2 4B first load ~25 min with the pip compiler -> 285 s with our fixes; one
This PR: If you meant something else by "there" - or want a specific log or profile attached - just tell me which, and I will |
Details
Fixes the multi-row 2-bit weights bug of openvinotoolkit/openvino#39010 (also reported as #355).
WeightsDequantizeToDynamicDequantizemarks the newIE.DynamicDequantizefor the DynDeq -> FakeQuantize bridge passonly for the KV-cached (one-row) pattern when the weights are 2-bit. A constant 2-bit weight used by a MatMul /
FullyConnected with M >= 2 rows (the prompt / prefill graph of an LLM) is therefore left unmarked and is dequantized
by the DynamicDequantize SW kernel, which returns zeros for these weights on NPU4000 and NPU5010: the layer output is
wrong (max. relative error 1.0 to over 20000 with the reproducer in #39010), while the same weights in a one-row graph are correct.
With this change constant 2-bit weights are marked in the multi-row pattern as well, so they take the same path as in
the one-row graphs (FakeQuantize -> group unroll -> palletized weights on the DPU; the weights stay 2-bit). The
weights-as-inputs (block argument) prefill pattern is not changed (
DontBlockArgPrefillPatternToDynamicDequantizestill holds).
Tests
weights_dequantize_to_dynamic_dequantize.mlir:U2WeightsConstPrefillPatternToDynamicDequantizenow expects themarker; new
I2WeightsConstPrefillPatternToDynamicDequantizecovers signed 2-bit weights without a zero point.weights_dequantize_to_dynamic_dequantize.mlirpasses for NPU3720, NPU4000 and NPU5010, andweights_dequantize_to_dynamic_dequantize_50XX+.mlirpasses for NPU5010. The same file fails with the unpatchedpass (both 2-bit const prefill tests unmarked). It also fails if every 2-bit DynamicDequantize is marked, because
that breaks
DontBlockArgPrefillPatternToDynamicDequantize; this PR therefore limits the change to constantweights.
The branch is based on
20e7912, one commit behind develop. The commit it is missing (#386) only changes CI files:our token cannot push workflow files to the fork.
Validation
y = x[M, 4096] @ W^T, u2 weights, scale per row or per group of 128, NPU5010): max.relative error 0.0003-0.0019 for M = 1, 2, 4, 16 with the fix (before: 1.0 or more for every M >= 2).
0.0005, top-1 agreement 98.4 %, the same NLL (NPU5010 and NPU4000).
[Bug][NPU] u2 (2-bit) weights: MatMul wrong for 2+ activation rows on NPU40XX/50XX (breaks 2-bit LLM prefill) - root cause and one-line fix openvino#39010 (comment)
3.4 ms on NPU5010).
Tickets
🤖 Generated with Claude Code