Skip to content

refactor(mooncake): move Mooncake client config to roles.<role>.mooncake_store_config - #596

Closed
nv-yna wants to merge 1 commit into
NVIDIA:mainfrom
nv-yna:yna/mooncake-store-config-in-roles
Closed

nv-yna wants to merge 1 commit into
NVIDIA:mainfrom
nv-yna:yna/mooncake-store-config-in-roles

Conversation

@nv-yna

@nv-yna nv-yna commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

A Mooncake client config is the JSON a vLLM or TRT-LLM worker reads from MOONCAKE_CONFIG_PATH. It says how that worker joins the pool and how much host memory each of its ranks lends. Recipes write it in the mooncake-master service's options.store_config, but the master never reads it, so the keys read like master settings. Since #595 a TRT-LLM role can also override them in roles.<role>.mooncake_store_config, so one setting can appear in two places:

roles:
  decode:
    mooncake_store_config:
      global_segment_size: 16GiB      # decode ranks lend 16 GiB
services:
  - name: mooncake-master
    type: mooncake-master
    options:
      store_config:
        global_segment_size: 8GiB     # not the master's memory: every worker's default, so prefill only

This came up in the review of #595 (comment). History: #157 added store_config on the engine (backend.mooncake_kv_store.store_config). #407 (schema 2.0) moved the master into services:, and the migrator moved store_config along to options.store_config. Everything else a role needs already lives under roles.<role>.

What a recipe looks like with this change

Each role that uses Mooncake carries its own client config, and the master entry describes only the master. A YAML anchor writes the keys the roles share once.

# before                                        # after
roles:                                          roles:
  prefill:                                        prefill:
    args: {kv-transfer-config: '...Mooncake...'}    args: {kv-transfer-config: '...Mooncake...'}
  decode:                                           mooncake_store_config: &mooncake
    args: {kv-transfer-config: '...Mooncake...'}      protocol: rdma
services:                                             metadata_server: P2PHANDSHAKE
  - name: mooncake-master                             global_segment_size: 8GB
    type: mooncake-master                         decode:
    options:                                        args: {kv-transfer-config: '...Mooncake...'}
      store_config:                                 mooncake_store_config:
        protocol: rdma                                <<: *mooncake
        metadata_server: P2PHANDSHAKE                 global_segment_size: 16GB   # now possible per role
        global_segment_size: 8GB                services:
                                                  - name: mooncake-master
                                                    type: mooncake-master

srtctl migrate -f recipe.yaml performs this rewrite. TRT-LLM has the same shape; see examples/trtllm/trtllm-serve-disagg-mooncake.yaml. The new examples/vllm/dynamo-disagg-mooncake.yaml shows the vLLM form.

Changes

  • Per-role client config for vLLM. RoleConfig.mooncake_store_config now applies to vLLM as well as TRT-LLM. vLLM writes /logs/mooncake_store_config_<role>.json for each role whose KV connector uses Mooncake, and sets that role's MOONCAKE_CONFIG_PATH. Before, it wrote one /logs/mooncake_store_config.json for every role. device_names_by_gpu process configs become mooncake_store_config_<role>_gpu<ids>.json, built from that role's keys.
  • One answer to "does this vLLM role use Mooncake". VLLMBackend.uses_mooncake_store resolves the connector the way the worker command does (kv_connector_classes): kv-transfer-config, else roles.<role>.args.connector, else engine.connector, including connectors a MultiConnector wraps. The file writer, worker env, dry run, role-field validator and the existing "master without a Mooncake connector" check all use it. is_mooncake_connector is the one place the class name is matched.
  • Backend members. mooncake_store_modes, mooncake_store_config_for_mode, mooncake_master_store_config and mooncake_pool_keys. The layering (role keys over the deprecated service keys) is implemented once in Backend. mooncake_pool_keys lists, per engine, the keys every client of a pool must share: vLLM metadata_server and protocol; TRT-LLM also model_key and namespace.
  • Validation. The validator checks that pool keys match across roles. It refuses mooncake_store_config on a role that reads no client config (SGLang, or no Mooncake connector), and without a mooncake-master service. This replaces feat(trtllm): run TRT-LLM's mooncake-store connector on the native mooncake-master service #595's rule that pool keys could not be set per role.
  • Deprecation, not removal. options.store_config (and engine.mooncake_kv_store.store_config) keeps working: its keys apply under every role's own. Loading a recipe that sets it logs a warning that names the replacement and srtctl migrate.
  • Migration. srtctl migrate moves options.store_config, including the schema-1 backend.mooncake_kv_store.store_config, into each role whose connector uses Mooncake. The engine decides which roles those are, so connectors resolve as at launch. A role's own keys win, and end-of-line comments travel with their keys. Override files (base plus override_*) and sweep files are left as they are, because a variant or sweep point can change which roles use Mooncake. The engine.mooncake_kv_store.store_config spelling is also left for the user. Each of these cases gets a note.
  • Dry run. Both engines show each role's config and path through the same hooks, replacing two engine-specific branches.
  • Docs and examples. docs/mooncake-kv-store.md, docs/services.md and docs/legacy-v1.md describe the per-role form, the anchor pattern and the migration. The TRT-LLM examples carry their client config in the roles. Schema docs are regenerated.

