mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[GH-ISSUE #4943] [RFC] Optional GPU read staging for fragmented Store destinations #1257
Labels
No labels
ascend
auto-closed
bug
bug
CI/Build
Common
documentation
enhancement
feature request
good first issue
help wanted
high priority
MetaX
nightly-failure
pull-request
PyTorch Backend
question
RFC
Roadmap
stale
Store
Tests
Transfer Engine
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
kvcache-ai/Mooncake#1257
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @wjinxu on GitHub (Oct 26, 2026).
Original GitHub issue: https://github.com/kvcache-ai/Mooncake/issues/4943
Motivation
Loading cached KV through
batch_get_into_multi_bufferscan turn each CPU-resident Store object into many small transfers to GPU pages. The proposal keeps the existing key layout and API but receives each key into a contiguous GPU staging buffer, then scatters successful reads to the caller's pages with one CUDA kernel per buffer fill.This is an opt-in performance experiment, not a claim that Store lookup or all production TTFT is transfer-bound.
Proposed scope
MC_STORE_GPU_STAGING=1enables it;MC_STORE_GPU_STAGING_BUFFER_BYTESsets the payload budget (default 256 MiB).prefer_alloc_in_same_nodeunchanged in both paths. Its current read implementation groups submissions by source endpoint, so benchmark it explicitly rather than assuming that grouping and staging are equivalent.Why a CUDA kernel
This adds an nvcc build requirement to CUDA-enabled Store builds. Other Mooncake modules already contain CUDA sources, but Store previously did not require this extra compilation step. Non-CUDA Store builds keep a no-op staging implementation.
We tried a
.cppimplementation usingcudaMemcpyBatchAsync. With 256 MiB of device data, measured over 20 post-warmup samples in rotating order:These are complete host-observed submit-and-wait times on the test system, not universal CUDA performance figures. The batch-copy timing includes constructing pointer arrays. It was therefore rejected as the default implementation for this fragmented workload. The custom kernel keeps a small source file and launches once per buffer fill. No runtime compilation or embedded PTX is proposed.
Controlled Store experiment
H200 reader host, separate CPU Store owner, CUDA 13, RDMA; same-host means separate owner and reader processes using RDMA loopback. Each reader process uses a distinct GPU, Store instances, staging buffer and disjoint private keys. GPU memory registrations and initialization are warmed up before timed samples.
We ran 1, 2 and 4 reader processes, two key layouts, same-host and cross-host owners, three fresh-process rounds, eight timed samples per mode per round. Processes synchronize before each measured API call. All four modes run against the same data with rotating order. Every read checks returned sizes and exact byte equality; keys are removed after each group. There are 36 groups, 2688 timed reads, plus 336 warmup reads.
The table reports the median of the three per-round API latency medians, in milliseconds. It is not an end-to-end serving throughput measurement.
Grouped direct means
prefer_alloc_in_same_node=true. On this system it was slower than ordinary direct reads; this result does not by itself establish the reason or justify changing that existing default. Staging gains survive comparison against the faster of the two direct baselines.Model validation
Earlier real Qwen3-Coder-30B-A3B-Instruct TP=2 tests used the same native Store build, 1K/8K/24K inputs, five repeated external-cache reads per length, greedy decoding with natural EOS, and a separate CPU owner. Resetting the local prefix cache intentionally forces external reads; this is a controlled hit-path experiment, not evidence of a production hit rate.
We additionally ran two vLLM TP=2 instances concurrently against the same cross-host owner for three fresh-instance rounds, swapping GPU assignments in round 2. Each mode completed 21 timed requests per round, including six mixed-length concurrent requests. All outputs matched across modes and ended naturally; the staged instance recorded native staging reads. Direct / staged median TTFT:
The serving instances ran while CPU-only native compilation was in progress, so these are controlled comparisons under shared-host activity, not isolated production capacity measurements. These model results use a saved native binary from before the type-layout-only cleanup; the final code was separately rebuilt and passed the focused regression suite.
Correctness and current draft limitations
After the final type-layout cleanup, CUDA and non-CUDA syntax checks and the CUDA native build passed. Four focused unit tests and both seven-check integration runs passed. The CUDA scatter test checks reordered, unaligned and odd-size fragments plus untouched guard bytes. Existing direct-read regression tests pass. Cross-host RDMA and same-host TCP integration checks cover exact-key buffer capacity, too-small-buffer fallback, changed addresses, irregular fragments, duplicate fanout, missing keys and concurrent calls. Traces confirm the native scatter and four buffer fills in a seven-key boundary case. The concurrent-call check is not a deterministic proof of busy-buffer fallback.
The prototype currently depends on a separate transfer-timeout draining change (
f8a6a60in the development branch). Timeout/exception ownership, failed initialization cleanup, and unregister failure behavior require explicit review before this is merge-ready. Successful-path benchmarks do not establish fault-path safety. Hot-cache admission is excluded because it can retain slices after the synchronous read.Related work and questions
get_into_ranges. This proposal addresses fragmented GPU destinations for existing full-object multi-buffer reads; destination unpacking is outside that RFC's scope.Feedback requested: is Store the right ownership boundary, is the extra nvcc requirement acceptable for CUDA Store builds
Before submitting a new issue...
@wjinxu commented on GitHub (Oct 26, 2026):
I've put together a small PR https://github.com/kvcache-ai/Mooncake/pull/4944 and run some basic tests. Feedback is welcome.
@github-actions[bot] commented on GitHub (Oct 26, 2026):
Thanks for opening this issue, @wjinxu!
105263726A maintainer will triage this when possible. To help us respond faster, please include:
Useful links: Documentation · Contributing guide