[Bugfix] Reject sampling params unsupported by diffusion models (#45418)

Signed-off-by: Guan-Ming (Wesley) Chiu <105915352+guan404ming@users.noreply.github.com>

Guan-Ming Chiu committed Jul 7, 2026 at 19:25 UTC ed051fab54cdf98fbcd25036af5eb02d2a3af1dd
5 files changed +78
.buildkite/test-amd.yaml
+2
@@ -380,6 +380,7 @@ steps:
380 - tests/test_outputs.py
381 - tests/test_pooling_params.py
382 - tests/test_ray_env.py
383 + - tests/test_sampling_params.py
384 - tests/multimodal
385 - tests/renderers
386 - tests/standalone_tests/lazy_imports.py
@@ -395,6 +396,7 @@ steps:
396 - pytest -v -s test_outputs.py
397 - pytest -v -s test_pooling_params.py
398 - pytest -v -s test_ray_env.py
399 + - pytest -v -s test_sampling_params.py
400 - pytest -v -s -m 'cpu_test' multimodal
401 - pytest -v -s renderers
402 - pytest -v -s tokenizers_
.buildkite/test_areas/misc.yaml
+2
@@ -351,6 +351,7 @@ steps:
351 - tests/test_outputs.py
352 - tests/test_pooling_params.py
353 - tests/test_ray_env.py
354 + - tests/test_sampling_params.py
355 - tests/multimodal
356 - tests/renderers
357 - tests/standalone_tests/lazy_imports.py
@@ -368,6 +369,7 @@ steps:
369 - pytest -v -s test_outputs.py
370 - pytest -v -s test_pooling_params.py
371 - pytest -v -s test_ray_env.py
372 + - pytest -v -s test_sampling_params.py
373 - pytest -v -s -m 'cpu_test' multimodal
374 - pytest -v -s renderers
375 - pytest -v -s reasoning
tests/test_sampling_params.py new
+50
@@ -0,0 +1,50 @@
1 +# SPDX-License-Identifier: Apache-2.0
2 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 +from dataclasses import dataclass
4 +
5 +import pytest
6 +
7 +from vllm import SamplingParams
8 +
9 +
10 +@dataclass
11 +class MockModelConfig:
12 + is_diffusion: bool = False
13 + max_logprobs: int = 20
14 + logits_processors: list | None = None
15 +
16 + def get_vocab_size(self) -> int:
17 + return 1024
18 +
19 +
20 +@pytest.mark.parametrize(
21 + "kwargs",
22 + [
23 + {"temperature": 0.7},
24 + {"temperature": 0.0},
25 + {"min_p": 0.1},
26 + {"seed": 42},
27 + {"min_tokens": 5},
28 + {"logit_bias": {0: 1.0}},
29 + {"bad_words": ["foo"]},
30 + {"allowed_token_ids": [0, 1]},
31 + ],
32 +)
33 +def test_diffusion_rejects_unsupported_params(kwargs: dict):
34 + params = SamplingParams(**kwargs)
35 + with pytest.raises(ValueError, match="not yet supported with diffusion"):
36 + params.verify(MockModelConfig(is_diffusion=True), None, None, None)
37 +
38 +
39 +def test_diffusion_accepts_default_params():
40 + SamplingParams().verify(MockModelConfig(is_diffusion=True), None, None, None)
41 +
42 +
43 +def test_diffusion_accepts_top_k_top_p():
44 + params = SamplingParams(top_p=0.9, top_k=10)
45 + params.verify(MockModelConfig(is_diffusion=True), None, None, None)
46 +
47 +
48 +def test_non_diffusion_models_unaffected():
49 + params = SamplingParams(temperature=0.7, top_k=10, seed=42)
50 + params.verify(MockModelConfig(), None, None, None)
tests/v1/sample/test_logprobs.py
+1
@@ -85,6 +85,7 @@ def _model_config(vocab_size: int = 10):
85 return SimpleNamespace(
86 max_logprobs=20,
87 logits_processors=None,
88 + is_diffusion=False,
89 get_vocab_size=lambda: vocab_size,
90 )
91
vllm/sampling_params.py
+23
@@ -745,6 +745,7 @@ class SamplingParams(
745 self._validate_logits_processors(model_config)
746 self._validate_allowed_token_ids(tokenizer)
747 self._validate_spec_decode(speculative_config)
748 + self._validate_diffusion(model_config)
749 self._validate_structured_outputs(
750 model_config, structured_outputs_config, tokenizer
751 )
@@ -878,6 +879,28 @@ class SamplingParams(
879 "are not yet supported with speculative decoding."
880 )
881
882 + def _validate_diffusion(self, model_config: ModelConfig) -> None:
883 + if not model_config.is_diffusion:
884 + return
885 +
886 + # Diffusion models denoise a whole canvas per step with a fixed
887 + # temperature schedule, so per-request sampling parameters are not
888 + # supported. Penalties are ignored by the sampler with a warning.
889 + if (
890 + self.temperature != 1.0
891 + or self.min_p > _SAMPLING_EPS
892 + or self.seed is not None
893 + or self.min_tokens > 0
894 + or self.logit_bias
895 + or self.bad_words
896 + or self.allowed_token_ids
897 + ):
898 + raise ValueError(
899 + "The temperature, min_p, seed, min_tokens, logit_bias, "
900 + "bad_words, and allowed_token_ids sampling parameters "
901 + "are not yet supported with diffusion models."
902 + )
903 +
904 def _validate_structured_outputs(
905 self,
906 model_config: ModelConfig,