Skip to content

Point mlx at Qwen3.6 decode matvec optimizations (~30 tok/s) - #63

Merged
goniz merged 4 commits into
mainfrom
cursor/qwen36-decode-opt-088d
Jul 15, 2026
Merged

Point mlx at Qwen3.6 decode matvec optimizations (~30 tok/s)#63
goniz merged 4 commits into
mainfrom
cursor/qwen36-decode-opt-088d

Conversation

@goniz

@goniz goniz commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

Updates the mlx submodule to the merged feat/vulkan tip from goniz/mlx#65:

df10f7b8fMerge pull request #65 from goniz/cursor/qwen36-decode-opt-088d

Vulkan decode optimizations for MoE gather matvec + safer deferred barriers (subgroup partial sizing + submit-tail barrier included).

Benchmarks (mlx-community/Qwen3.6-35B-A3B-8bit)

Prefill Decode
Baseline ~682 ~21.9
This change 683.9 31.0
Averages: prompt_tps=683.926, generation_tps=31.044, peak_memory=39.664

Merged MLX PR: goniz/mlx#65

Open in Web Open in Cursor 

goniz added 3 commits July 15, 2026 11:59
Updates mlx to cursor/qwen36-decode-opt-088d (~30.4 tok/s decode on
Qwen3.6-35B-A3B-8bit with prefill held near 683 tok/s).
Addresses Codex review on goniz/mlx#65; decode still ~30.4 tok/s.
Keeps Qwen3.6-35B-A3B-8bit around 684 prefill / 31 decode after
addressing Codex P1 on deferred submit memory visibility.
@goniz
goniz marked this pull request as ready for review July 15, 2026 10:35
Updates to merge commit df10f7b8f (goniz/mlx#65 Qwen3.6 decode opts).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

https://github.com/goniz/mlx-vulkan/blob/0aa7b9754ca1ee1c128fd8e471948b28160ecfda/mlx/mlx/backend/vulkan/kernels/mul_mv_affine8.comp#L82
P2 Badge Keep affine8 weight offsets byte-accurate

When an 8-bit affine weight row is not 4-byte aligned, such as a quantized layer with K/packed_row_bytes not divisible by 4, this floors the byte offset before indexing the new uint view. For col > 0 the row can start in the middle of a word, but both the packed fast path and the scalar fallback then read byte 0 of the floored word as k=0, mixing bytes from the previous row/column and producing incorrect matvec results; keep byte indexing or account for the intra-word byte offset.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@goniz

goniz commented Jul 15, 2026

Copy link
Copy Markdown
Owner Author

Codex P2 (affine8 weight offsets) — no code change

packed_row_bytes is set as w.strides(-2) * sizeof(uint32_t) in quantized.cpp, so it is always a multiple of 4 by construction. Therefore col * packed_row_bytes never has an intra-word byte offset, and (col * packed_row_bytes) >> 2 is an exact word index for every column.

The same applies to gather (w_matrix_stride_bytes is also stride * sizeof(uint32_t)). Misaligned rows are not representable on this path for affine uint8 packs.

Happy to add an assert in the C++ dispatcher if we want a belt-and-suspenders check, but the shader flooring is safe under the current packing contract.

@goniz
goniz merged commit 76e10ae into main Jul 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant