Repository navigation
Conversation
quantized_matmul used to cast an FP32 input's FP16 or BF16 scales and biases to FP32 before every call: two extra kernels per projection, or a second FP32 copy of every constant kept resident. On Metal the op now keeps them narrow. The one-row qmv_fast kernel reads them as they are and widens each value in registers (a new affine_qmv_fast_mixed entry). Every other route widens them inside eval_gpu first, as the op did. Outputs are bitwise identical to widening first; other backends and CPU streams keep the old cast.
bri-prism
marked this pull request as ready for review
October 28, 2026 20:35
zcbenz
reviewed
Oct 29, 2026
zcbenz
left a comment
Member
There was a problem hiding this comment.
It seems that all affine qmv/qmm kernels can actually benefit from this trick? If they do I think it would be a cleaner change updating them all than adding a new kernel. And btw please create pull requests from personal accounts as maintainers can't rebase PRs from org accounts.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
FP32
quantized_matmulinputs currently require FP16/BF16 affine scales and biases to be widened before each call. This keeps those constants narrow on Metal and reads them directly in the unbatched, one-rowqmv_fastpath, widening each load in registers. It avoids two conversion kernels per projection without changing the arithmetic.Other affine dispatches widen the constants inside
eval_gpubefore entering their existing kernels. CPU streams and floating-point quantization modes retain their existing input handling. Scale and bias gradients are cast back to their original dtypes. Both JIT and precompiled Metal entrypoints are included.Measured result
Apple M5 Pro, a local quantized text decoder, greedy 256-token decode, excluding prefill:
These measurements used one JIT binary with the new path temporarily disabled/enabled in the order off/on/off/on/off, with 32 warmup tokens per path. The table reports the median of three control samples and two candidate samples. Maximum adjacent control drift was 1.05% and 0.21%, respectively. Tokens and logits matched bitwise across all samples. The temporary control is absent from this PR, and the clean rebuilt candidate reproduced the same tokens and logits. These are workload-specific measurements; the model checkpoint and full-model harness are not included in this PR.
Validation
On M5 Pro, both JIT and precompiled Metal builds pass 85 tests, with one skipped and 6,261 subtests passed, using upstream's pytest configuration:
The tests cover FP16/BF16 constants, all seven affine bit widths, all three group sizes, aligned and partial output rows, strided and batched layouts, vector inputs, CPU streams, fallback dispatches, gradient dtypes, compiled forward/backward calls with fresh inputs, and export/import round trips. Temporary pipeline tracing confirmed selection of all 84 mixed-kernel variants; the tracing is removed.
Formatting, Python lint and stream-argument checks pass. Other Apple GPU generations and CUDA execution have not been tested. The throughput numbers above are from JIT execution; precompiled Metal was checked for correctness.
Operator reproduction
Run the following on main and this branch with the same build configuration. It measures synchronized operator wall time, including Python and dispatch overhead, on synthetic weights:
AI usage disclosure: Implementation, tests, benchmark analysis, and this description were prepared with AI assistance.