mirror of
https://github.com/kvcache-ai/Mooncake.git
synced 2026-11-05 01:17:55 +00:00
[PR #1389] [MERGED] [Store] Unified parallel tensor IO #2213
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#2213
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?
📋 Pull Request Information
Original PR: https://github.com/kvcache-ai/Mooncake/pull/1389
Author: @zxpdemonio
Created: 1/16/2026
Status: ✅ Merged
Merged: 4/27/2026
Merged by: @stmatengss
Base:
main← Head:cruz/flex_put_get📝 Commits (10+)
2a674c2[Store] add tensor object metadata and TP upsert APIsd46f11f[Store] align unified tensor parallelism APIs6c9d006[Store] route tensor into reads through ranged gets7efb1d1[Store] fix TP ragged reconstruction edge casesbc7f0d9[Store] add exact-match multi-axis shard IO support52e7f67[Store] optimize raw-buffer shard writes and reconstruction reads30101c6[Store] add batch writer-partition unified APIsb6aaa25[Store] format writer-shard updatesa0c1dea[Store] tighten tensor write wrapper layeringa36a9a0[Store] restore legacy tensor wrapper boundaries📊 Changes
11 files changed (+7639 additions, -148 deletions)
View changed files
➕
docs/source/design/unified-parallel-tensor-io.md(+405 -0)📝
docs/source/python-api-reference/mooncake-store.md(+228 -2)📝
mooncake-integration/integration_utils.h(+199 -2)📝
mooncake-integration/store/store_py.cpp(+357 -137)➕
mooncake-integration/store/store_py_internal.h(+1483 -0)➕
mooncake-integration/store/store_py_parallel_read.h(+1312 -0)➕
mooncake-integration/store/store_py_parallel_write.h(+1443 -0)📝
mooncake-store/include/real_client.h(+9 -0)📝
mooncake-store/src/real_client.cpp(+22 -0)📝
scripts/test_tensor_api.py(+1578 -3)📝
scripts/test_upsert_api.py(+603 -4)📄 Description
Motivation
This work is primarily driven by weight synchronization optimization for RL workloads. In RL systems, different components often consume the same model weights under different parallel layouts: some hold the full tensor, some only need a TP shard, and some run with mixed layouts such as DP+TP, EP+TP, or PP+TP. A storage path that only supports full tensors or plain TP shards causes unnecessary write amplification, unnecessary read amplification, and limited layout expressiveness. The goal of this update is to make the unified tensor IO layer suitable for RL-style weight sync by supporting richer layout identities while also optimizing both shard-oriented writes and shard/full reads.
What is supported now
The unified tensor IO path now supports not only heterogeneous TP, but also DP, EP, PP, and their combinations, including exact-match multi-axis shard identities such as DP+TP, PP+TP, and EP+TP. In other words, the system is no longer limited to “TP-only sharded tensors”; it can now persist and resolve multi-axis layout metadata through a single unified API surface.
Write-path optimization
On the write side, the key optimization for RL weight sync is to avoid having every writer store the full tensor when only a local shard needs to be persisted. This is implemented through
writer_partitionfor single-key APIs andwriter_partitionsfor batch APIs. In practice, this allows each writer to hold a full tensor locally but write only the shard it owns, directly reducing write amplification and network/storage overhead during synchronization. The_frompaths were also optimized to use raw-buffer shard planning instead of decoding tensor-object buffers into Python tensors and then reshaping or re-sharding them, which removes unnecessary decode, tensor materialization, and extra memcpy/clone work from the hot path.Read-path optimization
On the read side, the system now supports exact-match shard reads for multi-axis layouts, so consumers can fetch only the shard they need instead of reading a full tensor and slicing locally. This improves efficiency for TP-only consumers as well as mixed DP/TP, PP/TP, and EP/TP layouts. For cases that need the full tensor view, reconstruction is optimized by reusing the existing
get_into_ranges(...)ranged-read substrate and avoiding an extra intermediate tensor conversion. As a result, both full reconstruction and_intoreconstruction remain efficient while still working on top of the unified metadata model.RL semantics
For RL workloads, an important distinction is that DP metadata and writer-side partial persistence are not the same thing. If the requirement is “each DP rank has the full tensor, but only writes its owned slice for synchronization efficiency,” that is supported through
writer_partition/writer_partitions. If the requirement is “a DP parallelism spec alone should imply automatic partial persistence of a full tensor,” that is not the semantics of the DP metadata path. In the unified API, DP/EP/PP/TP describe layout identity, whilewriter_partition(s)provides the writer-side shard-only persistence optimization needed for RL weight sync.Additional improvements
This update also closes an important API symmetry gap by adding batch support for
writer_partitionsacross the unified put/upsert APIs, including_fromvariants. Batch equests now explicitly reject ambiguous mixed inputs such asparallelisms + writer_partitions. In addition, multi-axis shard metadata matching was fixed by canonicalizing the requested parallelism before comparison, which resolved incorrect mismatch behavior in cases such asPP+TPwhere axis order differed syntactically but not semantically.Validation
The changes were validated with focused local tests covering batch writer-partition full reconstruction, batch writer-partition
_intoround trips, batch writer-partition upsert and upsert-from paths, multi-axis batch shard reads, multi-axis batch_intoreads, and explicit invalid mixed-routing cases. Formatting was also rechecked and fixed with the repository formatter.Support Matrix
_into_into_into, full reconstruction where applicable_intowriter_partition/writer_partitionswriter_partitionsparallelisms+writer_partitionsin one batch requestHigh-level architecture
Public API shape
This PR centers tensor IO around the following API families:
The core public request objects are:
TensorParallelismdescribes where a tensor object belongs in the parallel layout.ReadTargetdescribes what the caller wants to materialize on read:Multi-axis write flow
For a request such as:
Mooncake internally performs:
This lets callers express
DP+TP,PP+TP, andEP+TPwrites without pre-splitting tensors themselves.Read-side semantics
Read behavior is explicit through
ReadTarget.as_storedshardfullThis avoids guessing read behavior from
parallelismalone.For example, a TP axis can appear in multiple valid read requests:
These requests mean different things, so the mode is explicit.
Reconstruction path
Full and reconstructed-shard reads lower to internal range plans and reuse:
The public API does not expose:
Those remain internal planner/runtime details.
Metadata model
Each stored tensor object carries enough metadata to describe both the logical tensor and the stored object.
layout_kindglobal_shapelocal_shapedtypelayout_axessplit_dimshard_rankshard_countFor shard sets, Mooncake also stores a manifest containing reconstruction-level information:
global_shapedtypesplit_dimshard_countHow Different Parallelism Axes Are Handled
The unified
with_parallelismAPI models parallelism as an explicit list of axes, but not every axis affects tensor storage in the same way.The key distinction is:
Axis semantics
TPrank,size, andsplit_dim; Mooncake can derive the shard range.DPPPEPDP+TPPP+TPEP+TPWhy TP is handled differently
TPis the only axis in the current implementation that directly tells Mooncake how to split a tensor.A TP axis carries:
From those fields, Mooncake can compute:
So for TP-containing layouts, Mooncake can safely derive the requested shard from a full source tensor.
That is why layouts such as:
can accept full-tensor input and internally store only the requested TP shard.
Why DP / PP / EP do not imply splitting
DP,PP, andEPidentify ownership, not a generic tensor slicing rule.For example:
means:
It does not tell Mooncake:
The same applies to PP and EP:
PPidentifies a pipeline stage.EPidentifies an expert or expert-local scope.Therefore pure
DP,PP, orEPlayouts store the passed tensor object directly. Mooncake does not invent an implicit split axis.Why multi-axis layouts are split only through TP
For multi-axis layouts, Mooncake separates scope from layout.
Example:
This means:
So the handling is:
This keeps the semantics explicit and avoids treating
mixedparallelism as a vague special case.Current write behavior by layout
parallelism=None[TP][DP][PP][EP][DP, TP][PP, TP][EP, TP]Summary
In short, this work extends unified tensor IO from a TP-centric design into a layout-aware IO layer that supports TP, DP, EP, PP, and their combinations, while also introducing the writer-side optimization that RL workloads actually need: each writer can persist only its owned shard instead of redundantly writing the full tensor. Combined with shard-direct reads, optimized full reconstruction, raw-buffer
_fromfast paths, and batch API symmetry, this makes the storage layer substantially better suited for RL weight synchronization and mixed-parallel deployment scenarios.Type of Change
How Has This Been Tested?
Checklist
./scripts/code_format.shbefore submitting.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.