[MyPy][1/N] Fix mypy errors in some tests/ directories and enforce follow-imports=silent (#49570)

Signed-off-by: Martin Hickey <martin.hickey@ie.ibm.com>
Co-authored-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
This commit is contained in:
Martin Hickey
2026-07-30 05:02:51 -07:00
committed by GitHub
co-authored by Harry Mellor
parent 89d97d9a16
commit 38a267cdd5
30 changed files with 166 additions and 101 deletions
@@ -348,10 +348,14 @@ def test_tp_sp_generation(
if use_inductor_graph_partition and not is_torch_equal_or_newer("2.9.0.dev"):
pytest.skip("inductor graph partition is only available in PyTorch 2.9+")
# Skip FP8 SP-only test on sm89 (compute capability 8.9)
# Skip FP8 SP-only test on sm89 (compute capability 8.9).
# An unknown capability (None) is left to fail in the test body rather than
# being silently skipped here.
capability = current_platform.get_device_capability()
if (
"fp8" in model_id.lower()
and current_platform.get_device_capability() < (9, 0)
and capability is not None
and capability < (9, 0)
and (not fuse_gemm_comms)
):
pytest.skip("FP8 reduction support begins with sm90 capable devices.")
@@ -9,7 +9,7 @@ import pytest
from tests.utils import wait_for_gpu_memory_to_clear
from tests.v1.attention.utils import full_cg_backend_configs as backend_configs
from vllm import LLM, SamplingParams
from vllm.config import CompilationConfig
from vllm.config import CompilationConfig, CUDAGraphMode
from vllm.platforms import current_platform
from vllm.utils.torch_utils import is_torch_equal_or_newer
from vllm.v1.attention.backends.registry import AttentionBackendEnum
@@ -97,7 +97,9 @@ def llm_pair(request):
trust_remote_code=True,
max_model_len=1024,
max_num_seqs=128,
compilation_config=CompilationConfig(cudagraph_mode="PIECEWISE"),
compilation_config=CompilationConfig(
cudagraph_mode=CUDAGraphMode.PIECEWISE
),
generation_config="vllm",
seed=42,
)
+5 -3
View File
@@ -75,7 +75,7 @@ def test_full_graph(
monkeypatch: pytest.MonkeyPatch,
model: str,
model_kwargs: dict[str, Any],
compilation_mode: int,
compilation_mode: CompilationMode,
):
if (
"w8a8" in model
@@ -197,7 +197,7 @@ def test_custom_compile_config(
],
)
def test_fp8_kv_scale_compile(
compilation_mode: int,
compilation_mode: CompilationMode,
model: str,
backend: AttentionBackendEnum | None,
):
@@ -213,7 +213,9 @@ def test_fp8_kv_scale_compile(
run_model(compilation_mode, model, **model_kwargs)
def run_model(compile_config: int | CompilationConfig, model: str, **model_kwargs):
def run_model(
compile_config: CompilationMode | CompilationConfig, model: str, **model_kwargs
):
compilation_config = (
compile_config
if isinstance(compile_config, CompilationConfig)
+4 -2
View File
@@ -12,7 +12,9 @@ from vllm.config import CompilationConfig, CompilationMode, CUDAGraphMode
from .common import FUSION_LOG_PATTERNS, AttentionBackendCase, Matches
def run_model(compile_config: int | CompilationConfig, model: str, **model_kwargs):
def run_model(
compile_config: CompilationMode | CompilationConfig, model: str, **model_kwargs
):
"""Run a model with the given compilation config for E2E fusion tests."""
compilation_config = (
compile_config
@@ -54,7 +56,7 @@ def run_model(compile_config: int | CompilationConfig, model: str, **model_kwarg
)
# Fetch match table from each worker via RPC and sum across workers.
worker_tables = llm.llm_engine.engine_core.collective_rpc(
worker_tables: list[dict[str, int]] = llm.llm_engine.engine_core.collective_rpc(
"get_compilation_match_table"
)
combined: defaultdict[str, int] = defaultdict(int)
+3 -1
View File
@@ -1,6 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from typing import get_args
from transformers import PretrainedConfig
from vllm.config.speculative import MTPModelTypes, SpeculativeConfig
@@ -34,7 +36,7 @@ def test_bailing_hybrid_mtp_hf_config_override():
assert overridden.model_type == "bailing_hybrid_mtp"
assert overridden.architectures == ["BailingMoeV25MTPModel"]
assert overridden.n_predict == 1
assert "bailing_hybrid_mtp" in MTPModelTypes.__args__
assert "bailing_hybrid_mtp" in get_args(MTPModelTypes)
def test_bailing_hybrid_mtp_model_arch_config():
+2 -2
View File
@@ -15,13 +15,13 @@ from vllm.v1.attention.backends.registry import AttentionBackendEnum
def test_mm_encoder_attn_backend_str_conversion():
config = MultiModalConfig(mm_encoder_attn_backend="FLASH_ATTN")
config = MultiModalConfig(mm_encoder_attn_backend="FLASH_ATTN") # type: ignore[arg-type]
assert config.mm_encoder_attn_backend == AttentionBackendEnum.FLASH_ATTN
def test_mm_encoder_attn_backend_invalid():
with pytest.raises(ValueError):
MultiModalConfig(mm_encoder_attn_backend="not_a_backend")
MultiModalConfig(mm_encoder_attn_backend="not_a_backend") # type: ignore[arg-type]
def test_mm_encoder_attn_backend_hash_updates():
@@ -14,6 +14,7 @@ methods only.
"""
import logging
from typing import Literal
import pytest
from transformers import PretrainedConfig
@@ -77,7 +78,7 @@ def test_override_ignores_missing_attribute(vllm_caplog: pytest.LogCaptureFixtur
@pytest.mark.cpu_test
@pytest.mark.parametrize("method", ["eagle", "eagle3"])
def test_eagle_draft_inherits_target_max_model_len(
method: str, vllm_caplog: pytest.LogCaptureFixture
method: Literal["eagle", "eagle3"], vllm_caplog: pytest.LogCaptureFixture
):
target_model_config = ModelConfig(LLAMA3_TARGET)
assert target_model_config.max_model_len > 2048
@@ -285,7 +285,7 @@ class TestPromptBuilding:
)
for i, exp in enumerate(expected):
assert engine_inputs[i]["prompt_token_ids"] == exp
assert engine_inputs[i]["prompt_token_ids"] == exp # type: ignore[typeddict-item]
class TestGeneration:
@@ -45,7 +45,7 @@ class ServerConfig(TypedDict, total=False):
model: str
arguments: list[str]
model_arg: str
tool_parser: ToolParser
tool_parser: type[ToolParser]
CONFIGS: dict[str, ServerConfig] = {
@@ -329,4 +329,5 @@ def test_weight_transfer_config_backend():
)
config = llm.llm_engine.vllm_config.weight_transfer_config
assert config is not None
assert config.backend == "nccl"
@@ -35,10 +35,12 @@ def _apply_qk_norm_rope(
q_by_head = q.view(*q.shape[:-1], q.shape[-1] // head_dim, head_dim)
q_by_head = q_norm.forward_native(q_by_head)
assert isinstance(q_by_head, torch.Tensor)
q = q_by_head.view(q.shape)
k_by_head = k.view(*k.shape[:-1], k.shape[-1] // head_dim, head_dim)
k_by_head = k_norm.forward_native(k_by_head)
assert isinstance(k_by_head, torch.Tensor)
k = k_by_head.view(k.shape)
q, k = rope.forward_native(positions, q, k)
+3 -4
View File
@@ -34,10 +34,9 @@ NUM_HEADS = [16]
@pytest.fixture
def _fp8_attention():
"""Create FP8-enabled MMEncoderAttention via config."""
from types import SimpleNamespace
from unittest.mock import patch
from unittest.mock import MagicMock, patch
from vllm.config import VllmConfig, set_current_vllm_config
from vllm.config import ModelConfig, VllmConfig, set_current_vllm_config
from vllm.config.multimodal import MultiModalConfig
if not is_flashinfer_cudnn_fp8_prefill_attn_supported():
@@ -45,7 +44,7 @@ def _fp8_attention():
mm_config = MultiModalConfig(mm_encoder_attn_dtype="fp8")
vllm_config = VllmConfig()
vllm_config.model_config = SimpleNamespace(multimodal_config=mm_config)
vllm_config.model_config = MagicMock(spec=ModelConfig, multimodal_config=mm_config)
# MMEncoderAttention reads torch.get_default_dtype() during init
# to determine the output dtype. In real model loading this is bf16.
+5 -6
View File
@@ -4,8 +4,7 @@
import contextlib
import json
from types import SimpleNamespace
from unittest.mock import patch
from unittest.mock import MagicMock, patch
import pytest
import torch
@@ -48,7 +47,7 @@ def _build_attention(mm_config, attn_backend=None):
invokes ``process_weights_after_loading`` to simulate the model loader's
auto-scan. Yields ``None`` if FlashInfer cuDNN is not available.
"""
from vllm.config import VllmConfig, set_current_vllm_config
from vllm.config import ModelConfig, VllmConfig, set_current_vllm_config
from vllm.model_executor.layers.attention.mm_encoder_attention import (
MMEncoderAttention,
)
@@ -65,7 +64,7 @@ def _build_attention(mm_config, attn_backend=None):
return
vllm_config = VllmConfig()
vllm_config.model_config = SimpleNamespace(multimodal_config=mm_config)
vllm_config.model_config = MagicMock(spec=ModelConfig, multimodal_config=mm_config)
with (
set_current_vllm_config(vllm_config),
@@ -212,7 +211,7 @@ def test_aiter_static_scales_loaded(tmp_path) -> None:
def test_static_scales_missing_layer(tmp_path) -> None:
"""Verify error when requested layer is not in the scale file."""
from vllm.config import VllmConfig, set_current_vllm_config
from vllm.config import ModelConfig, VllmConfig, set_current_vllm_config
from vllm.config.multimodal import MultiModalConfig
from vllm.v1.attention.backends.registry import AttentionBackendEnum
@@ -228,7 +227,7 @@ def test_static_scales_missing_layer(tmp_path) -> None:
mm_encoder_fp8_scale_path=str(scale_file),
)
vllm_config = VllmConfig()
vllm_config.model_config = SimpleNamespace(multimodal_config=mm_config)
vllm_config.model_config = MagicMock(spec=ModelConfig, multimodal_config=mm_config)
from vllm.model_executor.layers.attention.mm_encoder_attention import (
MMEncoderAttention,
+24 -9
View File
@@ -12,6 +12,7 @@ import vllm._custom_ops as ops
from vllm.model_executor.layers.mamba.ops.cpu import gdn_attention
from vllm.platforms import current_platform
from vllm.utils.torch_utils import set_random_seed
from vllm.v1.attention.backends.gdn_attn import GDNAttentionMetadata
if not current_platform.is_cpu():
pytest.skip("skipping CPU-only tests", allow_module_level=True)
@@ -452,12 +453,17 @@ def test_spec_aware_mixed_routing_preserves_token_order(
spec_indices = torch.tensor([0, 2])
nonspec_indices = torch.tensor([1, 3])
metadata = types.SimpleNamespace(
metadata = GDNAttentionMetadata(
num_prefills=1,
num_prefill_tokens=0,
num_decodes=0,
num_decode_tokens=0,
num_spec_decodes=0,
num_spec_decode_tokens=0,
num_actual_tokens=0,
spec_sequence_masks=torch.ones(1, dtype=torch.bool),
spec_token_indx=spec_indices,
non_spec_token_indx=nonspec_indices,
num_prefills=1,
num_decodes=0,
)
routed = []
@@ -501,13 +507,16 @@ def test_spec_aware_nonspec_materializes_state_indices(
state_indices = block_table[:, 0]
assert not state_indices.is_contiguous()
metadata = types.SimpleNamespace(
non_spec_state_indices_tensor=state_indices,
non_spec_query_start_loc=torch.tensor([0, 2, 4], dtype=torch.int32),
num_decodes=0,
num_decode_tokens=0,
metadata = GDNAttentionMetadata(
num_prefills=2,
num_prefill_tokens=4,
num_decodes=0,
num_decode_tokens=0,
num_spec_decodes=0,
num_spec_decode_tokens=0,
num_actual_tokens=4,
non_spec_state_indices_tensor=state_indices,
non_spec_query_start_loc=torch.tensor([0, 2, 4], dtype=torch.int32),
has_initial_state=torch.tensor([False, False]),
)
@@ -575,8 +584,14 @@ def test_spec_forward_prepares_native_conv_metadata(
state_indices = block_table[:, 0]
accepted_counts = torch.tensor([1, 4], dtype=torch.int32)
assert not state_indices.is_contiguous()
metadata = types.SimpleNamespace(
metadata = GDNAttentionMetadata(
num_prefills=0,
num_prefill_tokens=0,
num_decodes=0,
num_decode_tokens=0,
num_spec_decodes=2,
num_spec_decode_tokens=8,
num_actual_tokens=8,
spec_state_indices_tensor=block_table,
spec_query_start_loc=torch.tensor([0, 4, 8], dtype=torch.int32),
num_accepted_tokens=accepted_counts,
@@ -174,7 +174,9 @@ def test_forward_core_split_matches_unified(
batch = BatchSpec(seq_lens=seq_lens, query_lens=query_lens)
builder = GDNAttentionMetadataBuilder(
kv_cache_spec=MambaSpec(
# GDNAttentionMetadataBuilder declares kv_cache_spec as AttentionSpec but
# asserts isinstance(kv_cache_spec, MambaSpec). MambaSpec is correct here.
kv_cache_spec=MambaSpec( # type: ignore[arg-type]
block_size=BLOCK_SIZE, shapes=((16, 64),), dtypes=(torch.float16,)
),
layer_names=[PREFIX],
@@ -198,6 +200,7 @@ def test_forward_core_split_matches_unified(
# Full-batch chunk metadata for the unified reference path, built the same
# way the builder would for a non-split batch (backend-matched).
cu_full = meta_split.non_spec_query_start_loc
assert cu_full is not None
if builder.gdn_prefill_backend == "cutedsl":
from vllm.model_executor.layers.mamba.ops.gdn_chunk_cutedsl import (
prepare_metadata_cutedsl,
@@ -227,6 +230,7 @@ def test_forward_core_split_matches_unified(
)
# Size the state pools from the indices the builder actually produced.
assert meta_split.non_spec_state_indices_tensor is not None
pool_size = int(meta_split.non_spec_state_indices_tensor.max().item()) + 1
conv_state_shape, temporal_state_shape = (
MambaStateShapeCalculator.gated_delta_net_state_shape(
@@ -21,7 +21,9 @@ The kernel must also no-op when ``src_col < 0`` (fresh request) or
from __future__ import annotations
from collections.abc import Callable
from types import SimpleNamespace
from typing import Any
import numpy as np
import torch
@@ -31,6 +33,8 @@ from vllm.platforms import current_platform
from vllm.v1.worker import mamba_utils as worker_mamba_utils
from vllm.v1.worker.mamba_utils import precopy_mamba_align_fused_kernel
_parametrize: Callable[..., Callable[[Any], Any]]
try:
import pytest
@@ -40,17 +44,18 @@ try:
)
_parametrize = pytest.mark.parametrize
except ModuleNotFoundError: # allow running directly as ``python <thisfile>``
pytest = None
def _cuda_required(fn):
return fn
def _parametrize(_name, _values):
def _no_parametrize(_name, _values):
def _deco(fn):
return fn
return _deco
_parametrize = _no_parametrize
NUM_LAYERS = 3
CONV_WIDTH = 4 # conv_kernel - 1 + num_spec
@@ -308,8 +313,10 @@ def _make_preprocess_case(token_bias):
def test_preprocess_fused_align_matches_scalar_bookkeeping(monkeypatch, token_bias):
block_size = 4
mamba_spec = SimpleNamespace(block_size=block_size, num_speculative_blocks=1)
cache_config = SimpleNamespace(enable_prefix_caching=True)
kv_cache_config = SimpleNamespace()
# Fakes stand in for real config/context objects. The fused path tests
# below only touch the attributes preprocess_mamba actually reads.
cache_config: Any = SimpleNamespace(enable_prefix_caching=True)
kv_cache_config: Any = SimpleNamespace()
scalar_copy_calls = []
def fake_collect(
@@ -340,7 +347,7 @@ def test_preprocess_fused_align_matches_scalar_bookkeeping(monkeypatch, token_bi
scalar_case = _make_preprocess_case(token_bias)
fused_case = _make_preprocess_case(token_bias)
scalar_copy_bufs = SimpleNamespace(
scalar_copy_bufs: Any = SimpleNamespace(
mamba_group_ids=[0],
mamba_spec=mamba_spec,
offset=0,
@@ -357,8 +364,8 @@ def test_preprocess_fused_align_matches_scalar_bookkeeping(monkeypatch, token_bi
copy_bufs=scalar_copy_bufs,
)
ctx = _FakePrecopyContext(len(fused_case[1].req_ids))
fused_copy_bufs = SimpleNamespace(
ctx: Any = _FakePrecopyContext(len(fused_case[1].req_ids))
fused_copy_bufs: Any = SimpleNamespace(
mamba_group_ids=[0],
mamba_spec=mamba_spec,
offset=0,
@@ -261,7 +261,7 @@ def test_mistral_function_calling(vllm_runner, model: str, dtype: str) -> None:
model_output = outputs[0].outputs[0].text.strip()
assert model_output.startswith(tool_parser.bot_token), model_output
parsed_message = tool_parser.extract_tool_calls(model_output, None)
parsed_message = tool_parser.extract_tool_calls(model_output, None) # type: ignore[arg-type]
assert parsed_message.tools_called
@@ -304,7 +304,7 @@ def test_mistral_function_call_nested_json():
model_output = f"{parser.bot_token}get_current_weather{json.dumps(args_dict)}"
parsed = parser.extract_tool_calls(model_output, None)
parsed = parser.extract_tool_calls(model_output, None) # type: ignore[arg-type]
# Assertions: the tool call is detected and the full nested JSON is parsed
# without truncation.
@@ -337,7 +337,7 @@ def test_mistral_function_call_nested_json():
]
)
parsed = parser.extract_tool_calls(model_output, None)
parsed = parser.extract_tool_calls(model_output, None) # type: ignore[arg-type]
# Assertions: the tool call is detected and the full nested JSON is parsed
# without truncation.
@@ -323,7 +323,7 @@ def test_bitsandbytes_passes_revision_by_name():
return_value=["/folder/model.safetensors"],
),
):
bnb.BitsAndBytesModelLoader._prepare_weights(fake_self, "org/model", "myrev")
bnb.BitsAndBytesModelLoader._prepare_weights(fake_self, "org/model", "myrev") # type: ignore[arg-type]
mock_idx.assert_called_once()
assert mock_idx.call_args.kwargs.get("revision") == "myrev"
@@ -29,7 +29,7 @@ class BgeM3SparseEmbeddingsProcessor(
self.online_requests: dict[str, SparseEmbeddingCompletionRequestMixin] = {}
self.renderer: BaseRenderer = renderer
self.default_pooling_params = {}
pooler_config: PoolerConfig = vllm_config.model_config.pooler_config
pooler_config: PoolerConfig | None = vllm_config.model_config.pooler_config
if pooler_config is not None:
for param in ["use_activation", "dimensions"]:
if getattr(pooler_config, param, None) is None:
@@ -91,11 +91,11 @@ class BgeM3SparseEmbeddingsProcessor(
) -> list[SparseEmbeddingTokenWeight]:
token_ids = sparse_embedding.keys()
token_weights = sparse_embedding.values()
tokens = [None] * len(token_ids)
tokens: Sequence[str | None] = [None] * len(token_ids)
if return_tokens and self.renderer is not None:
tokens = convert_ids_list_to_tokens(
self.renderer.get_tokenizer(), token_ids
self.renderer.get_tokenizer(), list(token_ids)
)
sparse_embedding_output: list[SparseEmbeddingTokenWeight] = []
for token_id, weight, token in zip(token_ids, token_weights, tokens):
@@ -170,7 +170,7 @@ def load_image(
list of meta info for each image in *file_paths*
"""
imgs = []
imgs: list[np.ndarray] = []
metas = []
temporal_coords = []
location_coords = []
@@ -209,11 +209,11 @@ def load_image(
except Exception:
logger.exception("Could not extract timestamp for %s", file)
imgs = np.stack(imgs, axis=0) # num_frames, H, W, C
imgs = np.moveaxis(imgs, -1, 0).astype("float32") # C, num_frames, H, W
imgs = np.expand_dims(imgs, axis=0) # add batch di
stacked = np.stack(imgs, axis=0) # num_frames, H, W, C
stacked = np.moveaxis(stacked, -1, 0).astype("float32") # C, num_frames, H, W
stacked = np.expand_dims(stacked, axis=0) # add batch di
return imgs, temporal_coords, location_coords, metas
return stacked, temporal_coords, location_coords, metas
class PrithviMultimodalDataProcessor(IOProcessor[ImagePrompt, ImageRequestOutput]):
@@ -327,7 +327,7 @@ class PrithviMultimodalDataProcessor(IOProcessor[ImagePrompt, ImageRequestOutput
}
)
return prompts
return prompts # type: ignore[return-value]
def post_process(
self,
@@ -6,6 +6,8 @@ from vllm.platforms.interface import Platform, PlatformEnum
if TYPE_CHECKING:
from vllm.config import VllmConfig
from vllm.v1.attention.backends.registry import AttentionBackendEnum
from vllm.v1.attention.selector import AttentionSelectorConfig
else:
VllmConfig = None
@@ -20,16 +22,11 @@ class DummyPlatform(Platform):
def check_and_update_config(cls, vllm_config: VllmConfig) -> None:
vllm_config.compilation_config.custom_ops = ["all"]
@classmethod
def get_attn_backend_cls(
self,
backend_name,
head_size,
dtype,
kv_cache_dtype,
block_size,
use_mla,
has_sink,
use_sparse,
use_mm_prefix,
):
cls,
selected_backend: "AttentionBackendEnum",
attn_selector_config: "AttentionSelectorConfig",
num_heads: int | None = None,
) -> str:
return "vllm_add_dummy_platform.dummy_attention_backend.DummyAttentionBackend" # noqa E501
@@ -17,7 +17,9 @@ class DummyStatLogger(StatLoggerBase):
self.logged = False
self.engine_initialized = False
def record(self, scheduler_stats, iteration_stats, mm_cache_stats, engine_idx):
def record(
self, scheduler_stats, iteration_stats, mm_cache_stats=None, engine_idx=0
):
self.recorded.append(
(scheduler_stats, iteration_stats, mm_cache_stats, engine_idx)
)
@@ -92,7 +92,7 @@ def run_multimodal_gguf_test(
num_logprobs: int,
):
# Load images at runtime (inside subprocess) to avoid pickle issues
images = [ImageAsset(name).pil_image for name in model.image_names]
images = [ImageAsset(name).pil_image for name in model.image_names] # type: ignore[arg-type]
size_factors = [0.25, 0.5, 1.0]
inputs_per_image = [
(
@@ -31,6 +31,7 @@ async def test_hf_resolver_with_direct_path():
assert hf_resolver is not None
lora_request = await hf_resolver.resolve_lora(LORA_REPO_MODEL_NAME, LORA_REPO)
assert lora_request is not None
assert lora_request.lora_name == LORA_REPO
assert REPO_DOWNLOAD_DIR in lora_request.lora_path
assert "adapter_config.json" in os.listdir(lora_request.lora_path)
@@ -30,6 +30,7 @@ class DummyDraftProposer:
Args:
vllm_config: vLLM configuration containing model and speculative settings.
"""
assert vllm_config.speculative_config is not None
self.num_speculative_tokens = (
vllm_config.speculative_config.num_speculative_tokens
)
+2 -2
View File
@@ -44,7 +44,7 @@ class _ProcWithUnpack:
def test_get_processor_kwargs_from_processor_unpack_path_returns_full_union():
proc = _ProcWithUnpack()
keys = get_processor_kwargs_keys(get_processor_kwargs_type(proc))
keys = get_processor_kwargs_keys(get_processor_kwargs_type(proc)) # type: ignore[arg-type]
_assert_has_all_expected(keys)
@@ -63,5 +63,5 @@ def test_get_processor_kwargs_from_processor_module_scan_returns_full_union():
assert hasattr(mod, "_FakeProcessorKwargs")
proc = _ProcWithoutUnpack()
keys = get_processor_kwargs_keys(get_processor_kwargs_type(proc))
keys = get_processor_kwargs_keys(get_processor_kwargs_type(proc)) # type: ignore[arg-type]
_assert_has_all_expected(keys)
+5 -3
View File
@@ -12,13 +12,14 @@ import pytest
from vllm import SamplingParams
from vllm.config import VllmConfig
from vllm.config.parallel import DataParallelBackend
from vllm.engine.arg_utils import AsyncEngineArgs
from vllm.inputs import PromptType
from vllm.outputs import RequestOutput
from vllm.platforms import current_platform
from vllm.sampling_params import RequestOutputKind
from vllm.v1.engine.async_llm import AsyncLLM
from vllm.v1.engine.core_client import DPAsyncMPClient
from vllm.v1.engine.core_client import DPLBAsyncMPClient
from vllm.v1.metrics.loggers import StatLoggerBase
from vllm.v1.metrics.stats import IterationStats, MultiModalCacheStats, SchedulerStats
@@ -82,7 +83,7 @@ async def generate(
async def test_load(
model: str,
output_kind: RequestOutputKind,
data_parallel_backend: str,
data_parallel_backend: DataParallelBackend,
async_scheduling: bool,
):
if async_scheduling and data_parallel_backend == "ray":
@@ -162,7 +163,8 @@ async def test_load(
assert not engine.output_processor.has_unfinished_requests()
# testing internals here which may break
core_client: DPAsyncMPClient = engine.engine_core
core_client = engine.engine_core
assert isinstance(core_client, DPLBAsyncMPClient)
# the engines only synchronize stopping every N steps so
# allow a small amount of time here.
for _ in range(10):
+1 -1
View File
@@ -61,7 +61,7 @@ async def test_run_eagle_dp(monkeypatch: pytest.MonkeyPatch, attn_backend: str):
data_parallel_backend="mp", # ray takes more time
trust_remote_code=True,
max_model_len=16384,
attention_config={"backend": attn_backend},
attention_config={"backend": attn_backend}, # type: ignore[arg-type]
)
eagle_engine_args = replace(
+8 -3
View File
@@ -9,7 +9,7 @@ import pytest
from tests.v1.shutdown.utils import SHUTDOWN_TEST_TIMEOUT_SEC
from vllm import SamplingParams
from vllm.engine.arg_utils import AsyncEngineArgs
from vllm.inputs import TokensPrompt
from vllm.inputs import ExplicitEncoderDecoderPrompt
from vllm.sampling_params import RequestOutputKind
from vllm.v1.engine.async_llm import AsyncLLM
from vllm.v1.engine.exceptions import EngineGenerateError
@@ -29,9 +29,14 @@ async def test_async_llm_processor_error(model: str) -> None:
async_llm = AsyncLLM.from_engine_args(engine_args)
async def generate(request_id: str):
# [] is not allowed and will raise a ValueError in Processor.
# An encoder/decoder prompt is rejected by the Processor for a
# decoder only model.
generator = async_llm.generate(
TokensPrompt([]), request_id=request_id, sampling_params=SamplingParams()
ExplicitEncoderDecoderPrompt(
encoder_prompt="Hello my name is", decoder_prompt=None
),
request_id=request_id,
sampling_params=SamplingParams(),
)
try:
async for _ in generator:
+41 -24
View File
@@ -21,34 +21,55 @@ import sys
import regex as re
# Paths verified clean under follow_imports="silent". Matched before
# SEPARATE_GROUPS, so these files join the default group and are checked at the
# stricter setting even while a parent directory remains in SEPARATE_GROUPS.
#
# Fixing a directory means moving it from SEPARATE_GROUPS to here. Without that
# move the fixes are not enforced because "tests" claims every file below it.
SILENT_GROUPS = [
"tests/compile/correctness_e2e",
"tests/compile/fullgraph",
"tests/compile/fusions_e2e",
"tests/config",
"tests/entrypoints/generate",
"tests/entrypoints/tool_parsers",
"tests/entrypoints/weight_transfer",
"tests/kernels/core",
"tests/kernels/mamba",
"tests/models/language",
"tests/models/quantization",
"tests/plugins/bge_m3_sparse_plugin",
"tests/plugins/prithvi_io_processor_plugin",
"tests/plugins/vllm_add_dummy_platform",
"tests/plugins/vllm_add_dummy_stat_logger",
"tests/plugins_tests/gguf",
"tests/plugins_tests/lora_resolvers",
"tests/spec_decode",
"tests/transformers_utils",
"tests/v1/distributed",
"tests/v1/shutdown",
]
# After fixing errors resulting from changing follow_imports
# from "skip" to "silent", remove its directory from SEPARATE_GROUPS.
# from "skip" to "silent", move its directory to SILENT_GROUPS.
SEPARATE_GROUPS = [
"tests",
"tests/benchmarks",
"tests/compile/correctness_e2e",
"tests/config",
"tests/compile",
"tests/compile/fullgraph",
"tests/compile/fusions_e2e",
"tests/compile/passes",
"tests/distributed",
"tests/entrypoints/anthropic",
"tests/entrypoints/generate",
"tests/entrypoints/llm",
"tests/entrypoints/multimodal",
"tests/entrypoints/openai",
"tests/entrypoints/pooling",
"tests/entrypoints/serve",
"tests/entrypoints/speech_to_text",
"tests/entrypoints/tool_parsers",
"tests/entrypoints/unit_tests",
"tests/entrypoints/weight_transfer",
"tests/kernels",
"tests/kernels/attention",
"tests/kernels/core",
"tests/kernels/helion",
"tests/kernels/mamba",
"tests/kernels/moe",
"tests/kernels/quantization",
"tests/lora",
@@ -57,34 +78,23 @@ SEPARATE_GROUPS = [
"tests/model_executor/model_loader",
"tests/models",
"tests/models/test_initialization.py",
"tests/models/language",
"tests/models/multimodal",
"tests/models/quantization",
"tests/multimodal",
"tests/parser",
"tests/plugins_tests/gguf",
"tests/plugins_tests/lora_resolvers",
"tests/plugins/bge_m3_sparse_plugin",
"tests/plugins/prithvi_io_processor_plugin",
"tests/plugins/vllm_add_dummy_platform",
"tests/plugins/vllm_add_dummy_stat_logger",
"tests/plugins_tests",
"tests/quantization",
"tests/reasoning",
"tests/renderers",
"tests/samplers",
"tests/spec_decode",
"tests/tokenizers_",
"tests/tool_parsers",
"tests/tool_use",
"tests/transformers_utils",
"tests/utils_",
"tests/v1",
"tests/v1/attention",
"tests/v1/core",
"tests/v1/cudagraph",
"tests/v1/determinism",
"tests/v1/distributed",
"tests/v1/e2e",
"tests/v1/ec_connector",
"tests/v1/engine",
@@ -94,7 +104,6 @@ SEPARATE_GROUPS = [
"tests/v1/logits_processors",
"tests/v1/metrics",
"tests/v1/sample",
"tests/v1/shutdown",
"tests/v1/simple_kv_offload",
"tests/v1/spec_decode",
"tests/v1/streaming_input",
@@ -142,14 +151,22 @@ def group_files(changed_files: list[str]) -> dict[str, list[str]]:
A dictionary mapping file group names to lists of changed files.
"""
exclude_pattern = re.compile(f"^{'|'.join(EXCLUDE)}.*")
file_groups = {"": []}
silent_pattern = re.compile(f"^({'|'.join(SILENT_GROUPS)}).*")
file_groups: dict[str, list[str]] = {"": []}
file_groups.update({k: [] for k in SEPARATE_GROUPS})
# Longest path first so a sub-directory is not shadowed by its parent
separate_groups = sorted(SEPARATE_GROUPS, key=len, reverse=True)
for changed_file in changed_files:
# Skip files which should be ignored completely
if exclude_pattern.match(changed_file):
continue
# Already-fixed paths go in the default group, which runs at the
# stricter follow_imports setting from pyproject.toml
if silent_pattern.match(changed_file):
file_groups[""].append(changed_file)
continue
# Group files by mypy call
for directory in SEPARATE_GROUPS:
for directory in separate_groups:
if re.match(f"^{directory}.*", changed_file):
file_groups[directory].append(changed_file)
break