Remove Python 3.10 support now that it is EOL (#60402)

Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Harry Mellor
2026-10-08 02:30:52 -07:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 0004536dd0
commit 21d9758459
67 changed files with 141 additions and 219 deletions
+6 -22
View File
@@ -199,29 +199,13 @@ repos:
additional_dependencies: [PyYAML, regex]
verbose: true # full-scan `note:` lines are advisory, so the hook passes
require_serial: true # one full scan, not one per pre-commit file batch
- id: mypy-3.10 # TODO: Use https://github.com/pre-commit/mirrors-mypy when mypy setup is less awkward
name: Run mypy for Python 3.10
entry: python tools/pre_commit/mypy.py "3.10"
<<: &mypy_common
language: python
types_or: [python, pyi]
require_serial: true
additional_dependencies: ["mypy==1.20.2", regex, types-cachetools, types-setuptools, types-PyYAML, types-requests, types-torch, pydantic]
- id: mypy-3.11 # TODO: Use https://github.com/pre-commit/mirrors-mypy when mypy setup is less awkward
name: Run mypy for Python 3.11
- id: mypy # TODO: Use https://github.com/pre-commit/mirrors-mypy when mypy setup is less awkward
name: Run mypy for the oldest supported Python version
entry: python tools/pre_commit/mypy.py "3.11"
<<: *mypy_common
stages: [manual] # Only run in CI
- id: mypy-3.12 # TODO: Use https://github.com/pre-commit/mirrors-mypy when mypy setup is less awkward
name: Run mypy for Python 3.12
entry: python tools/pre_commit/mypy.py "3.12"
<<: *mypy_common
stages: [manual] # Only run in CI
- id: mypy-3.13 # TODO: Use https://github.com/pre-commit/mirrors-mypy when mypy setup is less awkward
name: Run mypy for Python 3.13
entry: python tools/pre_commit/mypy.py "3.13"
<<: *mypy_common
stages: [manual] # Only run in CI
language: python
types_or: [python, pyi]
require_serial: true
additional_dependencies: ["mypy==1.20.2", regex, types-cachetools, types-setuptools, types-PyYAML, types-requests, types-torch, pydantic]
- id: png-lint
name: Lint PNG exports from excalidraw
entry: tools/pre_commit/png-lint.sh
-3
View File
@@ -114,9 +114,6 @@ pre-commit run --all-files
# Run a specific hook:
pre-commit run ruff-check --all-files
# Run mypy as it is in CI:
pre-commit run mypy-3.12 --all-files --hook-stage manual
```
The line length limit for Python code is 88 characters. If you are not sure, use pre-commit to check.
+21 -27
View File
@@ -46,7 +46,7 @@ install(CODE "set(CMAKE_INSTALL_LOCAL_ONLY TRUE)" ALL_COMPONENTS)
# Supported python versions. These versions will be searched in order, the
# first match will be selected. These should be kept in sync with setup.py.
#
set(PYTHON_SUPPORTED_VERSIONS "3.10" "3.11" "3.12" "3.13" "3.14")
set(PYTHON_SUPPORTED_VERSIONS "3.11" "3.12" "3.13" "3.14")
# Supported AMD GPU architectures.
set(HIP_SUPPORTED_ARCHS "gfx906;gfx908;gfx90a;gfx942;gfx950;gfx1250;gfx1030;gfx1100;gfx1101;gfx1102;gfx1103;gfx1150;gfx1151;gfx1152;gfx1153;gfx1200;gfx1201")
@@ -134,40 +134,34 @@ endif()
#
# spinloop extension (pure CXX; must stay above the non-CUDA device branch so
# CPU builds define the target before the early return)
# This extension requires SABI 3.11 since it relies on Py_buffer support. Loading
# failure is handled gracefully on vLLM side for lower Python versions.
# Skip the target entirely on Python < 3.11 so the build doesn't break.
# This extension requires SABI 3.11 since it relies on Py_buffer support.
#
if(Python_VERSION VERSION_GREATER_EQUAL "3.11")
set(VLLM_SPINLOOP_EXT_SRC "csrc/spinloop.cpp")
set(SPINLOOP_COMPILE_FLAGS "")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64")
list(APPEND SPINLOOP_COMPILE_FLAGS "-mmwaitx")
endif()
define_extension_target(
spinloop
DESTINATION vllm
LANGUAGE CXX
SOURCES ${VLLM_SPINLOOP_EXT_SRC}
COMPILE_FLAGS ${SPINLOOP_COMPILE_FLAGS}
USE_SABI 3.11
WITH_SOABI)
set(VLLM_SPINLOOP_EXT_SRC "csrc/spinloop.cpp")
set(SPINLOOP_COMPILE_FLAGS "")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64")
list(APPEND SPINLOOP_COMPILE_FLAGS "-mmwaitx")
endif()
define_extension_target(
spinloop
DESTINATION vllm
LANGUAGE CXX
SOURCES ${VLLM_SPINLOOP_EXT_SRC}
COMPILE_FLAGS ${SPINLOOP_COMPILE_FLAGS}
USE_SABI 3.11
WITH_SOABI)
#
# fs_io extension (pure CXX; must stay above the non-CUDA device branch
# so CPU builds define the target before the early return).
# GIL-releasing filesystem helpers for FileSystemTierManager.
#
if(Python_VERSION VERSION_GREATER_EQUAL "3.11")
define_extension_target(
fs_io_C
DESTINATION vllm
LANGUAGE CXX
SOURCES csrc/fs_io.cpp
USE_SABI 3.11
WITH_SOABI)
endif()
define_extension_target(
fs_io_C
DESTINATION vllm
LANGUAGE CXX
SOURCES csrc/fs_io.cpp
USE_SABI 3.11
WITH_SOABI)
#
# Forward the non-CUDA device extensions to external CMake scripts.
+1 -1
View File
@@ -13,7 +13,7 @@
# vllm-dev: used for development
#
# Build arguments:
# PYTHON_VERSION=3.13|3.12 (default)|3.11|3.10
# PYTHON_VERSION=3.13|3.12 (default)|3.11
# VLLM_CPU_X86=false (default)|true (for cross-compilation)
# VLLM_CPU_ARM_BF16=false (default)|true (for cross-compilation)
#
+1 -9
View File
@@ -74,7 +74,7 @@ For an optimized workflow when iterating on C++/CUDA kernels, see the [Increment
For JIT kernel warmup conventions, see [JIT Kernel Warmup](./jit_kernel_warmup.md).
!!! tip
vLLM is compatible with Python versions 3.10 to 3.13. However, vLLM's default [Dockerfile](../../docker/Dockerfile) ships with Python 3.12 and tests in CI (except `mypy`) are run with Python 3.12.
vLLM is compatible with Python versions 3.11 to 3.14. However, vLLM's default [Dockerfile](../../docker/Dockerfile) ships with Python 3.12 and tests in CI (except `mypy`) are run with Python 3.12.
Therefore, we recommend developing with Python 3.12 to minimise the chance of your local environment clashing with our CI environment.
@@ -102,14 +102,6 @@ integration, use the configuration files in `tools/pre_commit/`:
pre-commit run -a # runs on all files (short for --all-files)
```
---
Some `pre-commit` hooks only run in CI. If you need to, you can run them locally with:
```bash
pre-commit run --hook-stage manual mypy-3.11
```
### Documentation
MkDocs is a fast, simple and downright gorgeous static site generator that's geared towards building project documentation. Documentation source files are written in Markdown, and configured with a single YAML configuration file, [mkdocs.yaml](../../mkdocs.yaml).
+4 -4
View File
@@ -37,7 +37,7 @@ See the vLLM SkyPilot YAML for serving, [serving.yaml](https://github.com/skypil
HF_TOKEN: <your-huggingface-token> # Change to your own huggingface token, or use --env to pass.
setup: |
conda create -n vllm python=3.10 -y
conda create -n vllm python=3.12 -y
conda activate vllm
pip install vllm==0.4.0.post1
@@ -136,7 +136,7 @@ SkyPilot can scale up the service to multiple service replicas with built-in aut
HF_TOKEN: <your-huggingface-token> # Change to your own huggingface token, or use --env to pass.
setup: |
conda create -n vllm python=3.10 -y
conda create -n vllm python=3.12 -y
conda activate vllm
pip install vllm==0.4.0.post1
@@ -248,7 +248,7 @@ This will scale the service up to when the QPS exceeds 2 for each replica.
HF_TOKEN: <your-huggingface-token> # Change to your own huggingface token, or use --env to pass.
setup: |
conda create -n vllm python=3.10 -y
conda create -n vllm python=3.12 -y
conda activate vllm
pip install vllm==0.4.0.post1
@@ -293,7 +293,7 @@ It is also possible to access the Llama-3 service with a separate GUI frontend,
cpus: 2
setup: |
conda create -n vllm python=3.10 -y
conda create -n vllm python=3.12 -y
conda activate vllm
# Install Gradio for web UI.
+1 -1
View File
@@ -30,7 +30,7 @@ When open a Github issue about the CPU backend, please add `[CPU Backend]` in th
## Requirements
- Python: 3.10 -- 3.13
- Python: 3.11 -- 3.14
=== "Intel/AMD x86"
+1 -1
View File
@@ -25,7 +25,7 @@ vLLM is a Python library that supports the following GPU variants. Select your G
## Requirements
- OS: Linux
- Python: 3.10 -- 3.13
- Python: 3.11 -- 3.14
!!! note
vLLM does not support Windows natively. To run vLLM on Windows, you can use the Windows Subsystem for Linux (WSL) with a compatible Linux distribution, or use some community-maintained forks, e.g. [https://github.com/SystemPanic/vllm-windows](https://github.com/SystemPanic/vllm-windows).
+1 -1
View File
@@ -8,7 +8,7 @@ This guide will help you quickly get started with vLLM to perform:
## Prerequisites
- OS: Linux
- Python: 3.10 -- 3.13
- Python: 3.11 -- 3.14
!!! note
vLLM also works on macOS with [vLLM-Metal](https://github.com/vllm-project/vllm-metal) for Apple Silicon GPU acceleration. See the [GPU installation guide](installation/gpu.md) and select the "Apple Silicon" tab.
@@ -1,6 +1,6 @@
[project]
name = "examples-online-structured-outputs"
requires-python = ">=3.10, <3.14"
requires-python = ">=3.11, <3.15"
dependencies = ["openai==1.78.1", "pydantic==2.11.4"]
version = "0.0.0"
+3 -2
View File
@@ -21,7 +21,6 @@ license-files = ["LICENSE"]
readme = "README.md"
description = "A high-throughput and memory-efficient inference and serving engine for LLMs"
classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
@@ -32,7 +31,7 @@ classifiers = [
"Topic :: Scientific/Engineering :: Artificial Intelligence",
"Topic :: Scientific/Engineering :: Information Analysis",
]
requires-python = ">=3.10,<3.15"
requires-python = ">=3.11,<3.15"
dynamic = [ "version", "dependencies", "optional-dependencies"]
[project.urls]
@@ -103,6 +102,8 @@ ignore = [
"B007",
# f-string format
"UP032",
# `StrEnum` changes `str()` and `format()` output of members
"UP042",
]
[tool.ruff.lint.pydocstyle]
-1
View File
@@ -22,7 +22,6 @@ torchcodec >= 0.14; platform_machine != "riscv64" and platform_machine != "ppc64
intel-openmp==2024.2.1; platform_machine == "x86_64"
# triton-cpu, only for x86_64 CPUs
triton @ https://github.com/triton-lang/triton-cpu/releases/download/v3.8.0/triton-3.8.0+cpu-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl ; platform_machine == "x86_64" and python_version == "3.10"
triton @ https://github.com/triton-lang/triton-cpu/releases/download/v3.8.0/triton-3.8.0+cpu-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl ; platform_machine == "x86_64" and python_version == "3.11"
triton @ https://github.com/triton-lang/triton-cpu/releases/download/v3.8.0/triton-3.8.0+cpu-cp312-abi3-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl ; platform_machine == "x86_64" and python_version >= "3.12"
+7 -7
View File
@@ -268,8 +268,8 @@ class cmake_build_ext(build_ext):
cfg = envs.CMAKE_BUILD_TYPE or default_cfg
cmake_args = [
"-DCMAKE_BUILD_TYPE={}".format(cfg),
"-DVLLM_TARGET_DEVICE={}".format(VLLM_TARGET_DEVICE),
f"-DCMAKE_BUILD_TYPE={cfg}",
f"-DVLLM_TARGET_DEVICE={VLLM_TARGET_DEVICE}",
]
verbose = envs.VERBOSE
@@ -293,7 +293,7 @@ class cmake_build_ext(build_ext):
# Pass the python executable to cmake so it can find an exact
# match.
cmake_args += ["-DVLLM_PYTHON_EXECUTABLE={}".format(sys.executable)]
cmake_args += [f"-DVLLM_PYTHON_EXECUTABLE={sys.executable}"]
# Pass the python path to cmake so it can reuse the build dependencies
# on subsequent calls to python.
@@ -305,7 +305,7 @@ class cmake_build_ext(build_ext):
# To override this, set the FETCHCONTENT_BASE_DIR environment variable.
fc_base_dir = os.path.join(ROOT_DIR, ".deps")
fc_base_dir = os.environ.get("FETCHCONTENT_BASE_DIR", fc_base_dir)
cmake_args += ["-DFETCHCONTENT_BASE_DIR={}".format(fc_base_dir)]
cmake_args += [f"-DFETCHCONTENT_BASE_DIR={fc_base_dir}"]
#
# Setup parallelism and build tool
@@ -313,13 +313,13 @@ class cmake_build_ext(build_ext):
num_jobs, nvcc_threads = self.compute_num_jobs()
if nvcc_threads:
cmake_args += ["-DNVCC_THREADS={}".format(nvcc_threads)]
cmake_args += [f"-DNVCC_THREADS={nvcc_threads}"]
if is_ninja_available():
build_tool = ["-G", "Ninja"]
cmake_args += [
"-DCMAKE_JOB_POOL_COMPILE:STRING=compile",
"-DCMAKE_JOB_POOLS:STRING=compile={}".format(num_jobs),
f"-DCMAKE_JOB_POOLS:STRING=compile={num_jobs}",
]
else:
# Default build tool to whatever cmake picks.
@@ -1374,7 +1374,7 @@ if _is_cuda() or _is_hip():
# copying the relevant .py files from the source repository.
ext_modules.append(CMakeExtension(name="vllm.triton_kernels", optional=True))
if not _is_xpu() and sys.version_info >= (3, 11):
if not _is_xpu():
ext_modules.append(CMakeExtension(name="vllm.spinloop"))
ext_modules.append(CMakeExtension(name="vllm.fs_io_C"))
@@ -630,7 +630,7 @@ async def _poll_until_api_server_running(
timeout=request_timeout,
):
return
except (aiohttp.ClientError, asyncio.TimeoutError) as exc:
except (TimeoutError, aiohttp.ClientError) as exc:
last_exc = exc
print("Test detected not started yet, sleeping for 1s")
remaining_s = deadline - time.monotonic()
+3 -3
View File
@@ -285,7 +285,7 @@ async def test_wait_timeout_completes_requests():
sigterm_sent.set()
await asyncio.wait_for(request_task, timeout=_SHUTDOWN_DETECTION_TIMEOUT)
except asyncio.TimeoutError:
except TimeoutError:
pass
finally:
state.stop_requesting = True
@@ -463,7 +463,7 @@ async def test_abort_timeout_fails_inflight_requests():
try:
await asyncio.wait_for(request_task, timeout=5)
except asyncio.TimeoutError:
except TimeoutError:
pass
finally:
state.stop_requesting = True
@@ -592,7 +592,7 @@ async def test_multi_api_server_shutdown():
try:
await asyncio.wait_for(request_task, timeout=_SHUTDOWN_DETECTION_TIMEOUT)
except asyncio.TimeoutError:
except TimeoutError:
pass
finally:
state.stop_requesting = True
@@ -579,7 +579,7 @@ async def test_serialize_and_serve_entrypoints(tmp_path):
try:
await asyncio.wait_for(fut, 180)
except asyncio.TimeoutError:
except TimeoutError:
pytest.fail("Server did not start successfully")
finally:
proc.terminate()
+3 -4
View File
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import asyncio
import mimetypes
import os
import shutil
@@ -292,7 +291,7 @@ async def test_fetch_video_http(video_url: str, num_frames: int):
try:
video_sync, metadata_sync = connector.fetch_video(video_url)
video_async, metadata_async = await connector.fetch_video_async(video_url)
except (TimeoutError, asyncio.TimeoutError) as e:
except TimeoutError as e:
pytest.skip(f"Timeout fetching video (CI network flakiness): {e}")
assert np.array_equal(video_sync, video_async)
@@ -324,7 +323,7 @@ async def test_fetch_video_http_with_dynamic_loader(
try:
video_sync, metadata_sync = connector.fetch_video(video_url)
video_async, metadata_async = await connector.fetch_video_async(video_url)
except (TimeoutError, asyncio.TimeoutError) as e:
except TimeoutError as e:
pytest.skip(f"Timeout fetching video (CI network flakiness): {e}")
assert np.array_equal(video_sync, video_async)
@@ -402,7 +401,7 @@ async def test_allowed_media_domains(video_url: str, num_frames: int):
try:
video_sync, metadata_sync = connector.fetch_video(video_url)
video_async, metadata_async = await connector.fetch_video_async(video_url)
except (TimeoutError, asyncio.TimeoutError) as e:
except TimeoutError as e:
pytest.skip(f"Timeout fetching video (CI network flakiness): {e}")
assert np.array_equal(video_sync, video_async)
+1 -1
View File
@@ -719,7 +719,7 @@ async def test_dp_pause_barrier_request_deadlock():
# Drive the staggered barrier. Old code deadlocks here.
try:
await asyncio.wait_for(client.call_utility_async("barrier"), timeout=30)
except asyncio.TimeoutError:
except TimeoutError:
for t in mid_barrier_tasks:
t.cancel()
pytest.fail(
+1 -1
View File
@@ -255,7 +255,7 @@ def main() -> int:
or os.environ.get("VLLM_BUILD_COMMIT")
or "",
"cuda": cuda_release(nvcc),
"generated_at": dt.datetime.now(dt.timezone.utc).isoformat(timespec="seconds"),
"generated_at": dt.datetime.now(dt.UTC).isoformat(timespec="seconds"),
"build_dirs": [],
"incomplete": False,
"errors": [],
+5 -1
View File
@@ -88,7 +88,11 @@ CHECK_IMPORTS = {
allowed_pattern=re.compile(r"^\s*import\s+pybase64(\s*|\s+as\s+base64\s*)$"),
),
"re": ForbiddenImport(
pattern=r"^\s*(?:import\s+re(?:$|\s|,)|from\s+re\s+import)",
# regex has no equivalent of the private sre modules
pattern=(
r"^\s*(?:import\s+re(?:$|\s|,)"
r"|from\s+re\s+import(?!(?:\s*,?\s*_(?:constants|parser))+\s*(?:#.*)?$))"
),
tip="Replace 'import re' with 'import regex as re' or 'import regex'.",
allowed_pattern=re.compile(r"^\s*import\s+regex(\s*|\s+as\s+re\s*)$"),
allowed_files={"setup.py"},
+2 -2
View File
@@ -10,7 +10,7 @@ Usage:
python tools/pre_commit/mypy.py <python_version> <changed_files...>
Args:
python_version: Python version to use (e.g., "3.10") or "local" to use
python_version: Python version to use (e.g., "3.11") or "local" to use
the local Python version.
changed_files: List of changed files to check.
@@ -152,7 +152,7 @@ def mypy(
Args:
targets: List of files or directories to check.
python_version: Python version to use (e.g., "3.10") or None to use
python_version: Python version to use (e.g., "3.11") or None to use
the default mypy version.
follow_imports: Value for the --follow-imports option or None to use
the default mypy behavior.
+2 -2
View File
@@ -253,7 +253,7 @@ async def fetch_spec_decode_metrics(
num_accepted_tokens=num_accepted_tokens,
accepted_per_pos=accepted_per_pos,
)
except (aiohttp.ClientError, asyncio.TimeoutError):
except (TimeoutError, aiohttp.ClientError):
return None
@@ -315,7 +315,7 @@ async def fetch_diffusion_metrics(
num_canvas_positions=num_canvas_positions,
num_committed_tokens=num_committed_tokens,
)
except (aiohttp.ClientError, asyncio.TimeoutError):
except (TimeoutError, aiohttp.ClientError):
return None
+2 -2
View File
@@ -8,9 +8,9 @@ from dataclasses import dataclass
from functools import partial
from pathlib import Path
from types import TracebackType
from typing import TYPE_CHECKING, ClassVar
from typing import TYPE_CHECKING, ClassVar, Self
from typing_extensions import Self, override
from typing_extensions import override
from vllm.utils.argparse_utils import FlexibleArgumentParser
from vllm.utils.collection_utils import full_groupby
+1 -2
View File
@@ -4,10 +4,9 @@ import argparse
import math
from dataclasses import dataclass, fields
from pathlib import Path
from typing import ClassVar, Literal, get_args
from typing import ClassVar, Literal, assert_never, get_args
import numpy as np
from typing_extensions import assert_never
from vllm.benchmarks.datasets import DEFAULT_NUM_PROMPTS
from vllm.utils.argparse_utils import FlexibleArgumentParser
+1 -1
View File
@@ -6,9 +6,9 @@ import signal
import subprocess
import time
from types import TracebackType
from typing import Self
import requests
from typing_extensions import Self
class ServerProcess:
+1 -2
View File
@@ -1,10 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Self
from pydantic import model_validator
from typing_extensions import Self
from vllm.config.utils import config, get_hash_factors, hash_factors
+1 -2
View File
@@ -2,11 +2,10 @@
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import os
from typing import TYPE_CHECKING, Any, Literal
from typing import TYPE_CHECKING, Any, Literal, Self
import torch
from pydantic import ConfigDict, Field, model_validator
from typing_extensions import Self
from vllm import envs
from vllm.config.utils import config
+1 -2
View File
@@ -5,13 +5,12 @@ import os
import socket
from collections.abc import Callable
from datetime import timedelta
from typing import TYPE_CHECKING, Any, Literal, overload
from typing import TYPE_CHECKING, Any, Literal, Self, overload
import regex as re
import torch
from pydantic import Field, field_validator, model_validator
from torch.distributed import ProcessGroup, ReduceOp, Store
from typing_extensions import Self
import vllm.envs as envs
from vllm.config.fault_tolerance import FaultToleranceConfig
+1 -2
View File
@@ -2,10 +2,9 @@
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import os
from typing import Any, Literal
from typing import Any, Literal, Self
from pydantic import Field, model_validator
from typing_extensions import Self
from vllm.config.utils import config
from vllm.logger import init_logger
+1 -2
View File
@@ -3,10 +3,9 @@
from collections.abc import Callable
from dataclasses import InitVar
from typing import TYPE_CHECKING, Any, ClassVar, Literal, cast
from typing import TYPE_CHECKING, Any, ClassVar, Literal, Self, cast
from pydantic import Field, field_validator
from typing_extensions import Self
from vllm.config.utils import config
from vllm.logger import init_logger
+1 -2
View File
@@ -4,10 +4,9 @@
import copy
import functools
from collections.abc import Callable, Mapping
from typing import TYPE_CHECKING, Any, Literal, get_args
from typing import TYPE_CHECKING, Any, Literal, Self, get_args
from pydantic import Field, SkipValidation, field_validator, model_validator
from typing_extensions import Self
from vllm.config import LoadConfig
from vllm.config.cache import CacheDType
+1 -2
View File
@@ -1,10 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from typing import Any, Literal
from typing import Any, Literal, Self
from pydantic import model_validator
from typing_extensions import Self
from vllm.config.utils import config
from vllm.utils.hashing import safe_hash
+1 -2
View File
@@ -2,10 +2,9 @@
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import hashlib
from typing import Literal
from typing import Literal, Self
from pydantic import Field, model_validator
from typing_extensions import Self
from vllm.config.utils import config
from vllm.logger import init_logger
+4 -8
View File
@@ -38,9 +38,7 @@ logger = init_logger(__name__)
# We prefer to use os.sched_yield as it results in tighter polling loops,
# measured to be around 3e-7 seconds. However on earlier versions of Python
# os.sched_yield() does not release the GIL, so we fall back to time.sleep(0)
USE_SCHED_YIELD = (sys.version_info[:3] >= (3, 11, 1)) or (
sys.version_info[:2] == (3, 10) and sys.version_info[2] >= 8
)
USE_SCHED_YIELD = sys.version_info[:3] >= (3, 11, 1)
def sched_yield():
@@ -52,8 +50,8 @@ def sched_yield():
def ensure_divisibility(numerator, denominator):
"""Ensure that numerator is divisible by the denominator."""
assert numerator % denominator == 0, "{} is not divisible by {}".format(
numerator, denominator
assert numerator % denominator == 0, (
f"{numerator} is not divisible by {denominator}"
)
@@ -146,9 +144,7 @@ def get_pp_indices(
try:
partitions = [int(layer) for layer in partition_list_str.split(",")]
except ValueError as err:
raise ValueError(
"Invalid partition string: {}".format(partition_list_str)
) from err
raise ValueError(f"Invalid partition string: {partition_list_str}") from err
if len(partitions) != pp_size:
raise ValueError(f"{len(partitions)=} does not match {pp_size=}.")
if sum(partitions) != num_hidden_layers:
+1 -1
View File
@@ -11,12 +11,12 @@ from typing import (
ClassVar,
Generic,
Protocol,
Self,
TypeVar,
runtime_checkable,
)
import torch
from typing_extensions import Self
if TYPE_CHECKING:
from vllm.config import VllmConfig
@@ -4,12 +4,11 @@
import pickle
from dataclasses import asdict, dataclass
from typing import TYPE_CHECKING, Any, ClassVar
from typing import TYPE_CHECKING, Any, ClassVar, Self
import pybase64 as base64
import torch
from torch.multiprocessing.reductions import rebuild_cuda_tensor, reduce_tensor
from typing_extensions import Self
from vllm import envs
from vllm.config.weight_transfer import WeightTransferConfig
@@ -15,10 +15,9 @@ in every caller.
from concurrent.futures import Future, ThreadPoolExecutor
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any, ClassVar, cast
from typing import TYPE_CHECKING, Any, ClassVar, Self, cast
import torch
from typing_extensions import Self
from vllm.distributed.weight_transfer.base import (
TrainerInitInfo,
@@ -5,10 +5,9 @@
from collections.abc import Iterator
from concurrent.futures import ThreadPoolExecutor
from dataclasses import asdict, dataclass
from typing import TYPE_CHECKING, ClassVar
from typing import TYPE_CHECKING, ClassVar, Self
import torch
from typing_extensions import Self
if TYPE_CHECKING:
from vllm.config import VllmConfig
@@ -24,7 +24,7 @@ import uuid
from collections.abc import Callable, Collection
from concurrent.futures import ThreadPoolExecutor
from dataclasses import asdict, dataclass, field
from typing import Any, ClassVar
from typing import Any, ClassVar, Self
import ray
import torch
@@ -33,7 +33,6 @@ from torch.multiprocessing.reductions import (
rebuild_cuda_tensor,
reduce_tensor,
)
from typing_extensions import Self
from vllm.distributed.weight_transfer.base import (
ParamMeta,
@@ -11,10 +11,9 @@ from collections.abc import Iterable
from concurrent.futures import ThreadPoolExecutor
from contextlib import nullcontext
from dataclasses import asdict, dataclass
from typing import TYPE_CHECKING, ClassVar
from typing import TYPE_CHECKING, ClassVar, Self
import torch
from typing_extensions import Self
if TYPE_CHECKING:
from vllm.config import VllmConfig
+2 -1
View File
@@ -17,6 +17,7 @@ from typing import (
Final,
Generic,
Literal,
Required,
TypeAlias,
TypeVar,
Union,
@@ -48,7 +49,7 @@ from PIL import Image
from pydantic import BaseModel, ConfigDict, TypeAdapter
# pydantic needs the TypedDict from typing_extensions
from typing_extensions import Required, TypedDict, override
from typing_extensions import TypedDict, override
from vllm import envs
from vllm.config import ModelConfig
+1 -1
View File
@@ -200,7 +200,7 @@ async def _probe_endpoint(
# vLLM returns 503 on EngineDeadError, so we should return
# immediately if vLLM responds with a non-200 status code.
return response.status == HTTPStatus.OK
except (aiohttp.ClientError, asyncio.TimeoutError) as e:
except (TimeoutError, aiohttp.ClientError) as e:
# Allow retry of connection errors.
logger.debug(
"Probe attempt %d/%d failed on port %d: %r",
+1 -2
View File
@@ -3,13 +3,12 @@
from collections.abc import Callable, Sequence
from pathlib import Path
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, overload
import cloudpickle
import torch.nn as nn
from pydantic import ValidationError
from tqdm.auto import tqdm
from typing_extensions import overload
from vllm.config import (
AttentionConfig,
+1 -2
View File
@@ -1,9 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from typing import TypeAlias, cast
from typing import TypeAlias, assert_never, cast
from fastapi.responses import JSONResponse, Response, StreamingResponse
from typing_extensions import assert_never
from vllm.logger import init_logger
from vllm.outputs import PoolingRequestOutput
+1 -2
View File
@@ -1,9 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from typing import cast
from typing import assert_never, cast
from fastapi.responses import JSONResponse, Response, StreamingResponse
from typing_extensions import assert_never
from vllm.exceptions import VLLMValidationError
from vllm.logger import init_logger
+2 -2
View File
@@ -1,9 +1,9 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from dataclasses import dataclass
from typing import TypeAlias
from typing import Required, TypeAlias
from typing_extensions import Required, TypedDict
from typing_extensions import TypedDict
from vllm.entrypoints.chat_utils import (
ChatCompletionContentPartImageEmbedsParam,
@@ -3,10 +3,10 @@
from http import HTTPStatus
from typing import assert_never
from fastapi import APIRouter, Depends, FastAPI, Request
from fastapi.responses import JSONResponse
from typing_extensions import assert_never
from vllm.entrypoints.serve.engine.protocol import ErrorResponse
from vllm.entrypoints.serve.tokenize.protocol import (
+2 -2
View File
@@ -3,9 +3,9 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING, Literal, TypeAlias
from typing import TYPE_CHECKING, Literal, NotRequired, TypeAlias, assert_never
from typing_extensions import NotRequired, TypedDict, assert_never
from typing_extensions import TypedDict
from vllm.exceptions import VLLMValidationError
+2 -2
View File
@@ -3,9 +3,9 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
from collections.abc import Mapping, Sequence
from typing import TYPE_CHECKING, Any, TypeAlias, TypeVar, final
from typing import TYPE_CHECKING, Any, NotRequired, TypeAlias, TypeVar, final
from typing_extensions import NotRequired, TypedDict
from typing_extensions import TypedDict
if TYPE_CHECKING:
import torch
+1 -2
View File
@@ -3,10 +3,9 @@
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Any, ClassVar, Generic, TypeVar
from typing import Any, ClassVar, Generic, Self, TypeVar
import torch
from typing_extensions import Self
from vllm.model_executor.layers.quantization.utils.quant_utils import QuantKey
@@ -3,10 +3,9 @@
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import ClassVar
from typing import ClassVar, Self
import torch
from typing_extensions import Self
from vllm.model_executor.layers.quantization.input_quant_fp8 import QuantFP8
from vllm.model_executor.layers.quantization.utils.fp8_utils import (
+1 -2
View File
@@ -6,11 +6,10 @@ import inspect
import time
import warnings
from contextlib import contextmanager, nullcontext
from typing import Any
from typing import Any, assert_never
import torch
from torch import nn
from typing_extensions import assert_never
import vllm.envs as envs
from vllm.config import (
+2 -1
View File
@@ -21,6 +21,7 @@ from typing import (
ClassVar,
Literal,
Protocol,
Self,
TypeAlias,
overload,
runtime_checkable,
@@ -31,7 +32,7 @@ import torch
import torch.nn as nn
from torch import Tensor
from transformers.models.whisper.tokenization_whisper import LANGUAGES
from typing_extensions import Self, TypeIs
from typing_extensions import TypeIs
from vllm.logger import init_logger
from vllm.model_executor.layers.quantization import QuantizationConfig
@@ -22,13 +22,12 @@ reference's out-of-vocab scheme.
import math
from collections.abc import Mapping, Sequence
from typing import Any
from typing import Any, assert_never
import numpy as np
import torch
from PIL import Image, ImageOps
from transformers import BatchFeature
from typing_extensions import assert_never
from vllm.config.multimodal import MultiModalDummyOptions
from vllm.inputs import MultiModalDataDict
+1 -1
View File
@@ -13,11 +13,11 @@ from typing import (
TypeAlias,
TypeGuard,
TypeVar,
assert_never,
)
import numpy as np
import torch
from typing_extensions import assert_never
from vllm.inputs import ModalityData, MultiModalDataDict, MultiModalUUIDDict
from vllm.utils.collection_utils import is_list_of
+2 -1
View File
@@ -13,10 +13,11 @@ from typing import (
NamedTuple,
Protocol,
TypeAlias,
assert_never,
)
import torch
from typing_extensions import TypeVar, assert_never
from typing_extensions import TypeVar
from vllm.config import SchedulerConfig
from vllm.inputs import (
+1 -1
View File
@@ -1000,7 +1000,7 @@ class HfRenderer(BaseRenderer[HfTokenizer]):
return await coro
try:
return await asyncio.wait_for(coro, timeout=timeout)
except asyncio.TimeoutError:
except TimeoutError:
self._replace_executor()
raise TimeoutError(
f"Chat template rendering timed out after "
+1 -2
View File
@@ -6,7 +6,7 @@ import math
import os
import stat
from pathlib import Path
from typing import Annotated, Any, Literal
from typing import Annotated, Any, Literal, Self
from pydantic import (
BaseModel,
@@ -19,7 +19,6 @@ from pydantic import (
field_validator,
model_validator,
)
from typing_extensions import Self
class SnapshotCompatibilityError(RuntimeError):
+2 -2
View File
@@ -24,7 +24,7 @@ import urllib.request
from collections.abc import Iterable
from contextlib import suppress
from dataclasses import dataclass
from datetime import datetime, timezone
from datetime import UTC, datetime
from pathlib import Path
from typing import NoReturn
@@ -872,7 +872,7 @@ class LocalSnapshotTools:
return SnapshotManifest(
schema_version=1,
boundary="post-engine-init-reloadable-state-released",
created_at=datetime.now(timezone.utc).isoformat(),
created_at=datetime.now(UTC).isoformat(),
artifact_bytes=self._artifact_bytes(workdir),
**identity.model_dump(),
model=source_model,
+2 -2
View File
@@ -4,10 +4,10 @@ import contextlib
from dataclasses import dataclass, field
from functools import lru_cache
from pathlib import Path
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, assert_never
import huggingface_hub
from typing_extensions import TypeVar, assert_never
from typing_extensions import TypeVar
from vllm import envs
from vllm.logger import init_logger
+1 -1
View File
@@ -69,7 +69,7 @@ def is_usage_stats_enabled():
def _get_current_timestamp_ns() -> int:
return int(datetime.datetime.now(datetime.timezone.utc).timestamp() * 1e9)
return int(datetime.datetime.now(datetime.UTC).timestamp() * 1e9)
def _detect_cloud_provider() -> str:
+2 -2
View File
@@ -8,9 +8,9 @@ This is similar in concept to the `collections` module.
import math
from collections import defaultdict
from collections.abc import Callable, Generator, Hashable, Iterable, Mapping, Sequence
from typing import Generic, Literal, TypeVar
from typing import Generic, Literal, TypeVar, assert_never, overload
from typing_extensions import TypeIs, assert_never, overload
from typing_extensions import TypeIs
T = TypeVar("T")
+1 -2
View File
@@ -12,10 +12,9 @@ import os
import sys
from functools import cache
from types import ModuleType
from typing import Any
from typing import Any, Never
import regex as re
from typing_extensions import Never
from vllm.logger import init_logger
+1 -2
View File
@@ -11,10 +11,9 @@ from enum import Enum, IntEnum
from fractions import Fraction
from functools import cached_property
from math import prod
from typing import TYPE_CHECKING, TypeVar
from typing import TYPE_CHECKING, Self, TypeVar
import torch
from typing_extensions import Self
from vllm.logger import init_logger
from vllm.utils.math_utils import cdiv, round_up
+1 -2
View File
@@ -10,12 +10,11 @@ import time
from abc import ABC, abstractmethod
from collections.abc import Iterable
from dataclasses import asdict, dataclass, field
from typing import Any, Protocol
from typing import Any, Protocol, Self
import prometheus_client
import torch
from pydantic import BaseModel, Field, ValidationError, model_validator
from typing_extensions import Self
import vllm.envs as envs
from vllm.config import VllmConfig
+18 -35
View File
@@ -4,10 +4,9 @@
from __future__ import annotations
import ast
import importlib
import json
import sys
from dataclasses import dataclass, field
from re import _constants, _parser # type: ignore[attr-defined]
from typing import TYPE_CHECKING
import torch
@@ -36,19 +35,6 @@ else:
oc = LazyLoader("oc", globals(), "outlines_core")
json_schema = LazyLoader("json_schema", globals(), "outlines_core.json_schema")
# Python 3.11+ sre_parse and sre_constants
# are deprecated, so we must import them from re
if sys.version_info >= (3, 11):
# Hack to get around pre-commit regex module rule
# because going through re is the only way to get sre_parse
# and sre_constants in Python 3.11+
_re = importlib.import_module("re")
sre_parse = _re._parser
sre_constants = _re._constants
else:
import sre_constants
import sre_parse
@dataclass
class OutlinesBackend(StructuredOutputBackend):
@@ -261,20 +247,20 @@ def _prefix_needs_context(parsed) -> bool:
tokens = parsed.data if hasattr(parsed, "data") else parsed
for ttype, tval in tokens:
# literal, character class, or dot always consumes
if ttype in (sre_parse.LITERAL, sre_parse.IN, sre_parse.ANY):
if ttype in (_parser.LITERAL, _parser.IN, _parser.ANY):
return True
# quantified subpattern: check inner pattern
elif ttype == sre_parse.MAX_REPEAT:
elif ttype == _parser.MAX_REPEAT:
_, mx, sub = tval
if mx != 0 and subpattern_consumes(sub):
return True
# alternation: if any branch consumes, the whole does
elif ttype == sre_parse.BRANCH:
elif ttype == _parser.BRANCH:
_, branches = tval
if any(subpattern_consumes(br) for br in branches):
return True
# grouped subpattern: recurse into its contents
elif ttype == sre_parse.SUBPATTERN and subpattern_consumes(tval[3]):
elif ttype == _parser.SUBPATTERN and subpattern_consumes(tval[3]):
return True
# No consumers, return False
return False
@@ -282,14 +268,11 @@ def _prefix_needs_context(parsed) -> bool:
tokens = parsed.data if hasattr(parsed, "data") else parsed
for ttype, tval in tokens:
# Direct anchors or look-around
if ttype == sre_parse.AT or ttype in (
sre_constants.ASSERT,
sre_constants.ASSERT_NOT,
):
if ttype == _parser.AT or ttype in (_constants.ASSERT, _constants.ASSERT_NOT):
return True
# Nested subpattern: check
if ttype == sre_parse.SUBPATTERN:
if ttype == _parser.SUBPATTERN:
# tval: (group, add_flags, del_flags, subpattern)
if _prefix_needs_context(tval[3]):
return True
@@ -298,7 +281,7 @@ def _prefix_needs_context(parsed) -> bool:
# if any branch has a prefix anchor => True,
# else if at least one branch consumes => prefix ends => False
elif ttype == sre_parse.BRANCH:
elif ttype == _parser.BRANCH:
saw_consumer = False
for br in tval[1]:
if _prefix_needs_context(br):
@@ -309,11 +292,11 @@ def _prefix_needs_context(parsed) -> bool:
return False
# Immediate consumer tokens
elif ttype in (sre_parse.LITERAL, sre_parse.IN, sre_parse.ANY):
elif ttype in (_parser.LITERAL, _parser.IN, _parser.ANY):
return False
# if subpattern has anchor => True, if it can consume => stop
elif ttype == sre_parse.MAX_REPEAT:
elif ttype == _parser.MAX_REPEAT:
if _prefix_needs_context(tval[2]):
return True
if subpattern_consumes(tval[2]):
@@ -327,25 +310,25 @@ def _check_unsupported(parsed) -> None:
tokens = parsed.data if hasattr(parsed, "data") else parsed
for ttype, tval in tokens:
# backreference
if ttype in (sre_parse.GROUPREF, sre_parse.GROUPREF_EXISTS):
if ttype in (_parser.GROUPREF, _parser.GROUPREF_EXISTS):
raise ValueError("Backreferences are unsupported.")
# look-around assertion
elif ttype in (sre_constants.ASSERT, sre_constants.ASSERT_NOT):
elif ttype in (_constants.ASSERT, _constants.ASSERT_NOT):
raise ValueError("Look-Around assertion are unsupported.")
# unicode word boundaries
elif ttype == sre_parse.AT:
if tval in (sre_constants.AT_BOUNDARY, sre_constants.AT_NON_BOUNDARY):
elif ttype == _parser.AT:
if tval in (_constants.AT_BOUNDARY, _constants.AT_NON_BOUNDARY):
raise ValueError("Unicode word boundaries are unsupported.")
elif ttype == sre_parse.BRANCH:
elif ttype == _parser.BRANCH:
# tval is (None, branches)
for branch in tval[1]:
_check_unsupported(branch)
# tval is (min, max, subpattern)
elif ttype == sre_parse.MAX_REPEAT:
elif ttype == _parser.MAX_REPEAT:
_check_unsupported(tval[2])
@@ -357,9 +340,9 @@ def validate_regex_is_buildable(pattern: str) -> None:
https://docs.rs/regex-automata/latest/regex_automata/dfa/trait.Automaton.html#method.universal_start_state
"""
try:
parsed = sre_parse.parse(pattern)
parsed = _parser.parse(pattern)
except sre_constants.error as e:
except _constants.error as e:
raise VLLMValidationError(f"Error parsing regex: {e}") from e
try:
+1 -6
View File
@@ -229,12 +229,7 @@ class WorkspaceManager:
# Walk up the stack skipping WorkspaceManager frames
curr_frame = curr_frame.f_back
while curr_frame is not None:
# TODO: This only catches instance methods (self), missing
# classmethods and staticmethods. Once Python 3.11+ is the
# minimum supported version, use co_qualname instead:
# qualname = curr_frame.f_code.co_qualname
# if qualname.startswith("WorkspaceManager."):
if isinstance(curr_frame.f_locals.get("self"), WorkspaceManager):
if curr_frame.f_code.co_qualname.startswith("WorkspaceManager."):
curr_frame = curr_frame.f_back
continue
filename = os.path.basename(curr_frame.f_code.co_filename)