Fix fp quantized matvec for output dim < 8#3804
Conversation
|
Independently reproduced and verified this fix on an Apple M3 Max (Metal), building from source at this branch's base: Before (unpatched
After this one-line change (
The |
|
The failing macOS checks here look unrelated to this change. On the macOS jobs the MLX test suite itself passes: and Linux (CPU + all CUDA variants), lint, and docs are green. The macOS job then fails in the separate The crash is in the I've reopened the PR to re-run CI; the new run is currently waiting on workflow approval. Happy to rebase if that's easier. |
|
For whoever picks up the macOS CI fix — this looks like a known OpenMPI 5.0.8 PRRTE bug rather than anything specific to this PR: open-mpi/ompi#13357. The crash in the which lines up with #13357: Since it's in the PRRTE bundled with |
fp_qmv_impl's out_vec_size < 8 branch (taken when the weight matrix has fewer than one full output tile) read the fp8 group scale as a raw byte in its full-block loop and passed it straight to qdot, instead of decoding it with dequantize_scale like every sibling site -- including the remainder loop of the same branch. This corrupted mxfp4/mxfp8/nvfp4 matvec whenever the output dimension is < 8 (rel_err ~2e2). Affine quantization uses different kernels and is unaffected. Also extend test_fp_qmv with small output dims (M = 5, 7) which exercise the previously-untested out_vec_size < 8 path.
b091549 to
a0aa251
Compare
Summary
fp_qmv_impl(the Metalquantized_matmulmatvec path,M == 1) has anout_vec_size < 8branch that is taken when the weight matrix has fewer thanone full output tile. Its full-block loop read the fp8 group scale as a raw
byte and passed it straight to
qdot:Every sibling site decodes the scale first -- including the remainder loop of
this same branch (and the other loops in
fp_qmv_impl):U s = dequantize_scale<U, group_size>(sl[0]);qdotmultiplies bysdirectly, so the undecoded byte corrupts the resultfor any fp quantization mode (mxfp4 / mxfp8 / nvfp4) whose output dimension is
< 8. Affine quantization uses different kernels and is unaffected.Fixes #3762.
Repro (M3 Max, Metal)
x @ dequantize(w).Tvsquantized_matmul, mxfp4,group_size=32,K=512:Affine control is ~1e-7 throughout, unchanged.
Testing
test_fp_qmvwith output dimsM = 5, 7, which exercise thepreviously-untested
out_vec_size < 8path.python -m pytest python/tests/test_quantized.py: 32 passed, 2896 subtests.