Skip to content

spark25 cuda: TF_KV_SHARE keeps prompts as the pool's pages in the prompt_radix store (on #1653) - #1756

Merged
ashhart merged 3 commits into
ashhart:mainfrom
jschmied:kv-share-radix-spark
Oct 31, 2026
Merged

ashhart merged 3 commits into
ashhart:mainfrom
jschmied:kv-share-radix-spark

Conversation

@jschmied

@jschmied jschmied commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1657: Spark2.5 on the native-CUDA prompt_radix adapter, off by default. On main, after #1659 and #1653 (both merged).

Two commits:

Unset or 0: as before.

Gates (GB10, Spark-X2.6-4B 8-bit)

gate result
tf-cuda-test spark25-pages, final binary TF_KV_SHARE=4: PASS, resume at 1280, reply and logits same as linear. Unset: PASS. The same code before the move onto main: 4 more share PASS
chat suite, 64 turns (content + reasoning) nocache / copy / share: 64/64 equal. Cached tokens: copy 243,309, share 235,520
long chat, 48 turns 48/48 equal. Cached tokens: copy 240,379, share 233,472
capacity, round-robin, 4 GiB, 72 turns 72/72 equal. Copy store: 15 states, 19,808 cached tokens. Share: 64 states, 149,504 cached tokens, evicted 21, failed 0
evictions, round-robin, 1 GiB 72/72 equal. Copy: 4 states, 4,899 cached tokens. Share: 31 states, 77,312 cached tokens, evicted 60, failed 0
v.sh (lean 0 new, zig build test, CI set, diff-check) green on the final head

Default path (TF_KV_SHARE unset, --prompt-cache-gib 0). Base (#1653's commits without these two) vs these two on top, fresh server per arm, ABBA over 2 rounds, aggregate tok/s, greedy token_sha equal in every cell:

streams delta of medians (chat/code, T 1.0/greedy)
1 +0.24 / +0.24 / +0.15 / +0.22 %
4 +0.30 / +0.32 / +0.22 / +0.33 %
8 +0.19 / +0.25 / +0.18 / +0.17 %

The Gemma 4 wiring follows #1619.

jschmied and others added 3 commits October 31, 2026 22:43
… pool's pages, in one prompt_radix store

A family on the core KV pool that declares share_pool and share_attach gets one prompt_radix store over that
pool (native/cuda_prompt_pages.zig): the tree holds the prompt pages themselves, a page edge's state past them
comes from the family's snap_* decls, and n caps those states. The host makes no prompt_cache store then, and
the cache budget becomes pool pages (Budget.kept_ppm). core/kv_prompts.zig is what the family calls: begin
(resume point, adopted pages, marks), keep at a mark, report, and Blob, a state's copied rows in pages the store
holds. Pool.hold takes those pages, asking the store to reclaim first as promise does. Unset or 0: as before.
…tate's rings in store-held pages

With the shared store a prompt pass begins at the store's resume point: the matched pages adopted into the
stream's lease, its sliding rings restored there from the kept state. Chunks cut at the store's marks (page
edges, 256 tokens); at each the store takes the pages it lacks, the stream's copies swapped for the tree's,
and the state's rings go into pool pages the store holds (snap_bytes counts those). Unset: as before.
tf-cuda-test spark25-pages with TF_KV_SHARE=4 resumes a kept prompt plain and drafted, equal to linear.
@ashhart
ashhart force-pushed the kv-share-radix-spark branch from 20afc28 to e2edae2 Compare October 31, 2026 22:43
@ashhart
ashhart merged commit 6d3fa01 into ashhart:main Oct 31, 2026
9 checks passed
@ashhart

ashhart commented Oct 31, 2026

Copy link
Copy Markdown
Owner

Thank you @jschmied. This is merged into main with your commits under your own name, so you're listed as a TensorFold contributor. It ships in the next release, credited to you in the changelog and the release notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants