[feat] Add suppport for mooncake connector for P/D; custom P/D init kwargs - #1926
Draft
SumanthRH wants to merge 2 commits into
Draft
[feat] Add suppport for mooncake connector for P/D; custom P/D init kwargs#1926SumanthRH wants to merge 2 commits into
SumanthRH wants to merge 2 commits into
Conversation
Signed-off-by: SumanthRH <sumanthrh@anyscale.com>
Signed-off-by: SumanthRH <sumanthrh@anyscale.com>
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 does this PR do?
Extends prefill/decode (P/D) disaggregated serving in two ways.
First, it adds role-specific engine init kwargs (
prefill_init_kwargs/decode_init_kwargs) so prefill and decode servers can be launched with different vLLM args (e.g. a differentall2all_backendorkv_transfer_configper role).Second, it adds a Mooncake P2P KV-transfer path alongside the existing NIXL path, including bootstrap-server-based router discovery and a runtime patch that keeps a
MultiConnector(Mooncake P2P + store) stack from tripping a Prometheus-stats assert in vLLM. It also ships a newmooncakeoptional-dependency extra, CPU unit tests for the new config/CLI/router logic, and docs.Changes
Config + validation
InferenceEngineConfig.prefill_init_kwargs/decode_init_kwargs(bothDict[str, Any], default empty) inskyrl/train/config/config.py. Pass-through vLLM engine kwargs applied per role.validate_inference_engine_cfg(skyrl/train/utils/utils.py) enforces that these requireenable_pd=true, are mutually exclusive withengine_init_kwargs, and — new — runs a fail-fast completeness check: since role kwargs replaceengine_init_kwargsentirely, each ofprefill_init_kwargs/decode_init_kwargsmust be set and must itself carry akv_transfer_config. This fails at config-validation time instead of per-role at serve-setup time inget_pd_cli_args.Role-specific CLI-arg plumbing
get_pd_cli_args(inference_servers/utils.py) gainsrole/role_init_kwargs: applies role kwargs onto a deep copy of the base args before readingkv_transfer_config.create_inference_servers(inference_servers/setup.py) builds separateprefill_cli_args/decode_cli_argsviaget_config_as_dict(...); each server group uses its own args.kv_rolerelaxed tosetdefault("kv_role", "kv_both")so Mooncake's push flow can set explicitkv_producer/kv_consumer.Mooncake connector detection
get_pd_p2p_connector_name(kv_config)resolves the P2P connector from a bareNixlConnector/MooncakeConnectoror aMultiConnectorwrapping exactly one P2P + optional store connectors; raisesValueErrorotherwise.SUPPORTED_PD_P2P_CONNECTORS = ("NixlConnector", "MooncakeConnector"). Replaces the old "only NixlConnector" string check.Router bootstrap ports
build_router_args(inference_servers/utils.py) gainsprefill_bootstrap_portsandpd_kv_connector. For Mooncake,prefill_urlsbecomeslist(zip(prefill_urls, prefill_bootstrap_ports))andkv_connector="mooncake"is passed toRouterArgs.create_inference_serverscomputesprefill_bootstrap_ports = NIXL_SIDE_CHANNEL_BASE_PORT + i*servers_per_group + jacross prefill servers when the resolved P2P connector isMooncakeConnector, and setspd_kv_connector="mooncake".Server-actor bootstrap port
VLLMServerActor(inference_servers/vllm_server_actor.py) setsVLLM_MOONCAKE_BOOTSTRAP_PORT = nixl_side_channel_base + server_idxfor Mooncake (matching the router's per-server value); the NIXL side-channel path (find_and_reserve_port+_setup_nixl_side_channel) is unchanged. Also callsapply_multi_connector_stats_patch()before building the engine.MultiConnector stats patch
skyrl/backends/skyrl_train/patches/vllm/patch_multi_connector_stats.py: a runtime monkeypatch of vLLM'sMultiKVConnectorPromMetrics.observethat skips child connectors which reportKVConnectorStatsbut have no registered Prometheus metrics class (e.g.MooncakeConnector) instead of asserting. Without it, aMultiConnector(Mooncake P2P + store) stack crashesAsyncLLM.output_handleron the first stats flush and hangs in-flight requests.Packaging
mooncakeoptional-dependency extra inpyproject.toml:mooncake-transfer-engine; sys_platform == 'linux'— the off-the-shelf PyPI wheel providing the Mooncake python bindings andmooncake_masterbinary (store connector + P2P PD transfer). Linux-only and intentionally not in the uv conflicts set (it does not clash with thefsdp/megatron/jaxbackend extras).uv.lockupdated accordingly.Docs
.claude/docs/inference.mdP/D Disaggregation section rewritten to document the supported P2P transfer connectors (NixlConnectorpull-based vsMooncakeConnectorpush-based, bare or inside aMultiConnectorwith a store connector), the bootstrap-port/kv_connector=mooncakerouter mode, the stats patch, and the role-specificprefill_init_kwargs/decode_init_kwargsrules.docs/content/docs/configuration/config.mdx: addsprefill_init_kwargs/decode_init_kwargsto the config listing and field reference (per-role pass-through kwargs, mutual exclusion withengine_init_kwargs, both-required + per-rolekv_transfer_config).Test Plan
Tests added (CPU, no GPU):
tests/train/test_config.py— role-kwargs config validation:test_role_init_kwargs_conflict_with_engine_init_kwargs_rejected,test_role_init_kwargs_require_enable_pd,test_partial_role_init_kwargs_rejected(partial/missingkv_transfer_configrejected),test_valid_pd_role_init_kwargs_passes.tests/backends/skyrl_train/inference_servers/test_build_vllm_cli_args.py:TestGetPDP2PConnectorName—test_bare_nixl,test_bare_mooncake,test_multiconnector_resolves_single_p2p,test_multiconnector_zero_p2p_raises,test_multiconnector_two_p2p_raises,test_unsupported_bare_connector_raises.TestGetPDCLIArgs—test_role_init_kwargs_applied,test_kv_role_defaults_to_kv_both,test_kv_role_preserved_when_set,test_missing_kv_transfer_config_raises.test_build_vllm_cli_args_succeeds_on_gpu_less_host— marked@pytest.mark.vllm(importsvllm.platforms); it needs the vllm package (only present under--extra fsdp/--extra megatron) and was NOT run in the CPU-only env (errors withModuleNotFoundError: No module named 'vllm'there, so it is deselected below).tests/backends/skyrl_train/inference_servers/test_vllm_router.py— Mooncakepd_moderouter args:test_pd_mode_mooncake(prefill URLs zipped with bootstrap ports,kv_connector="mooncake"),test_pd_mode_bootstrap_ports_length_mismatch_raises,test_pd_mode_nixl_default_has_none_bootstrap_port.uv run --isolated --extra dev --extra skyrl-train pytest \ tests/train/test_config.py::test_role_init_kwargs_conflict_with_engine_init_kwargs_rejected \ tests/train/test_config.py::test_role_init_kwargs_require_enable_pd \ tests/train/test_config.py::test_partial_role_init_kwargs_rejected \ tests/train/test_config.py::test_valid_pd_role_init_kwargs_passes \ tests/backends/skyrl_train/inference_servers/test_build_vllm_cli_args.py \ tests/backends/skyrl_train/inference_servers/test_vllm_router.py \ -m "not vllm"Manual / GPU validation (multi-node serve):
uv run --isolated --extra dev --extra fsdp pytest tests/backends/skyrl_train/gpu/gpu_ci/integrations/test_pd_routing.py -v -s.enable_pd=trueand role-specificprefill_init_kwargs/decode_init_kwargscarrying aMooncakeConnector(optionally aMultiConnectorwithMooncakeStoreConnector); verify the router discovers each prefill's bootstrap server, requests complete, and the tolerantMultiKVConnectorPromMetrics.observepatch log line appears without the output-handler crash/hang.