Repository navigation
Conversation
…oncake-master service TRT-LLM recipes can now declare the same mooncake-master service SGLang and vLLM use. srtctl renders one Mooncake client config per role that selects kv_connector_config.connector: mooncake-store and points that role's workers at it with MOONCAKE_CONFIG_PATH, which TRT-LLM's connector reads before its own mooncake_store block. trtllm-serve and dynamo.trtllm join the pool the same way, with no trtllm-serve mooncake_master, donor processes, or worker wrapper. - TRTLLMBackend.mooncake_kv_store (TRTLLMMooncakeKVStoreConfig): the service's options.store_config holds the client config keys every role shares - roles.<role>.mooncake_store_config (a RoleConfig field, read through role_mooncake_store_config) layers one role's keys over it; keys the whole pool must agree on (model_key, namespace, metadata_server, protocol, master_server_address) are refused there, and the field is refused on SGLang and vLLM roles - role defaults to both (prefill, agg) or capacity (decode); model_key defaults to the served model name, since the pool belongs to one job - Backend.mooncake_store_configs(infra_node_ip, served_model_name) lists the files the orchestrator writes; get_mooncake_worker_env takes the worker mode - the connector is recognized by its resolved module, as TRT-LLM does - load-time checks for what TRT-LLM would reject in every rank after the model loads: no mooncake_store block or block-only keys alongside the master, no external master, sizes as byte counts or binary units, positive transfer_batch_size and local_buffer_size, boolean stage_through_host - without a mooncake-master service, a connector role must find a client config itself: MOONCAKE_CONFIG_PATH in its env, or a mooncake_store block with its own run_dir when trtllm-serve runs the engine - examples for trtllm-serve and Dynamo, docs, regenerated schema docs, tests, launch snapshots Signed-off-by: Yuewei Na <nv-yna@users.noreply.github.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #595 +/- ##
=======================================
Coverage ? 85.34%
=======================================
Files ? 161
Lines ? 23363
Branches ? 0
=======================================
Hits ? 19939
Misses ? 3424
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This branch has not been deployed
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.
Problem
SGLang and vLLM recipes share a Mooncake Store pool by declaring a
mooncake-masterservice. TRT-LLM recipes cannot: onmain, a TRT-LLM recipe with that service fails to load withengine.mooncake_kv_store: Unknown field. The only TRT-LLM route today is TRT-LLM's own provisioning (trtllm-serve mooncake_masterand amooncake_storeblock in the engine config), whichdynamo.trtllmdoes not run at all.TRT-LLM's
mooncake-storeconnector reads its Mooncake client config from the JSON file named byMOONCAKE_CONFIG_PATHbefore it looks at its ownmooncake_storeblock (config.py), andtrtllm-serveskips its own provisioning when that variable is set (master.py). That is the same mechanism srtctl already uses for vLLM, so TRT-LLM can join the same master.What a TRT-LLM recipe looks like with this PR
From
examples/trtllm/trtllm-serve-disagg-mooncake.yaml(Mooncake-relevant keys only):Before workers start, srtctl writes one client config per role that selects the connector (output of the mock orchestrator for this example):
Each file layers, later wins: the role default (
bothfor prefill and agg,capacityfor decode) andmodel_key(the served model name), the service'soptions.store_config, thenroles.<role>.mooncake_store_config;master_server_addressis always the master srtctl launched. The master is the usualmooncake_master --port=8700 --enable_http_metadata_server=true ...on the infra node, gated on ports 8700, 8701, and 8702. Each worker's srun task gets its role's file, so every ranktrtllm-llmapi-launchstarts inherits it:With
frontend.type: dynamothe same recipe launchestrtllm-llmapi-launch python3 -m dynamo.trtllm ... --extra-engine-args /logs/trtllm_config_prefill.yamlwith the same file and variable (examples/trtllm/dynamo-disagg-mooncake.yaml); no wrapper is needed becausedynamo.trtllmprovisions nothing and the connector reads the variable.How the structure lines up with SGLang and vLLM
mooncake-masterserviceMOONCAKE_*in each role'senvoptions.store_configoptions.store_config(same field as vLLM)roles.<role>.envroles.<role>.mooncake_store_configMOONCAKE_CONFIG_PATH→/logs/mooncake_store_config.jsonMOONCAKE_CONFIG_PATH→/logs/mooncake_store_config_<role>.jsondisaggregation-transfer-backend: mooncakeand the cache-linker flagskv-transfer-configwithMooncakeStoreConnectorkv_connector_config: {connector: mooncake-store}MC_*)roles.<role>.envroles.<role>.envroles.<role>.envmooncake-storeservices (by default SGLang decode workers run no Mooncake client)global_segment_sizein-processcapacity(lends memory, moves no KV)model_keydefaultsPer-role settings follow the rest of the schema: they live under
roles.<role>, layered over a shared default by one accessor (role_mooncake_store_config, likerole_kv_events). Keys every server of the pool must agree on (model_key,namespace,metadata_server,protocol,master_server_address) are refused there and stay inoptions.store_config.Changes
TRTLLMBackend.mooncake_kv_store(TRTLLMMooncakeKVStoreConfig), filled from a declaredmooncake-masterservice.RoleConfig.mooncake_store_config(TRT-LLM only), read throughrole_mooncake_store_config; refused on SGLang and vLLM roles with a pointer to their existing knobs.Backend.mooncake_store_configs(infra_node_ip, served_model_name)lists the files the orchestrator writes;get_mooncake_worker_envtakes the worker mode so TRT-LLM can point each role at its own file.model_keydefaults to the served model name. TRT-LLM deliberately has no default (config.py) so two checkpoints sharing a pool cannot read each other's KV; this pool belongs to one job, and an external master is refused for TRT-LLM.mooncake_storeblock or its block-only keys (segment_size,pool,run_dir,master_timeout) next to the master, an emptymodel_key, an unknownrole, sizes that are not byte counts or binary units (TRT-LLM readsGBas 1000³ and refuses it), non-positivetransfer_batch_sizeorlocal_buffer_size, andstage_through_hostgiven as a string. Without a master service, a connector role must find a client config itself (MOONCAKE_CONFIG_PATHin itsenv, or amooncake_storeblock with its ownrun_dirwhen trtllm-serve runs the engine).trtllm-serve, Dynamo), docs (docs/mooncake-kv-store.md,docs/services.md), regenerated schema docs, tests, and launch snapshots.Validation
ruffand the schema-docs check pass.ty check: CI'stypecheckfails with the same 11invalid-attribute-overridediagnosticsmaincurrently fails with under ty 0.0.86 (frozen dataclass fields overriding theRoleSettings/Backendattributes), plus one of the same kind for the newRoleSettings.mooncake_store_config. With ty 0.0.85 it passes.make snapshots: snapshots for the two new examples are included; the per-role field andmodel_keydefault change nosrunlaunch of any example.trtllm-serveand Dynamo), Qwen3-0.6B with one prefill and one decode worker on a GB300 node, TRT-LLM 1.3.0rc23.post1 built fromfeat/m3_with_msaat1ab6bbc990(the connector API from [None][feat] BREAKING: Refine Mooncake connector API TensorRT-LLM#19706) and Mooncake 0.3.13: the native master took 1,375 pages (5.05 GB across the prefill segment and the decodecapacitysegment); after the prefill GPU cache evicted them, repeated requests read 1,374 pages (5.04 GB) back from the pool with identical greedy outputs. The prefill client config that run wrote is identical to what this branch renders.Limitations
roles.<role>.mooncake_store_configis read by TRT-LLM only in this PR. vLLM still writes one file for every role, and SGLang takes Mooncake settings as environment variables.MOONCAKE_MASTER,MOONCAKE_TE_META_DATA_SERVER, andMOONCAKE_LOCAL_HOSTNAMEto TRT-LLM workers; TRT-LLM reads only the file, so they are inert there (documented).main([TRTLLM-12891][feat] Integrate Mooncake connector into KVCMv2 TensorRT-LLM#19171) keeps the same file contract; GPU validation used thefeat/m3_with_msabuild.