@codecov-commenter

codecov-commenter commented Oct 10, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.54140% with 7 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@52843d6). Learn more about missing BASE report.

Files with missing lines Patch % Lines
src/srtctl/core/migrate.py 93.97% 5 Missing ⚠️
src/srtctl/backends/vllm.py 93.54% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #596   +/-   ##
=======================================
  Coverage        ?   85.51%           
=======================================
  Files           ?      165           
  Lines           ?    24537           
  Branches        ?        0           
=======================================
  Hits            ?    20982           
  Misses          ?     3555           
  Partials        ?        0           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…ake_store_config

The Mooncake client config (the JSON a worker reads from MOONCAKE_CONFIG_PATH)
lived in the mooncake-master service's options.store_config, although the master
never reads it: it says how each worker joins the pool and how much host memory
its ranks lend. It now lives with the other per-role settings, in
roles.<role>.mooncake_store_config, for vLLM as well as TRT-LLM.

- vLLM writes one client config per role whose KV connector uses Mooncake
  (/logs/mooncake_store_config_<role>.json) and points that role's
  MOONCAKE_CONFIG_PATH at it. device_names_by_gpu process configs are per role
  too (mooncake_store_config_<role>_gpu<ids>.json), for Mooncake roles only.
- The vLLM connector is resolved like the worker command (kv_connector_classes),
  so a Mooncake connector chosen through engine.connector or
  roles.<role>.args.connector counts as well as kv-transfer-config. The vLLM
  master check uses the same answer, and is_mooncake_connector is the one place
  the class name is matched.
- Backend.mooncake_store_modes, mooncake_store_config_for_mode,
  mooncake_master_store_config and mooncake_pool_keys: one layering in the base
  class, and one table per engine of the keys every client of a pool must
  share. The validator checks those match across roles, and refuses the field
  on roles that read no client config and without a mooncake-master service.
- options.store_config is deprecated, not removed: its keys still apply under
  every role's own, and loading a recipe that sets it logs a warning.
- srtctl migrate moves options.store_config (including schema-1
  backend.mooncake_kv_store.store_config) into each Mooncake role, under the
  role's own keys, keeping end-of-line comments with their keys. Override and
  sweep files, whose variants can change a role's connector, are left as they
  are, as is engine.mooncake_kv_store.store_config; a note says so.
- The dry run shows each role's config through the same hooks for both engines.
- examples/vllm/dynamo-disagg-mooncake.yaml and its launch snapshot. The TRT-LLM
  examples carry their client config in the roles. Docs updated.

Signed-off-by: Yuewei Na <nv-yna@users.noreply.github.com>
@nv-yna
nv-yna force-pushed the yna/mooncake-store-config-in-roles branch from 978d925 to 76773e5 Compare October 19, 2026 23:15
@nv-yna
nv-yna marked this pull request as ready for review October 19, 2026 23:15
@github-actions

Copy link
Copy Markdown

src/srtctl diff: +349 -168

@nv-yna nv-yna closed this Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants