Repository navigation
Conversation
Owner
|
Thanks @jschmied. I read this as a kept-state change on top of #2215. By reading, Flash Next, Gemma 4 and Nemotron copy the same bytes, in the same order, at the same kept offsets as main. A few things before it can follow #2215:
A small one: main's Nemotron staging copy in |
core/state_walk.zig: a family's live parts in order, walked onto kept bytes (one buffer or pages leased from a kv_pool) through one backend copy hook. GLM CUDA's Plan parts, page lease and Pool.move are the core's; the copies are main's (dst, src, length and order).
snapshot.copy and spill build their parts over Walk(Ref, Ref.at); the hook is the copy_u32 dispatch they used. Kept bytes stay in the state's buffer.
jschmied
force-pushed
the
statewalk-families
branch
from
November 7, 2026 03:52
45836c7 to
eda4fd4
Compare
Contributor
Author
|
Thanks @ashhart. All four are done, on
The staging copy in Four things you should know:
|
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.
What this changes
A cleanup, no gain: Qwen 3.5, Gemma 4, Nemotron and Flash Next on CUDA move their kept-state copies and spills onto #2215's
core/state_walk.zig. Each family's own loop that split live pieces at page ends is gone. No kernel, flag or allocation changes, and the copies are the same copies.5a45539af. This head doesn't apply to main past that:733e4144b(QwenpageCopies, a 2D copy a page) and4f6017ced(Flash Next.rows) landed in the same loops, and need a port and new evidence.atc overlapwas cut short by its limits and marked every pair unknown.flashnext/cuda_snap.zig: EXL3 Flash Next on CUDA: one rank, offloaded experts, sm_120 gate (1/8) #1441-EXL3 Flash Next: KV pages from the core pool (4/8) #1444, EXL3 Flash Next: host-resident K/V on the tier (6/8) #1522, flashnext cuda: prompt cache marks inside a chunk are kept on the way instead of cutting the pass #1866, core: a bounded ladder of intermediate prompt-cache checkpoints #1953.qwen3_5/cuda_reuse.zig: qwen CUDA: a faster opt-in paged path (TF_QWEN_KV_PAGES=256), --parallel a cap with pages set #2011, qwen3_5 cuda: the 27B as a pipeline stage, logits byte-equal to the whole model at 2 and 3 stages (RFC #2005 step 2, stacked on #2241) #2115 (both ours).nemotron/cuda_reuse.zig: Living Weights: slide-forget counting only with --slide-forget, Metal's mask shift for wide pockets (#678) #2026.gemma4/cuda_snap.zig: gemma4 cuda: TF_GEMMA4_CHUNK_SOLO, on a solo-chunk rule shared in lanes (#1554 option C) #2391 (ours).What each family moves
cuda_reuse.zig):Runsis gone. EachLayoutpiece is a walk part, and on pagesspanis the piece's length in a page andpagethe page's bytes. One hook,KeptCopy, has both of main's arms at the same offsets: device-to-device for a state in device memory (Copy.dev, qwen CUDA: an integrated GPU keeps prompt states in device memory, without pinning a copy each save (#2043) #2113's default on an integrated GPU), device-to-host and host-to-device otherwise. Pieces can number in the thousands, so it's one walk call a piece, with no parts array.cuda_snap.zig):eachbuilds parts from the ring runs and the paged global rows. Kept bytes are a buffer, or offsets the hook hands tokv_prompts.Blob.cuda_reuse.zig):rowSpananddeviceRowsare gone. Rows are parts on the bound pages, and Mamba parts are whole. It walks one part at a time because rows and Mamba go to two kept buffers.error.PastPagesstays as a check before the part's first copy. The staging copy inhostMoveis download-only (.into = true), as on main.cuda_snap.zig):movebuilds parts from the whole pieces and the paged attention rows, with one device-to-device hook.Checks on this head
eda4fd4b7zig build test,test-cuda-host,test-kernel-contract,test-golden,test-server-security,test-pull-security,fuzz-cortheon,test-gemma4-cuda-host,test-glm-expiry,test-learn-recovery,check-release-paths, a plainzig build.zig fmtandgit diff --checkare clean.testblock main has in the touched files is byte-equal here (25 blocks);core/root.zig's test block only gains_ = state_walk;.test-glm-snapshots-hostdoesn't build on main5a45539af: modulecopieslackscore, whichnative/cuda_snaps.zig:11needs sincefc8bd41ed. With that one import added locally, not in this PR: 21/21 on main, on core: one walk for kept prompt states, GLM on it (CUDA and Metal) #2215 and on this head.30f293bf3b163bb0, across device and host, paged and not, save and restore.4cd007311d2a0cf.771ef7c7710a4c56. On a refused plan (5,059,SnapShapealike) main queues the copies before the refused piece, and the walk refuses before any.Receipt
afe1d25e, this head's913d5f80. Two cold builds of one commit differ here, so these md5s name these two builds, not the sources.ignore_eos, 48 tokens,return_token_ids,--context 16384. A fresh run replays the same prompts with--prompt-cache-gib 0.Exactness. In every row, main and this branch match on tokens and
cached_tokenson all four turns, both match a fresh run, and every resumed turn hascached_tokens> 0.cached_tokens--prompt-cache-diskTF_QWEN_KV_PAGES=256,_ALL=1,--parallel 2--prompt-cache-diskTF_KV_PAGES=all,--parallel 2--prompt-cache-diskTF_FLASHNEXT_KV_PAGES=256,_ALL=1,--parallel 2--prompt-cache-diskThe page switches alone don't page the first stream, so at
--parallel 1these arms would sit on the window. That's why they run with_ALLorall, and each one's arm is checked above.Real copies under nsys, one resumed turn, main against this branch, kind and bytes of each copy in order: identical in all six cells (Qwen 3.5 device, host and both paged; Flash Next window and paged). Same bytes in the paged cells as in their window controls, in many more copies.
A disk-kept state saved by main and reused here. Main writes with
--prompt-cache-diskand stops. Main and this branch each read their own copy of the store after a restart:resume_fromdisk_tokenscached_tokensand tokens equal main's, the writer's and a fresh run's.Limit. Nemotron keeps its states on the device on a GB10, with the disk tier on too, so
hostMoveisn't reached here. Its download arm is in the oracle and the host tests. Its upload isn't covered by either: it uses the same parts and walk, and the hook picks the direction.Resumed time to first token. A-B-B-A, median of 12 warm turns, and mean cold, in seconds:
Checklist
## Unreleased, citing (cuda: Qwen 3.5, Gemma 4, Nemotron and Flash Next keep states through core's walk, no gain, a cleanup (#1293, on #2215) #2392, part of Metal: KV pages from the core pool #1293).