Repository navigation
[Bugfix][M9] Restore model-neutral PD coordinator metadata - #140
Conversation
PDEngine rebuilt every worker ready payload as OuroConfig, so any non-Ouro family failed at coordinator startup (Nanbeige TypeError num_loops, Huginn TypeError n_embd). The coordinator only validates vocab_size, total_ut_steps and max_position_embeddings in add_request. Replace the OuroConfig reconstruction with a coordinator-scoped PDModelInfo adopted from the ready report, ignoring family-specific fields and failing fast at startup when required limits are missing or mistyped. Drop the OuroConfig import. Add CPU regression tests covering the helper, the real PDEngine startup path on a Nanbeige payload, and request validation against Nanbeige limits. Signed-off-by: youhengfei <474029121@qq.com>
|
Please create a unified The current flow is: The expected flow is: The model configuration is already knowable before worker startup. The coordinator should not need a worker round trip to recover it, or introduce a separate Please keep model-specific configuration within the unified |
There was a problem hiding this comment.
Following up on @bjf-frz's comment above: I agree with the unified ModelConfig direction. Please treat this as a continuation of that review rather than as an approval of the current approach. I withdraw my earlier suggestion to send the limits from the worker, because it would add to the worker round trip that comment asks to remove.
Some pointers that may help with the change:
- The entry points already resolve the config and drop it.
PDEngine.__init__callsmodel, revision, _ = resolve_model_config(model, revision=revision)(vllm_rlt/pd/engine.py), andentrypoints/llm.pydoes the same. The third value is the parsedconfig.json, discarded with_.entrypoints/serve.pyandentrypoints/pd_serve.pyalready keep it asconfig.- Every family has
Config.from_dict(ouro.py,nanbeige.py,huginn.py). - So the entry point can build the family config once: from a path via
from_dict, use a config dataclass as is, or takemodule.configfrom annn.Module. It can then pass that object to the coordinator / single-stage engine and to the workers. Today the worker resolves and parsesconfig.jsona second time, throughAutoModelForCausalLM.from_pretrained→resolve_model_config.
- With that object,
PDModelInfoandfrom_readyare no longer needed.add_request()can validate against theModelConfigdirectly. Attribute access also covers families that expose limits as properties, such as Huginn'stotal_ut_stepsandmax_position_embeddings, whichasdictdrops from the current ready payload.- Whether PD supports Huginn (#69) then becomes an explicit model-type check, not a side effect of the metadata shape.
- The
"model metadata lacks"expectation in the new test would change accordingly.
- The ready message can then carry only runtime results. That means KV blocks / block size / depths, transport info, and the P/D compatibility fingerprint computed on the worker. Its
model=asdict(...)field can go. - The single-stage path has the same dependency.
StageClientrebuildsmodel_configasSimpleNamespace(**message["model"], ...)from the ready message (vllm_rlt/engine/llm_engine.py), andentrypoints/cli.pyreadsllm.engine.model_config.total_ut_stepsfrom it. Passing the entryModelConfigthrough covers this consumer too.
What I verified on the current head, in case it is useful for the rework:
- The regression comes from
c3ce155(#118), which replaced the coordinator-side three-field model info withOuroConfig(**ready["model"]). PDEngine.model_configis only read inadd_request().- The branch merges cleanly with current main.
tests/test_pd.pypasses on CPU: 14 passed, 25 skipped.- The Nanbeige startup test, which mocks only the process boundary, is a good shape to keep. It can assert that request validation uses the entry
ModelConfigand that startup no longer needsmodelin the ready message.
0z5a
left a comment
There was a problem hiding this comment.
Requesting changes to replace my earlier approval, which predates the direction set in @bjf-frz's comment above. Please rework this around a unified ModelConfig created at the entry point and passed to the coordinator and the workers, as described there. The worker ready message should then carry only runtime results. My review above lists where the config is already resolved at the entry points and which consumers depend on the ready-message model payload.
Restore Nanbeige PD startup by resolving ModelConfig at deployment entry points and passing the concrete model configuration to clients and workers. - Preserve family-specific configuration and derived request limits. - Reuse supplied configuration when loading checkpoint weights. - Remove PDModelInfo and ready-message configuration reconstruction. - Keep runtime capacity, transport metadata and fingerprint checks in ready. - Reject unsupported PD model families before spawning workers. - Cover configuration propagation, checkpoint loading and request validation. Validation: - CPU: 834 passed, 329 skipped. - PD GPU: 38 passed, 1 skipped on two H100s. - GSM8K-100: Ouro 69/100, Nanbeige 63/100; native and PD token sequences match on all 100 questions for each model. Signed-off-by: youhengfei <474029121@qq.com>
|
Thanks @bjf-frz and @0z5a. Reworked in af66511 following the entry-owned configuration flow:
Validation on the updated implementation:
The architecture documentation now reflects this ownership contract. Please take another look. |
0z5a
left a comment
There was a problem hiding this comment.
Thanks for the rework. af66511 follows the entry-owned flow from @bjf-frz's comment:
- The entry point builds
ModelConfigonce. - The coordinator and
StageClientkeep it and pass it to the workers. - The checkpoint loaders reuse it without reading
config.jsonagain. PDModelInfois gone.- The ready message now carries only runtime capacity, transport info and the fingerprint.
Huginn's derived limits now come through the properties, and the CLI's model_config.total_ut_steps reads from the same object.
I merged the branch with current main (66920da) and checked it: the full CPU suite passes (835 passed, 369 skipped), and ruff check and format are clean.
Two optional nits, not blocking:
prepare_modelchecks that a module or config source matchesmodel_config, but for a path source it trusts the caller. That is fine for the current entry points, which build both from the same resolved checkpoint. A one-line comment would make the contract explicit.ModelConfig.model_typebuilds the fullto_dict()on every access. It is only read at startup, so this is cosmetic.
LGTM.
|
lgtm |
Resolve conflicts with InferMatrixLab#140 (model-neutral PD coordinator metadata): - vllm_rlt/pd/engine.py: take main's prepare_model path, which resolves the model configuration at the entry point and passes it to the workers. This supersedes this branch's reconstruction of the config class from the ready message, so _CONFIG_CLASSES and its test are removed. main's explicit rejection of Huginn in PD is kept. - tests/test_pd.py: keep main's Huginn-rejection and Nanbeige startup tests next to this branch's default-budget test. The coalesced transfers, UCX error-handling mode and 256 MiB / 2 GiB default budget are unchanged. CPU: 838 passed, 369 skipped; ruff check passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
Resolve the LLM constructor conflict with InferMatrixLab#140: existing LLMEngine, StageClient and PDEngine instances are still adopted directly, and other sources go through prepare_model so StageClient receives the entry-owned ModelConfig. Signed-off-by: 0z5a <dezhen.lu@student.uni-tuebingen.de>
Purpose
Restore Nanbeige PD startup after #118 by creating a unified
ModelConfigbefore worker startup and passing it through deployment initialization.The regression reconstructed every worker's configuration as
OuroConfig; a Nanbeige payload fails withTypeError: unexpected keyword argument 'num_loops'. Nanbeige PD was supported before the refactor through #77.Required human contributor answers
1. What outcome are you trying to achieve?
Restore PD serving with Nanbeige checkpoints while preserving model-neutral configuration ownership.
2. What is the highest-leverage variable for that outcome?
Create and validate model configuration at the deployment entry point, so request validation and worker initialization consume the same configuration.
3. How will this work move that variable rather than create busywork?
Implement the requested initialization contract: retain model-specific configuration inside a unified
ModelConfig, pass it to the coordinator and workers, and reserve worker ready messages for runtime results.4. Who is the customer or user, and what do they actually need?
Nanbeige PD users need their checkpoints to start and generate correctly, as supported before the refactor.
PR necessity and bugfix evidence
This fixes a startup regression. The contributor reproduced the failing configuration conversion at the CPU metadata boundary:
Implementation
ModelConfigretains the concrete Ouro, Nanbeige or Huginn configuration. Common limits delegate to its fields and derived properties.docs/unified_execution.mddocuments the ownership contract.Validation
Reviewed commit:
af665110067fc47776207593d78d107a1bbe17a9PR baseline:
4a350344027960a48384626aa646f1765fda6d4fContributor-reported results on the updated implementation
Validation report:
These results establish agreement for the tested configurations, not general equivalence across all workloads.
Independent reviewer verification
On the reviewed commit, Python 3.12.3, Torch 2.13.0+cu130 and Transformers 4.55.0:
python -m pytest -q tests/test_auto_model.py tests/test_stage_engine.py tests/test_pd.py -m 'not gpu'96 passed, 34 deselected in 18.89s. GPU tests and GSM8K were not rerun by the reviewer.
The commit's lint and CPU CI check also passed.