From ad0f67a7ec8f0393c8b4ae50a2a0e66672db372f Mon Sep 17 00:00:00 2001 From: Nishant Revur Date: Tue, 6 Oct 2026 11:03:44 -0700 Subject: [PATCH] [Bugfix][Spec Decode] Keep heterogeneous-vocab draft models on Model Runner V1 (#59541) Signed-off-by: Nishant Revur Co-authored-by: Claude --- tests/test_config.py | 24 ++++++++++++++++++++++++ vllm/config/vllm.py | 5 +++++ 2 files changed, 29 insertions(+) diff --git a/tests/test_config.py b/tests/test_config.py index 9d4567874b..a0c64099dc 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -936,6 +936,30 @@ def test_v2_model_runner_supports_extract_hidden_states(): assert config._get_v2_model_runner_unsupported_features() == [] +@pytest.mark.parametrize("use_heterogeneous_vocab", [False, True]) +def test_v2_model_runner_heterogeneous_vocab_draft_falls_back_to_v1( + use_heterogeneous_vocab, +): + """The V2 draft-model speculator exchanges token ids with the target + without a vocab mapping, so a heterogeneous-vocab (TLI) draft must stay on + V1, where VocabMapping translates them.""" + config = VllmConfig() + config.speculative_config = cast( + SpeculativeConfig, + SimpleNamespace( + method="draft_model", + parallel_drafting=False, + enable_adaptive_verification=False, + use_heterogeneous_vocab=use_heterogeneous_vocab, + ), + ) + + expected = ["heterogeneous-vocabulary draft models"] + assert config._get_v2_model_runner_unsupported_features() == ( + expected if use_heterogeneous_vocab else [] + ) + + def test_v2_model_runner_supports_custom_logits_processors(): config = VllmConfig() config.model_config = cast( diff --git a/vllm/config/vllm.py b/vllm/config/vllm.py index dec1f27fe1..b847da4320 100644 --- a/vllm/config/vllm.py +++ b/vllm/config/vllm.py @@ -3159,6 +3159,11 @@ class VllmConfig: ): unsupported.append("parallel drafting for EAGLE speculative decoding") + # The V2 draft-model speculator has no token mapping between the + # draft and target vocabularies (TLI is TBD in #47172). + if getattr(speculative_config, "use_heterogeneous_vocab", False): + unsupported.append("heterogeneous-vocabulary draft models") + if self.parallel_config.use_ubatching: unsupported.extend(self._get_dbo_unsupported_features())