A symbol scan over every tracked file found 123 top-level definitions in vllm/ with zero references, including references inside strings. All of them came from features this fork deleted earlier. - Delete dead attention helpers: MLADCPManager, split_prefill_chunks, the reshape helpers, compute_varlen_chunk_metadata, the LINEAR backend's unused BailingLinearAttentionBackend, and the sparse flash-attn entry points. - Delete the CPU and AMX op wrappers from _custom_ops.py: cpu_mla_decode, cpu_mla_extend, cpu_mla_get_scheduler_metadata, gather_mla_context_cache_cpu. - Delete dead quantization helpers: awq_pack, gptq_pack, gptq_quantize_weights, get_and_maybe_dequant_weights, marlin_quant_fp8_torch, the rand_marlin_weight_*_like pair, ocp_mx_weight_dtype_and_rows, get_fp8_block_weight_scale, input_to_float8. - Delete dead model helpers: resolve_visual_encoder_outputs, run_dp_sharded_vision_model, fast_topk, get_layer_index, is_pp_missing_parameter, skip_spec_layers, KimiK3MergedQKVGateLinear, selective_scan_fn, causal_conv1d_update_torch. - Delete dead utils: format_kib, format_mib, chunk_list, prev_power_of_2, split_host_port, join_host_port, make_zmq_path, make_async_with_semaphore, is_meta_module, is_non_overlapping_and_dense, supports_xpu_graph, create_kv_caches_with_random*, and the unused has_* capability probes. - Delete the unreachable deep-gemm mega-MoE warmup path, which imported vllm.models.deepseek_v4.nvidia.model and vllm.models.kimi_k3.nvidia.model, neither of which exists anymore. - Drop the imports and the two now-empty guards left behind. Verified statically: every changed file compiles, no unused import remains, and no deleted name is referenced in vllm, tests or csrc. The runtime gates still need the Python environment rebuilt. Co-authored-by: Hinata <hinata@idihore.id> Signed-off-by: MOVZX <movzx@yahoo.com>
134 lines
3.5 KiB
Python
134 lines
3.5 KiB
Python
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
|
"""Contains helpers that are applied to collections.
|
|
|
|
This is similar in concept to the `collections` module.
|
|
"""
|
|
|
|
import math
|
|
from collections import defaultdict
|
|
from collections.abc import Callable, Hashable, Iterable, Mapping, Sequence
|
|
from typing import Generic, Literal, TypeVar, assert_never, overload
|
|
|
|
from typing_extensions import TypeIs
|
|
|
|
T = TypeVar("T")
|
|
|
|
_K = TypeVar("_K", bound=Hashable)
|
|
_V = TypeVar("_V")
|
|
|
|
|
|
class LazyDict(Mapping[str, _V], Generic[_V]):
|
|
"""Evaluates dictionary items only when they are accessed.
|
|
|
|
Adapted from: https://stackoverflow.com/a/47212782/5082708
|
|
"""
|
|
|
|
def __init__(self, factory: dict[str, Callable[[], _V]]):
|
|
self._factory = factory
|
|
self._dict: dict[str, _V] = {}
|
|
|
|
def __getitem__(self, key: str) -> _V:
|
|
if key not in self._dict:
|
|
if key not in self._factory:
|
|
raise KeyError(key)
|
|
self._dict[key] = self._factory[key]()
|
|
return self._dict[key]
|
|
|
|
def __setitem__(self, key: str, value: Callable[[], _V]):
|
|
self._factory[key] = value
|
|
|
|
def __iter__(self):
|
|
return iter(self._factory)
|
|
|
|
def __len__(self):
|
|
return len(self._factory)
|
|
|
|
|
|
def as_list(maybe_list: Iterable[T]) -> list[T]:
|
|
"""Convert iterable to list, unless it's already a list."""
|
|
return maybe_list if isinstance(maybe_list, list) else list(maybe_list)
|
|
|
|
|
|
def is_list_of(
|
|
value: object,
|
|
typ: type[T] | tuple[type[T], ...],
|
|
*,
|
|
check: Literal["first", "all"] = "first",
|
|
) -> TypeIs[list[T]]:
|
|
if not isinstance(value, list):
|
|
return False
|
|
|
|
if check == "first":
|
|
return len(value) == 0 or isinstance(value[0], typ)
|
|
elif check == "all":
|
|
return all(isinstance(v, typ) for v in value)
|
|
|
|
assert_never(check)
|
|
|
|
|
|
def is_list_of_numbers(value: object) -> bool:
|
|
"""Check every item is an int or finite float, excluding booleans."""
|
|
return isinstance(value, list) and all(
|
|
type(v) is int or (type(v) is float and math.isfinite(v)) for v in value
|
|
)
|
|
|
|
|
|
@overload
|
|
def common_prefix(items: Sequence[str]) -> str: ...
|
|
|
|
|
|
@overload
|
|
def common_prefix(items: Sequence[Sequence[T]]) -> Sequence[T]: ...
|
|
|
|
|
|
def common_prefix(items: Sequence[Sequence[T] | str]) -> Sequence[T] | str:
|
|
"""Find the longest prefix common to all items."""
|
|
if len(items) == 0:
|
|
return []
|
|
if len(items) == 1:
|
|
return items[0]
|
|
|
|
shortest = min(items, key=len)
|
|
if not shortest:
|
|
return shortest[:0]
|
|
|
|
for match_len in range(1, len(shortest) + 1):
|
|
match = shortest[:match_len]
|
|
for item in items:
|
|
if item[:match_len] != match:
|
|
return shortest[: match_len - 1]
|
|
|
|
return shortest
|
|
|
|
|
|
def flatten_2d_lists(lists: Iterable[Iterable[T]]) -> list[T]:
|
|
"""Flatten a list of lists to a single list."""
|
|
return [item for sublist in lists for item in sublist]
|
|
|
|
|
|
def full_groupby(values: Iterable[_V], *, key: Callable[[_V], _K]):
|
|
"""Unlike [`itertools.groupby`][], groups are not broken by
|
|
non-contiguous data.
|
|
"""
|
|
groups = defaultdict[_K, list[_V]](list)
|
|
|
|
for value in values:
|
|
groups[key(value)].append(value)
|
|
|
|
return groups.items()
|
|
|
|
|
|
def swap_dict_values(obj: dict[_K, _V], key1: _K, key2: _K) -> None:
|
|
"""Swap values between two keys."""
|
|
v1 = obj.get(key1)
|
|
v2 = obj.get(key2)
|
|
if v1 is not None:
|
|
obj[key2] = v1
|
|
else:
|
|
obj.pop(key2, None)
|
|
if v2 is not None:
|
|
obj[key1] = v2
|
|
else:
|
|
obj.pop(key1, None)
|