[Bugfix] Restore multimodal support on the plain "vllm" throughput backend (#52168)
Signed-off-by: Michal Ganczarenko <michal.ganczarenko@intel.com>
Michał Ganczarenko committed
Aug 28, 2026 at 12:28 UTC
d1922cb5a718259976fcb9044c18c9711c9ca694
2 files changed
+50
-4
tests/benchmarks/test_throughput_cli.py
+47
@@ -230,3 +230,50 @@ def test_get_requests_resolves_mmvu(
230
requests = get_requests(args, hf_tokenizer)
231
assert len(requests) == 3
232
assert all(isinstance(r, SampleRequest) for r in requests)
233
+
234
+
235
+@pytest.mark.benchmark
236
+def test_get_requests_allows_multimodal_on_plain_vllm_backend(
237
+ monkeypatch: pytest.MonkeyPatch,
238
+ hf_tokenizer: PreTrainedTokenizerBase,
239
+) -> None:
240
+ """Regression: --backend vllm must accept multimodal datasets such as ASR.
241
+
242
+ _run_vllm_requests forwards multi_modal_data straight to LLM.generate, so
243
+ the vllm-chat-only gate in get_samples rejected a backend that always
244
+ worked.
245
+ """
246
+ import vllm.benchmarks.datasets.datasets as dsmod
247
+
248
+ class _StubASRDataset:
249
+ IS_MULTIMODAL = True
250
+ SUPPORTED_DATASET_PATHS = {"openslr/librispeech_asr"}
251
+
252
+ def __init__(self, **kwargs):
253
+ self.__dict__.update(kwargs)
254
+
255
+ def sample(self, *, num_requests, tokenizer, **kwargs): # noqa: ARG002
256
+ return [
257
+ SampleRequest(prompt="q", prompt_len=1, expected_output_len=1)
258
+ for _ in range(num_requests)
259
+ ]
260
+
261
+ monkeypatch.setattr(dsmod, "ASRDataset", _StubASRDataset)
262
+
263
+ parser = FlexibleArgumentParser()
264
+ add_cli_args(parser)
265
+ args = parser.parse_args(
266
+ [
267
+ "--dataset-name",
268
+ "hf",
269
+ "--dataset-path",
270
+ "openslr/librispeech_asr",
271
+ "--backend",
272
+ "vllm",
273
+ "--num-prompts",
274
+ "3",
275
+ ]
276
+ )
277
+ requests = get_requests(args, hf_tokenizer)
278
+ assert len(requests) == 3
279
+ assert all(isinstance(r, SampleRequest) for r in requests)
vllm/benchmarks/throughput.py
+3
-4
@@ -567,10 +567,9 @@ def _to_serve_args(args: argparse.Namespace) -> argparse.Namespace:
567
568
def get_requests(args, tokenizer):
569
serve_args = _to_serve_args(args)
570
- # Throughput reuses bench serve's dataset dispatch. vllm-chat is the only
571
- # multimodal-capable throughput backend, so it is the only one allowed past
572
- # the multimodal gates inside get_samples; other backends raise there.
573
- mm_backends = ("vllm-chat",) if args.backend == "vllm-chat" else ()
570
+ # Both offline vLLM backends forward multi_modal_data to the engine;
571
+ # "hf" and "mii" are text-only and get rejected inside get_samples.
572
+ mm_backends = ("vllm", "vllm-chat")
573
requests = get_samples(serve_args, tokenizer, multimodal_backends=mm_backends)
574
requests = assign_loras(requests, args)
575
requests = filter_requests_for_dp(requests, args.data_parallel_size)