From 1ea7c63f4af7bb4fd6f025c8db44434ab274cb51 Mon Sep 17 00:00:00 2001 From: Artem Perevedentsev Date: Tue, 22 Sep 2026 17:00:05 +0300 Subject: [PATCH] [Bugfix][Structured Output] Disallow MRV1 + PP>1 + async sched + structured output (#56250) Signed-off-by: Artem Perevedentsev Co-authored-by: CNE Pierre FICHEPOIL --- tests/test_config.py | 46 ++++++++++++++++++++++++++++++++++++++++++-- vllm/config/vllm.py | 23 ++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/tests/test_config.py b/tests/test_config.py index 69a3ca2229..0720007135 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1082,10 +1082,11 @@ def test_models_default_to_v2_model_runner(model_config, expected, monkeypatch): def test_v1_model_runner_rejects_v2_only_features(): config = SimpleNamespace( - parallel_config=SimpleNamespace( + parallel_config=ParallelConfig( prefill_context_parallel_size=2, - enable_batch_sharded_sampling=False, + distributed_executor_backend="mp", ), + scheduler_config=SchedulerConfig.default_factory(async_scheduling=False), speculative_config=None, model_config=None, ) @@ -1245,6 +1246,47 @@ def test_async_scheduling_with_pipeline_parallelism_is_allowed(): assert cfg.scheduler_config.async_scheduling is True +def test_v1_model_runner_drops_async_scheduling_with_pipeline_parallelism(monkeypatch): + """PP>1 must stay buildable whenever the V1 model runner is selected, such + as the external_launcher fallback; async scheduling is dropped instead.""" + monkeypatch.setenv("VLLM_USE_V2_MODEL_RUNNER", "0") + + cfg = VllmConfig( + scheduler_config=SchedulerConfig( + max_model_len=8192, + is_encoder_decoder=False, + ), + parallel_config=ParallelConfig( + pipeline_parallel_size=2, + distributed_executor_backend="mp", + nnodes=2, + ), + ) + assert cfg.scheduler_config.async_scheduling is False + + +def test_v1_model_runner_rejects_pipeline_parallelism_with_async_scheduling(): + """Only the async combination desyncs the grammar FSM (#45014), so plain + PP>1 must stay usable on the V1 model runner.""" + config = SimpleNamespace( + parallel_config=ParallelConfig( + pipeline_parallel_size=2, + distributed_executor_backend="mp", + ), + scheduler_config=SchedulerConfig.default_factory(async_scheduling=False), + speculative_config=None, + model_config=None, + ) + config._dflash_needs_multi_kv_group = lambda: False + config._is_dflash2_draft = lambda: False + + assert VllmConfig._get_v1_model_runner_unsupported_features(config) == [] + + config.scheduler_config.async_scheduling = True + unsupported = VllmConfig._get_v1_model_runner_unsupported_features(config) + assert "pipeline parallelism with async scheduling" in unsupported + + def test_data_parallel_rpc_port_has_fixed_default(): assert ParallelConfig().data_parallel_rpc_port == 29550 diff --git a/vllm/config/vllm.py b/vllm/config/vllm.py index 53734468d3..15bfb42559 100644 --- a/vllm/config/vllm.py +++ b/vllm/config/vllm.py @@ -1522,6 +1522,15 @@ class VllmConfig: "DP+EP generation accuracy." ) self.scheduler_config.async_scheduling = False + elif ( + self.parallel_config.pipeline_parallel_size > 1 + and not self.use_v2_model_runner + ): + logger.warning_once( + "Async scheduling is disabled because the V1 model runner " + "does not support it with pipeline parallelism." + ) + self.scheduler_config.async_scheduling = False else: self.scheduler_config.async_scheduling = True @@ -2962,6 +2971,20 @@ class VllmConfig: if self.parallel_config.prefill_context_parallel_size > 1: unsupported.append("prefill context parallel") + # Note(arpera): + # MRV1 + PP>1 + async sched + structured output + # does not work in vLLM. For more info see: + # https://github.com/vllm-project/vllm/issues/45014 + # Since recently MRV1 has been deprecated then + # there was decided not to fix the issue but instead + # to disallow such configuration. + # At the same time MRV2 works fine in this case. + if ( + self.parallel_config.pipeline_parallel_size > 1 + and self.scheduler_config.async_scheduling + ): + unsupported.append("pipeline parallelism with async scheduling") + # DSpark is implemented only by the V2 GPU model runner. if self.speculative_config: if self.speculative_config.method == "dspark":