diff --git a/.buildkite/test-amd.yaml b/.buildkite/test-amd.yaml index 9c1b2077a7e6..61d43db4b089 100644 --- a/.buildkite/test-amd.yaml +++ b/.buildkite/test-amd.yaml @@ -380,6 +380,7 @@ steps: - tests/test_outputs.py - tests/test_pooling_params.py - tests/test_ray_env.py + - tests/test_sampling_params.py - tests/multimodal - tests/renderers - tests/standalone_tests/lazy_imports.py @@ -395,6 +396,7 @@ steps: - pytest -v -s test_outputs.py - pytest -v -s test_pooling_params.py - pytest -v -s test_ray_env.py + - pytest -v -s test_sampling_params.py - pytest -v -s -m 'cpu_test' multimodal - pytest -v -s renderers - pytest -v -s tokenizers_ diff --git a/.buildkite/test_areas/misc.yaml b/.buildkite/test_areas/misc.yaml index 7aeb84050660..fd6ef2e61bae 100644 --- a/.buildkite/test_areas/misc.yaml +++ b/.buildkite/test_areas/misc.yaml @@ -351,6 +351,7 @@ steps: - tests/test_outputs.py - tests/test_pooling_params.py - tests/test_ray_env.py + - tests/test_sampling_params.py - tests/multimodal - tests/renderers - tests/standalone_tests/lazy_imports.py @@ -368,6 +369,7 @@ steps: - pytest -v -s test_outputs.py - pytest -v -s test_pooling_params.py - pytest -v -s test_ray_env.py + - pytest -v -s test_sampling_params.py - pytest -v -s -m 'cpu_test' multimodal - pytest -v -s renderers - pytest -v -s reasoning diff --git a/tests/test_sampling_params.py b/tests/test_sampling_params.py new file mode 100644 index 000000000000..e5d811fbb137 --- /dev/null +++ b/tests/test_sampling_params.py @@ -0,0 +1,50 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: Copyright contributors to the vLLM project +from dataclasses import dataclass + +import pytest + +from vllm import SamplingParams + + +@dataclass +class MockModelConfig: + is_diffusion: bool = False + max_logprobs: int = 20 + logits_processors: list | None = None + + def get_vocab_size(self) -> int: + return 1024 + + +@pytest.mark.parametrize( + "kwargs", + [ + {"temperature": 0.7}, + {"temperature": 0.0}, + {"min_p": 0.1}, + {"seed": 42}, + {"min_tokens": 5}, + {"logit_bias": {0: 1.0}}, + {"bad_words": ["foo"]}, + {"allowed_token_ids": [0, 1]}, + ], +) +def test_diffusion_rejects_unsupported_params(kwargs: dict): + params = SamplingParams(**kwargs) + with pytest.raises(ValueError, match="not yet supported with diffusion"): + params.verify(MockModelConfig(is_diffusion=True), None, None, None) + + +def test_diffusion_accepts_default_params(): + SamplingParams().verify(MockModelConfig(is_diffusion=True), None, None, None) + + +def test_diffusion_accepts_top_k_top_p(): + params = SamplingParams(top_p=0.9, top_k=10) + params.verify(MockModelConfig(is_diffusion=True), None, None, None) + + +def test_non_diffusion_models_unaffected(): + params = SamplingParams(temperature=0.7, top_k=10, seed=42) + params.verify(MockModelConfig(), None, None, None) diff --git a/tests/v1/sample/test_logprobs.py b/tests/v1/sample/test_logprobs.py index ec1502727923..fba240fea6a6 100644 --- a/tests/v1/sample/test_logprobs.py +++ b/tests/v1/sample/test_logprobs.py @@ -85,6 +85,7 @@ def _model_config(vocab_size: int = 10): return SimpleNamespace( max_logprobs=20, logits_processors=None, + is_diffusion=False, get_vocab_size=lambda: vocab_size, ) diff --git a/vllm/sampling_params.py b/vllm/sampling_params.py index 5df2e8cfc177..f0966902d363 100644 --- a/vllm/sampling_params.py +++ b/vllm/sampling_params.py @@ -745,6 +745,7 @@ def verify( self._validate_logits_processors(model_config) self._validate_allowed_token_ids(tokenizer) self._validate_spec_decode(speculative_config) + self._validate_diffusion(model_config) self._validate_structured_outputs( model_config, structured_outputs_config, tokenizer ) @@ -878,6 +879,28 @@ def _validate_spec_decode( "are not yet supported with speculative decoding." ) + def _validate_diffusion(self, model_config: ModelConfig) -> None: + if not model_config.is_diffusion: + return + + # Diffusion models denoise a whole canvas per step with a fixed + # temperature schedule, so per-request sampling parameters are not + # supported. Penalties are ignored by the sampler with a warning. + if ( + self.temperature != 1.0 + or self.min_p > _SAMPLING_EPS + or self.seed is not None + or self.min_tokens > 0 + or self.logit_bias + or self.bad_words + or self.allowed_token_ids + ): + raise ValueError( + "The temperature, min_p, seed, min_tokens, logit_bias, " + "bad_words, and allowed_token_ids sampling parameters " + "are not yet supported with diffusion models." + ) + def _validate_structured_outputs( self, model_config: ModelConfig,