Repository navigation
Conversation
Between requests every rank but 0 sat in a CUDA wait on the broadcast it had posted for rank 0's next step, with NCCL's progress thread polling beside it: two threads at full load on each waiting host, idle or not (ashhart#1033). Rank 0 now sends an idle step when its last stream is released, and a wake record on the ranks' liveness lines (cuda/tp_watch) before its next step. A waiting rank that reads the idle step sleeps on a futex until that wake, and only then posts its receive; the ranks start asleep, so the first step wakes them. Rounds themselves are unchanged. A rank that dies or fails while the others sleep still stops them through the same lines.
|
Thanks @Bizuayeu, this follows the idle-wait direction we asked for, and the A/B results help. Source review found no production blocker: early wakes are counted, idle stays between rounds, and shutdown wakes the follower for its end step. We'll carry this onto 1.1.2, preserving stepped admission, then gate decode equality/speed, idle CPU and TTFT on the combined tree. In our carry we'll also bound the new tp_watch test's waits and stop its watcher on every failure path, so a broken wake fails the test instead of hanging it. We'll include cancellation and idle shutdown in that gate. Posted by Ash's AI Assistant Synthena |
7a35983 to
7bfd979
Compare
(comment) Thanks. In case it helps the carry, the branch is now on main ( |
…dits The 1.1.2 section had no entries for the contributed pull requests carried into this release, so neither their changes nor their authors reached the release notes. Add an entry for each, written from its commits: Flash Next's CUDA prompt tiles and structured output (#1046, #1062), --thinking-reserve, the long-loop guard and the --vision template diagnostic (#1064, #1075, #1076), GLM's Metal eh_proj tile and CUDA waiting ranks (#1066, #1053), M1's simdgroup cap (#1055), Nemotron's CUDA image and shared-window fixes (#1057, #1058), Qwen's live-row expert routing (#1047), the shared CUDA operators and contract fixture (#1056, #1068, #1070, #1071, #1073), the ROCm receipt, drafter and draft-count work (#1043, #1044, #1045), the ModelOpt recipe numbers (#1042), the Windows host build (#1034) and the session store's allocation-free rollback (#637). Thank #643's and #1060's reporters as the other entries thank theirs.
|
The GLM CUDA waiting-rank change is included in 1.1.2 (https://github.com/ashhart/TensorFold/releases/tag/v1.1.2), with your original authorship retained. Waiting ranks sleep on their watch lines while rank 0 has no active stream and wake for new work. Our follow-up, 3589cd0, sends the prompt cache's setup step through rank 0, so ranks that start asleep wake for it at TP=2 and above. Closing this as carried, and thank you. It landed as 86a34f3. - Synthema, Ash's AI Assistant. |
Thank you for carrying it, and for 3589cd0. We retested 1.1.2 at TP=2 and TP=3 in #1033 (comment): idle ranks stay quiet, and requests that resume from the prompt cache while the other ranks sleep are answered, at TP=2 with v1.1.1's tokens. |
What this changes
While GLM-5.3-Flash's CUDA ranks have no stream, the ranks other than 0 sleep instead of spinning, the direction in #1033 (comment). Rank 0 sends an idle step when its last stream is released, and a wake record on the ranks' liveness lines (
cuda/tp_watch.zig) before its next step; a waiting rank that reads the idle step sleeps on a futex until that wake and only then posts its receive. The ranks start asleep, so the first request wakes them. Rounds are unchanged. A rank that fails or dies while the others sleep still stops them through the same lines, and a stop while they sleep wakes them for the end step.The idle step goes out from the GLM lanes'
releasewhen no lane is left, so a request already queued behind the last one still costs one idle step and one wake (a TCP write and one NCCL step). A hook before the lane host's wait would avoid that, but it touches the lane core; the step can move there if you prefer.Receipt
7bfd9798ond1018b31(main: 1.1.1 and five commits that change no Zig file), Zig 0.17.0, CUDA 13.3 (nvcc 13.3.73), NCCL 2.30.7, driver 580.178.04; two DGX Spark (GB10, sm_121) hosts over a direct ConnectX-7 link, one GPU each; checkpointnvidia/GLM-5.3-Flash-NVFP4at423acf37; TP=2,serveper rank withTF_GLM_RANK,TF_GLM_WORLDandNCCL_COMM_ID, drafts on,TF_HEAT_HIGH=92andTF_HEAT_LOW=88. Before is 1.1.1 (b10231b9), built the same way. Two settings:--context 245760 --parallel 1, every core (no pinning);--context 131072 --parallel 2, every core, excepttools/bench_concurrent.py, which ran on the efficiency cores (0-4, 10-14) for both builds, as in the first receipt.token_shaper prompt, the same before and after; the second and third replies resume from the prompt cache, so resumed equals fresh. Drafted equals"draft": falseon three prompts (whole messages), before and after. With--parallel 2: two requests at once (256 and 96 tokens), the shorter one released while the other runs, each equal to itself alone after the ranks slept;tools/bench_cache.py's five rows, two of them concurrent, give onetoken_shabefore and after;tools/bench_concurrent.py --levels 2 --alone --serial(efficiency cores) finds every pair equal to alone (24 of 24) and to serial (6 of 6) in its four cells, none failed, before and after.tools/bench_openai.py --tokens 512 --reps 5(--parallel 2), median tok/s before → after (at temperature 1.0 the five reps spread widely, 32.8 to 39.4 tok/s on fibonacci-raw, and follow each other within 0.2 tok/s from before to after):Two streams at once,
bench_concurrent.py's aggregate tok/s before → after: code 44.2 → 44.3 at temperature 1.0 and 62.3 → 62.5 at 0, chat 39.4 → 39.6 and 43.1 → 43.1. At--parallel 1, 512 tokens after a short prompt, median of three: 43.67 → 43.78.ttft_sfromtools/bench_cache.py --require-cold(2,570 prompt tokens; its first step after idle carries the wake) is 1.820 s before and 1.785 s after, andbench_openai'sttft_smedians differ by under 1 ms. At--parallel 1, the forty requests below have a median time to first token of 4.700 s before and 4.675 s after (about 5,900 prompt tokens, no heat wait in either).zig build test-cuda-host2178/2184 with 6 skipped (the new line test passes),zig buildandzig build native,zig fmt --checkandzig ast-checkon the changed files,tools/zig/lean_check.py449 problems, the same lines as on the base.NCCL_COMM_IDdoes not bootstrap, fabric: tensor parallelism across CUDA processes (bootstrap, NCCL, mailbox and RoCE collectives, plan link, fail-fast) (DeepSeek-V4.1 stack 3/14) #636), other CUDA GPUs, andbench_concurrent.pyon every core for both builds.The first receipt, on 1.1.0 (
7a359838onb7ce8121), was this description's earlier version; the rebase onto 1.1.1 kept the change to the same four files (+83/−4) and only met 1.1.1's new follow kinds incuda_follow.zig.Checklist
"draft": false, a resumed prompt equals a fresh one, and concurrent equals solo (above).bench_cache.pyrequest 1.785 s against 1.820 s; above).