JACCL Recv/Send -12 on 4-node TB5 after a successful first generate #4247
Replies: 5 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 |
Follow-up: undrained
|
| cell | after generate 1 | idle | generate 2 |
|---|---|---|---|
| A | close(), no mx.synchronize() |
0 s | C++ Recv failed with error code -12 |
| D | leave generator open, new generator for turn 2 | 0 s | ok |
| F | mx.synchronize() then close() |
0 s | ok |
| H | same as F | 30 s quiet | ok |
| I | same as F | 300 s quiet | ok |
Generate 1 is always fine. The abort is an uncaught std::invalid_argument, not a Python exception. Shared seed and the arm barrier were already in place; they do not cover this class.
Serve now drains with mx.synchronize() before close(). That is a workaround, not a library fix. A third generate and a multi-hour soak are not certified.
Scripts: https://huggingface.co/guruswami-ai/deepseek-v4-pro-0813-mlx-tp4-recipe
Follow-up: HTTP serve after a long idleThe drain ( One
No Recv/Send -12. The process is still serving. This is not a multi-hour generate soak. It is the idle-then-second class on the real HTTP path, including a 2.5 h gap that is longer than the 300 s ladder cell. The C++ abort if you |
Follow-up, 15 August 2026Same four-node TB5 JACCL mesh. We split the original “second generate dies with -12” report. There are at least two classes. 1. Undrained
|
Status, 17 August 2026The 14–15 August numbers stand. DeepSeek-V4-Pro-0813 (MXFP4/MXFP8 + DSpark) loads on four M3 Ultra 512 GB nodes under We are parking further TP4 work on this model. A later isolation needed no model: unique 256 MiB
No patch attached. |
Uh oh!
There was an error while loading. Please reload this page.
JACCL Recv/Send -12 on a 4-node TB5 mesh after a successful first generate
Four M3 Ultra 512 GB Studios, Thunderbolt 5, JACCL,
mlx.launch, world=4,MLX_METAL_FAST_SYNCH=0. Hostfile namesrdma_enNdevices. After a full-fleet reboot we runmlx.distributed_config --auto-setuponce and check 3PORT_ACTIVEdevices per node (6 edges).We are serving DeepSeek-V4-Pro-0813 TP4 (MXFP4/MXFP8, DSpark via an omlx overlay). Load + first generate is usually fine (e.g. 128 tokens at 19 tok/s, all ranks agree). A later generate in the same process (second
BatchGenerator, second HTTP/v1/chat/completions, or second DeepSeek Harness turn) often dies with:or
Send failed with error code -12. Rank 1 or 3 exits 255.mlx.launchthen printsexit 0. That exit code is wrong and hid a failure from our wrappers.What is not sufficient to explain every -12
uuid4()nonces: we removed those. Lengths are all-gathered.mx.random.seed: without it, sampled decode parked at 49/48/45/47 tokens and died. With a shared seed, sampled works. The remaining -12 still happens on greedy second requests.After a crash, leftover Python ranks must be killed. If a rank is stuck
Us+andibv_devinfohangs, only a full-fleet reboot plus a fresh--auto-setuprecovers the mesh.Why we are filing this here
The Python overlay can be wrong and we will keep hardening it. The combination of (1) death on a second collective sequence after a long load of all-gathers, (2)
mlx.launchreporting 0, and (3) RDMA needing a fleet reboot, looks like a transport/lifecycle problem as much as an app bug.A four-node TB5 JACCL soak that does: load a large sharded model, generate, idle a few seconds, generate again, repeat, would catch this. We can help reproduce.
The rest of the stack (Pro-0813 + DSpark + gather, 15–23 tok/s interactive, 32 k context) is written up on mlx-lm and omlx discussions in the same batch. The model is usable when the mesh stays up. The mesh is the part we cannot fix from Python alone.
All reactions