omlx 0.5.7 as a library: Pro-0813 DSpark under mlx.launch TP4 (32-head ring GEMM) #2642
Replies: 4 comments
|
Recipe and scripts (convert / shard_mtp / BatchGenerator smoke / OpenAI serve). No converted weights — rebuild from https://huggingface.co/guruswami-ai/deepseek-v4-pro-0813-mlx-tp4-recipe |
Interim: still gather; serve survived three HTTP turnsServing stays on the gather fallback. The native 32-head The singleton OpenAI path (omlx 0.5.7 as a library under The second-generate JACCL -12 was an undrained Recipe: https://huggingface.co/guruswami-ai/deepseek-v4-pro-0813-mlx-tp4-recipe |
Follow-up, 15 August 2026Same setup: omlx 0.5.7 as a library under Pad-to-64 is not a substitute for a 32-head kernelThe original post asked for a 32-head Two fresh processes, same 4 096-token prompt, shared seed
Acceptance is the same. IDs diverge at generated token 10 ( A wrapper that only pads axis 1 still changes the numerics. Please do not treat pad-to-64 as proven lossless. Context on gatherHiding the 64-head symbol still unlocks long context. One-process climb, 32 new tokens:
|
|
Parking Pro-0813 TP4 as a daily driver (17 August 2026). omlx 0.5.7-as-library still loads and DSpark still decodes on a fresh process. Long-lived JACCL is the blocker: ml-explore/mlx#4319 / FB24371487. Full note on mlx discussion 4247. |
Uh oh!
There was an error while loading. Please reload this page.
Using omlx 0.5.7 as a library for DeepSeek-V4-Pro DSpark under mlx.launch (TP4)
Report from a four-node M3 Ultra 512 GB Thunderbolt 5 mesh. We are not running the omlx menu-bar / single-node HTTP server. We import the 0.5.7 overlay (
deepseek_v4+mlx_lm_mtp) undermlx.launchso Pro-0813's own DSpark drafter exists in distributed TP4.It works. Interactive decode 15–23 tok/s, DSpark armed, out to 32 k prompt tokens, behind a small OpenAI server that DeepSeek Harness can drive. A failing unit-test task went through bash + edit and passed. This is the first trillion-class open-weight we have run on this mesh that is useful as an agent, not just a load test.
What omlx provided that stock mlx-lm 0.31.3 does not
deepseek_v4model class (mlx-lm PRs still unreleased).mtp.*(base sanitize drops them).BatchGenerator/GenerationBatchpath where DSpark actually arms.stream_generatenever does.SparseCompressedAttentiononce the 64-head ring kernel is hidden.Model.shard()still does not shardself.mtp. We added a matchingshard_mtp()for the three stages (targets 58/59/60, depth 5, 32 heads/rank).Ring GEMM: 64-head kernel vs 32-head TP4
Stock
dspark_ring_gemmis compiled for M=64 (Flash single-node). Pro-0813 has 128 heads; TP4 leaves 32 per rank. Python turns the kernel on once pooled KV exceedsindex_topk1024 (~4 k prompt at compress_ratio 4). Then:Hiding the symbol forces gather. After that:
We did compile a 32-head kernel (accept M in {32,64}, values BM 64→32). At 4 k: native 11.4 tok/s / 56% accept vs gather 10.9 / 70%. Then 16 k after a native switch died in JACCL Recv -12. Serving stays on gather. A correct official 32-head kernel would be the highest-leverage omlx change for Pro TP4.
DSpark is singleton-only
_omlx_mtp_rowwise_unsupported = Trueon DSpark (caches are singleton / committed-only). Measured: B=2 and B=4 havemtp_activated=0. B=4 aggregate ~29 tok/s is ~7 tok/s per stream, worse per user than one DSpark stream at 15.If that flag is staying, it should be documented as a contract. If row-wise DSpark is planned, Pro TP4 is a good test case.
Other notes for this overlay
set_mtp_active(True)must happen beforemlx_lm.load.mx.random.seedon every rank or sampled decode desynchronises and JACCL dies.MLX_METAL_FAST_SYNCH=0.mlx.launchprocess is still common. That is likely mlx/JACCL, not the Python overlay, but it is the main reason this is not a 24/7 server.Ask
mlx.launch. That is how this cluster run exists._omlx_mtp_rowwise_unsupported.Happy to share the
shard_mtphelper, the ring-gate, and the 32-head patch. Not asking you to adopt our HTTP server.All reactions