main
py 168 lines 5.62 KB
Raw
1 # SPDX-License-Identifier: Apache-2.0
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import pytest
4
5 from vllm.engine.arg_utils import EngineArgs
6 from vllm.model_executor.layers.quantization.quark.utils import deep_compare
7
8
9 def test_cuda_empty_vs_unset_configs(monkeypatch: pytest.MonkeyPatch):
10 """Test that configs created with normal (untouched) CUDA_VISIBLE_DEVICES
11 and CUDA_VISIBLE_DEVICES="" are equivalent. This ensures consistent
12 behavior regardless of whether GPU visibility is disabled via empty string
13 or left in its normal state.
14 """
15
16 def create_config():
17 engine_args = EngineArgs(
18 model="deepseek-ai/DeepSeek-V2-Lite", trust_remote_code=True
19 )
20 return engine_args.create_engine_config()
21
22 # Create config with CUDA_VISIBLE_DEVICES set normally
23 normal_config = create_config()
24
25 # Create config with CUDA_VISIBLE_DEVICES=""
26 with monkeypatch.context() as m:
27 m.setenv("CUDA_VISIBLE_DEVICES", "")
28 empty_config = create_config()
29
30 normal_config_dict = vars(normal_config)
31 empty_config_dict = vars(empty_config)
32
33 # Remove instance_id before comparison as it's expected to be different
34 normal_config_dict.pop("instance_id", None)
35 empty_config_dict.pop("instance_id", None)
36
37 assert deep_compare(normal_config_dict, empty_config_dict), (
38 'Configs with normal CUDA_VISIBLE_DEVICES and CUDA_VISIBLE_DEVICES=""'
39 " should be equivalent"
40 )
41
42
43 def test_ray_runtime_env(monkeypatch: pytest.MonkeyPatch):
44 # In testing, this method needs to be nested inside as ray does not
45 # see the test module.
46 def create_config():
47 engine_args = EngineArgs(
48 model="deepseek-ai/DeepSeek-V2-Lite", trust_remote_code=True
49 )
50 return engine_args.create_engine_config()
51
52 config = create_config()
53 parallel_config = config.parallel_config
54 assert parallel_config.ray_runtime_env is None
55
56 import ray
57
58 ray.init()
59
60 runtime_env = {
61 "env_vars": {
62 "TEST_ENV_VAR": "test_value",
63 # In future ray versions, this will be default, so when setting a
64 # task or actor with num_gpus=None/0, the visible devices env var
65 # won't be overridden resulting in no GPUs being visible on a gpu
66 # machine.
67 "RAY_ACCEL_ENV_VAR_OVERRIDE_ON_ZERO": "0",
68 },
69 }
70
71 config_ref = ray.remote(create_config).options(runtime_env=runtime_env).remote()
72
73 config = ray.get(config_ref)
74 parallel_config = config.parallel_config
75 assert parallel_config.ray_runtime_env is not None
76 assert (
77 parallel_config.ray_runtime_env.env_vars().get("TEST_ENV_VAR") == "test_value"
78 )
79
80 ray.shutdown()
81
82
83 def test_unrecognized_env(monkeypatch):
84 import os
85
86 from vllm.envs import environment_variables
87
88 # Remove any existing unrecognized VLLM env vars that might interfere
89 for env in list(os.environ):
90 if env.startswith("VLLM_") and env not in environment_variables:
91 monkeypatch.delenv(env, raising=False)
92
93 # Test that if fail_on_environ_validation is True, then an error
94 # is raised when an unrecognized vLLM environment variable is set
95 monkeypatch.setenv("VLLM_UNRECOGNIZED_ENV_VAR", "some_value")
96 engine_args = EngineArgs(
97 fail_on_environ_validation=True,
98 )
99 with pytest.raises(ValueError, match="Unknown vLLM environment variable detected"):
100 engine_args.create_engine_config()
101
102 # Test that if fail_on_environ_validation is False, then no error is raised
103 engine_args = EngineArgs()
104 engine_args.create_engine_config()
105
106 # Test that when the unrecognized env var is removed, no error is raised
107 monkeypatch.delenv("VLLM_UNRECOGNIZED_ENV_VAR")
108 engine_args = EngineArgs(
109 fail_on_environ_validation=True,
110 )
111 engine_args.create_engine_config()
112
113
114 def test_get_diff_sampling_param_includes_penalties():
115 """``--override-generation-config`` must apply presence_penalty and
116 frequency_penalty as server-side defaults, like the other sampling
117 params. Regression test for the whitelist silently dropping them.
118
119 Called unbound with a lightweight stand-in so no model is loaded:
120 generation_config="vllm" makes the method skip try_get_generation_config
121 and read only override_generation_config.
122 """
123 from types import SimpleNamespace
124
125 from vllm.config.model import ModelConfig
126
127 fake = SimpleNamespace(
128 generation_config="vllm",
129 override_generation_config={
130 "presence_penalty": 1.5,
131 "frequency_penalty": 0.5,
132 "temperature": 0.6,
133 },
134 )
135
136 diff = ModelConfig.get_diff_sampling_param(fake)
137
138 assert diff["presence_penalty"] == 1.5
139 assert diff["frequency_penalty"] == 0.5
140 assert diff["temperature"] == 0.6
141
142
143 def test_generation_config_penalties_survive_diff_sampling_filter():
144 """``generation_config.json`` penalties must survive the diff-sampling
145 whitelist (regression for #50767, auto path).
146
147 Covers the ``generation_config="auto"`` branch, where the override
148 dict is empty and the values come from ``try_get_generation_config``.
149 """
150 from types import SimpleNamespace
151
152 from vllm.config.model import ModelConfig
153
154 fake = SimpleNamespace(
155 generation_config="auto",
156 override_generation_config={},
157 try_get_generation_config=lambda: {
158 "presence_penalty": 1.1,
159 "frequency_penalty": 0.7,
160 "temperature": 0.9,
161 },
162 )
163
164 diff = ModelConfig.get_diff_sampling_param(fake)
165
166 assert diff["presence_penalty"] == 1.1
167 assert diff["frequency_penalty"] == 0.7
168 assert diff["temperature"] == 0.9