Repository navigation
Conversation
The MoE layout takes a geometry (the 35B's by default, unchanged, or the Qwen3.5-122B-A10B's), chosen by hidden size and depth before any check. The 122B's draft was trained for blocks of 16 and runs its first 8 rows. Its GGUF is refused until it has run.
…ion shapes GDN gets a 64-value-head variant and paged attention a kv2_g16 group whose softmax takes a second pass over the tile's lanes (4 x 128 fused rows exceed the 256 threads). The draft convolution takes every hidden width, the 122B's 3072 among them, which its test now runs. All 1816 kernels the library already had are AIR-identical; 26 are new.
…, not defaulted The block-size contract names 'at least' the engine's rows; both geometries are checked at compile time. Drops a test that restated a default.
The README model table gets the 122B (MLX only, as its GGUF is refused), and DEVELOPMENT.md says a draft's block is 8 rows or, for the 122B's draft, 16 of which the engine drafts the first 8. The ExecutionLimits comment now says what inspectModelRoot checks (the block the family declares), and two comments no longer name a local deployment.
jianc99
added a commit
that referenced
this pull request
Oct 23, 2026
The family's draft width, layout and arena sizing had no test of their own, and the choice of a family by its sizes had none for a config that differs from every family in the first size. These tests come from ezoushen's version of this family (#529), adapted to the family as a value of the MoE architecture (kQwen3_5_122BLayout): - draft-attention runs the draft kernels at the 122B draft's width, 3072 (dynamic width 768); - model-execution-plans holds every family's layout to requireQwenLayout (forEachFamily), and sizes the 122B's arenas and checks its lane scratch at Apple9, 10 and 11 with 12, 20 and 40 cores: loadedModel takes a family's layout and draft, by default its architecture's first family's; - model-configuration refuses the Qwen3.6-35B-A3B's config at a hidden size of neither MoE family, 4096, as it differs from the first family of its model type (Qwen3.6-35B-A3B 2048). The 122B's config at the 35B's 40 layers is the refusal #539 tests. #529's tests of an exact draft block and of a refused 122B GGUF do not apply: this family drafts the first 8 rows of its block of 16 and serves its GGUF. Tests: on the M5 Pro (64 GB), at the head of this series and with #536 and the other fixes since 1.4.0 merged on top of it, make all and check-native-build build without a warning, model-configuration and model-execution-plans pass (test-engine-cpu), and so does draft-attention under MTL_SHADER_VALIDATION=1. Co-authored-by: ezoushen <ezoushen@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
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.
Refs #528.
What changes
Splash loads
ornith-ai/Ornith-1.5-122B-MLX-4bit(Qwen3.5-122B-A10B) withincoai/Ornith-1.5-122B-DFlash2. On Apple M5 Max (40-core GPU, 128 GB), the attention replacement reduces cold 64K prefill 83.9→52.0 s (1.61x) and append 4K at 128K history 13.3→7.05 s (1.89x).Qwen3_6MoeLayoutretains the 35B default and selects the 122B geometry by exact hidden size and layer count. Other configs retain the 35B fallback and refusal behavior. The 122B GGUF is refused until tested.install/families.pypairs the target with its draft.kv2_g16kernels with virtual groups for both INT8 and BF16 KV. Projection writes the grouped query layout directly, and the gate consumes it directly. Physical K/V storage and workspace capacity stay unchanged. The obsolete second softmax pass is removed.Attention performance
Upstream
maincannot load this target, so the comparison is against this PR's previous head2d6c8a3d(g16 kernels).The old g16 tile fused 128 rows and ran at about half the per-FLOP rate of the 64-row g8 tile. Four virtual groups of eight query heads run over the two physical KV heads on the existing 8-head tile. Each physical KV head supplies two query groups, so query group
greads physical KV headg / 2.INT8 KV, one layer, medians of 7 alternating runs after at least 1.5 s GPU warmup per arm, clock-qualified on Apple M5 Max (40-core GPU, 128 GB), Xcode 26.6. Every comparison is bit-equal (maximum absolute difference 0); 128/512-row prefill tails also improve. These recorded measurements were taken at
759e9dc5; this port preserves the measured attention instructions and host graph.End-to-end wall times with the official Ornith 1.5 122B MLX 4-bit target and paired DFlash2 draft, comparing the prior g16 build (
e2e239a3) with the measured virtual-group build (759e9dc5):One clock-qualified AB pair on the same M5 Max, medians of 3 cold requests and 2 append requests per arm. Greedy 300-token outputs at 32K/64K matched byte-for-byte with all-row verification.
Existing models are unaffected
Compiled kernel identity against a fresh build of merge base
1482f6b: 1,816 existing kernels strictly AIR-identical; 26 additions (13 attention and 13 GDN), zero changed or removed.Host route tests assert the existing split/reduce, QKV and gate pipeline names for every other supported attention geometry. The virtual-group route is selected only for dense 32-query/2-KV-head attention at dimension 256.
Tests
All attention cases passed, including 56 prefill and 22 verify cases across INT8/BF16 KV, CPU route selection and the full Q8 flash-attention matrix; the final cleanup production library is byte-identical to the full-check build. Timing-sensitive failures also fail or flake on
mainat1482f6bon this machine and do not touch attention: backend watchdog 0/10 passes on both builds, Handoff 5/10 here versus 4/10 on main, and three Python timeouts that pass in isolation and 60/60 on main. The kernel-input fixture was fixed in82368b00and re-checked with positive and negative controls.Earlier real-model validation at
2d6c8a3dThese measurements predate the attention replacement. Apple M5 Max 128 GB, macOS 27.0; official MLX 4-bit target at
310ebeb, draft ata5ed739,--language-only --verify-rows all --max-memory 80G. Loaded in 16 s, 256K context, no restarts, 5/5 smoke prompts. Greedy, thinking off.Medians of three trials, taken in a second pass when the machine was calm (load average 4-8, swap usage unchanged); the three 25K cold-prefill TTFTs were 21, 27 and 36 s.
Quality against mlx-lm on the same checkpoint: 10/10 arithmetic word problems on both; HumanEval first 40 executed 36/40 here (fails 10, 17, 32, 38) against 37/40 (fails 10, 32, 38); problem 17's solution misses the empty-string case. The sets are small, and the mlx-lm figures were measured earlier on the same machine.
Not covered
model-vision.safetensorsbut does not contain it, so this is text only.make test-realand model-dependent benchmark targets were not run at82368b00.