Repository navigation
Conversation
|
Thanks @laidick, this is a careful PR, and it meets every point we asked for on #2396:
The off-grid cost numbers are useful too. A few things before it can land:
On the order: this sits on #2176, so it rebases once #2176 lands. Your last commit makes |
…s opt-in sends no other family message starts requestStep reads the switch the family names (request_starts_switch) through profile.lookup; a family that names none gets no message starts. Qwen's dense and MoE entry points name TF_QWEN_REQUEST_STARTS, so its name, its refusal with TF_QWEN_KV_SHARE and its tests are unchanged, and unset is main's path. The shape follows #2404's (0279d37), without its GLM engine changes, so #2404 can drop its copy. A host test walks the real CUDA registry: Qwen's switch reaches only Qwen, a second family's switch only that family, unset none.
…umes at its history (ashhart#2396) TF_GLM_REQUEST_STARTS=1 (default off) asks the server for message starts on GLM's 2,048-row grid. Rank 0 sends a pass's cuts to the other ranks before its first step, every rank chunks to min(len, start + 2048, next start), and a kept state resumes only where a cold pass cuts. A pass with starts takes no solo or batched pass. TF_KV_SHARE above 0 is refused at startup by name. With the switch off the cuts are empty, which is the old grid exactly.
…fused with --learn-conversations cuda_engine.zig back under 600 lines: setCuts and the cut-aware step size move into cuda_prompt_cuts (set, stepRows). TF_GLM_REQUEST_STARTS=1 with --learn-conversations is refused by name before any rank opens, since the disk states' 4-row pool cannot take a message-start row yet.
0279d37 to
c2a2479
Compare
|
Thank you for the careful review, @ashhart. I've made all five changes. They are in
On the other points:
Host checks are all green:
The logs and the driver for receipt 6 are on my side if you'd like them attached. |
|
Thanks @laidick, all five are in:
Thanks also for the note on TR3's template. One thing for your rebase: #1423 is queued ahead of this and takes |
…s opt-in sends no other family message starts requestStep reads the switch the family names (request_starts_switch) through profile.lookup; a family that names none gets no message starts. Qwen's dense and MoE entry points name TF_QWEN_REQUEST_STARTS, so its name, its refusal with TF_QWEN_KV_SHARE and its tests are unchanged, and unset is main's path. The shape follows #2404's (0279d37), without its GLM engine changes, so #2404 can drop its copy. A host test walks the real CUDA registry: Qwen's switch reaches only Qwen, a second family's switch only that family, unset none.
|
@laidick, a heads-up for your rebase: #1423 landed this morning, and |
Part of #2396: the shared store (
TF_KV_SHARE) is refused with this switch, not covered. Stacked on #2176: the first three commits are #2176 cherry-picked ontomain(c70d67bb2). The last two commits are new here:0a14c8813(the change) andc2a2479f3(the review changes).What it does
TF_GLM_REQUEST_STARTS=1on rank 0 (opt-in, off by default, likeTF_QWEN_REQUEST_STARTS) asks the server for message starts on GLM's 2,048-row grid. A chat's next turn then resumes where its previous turn's history ends, instead of at the last 2,048-row point.native/cuda_snaps.zig:requestStep(F)reads each family's own switch (F.request_starts_switch). Qwen namesTF_QWEN_REQUEST_STARTS, GLM namesTF_GLM_REQUEST_STARTS. One family's switch does not opt the other in.cuda_prompt_cuts.zig): a pass with cuts chunks tomin(len, start + 2048, next start)(nextCut). A kept state resumes only where a cold pass would cut (coldCut).setstores a sequence's starts, andstepRowssizes a step, refusing a solo pass when there are cuts. With no cuts this is today's grid exactly, so the switch off changes nothing.cuda_engine.zigcalls these and is 599 lines.cuda_follow.zig): a newKind.cutsstep sends the pass's starts to the other ranks before its first prompt step. That covers both the whole-pass and the stepped follower paths.cuda_lanes.zig):resumeFromusescoldCutinstead of% prefill_rows. A stream with starts takes no batched pass (canBatch) and no solo pass (cuda_prompt_solo.zig, and the engine refuses one).TF_GLM_REQUEST_STARTS=1is refused by name before any rank opens, in two cases. WithTF_KV_SHAREabove 0 it givesGlmRequestStartsWithSharedKv, because there is no shared store. With--learn-conversationsit givesGlmRequestStartsWithLearnConversations, until the disk image takes off-grid rows.copiesmodule inglm_family_host.ziggets itscoreimport. Without it,test-glm-snapshots-hostdoes not compile once a GLMrequestStepis reached. Onmainit already fails to compile on macOS for the same reason.Receipts: 2× GB10 at TP=2
Setup:
Mia-AiLab/GLM-5.3-Flash-EXL3-TR3-4bpw@9eaebb7c. Drafter: DFlash2incoai/GLM-5.3-Flash-DFlash2@bf582e4e, unless the run is marked MTP.--context 131072 --parallel 2, RoCE.main=c70d67bb2, branch =0279d373cfor the receipts below (before the review). The two-chat and picture runs usec2a2479f3. All builds use the same fatbins (nvcc 13.0.2, sm_121), with host binaries cross-built.max_tokens120, one request at a time.Chats:
1. Same tokens as a fresh run;
cached_tokens= "resumed at".main, switch off, switch on, and switch on with--prompt-cache-gib 0, with DFlash2 and also with MTP alone (long and short chats). The mid chat ran on its own in four runs:main, off, on, and on with cache 0.usage.prompt_tokens_details.cached_tokensequals rank 0'sprompt cache: … resumed at N.2. Both ranks cut at the same rows. The
TF_GLM_PROF=1run logsglm prompt chunk rank=… start=… rows=…on both ranks. For the cold prompt, rank 0 and rank 1 log the same 26(start, rows)pairs:(0,783) (783,1546) (2329,1580) … (36707,816) (37523,3). With the switch off, both log the grid(0,2048) … (36864,662). A resume sends the samefromto every rank in thechunkstep; a rank that does not cut there refuses withBadResume.3. The re-prefill is gone. "Resumed at" values and time to first token (TTFT):
mainresumed atmainTTFT sNotes:
min_chunkof 256: no start is planned there.4. Switch off =
main. Theoffruns (branch binary, no switch) matchmainin every reply hash,cached_tokensand "resumed at", across short, mid, cold and long.5. Cost of off-grid cuts. Cold 48-message prompt,
TF_GLM_PROF=1, rank 0. Rank 1 is within 0.01 s.6. Two chats at once, and a picture (review). Branch
c2a2479f3, switch on,--parallel 2 --vision, with the 1104 recipe's vision template (--chat-template; TR3's own template writes no image placeholder). Chats:Three runs:
alone: A, then B, then C, one request at a time.interleaved: A's and B's turn k sent at the same moment (two streams live), then C.fresh:alonewith--prompt-cache-gib 0.Results:
aloneandinterleaved, each turn'scached_tokensequals rank 0's "resumed at" for that prompt length, and the two runs resume at the same rows.--learn-conversationswith the switch on: atmainthe server already refuses--learn-conversationsfor GLM before the family opens ("keeps conversation states on disk for Nemotron, the Qwen hybrids and Flash Next only on CUDA"), so both ranks stop there on the pair. The new GLM refusal sits inopen()for when GLM-5.3-Flash on CUDA keeps conversation states on disk, every rank's part (--learn-conversations) #1411 lets GLM take the flag. A host test checks it throughopen()andexplain.Host tests
zig build test-glm-request-starts-host test-request-starts-host test-qwen35-request-starts-host test-glm-snapshots-host test-glm-admission-host test-glm-logprobs-hostpass (55/55), pluscompile-glm-native-open,compile-glm-prompt-gate-hostandcompile-glm-fp8-gate-host.addTest(.{ .root_module = glm })) gives 197 pass, 1 skip (main: 186 pass, 1 skip);nativegives 155 pass, 2 skip;qwen35passes.test-glm*/exl3*/lane*/request*host steps pass on macOS. The other 3 (test-glm-sampling,test-lanes-see,test-exl3-prompt-host) also fail onmainhere.python3 tools/zig/lean_check.py: 155 problems on the branch, the same 155 asmainc70d67bb2, so none are added. Every changed file is at or under 600 lines (cuda_engine.zig599,cuda_lanes.zig600).zig fmt --checkis clean.Shared with #2215 and #2358
glm/cuda_native.zigopen()(this PR addsrequestStartsAlone()as its first line), the GLM recipe's request list, and the changelog. This switch refusesTF_KV_SHARE, so the two never run together; whichever lands second rebases a few lines.Receipts and scripts (driver, rank launcher, window runner) are from
laidick's two Sparks. I can attach the logs if useful.