Enable CP HiCache direct transfers to use layer-page host layout

CP shared-KV HiCache transfers are per-layer, so the host layout should match the access pattern instead of forcing page-major strides through every layer. This adds a direct-only layer_page_first layout, routes per-layer KV and NSA index backup/load through the TAI LF<->LPF direct kernels, and keeps storage/page-buffer metadata paths fail-fast until their page-level contract is redesigned.\n\nThe direct controller keeps host indices in caller order for both page_first_direct and layer_page_first because the TAI direct path requires CPU index descriptors and owns descriptor coalescing. All-layer backup intentionally loops over per-layer direct kernels rather than using the sgl-kernel all-layer direct ABI.\n\nConstraint: layer_page_first is currently host-only CP HiCache; storage backends assume page-major contiguous page metadata.\nConstraint: TAI LPF direct kernels require CPU int64 page indices and complete page spans.\nRejected: silently fallback to SM copy when TAI LPF kernels are missing | that hides production performance regressions.\nRejected: support storage page metadata in this commit | LPF requires a layer-page-level storage contract, not a one-pointer-per-page contract.\nConfidence: medium\nScope-risk: moderate\nDirective: Do not enable storage or kernel backend for layer_page_first without redesigning page-buffer metadata and adding remote ETE coverage.\nTested: local py_compile for touched runtime files.\nTested: remote py_compile in g0034 container for touched runtime files.\nTested: remote targeted pytest: 5 passed for parser/storage/layout/move_indices smoke coverage.\nNot-tested: full CP HiCache ETE with --hicache-mem-layout layer_page_first after this commit step.\nNot-tested: combined CUDA roundtrip tests in one pytest process; previous independent runs passed but combined run exposed a host-memory registration lifecycle issue.
This commit is contained in:
laoyao0822
2026-06-10 02:03:07 +08:00
parent 5e22279670
commit 24da983ff5
8 changed files with 1796 additions and 9 deletions
@@ -75,6 +75,23 @@ def test_cp_shared_kv_prefill_bs_gt1_parser_limits():
assert args.cp_shared_kv_prefill_max_total_extend_tokens == 8192
def test_hicache_mem_layout_parser_accepts_layer_page_first():
import argparse
parser = argparse.ArgumentParser()
ServerArgs.add_cli_args(parser)
raw_args = parser.parse_args(
[
"--model-path",
"dummy",
"--hicache-mem-layout",
"layer_page_first",
]
)
args = ServerArgs.from_cli_args(raw_args)
assert args.hicache_mem_layout == "layer_page_first"
class TestLoadBalanceMethod(unittest.TestCase):
def test_non_pd_defaults_to_round_robin(self):
server_args = ServerArgs(model_path="dummy", disaggregation_mode="null")
@@ -556,6 +573,7 @@ class TestHiCacheArgs(CustomTestCase):
("kernel", "page_first"),
("direct", "layer_first"),
("direct", "page_first_direct"),
("direct", "layer_page_first"),
]
for io_backend, mem_layout in cases:
@@ -598,6 +616,26 @@ class TestHiCacheArgs(CustomTestCase):
hicache_mem_layout="page_first_kv_split",
)
def test_cp_hicache_rejects_kernel_layer_page_first_layout(self):
with self.assertRaisesRegex(
ValueError, "CP shared KV HiCache.*kernel.*layer_page_first"
):
self._normalize_and_validate_cp_hicache_args(
hicache_io_backend="kernel",
hicache_mem_layout="layer_page_first",
)
def test_hicache_storage_rejects_layer_page_first_layout(self):
args = self._make_args(
enable_hierarchical_cache=True,
hicache_storage_backend="mooncake",
hicache_io_backend="direct",
hicache_mem_layout="layer_page_first",
)
with self.assertRaisesRegex(ValueError, "layer_page_first.*storage"):
args._handle_hicache()
def test_cp_hicache_rejects_kernel_ascend_backend(self):
with self.assertRaisesRegex(ValueError, "CP shared KV HiCache.*kernel_ascend"):
self._normalize_and_validate_cp_hicache_args(