Pack eight value rows per SIMD-group in gated_delta_seq - #4409
Open
wyanzhao wants to merge 2 commits into
Open
Conversation
tpegolotti
force-pushed
the
gated-delta-update
branch
from
August 26, 2026 14:29
24ce3d9 to
60af0df
Compare
wyanzhao
force-pushed
the
packed-gdn-seq-4020
branch
from
August 26, 2026 16:44
42d1178 to
10c6a84
Compare
wyanzhao
force-pushed
the
packed-gdn-seq-4020
branch
from
August 28, 2026 06:07
10c6a84 to
700c58e
Compare
wyanzhao
marked this pull request as draft
September 3, 2026 01:21
zcbenz
marked this pull request as ready for review
September 4, 2026 23:10
tpegolotti
reviewed
Sep 5, 2026
tpegolotti
left a comment
Collaborator
There was a problem hiding this comment.
Thanks for the PR! The performance is indeed faster. The only open question is if we should leave the previous kernel for the cases where Dk != 128.
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.
The sequential gated delta kernel now packs eight value rows into each SIMD-group, using four lanes per row. This uses the layout from mlx-lm#1559.
GATED_DELTA_PACKED=0selects the original kernel for comparison.This applies to supported sequential calls with
Dk=128andDvdivisible by 8. It keeps the existing public shape support and chunk-8/NAX-16 dispatch. For the long-sequence measurements, I setGATED_DELTA_CHUNK=0: M5 would normally use NAX-16 at those lengths.On M5 Max with
(Hk, Hv)=(16,32)andDk=Dv=128, I got the results below. Speedups are paired geometric means of original time / packed time in one binary. Timing includes public-API graph construction, dispatch, GPU execution and both outputs.These are the first session's results. I repeated the measurements in a second session and all six improvements were significant again. Default B1/T1 and B1/T8 fp32, plus the unchanged chunk-8/NAX-16 controls at B1/T2048/fp32, showed no significant difference. I haven't measured model performance.
test_fast_gated_deltapassed 6 tests with 1 Torch-related skip;test_fastpassed 30 with 1 skip. I used the macOS 26.5 SDK for the build and tests. Building with the macOS 27 SDK failed in unchanged NAX code against its MPP headers.Dispatch, validation and reproduction
The public fast path still requires GPU, no mask,
Dk=Dv=128, and one of(Hk,Hv)=(24,24), (32,32), (16,16), (16,32), (16,48), (16,64). BothGATED_DELTA_CHUNK=0and=1select sequential execution. The packed kernel uses grid(32, Dv/8, B*Hv)and threadgroup(32,2,1); the original uses(32,Dv,B*Hv)and(32,4,1).The regression test compares both outputs for all six head pairs, fp32/fp16/bf16 and both sequential chunk settings, evaluating each result before changing the environment. Bitwise equality is toolchain-dependent and is not required by the test. All pre-commit hooks passed.
Measured commit:
7fb64079288670f88e688af868767a8f1a03a10d. M5 Max, 128 GiB, macOS 27.0 (26A5425a), Python 3.12.13, macOS 26.5 SDK. Binary:libmlx.dylib:4c196a02d790+mlx.metallib:4a03a40e46ac.Each cell had passing A/A calibration, followed by 15 fixed alternating A/B pairs in each of two sessions. Timing used 60 seconds of initial saturation, at least 90 seconds of cooldown and a 5% within-arm drift limit with one cooled retry. Both sessions passed drift checks; the six reported effects passed the sign-test, Wilcoxon and A/A-noise checks. The sessions are separate estimates, not pooled. This compares the preserved original kernel with the packed kernel in one PR binary, not two separately built checkouts.
With a source build of this branch using the macOS 26.5 SDK, run from the
checkout root:
Save the script below as
repro_4409.pyin the built checkout root. Use the same Python environment used to build MLX, and stop other GPU work before measuring.--smokechecks outputs and exercises short timing loops without estimating speedups. Use--helpto select a single case. Output files must be new names.The script covers the six reported rows and four controls. It fixes the input seed to 20260905, checks both returned outputs, and records the chunk setting and invocation count for every case. Build with the macOS 26.5 SDK, as above.
This is an independent reproducer of the workloads, not the driver used for the existing table. It warms both arms, runs 15 alternating A/A pairs, then 15 alternating A/B pairs. Each stage gets 60 seconds of saturation, with a 90-second cooldown before A/B. It reports the geometric mean of OFF/ON time ratios and a Student-t 95% interval in log space. A/A must include 1 in its interval; either stage stops on more than 5% within-arm drift, retaining the rejected result without retrying. It does not implement the original sign-test, Wilcoxon or A/A-noise significance checks.
The JSON includes raw sample times, input shapes, numerical checks, source revision, device and binary hashes. New estimates depend on the machine and build; they do not replace the measurements above.