Compare commits

...
Author SHA1 Message Date
Arpit KhandelwalandKevin H. Luu 4fd9d6a85c [Core] Rename PassConfig flags as per RFC #27995 (#29646)
Signed-off-by: arpitkh101 <arpit5khandelwal@gmail.com>
Co-authored-by: Luka Govedič <ProExpertProg@users.noreply.github.com>
(cherry picked from commit d7284a2604)
2025-12-02 20:38:43 -08:00
Lucas WilkinsonandKevin H. Luu a1d627e40f [BugFix] Fix assert in build_for_cudagraph_capture (#29893)
Signed-off-by: Lucas Wilkinson <lwilkins@redhat.com>
(cherry picked from commit 5cdd664509)
2025-12-02 16:59:56 -08:00
Isotr0pyandKevin H. Luu 2f055ec1c1 [Bugfix] Fix incorrect channel order for idefics3 in edge case (#29881)
Signed-off-by: Isotr0py <mozf@mail2.sysu.edu.cn>
Signed-off-by: Isotr0py <2037008807@qq.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
(cherry picked from commit 0ec8422171)
2025-12-02 15:27:01 -08:00
Julien DenizeandKevin H. Luu 6a6108511f [BUGFIX] Fix regex pattern for Mistral Tool Call (#29918)
Signed-off-by: juliendenize <julien.denize@mistral.ai>
(cherry picked from commit 1b1e35aaf9)
2025-12-02 15:08:47 -08:00
Julien DenizeandKevin H. Luu 9057fc2f1b [BUGFIX] llama_4_scaling wrongly passed to DeepseekAttention (#29908)
Signed-off-by: juliendenize <julien.denize@mistral.ai>
(cherry picked from commit 5e5646e206)
2025-12-02 15:08:34 -08:00
ChaunceyandKevin H. Luu a05b580540 [Bugfix] fix --scheduling-policy=priority & n>1 crashes engine (#29764)
Signed-off-by: chaunceyjiang <chaunceyjiang@gmail.com>
Signed-off-by: Nick Hill <nhill@redhat.com>
Co-authored-by: Nick Hill <nhill@redhat.com>
(cherry picked from commit 0a9caca9f5)
2025-12-02 15:08:24 -08:00
Sage MooreandKevin H. Luu b6ae5aeca6 [Bugfix][EPLB] Prevent user-provided EPLB config from being overwritten with defaults (#29911)
Signed-off-by: Sage Moore <sage@neuralmagic.com>
(cherry picked from commit e6f114ac25)
2025-12-02 15:08:06 -08:00
jthomson04andKevin H. Luu 5c7c09af8f [Perf] Avoid pageable HtoD transfer in MinTokensLogitsProcessor (#29826)
Signed-off-by: jthomson04 <jwillthomson19@gmail.com>
(cherry picked from commit 1528e079e2)
2025-12-02 14:57:40 -08:00
Benjamin BartelsandKevin H. Luu 7f718169d1 [CI/Build] Fixes missing runtime dependencies (#29822)
Signed-off-by: bbartels <benjamin@bartels.dev>
(cherry picked from commit 2d613de9ae)
2025-12-02 12:33:30 -08:00
Matthew BonanniandKevin H. Luu 339e84ce86 [Bugfix] Fix DeepSeek R1 MTP weight loading (#29545)
Signed-off-by: Matthew Bonanni <mbonanni@redhat.com>
Co-authored-by: Benjamin Chislett <bchislett@nvidia.com>
(cherry picked from commit 51c57b51dd)
2025-12-02 12:33:18 -08:00
Cyrus LeungandKevin H. Luu 34a8559be7 [Chore] Use tokenizer.encode and tokenizer.decode directly (#29851)
Signed-off-by: DarkLight1337 <tlleungac@connect.ust.hk>
(cherry picked from commit 68ffbca7e4)
2025-12-02 12:32:14 -08:00
Harry MellorandKevin H. Luu 85fb2e3120 Remove default values from InitVars so that they're not stored (#29859)
Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
(cherry picked from commit 951445a52d)
2025-12-02 12:32:06 -08:00
57 changed files with 607 additions and 286 deletions
+4 -1
View File
@@ -108,7 +108,10 @@ def benchmark_batched_propose(args):
device_config=DeviceConfig(device=current_platform.device_type), device_config=DeviceConfig(device=current_platform.device_type),
parallel_config=ParallelConfig(), parallel_config=ParallelConfig(),
load_config=LoadConfig(), load_config=LoadConfig(),
scheduler_config=SchedulerConfig(), scheduler_config=SchedulerConfig(
max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
),
) )
# monkey patch vllm.v1.worker.gpu_model_runner.get_pp_group # monkey patch vllm.v1.worker.gpu_model_runner.get_pp_group
+6 -1
View File
@@ -364,7 +364,12 @@ RUN CUDA_VERSION_DASH=$(echo $CUDA_VERSION | cut -d. -f1,2 | tr '.' '-') && \
cuda-cudart-${CUDA_VERSION_DASH} \ cuda-cudart-${CUDA_VERSION_DASH} \
cuda-nvrtc-${CUDA_VERSION_DASH} \ cuda-nvrtc-${CUDA_VERSION_DASH} \
cuda-cuobjdump-${CUDA_VERSION_DASH} \ cuda-cuobjdump-${CUDA_VERSION_DASH} \
libcublas-${CUDA_VERSION_DASH} && \ # https://github.com/vllm-project/vllm/issues/29590
libcurand-dev-${CUDA_VERSION_DASH} \
libcublas-${CUDA_VERSION_DASH} \
# Fixes nccl_allocator requiring nccl.h at runtime
# https://github.com/vllm-project/vllm/blob/1336a1ea244fa8bfd7e72751cabbdb5b68a0c11a/vllm/distributed/device_communicators/pynccl_allocator.py#L22
libnccl-dev && \
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/*
ARG PIP_INDEX_URL UV_INDEX_URL ARG PIP_INDEX_URL UV_INDEX_URL
+2 -2
View File
@@ -326,7 +326,7 @@ def async_tp_pass_on_test_model(
vllm_config = VllmConfig() vllm_config = VllmConfig()
vllm_config.compilation_config = CompilationConfig( vllm_config.compilation_config = CompilationConfig(
pass_config=PassConfig( pass_config=PassConfig(
enable_async_tp=True, fuse_gemm_comms=True,
), ),
) )
vllm_config.device_config = DeviceConfig(device=torch.device("cuda")) vllm_config.device_config = DeviceConfig(device=torch.device("cuda"))
@@ -413,7 +413,7 @@ def test_async_tp_pass_correctness(
"mode": CompilationMode.VLLM_COMPILE, "mode": CompilationMode.VLLM_COMPILE,
"compile_sizes": [2, 4, 8], "compile_sizes": [2, 4, 8],
"splitting_ops": [], "splitting_ops": [],
"pass_config": {"enable_async_tp": async_tp_enabled}, "pass_config": {"fuse_gemm_comms": async_tp_enabled},
} }
async_tp_args = [ async_tp_args = [
@@ -295,7 +295,7 @@ def all_reduce_fusion_pass_on_test_model(
) )
) )
vllm_config.compilation_config.pass_config = PassConfig( vllm_config.compilation_config.pass_config = PassConfig(
enable_fi_allreduce_fusion=True, enable_noop=True fuse_allreduce_rms=True, eliminate_noops=True
) )
vllm_config.device_config = DeviceConfig(device=torch.device("cuda")) vllm_config.device_config = DeviceConfig(device=torch.device("cuda"))
vllm_config.parallel_config.rank = local_rank # Setup rank for debug path vllm_config.parallel_config.rank = local_rank # Setup rank for debug path
@@ -192,7 +192,7 @@ def test_attn_quant(
splitting_ops=splitting_ops, splitting_ops=splitting_ops,
# Common # Common
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
pass_config=PassConfig(enable_attn_fusion=True, enable_noop=True), pass_config=PassConfig(fuse_attn_quant=True, eliminate_noops=True),
# Inductor caches custom passes by default as well via uuid # Inductor caches custom passes by default as well via uuid
inductor_compile_config={"force_disable_caches": True}, inductor_compile_config={"force_disable_caches": True},
) )
@@ -282,9 +282,9 @@ def test_tp2_attn_quant_allreduce_rmsnorm(
# Common # Common
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
pass_config=PassConfig( pass_config=PassConfig(
enable_attn_fusion=True, fuse_attn_quant=True,
enable_noop=True, eliminate_noops=True,
enable_fi_allreduce_fusion=True, fuse_allreduce_rms=True,
), ),
# Inductor caches custom passes by default as well via uuid # Inductor caches custom passes by default as well via uuid
inductor_compile_config={"force_disable_caches": True}, inductor_compile_config={"force_disable_caches": True},
@@ -384,10 +384,10 @@ def test_tp2_attn_quant_async_tp(
# Common # Common
level=CompilationMode.VLLM_COMPILE, level=CompilationMode.VLLM_COMPILE,
pass_config=PassConfig( pass_config=PassConfig(
enable_attn_fusion=True, fuse_attn_quant=True,
enable_noop=True, eliminate_noops=True,
enable_sequence_parallelism=True, enable_sp=True,
enable_async_tp=True, fuse_gemm_comms=True,
), ),
# Inductor caches custom passes by default as well via uuid # Inductor caches custom passes by default as well via uuid
inductor_compile_config={"force_disable_caches": True}, inductor_compile_config={"force_disable_caches": True},
@@ -153,7 +153,7 @@ class TestAllReduceRMSNormStaticQuantFP8Model(torch.nn.Module):
] ]
def ops_in_model(self): def ops_in_model(self):
if self.vllm_config.compilation_config.pass_config.enable_fusion: if self.vllm_config.compilation_config.pass_config.fuse_norm_quant:
return [torch.ops._C.fused_add_rms_norm_static_fp8_quant.default] return [torch.ops._C.fused_add_rms_norm_static_fp8_quant.default]
elif RMSNorm.enabled(): elif RMSNorm.enabled():
return [ return [
@@ -183,7 +183,7 @@ class TestAllReduceRMSNormStaticQuantFP8Model(torch.nn.Module):
@pytest.mark.parametrize("seq_len", [16]) @pytest.mark.parametrize("seq_len", [16])
@pytest.mark.parametrize("hidden_size", [16]) @pytest.mark.parametrize("hidden_size", [16])
@pytest.mark.parametrize("dtype", [torch.float16, torch.bfloat16]) @pytest.mark.parametrize("dtype", [torch.float16, torch.bfloat16])
@pytest.mark.parametrize("enable_fusion", [True, False]) @pytest.mark.parametrize("fuse_norm_quant", [True, False])
@pytest.mark.parametrize("dynamic", [False, True]) @pytest.mark.parametrize("dynamic", [False, True])
@pytest.mark.skipif(envs.VLLM_TARGET_DEVICE not in ["cuda"], reason="Only test on CUDA") @pytest.mark.skipif(envs.VLLM_TARGET_DEVICE not in ["cuda"], reason="Only test on CUDA")
def test_sequence_parallelism_pass( def test_sequence_parallelism_pass(
@@ -193,7 +193,7 @@ def test_sequence_parallelism_pass(
seq_len: int, seq_len: int,
hidden_size: int, hidden_size: int,
dtype: torch.dtype, dtype: torch.dtype,
enable_fusion: bool, fuse_norm_quant: bool,
dynamic: bool, dynamic: bool,
): ):
num_processes = 2 num_processes = 2
@@ -211,7 +211,7 @@ def test_sequence_parallelism_pass(
seq_len, seq_len,
hidden_size, hidden_size,
dtype, dtype,
enable_fusion, fuse_norm_quant,
dynamic, dynamic,
), ),
nprocs=nprocs, nprocs=nprocs,
@@ -229,7 +229,7 @@ def sequence_parallelism_pass_on_test_model(
seq_len: int, seq_len: int,
hidden_size: int, hidden_size: int,
dtype: torch.dtype, dtype: torch.dtype,
enable_fusion: bool, fuse_norm_quant: bool,
dynamic: bool, dynamic: bool,
): ):
current_platform.seed_everything(0) current_platform.seed_everything(0)
@@ -260,9 +260,9 @@ def sequence_parallelism_pass_on_test_model(
cudagraph_mode=CUDAGraphMode.NONE, # avoid piecewise warnings cudagraph_mode=CUDAGraphMode.NONE, # avoid piecewise warnings
custom_ops=custom_ops_list, custom_ops=custom_ops_list,
pass_config=PassConfig( pass_config=PassConfig(
enable_sequence_parallelism=True, enable_sp=True,
enable_fusion=enable_fusion, fuse_norm_quant=fuse_norm_quant,
enable_noop=True, eliminate_noops=True,
), ),
) # NoOp needed for fusion ) # NoOp needed for fusion
device_config = DeviceConfig(device=torch.device("cuda")) device_config = DeviceConfig(device=torch.device("cuda"))
@@ -297,7 +297,7 @@ def sequence_parallelism_pass_on_test_model(
sequence_parallelism_pass, sequence_parallelism_pass,
] ]
if enable_fusion: if fuse_norm_quant:
fusion_pass = RMSNormQuantFusionPass(vllm_config) fusion_pass = RMSNormQuantFusionPass(vllm_config)
passes_for_backend.append(fusion_pass) passes_for_backend.append(fusion_pass)
+3 -1
View File
@@ -122,7 +122,9 @@ def test_full_graph(
CompilationConfig( CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
custom_ops=["+rms_norm"], custom_ops=["+rms_norm"],
pass_config=PassConfig(enable_fusion=True, enable_noop=True), pass_config=PassConfig(
fuse_norm_quant=True, fuse_act_quant=True, eliminate_noops=True
),
), ),
*model_info, *model_info,
) )
+65 -12
View File
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
import copy import copy
import logging
from contextlib import nullcontext from contextlib import nullcontext
from unittest.mock import patch from unittest.mock import patch
@@ -10,8 +11,9 @@ from pydantic import ValidationError
from vllm.compilation.counter import compilation_counter from vllm.compilation.counter import compilation_counter
from vllm.compilation.fix_functionalization import FixFunctionalizationPass from vllm.compilation.fix_functionalization import FixFunctionalizationPass
from vllm.config import CompilationConfig, CUDAGraphMode, VllmConfig from vllm.config import CompilationConfig, CUDAGraphMode, VllmConfig
from vllm.config.compilation import CompilationMode from vllm.config.compilation import CompilationMode, PassConfig
from vllm.engine.arg_utils import EngineArgs from vllm.engine.arg_utils import EngineArgs
from vllm.logger import _print_warning_once
from vllm.platforms import current_platform from vllm.platforms import current_platform
from vllm.utils.torch_utils import _is_torch_equal_or_newer from vllm.utils.torch_utils import _is_torch_equal_or_newer
@@ -191,7 +193,7 @@ def test_splitting_ops_dynamic():
config = VllmConfig( config = VllmConfig(
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
pass_config={"enable_attn_fusion": True, "enable_noop": True}, pass_config=PassConfig(fuse_attn_quant=True, eliminate_noops=True),
custom_ops=["+quant_fp8"], custom_ops=["+quant_fp8"],
cudagraph_mode=CUDAGraphMode.PIECEWISE, cudagraph_mode=CUDAGraphMode.PIECEWISE,
) )
@@ -206,7 +208,7 @@ def test_splitting_ops_dynamic():
config = VllmConfig( config = VllmConfig(
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
pass_config={"enable_attn_fusion": True, "enable_noop": True}, pass_config=PassConfig(fuse_attn_quant=True, eliminate_noops=True),
custom_ops=["+quant_fp8"], custom_ops=["+quant_fp8"],
cudagraph_mode=CUDAGraphMode.PIECEWISE, cudagraph_mode=CUDAGraphMode.PIECEWISE,
# work around for accessing all attntion ops # work around for accessing all attntion ops
@@ -219,7 +221,7 @@ def test_splitting_ops_dynamic():
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
use_inductor_graph_partition=True, use_inductor_graph_partition=True,
pass_config={"enable_attn_fusion": True, "enable_noop": True}, pass_config=PassConfig(fuse_attn_quant=True, eliminate_noops=True),
custom_ops=["+quant_fp8"], custom_ops=["+quant_fp8"],
cudagraph_mode=CUDAGraphMode.PIECEWISE, cudagraph_mode=CUDAGraphMode.PIECEWISE,
) )
@@ -227,7 +229,7 @@ def test_splitting_ops_dynamic():
# With inductor graph partition, attn_fusion and splitting_ops # With inductor graph partition, attn_fusion and splitting_ops
# work together. Default splitting_ops include attention ops. # work together. Default splitting_ops include attention ops.
assert config.compilation_config.splitting_ops_contain_attention() assert config.compilation_config.splitting_ops_contain_attention()
# enable_attn_fusion is directly supported under # fuse_attn_quant is directly supported under
# use_inductor_graph_partition=True, and cudagraph_mode # use_inductor_graph_partition=True, and cudagraph_mode
# is unchanged. # is unchanged.
assert config.compilation_config.cudagraph_mode == CUDAGraphMode.PIECEWISE assert config.compilation_config.cudagraph_mode == CUDAGraphMode.PIECEWISE
@@ -301,7 +303,7 @@ def test_should_split():
"cudagraph_capture_sizes", "cudagraph_capture_sizes",
"max_cudagraph_capture_size", "max_cudagraph_capture_size",
"tp_size", "tp_size",
"enable_sequence_parallelism", "enable_sp",
"max_num_batched_tokens", "max_num_batched_tokens",
"cudagraph_mode", "cudagraph_mode",
"expected_max_size", "expected_max_size",
@@ -339,7 +341,7 @@ def test_cudagraph_sizes_post_init(
cudagraph_capture_sizes, cudagraph_capture_sizes,
max_cudagraph_capture_size, max_cudagraph_capture_size,
tp_size, tp_size,
enable_sequence_parallelism, enable_sp,
max_num_batched_tokens, max_num_batched_tokens,
cudagraph_mode, cudagraph_mode,
expected_max_size, expected_max_size,
@@ -355,11 +357,12 @@ def test_cudagraph_sizes_post_init(
compilation_config = CompilationConfig( compilation_config = CompilationConfig(
cudagraph_capture_sizes=cudagraph_capture_sizes, cudagraph_capture_sizes=cudagraph_capture_sizes,
max_cudagraph_capture_size=max_cudagraph_capture_size, max_cudagraph_capture_size=max_cudagraph_capture_size,
pass_config={ pass_config=PassConfig(
"enable_sequence_parallelism": enable_sequence_parallelism, enable_sp=enable_sp,
"enable_fusion": True, fuse_norm_quant=True,
"enable_noop": True, fuse_act_quant=True,
}, eliminate_noops=True,
),
cudagraph_mode=cudagraph_mode, cudagraph_mode=cudagraph_mode,
) )
engine_args = EngineArgs( engine_args = EngineArgs(
@@ -375,3 +378,53 @@ def test_cudagraph_sizes_post_init(
vllm_config.compilation_config.max_cudagraph_capture_size vllm_config.compilation_config.max_cudagraph_capture_size
== expected_max_size == expected_max_size
) )
def test_pass_config_deprecation(caplog_vllm):
caplog_vllm.set_level(logging.WARNING)
# Clear cache to ensure warnings are re-issued
_print_warning_once.cache_clear()
# Test enable_fusion -> fuse_norm_quant, fuse_act_quant
caplog_vllm.clear()
config = PassConfig(enable_fusion=True)
assert "enable_fusion is deprecated" in caplog_vllm.text
assert config.fuse_norm_quant is True
assert config.fuse_act_quant is True
assert config.enable_fusion is None
# Test enable_attn_fusion -> fuse_attn_quant
caplog_vllm.clear()
config = PassConfig(enable_attn_fusion=True)
assert "enable_attn_fusion is deprecated" in caplog_vllm.text
assert config.fuse_attn_quant is True
assert config.enable_attn_fusion is None
# Test enable_noop -> eliminate_noops
caplog_vllm.clear()
config = PassConfig(enable_noop=True)
assert "enable_noop is deprecated" in caplog_vllm.text
assert config.eliminate_noops is True
assert config.enable_noop is None
# Test enable_sequence_parallelism -> enable_sp
caplog_vllm.clear()
config = PassConfig(enable_sequence_parallelism=True)
assert "enable_sequence_parallelism is deprecated" in caplog_vllm.text
assert config.enable_sp is True
assert config.enable_sequence_parallelism is None
# Test enable_async_tp -> fuse_gemm_comms
caplog_vllm.clear()
config = PassConfig(enable_async_tp=True)
assert "enable_async_tp is deprecated" in caplog_vllm.text
assert config.fuse_gemm_comms is True
assert config.enable_async_tp is None
# Test enable_fi_allreduce_fusion -> fuse_allreduce_rms
caplog_vllm.clear()
config = PassConfig(enable_fi_allreduce_fusion=True)
assert "enable_fi_allreduce_fusion is deprecated" in caplog_vllm.text
assert config.fuse_allreduce_rms is True
assert config.enable_fi_allreduce_fusion is None
+5 -1
View File
@@ -223,7 +223,11 @@ def test_fix_functionalization(
model_config=ModelConfig(dtype=dtype), model_config=ModelConfig(dtype=dtype),
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
custom_ops=["all"], custom_ops=["all"],
pass_config=PassConfig(enable_fusion=do_fusion, enable_noop=True), pass_config=PassConfig(
fuse_norm_quant=do_fusion,
fuse_act_quant=do_fusion,
eliminate_noops=True,
),
), ),
) )
+3 -1
View File
@@ -159,7 +159,9 @@ def test_fusion_rmsnorm_quant(
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
custom_ops=custom_ops, custom_ops=custom_ops,
pass_config=PassConfig(enable_fusion=True, enable_noop=True), pass_config=PassConfig(
fuse_norm_quant=True, fuse_act_quant=True, eliminate_noops=True
),
), ),
) )
with vllm.config.set_current_vllm_config(vllm_config): with vllm.config.set_current_vllm_config(vllm_config):
+11 -6
View File
@@ -318,13 +318,18 @@ def test_attention_quant_pattern(
torch.set_default_dtype(dtype) torch.set_default_dtype(dtype)
torch.manual_seed(42) torch.manual_seed(42)
model_config = ModelConfig(
model=model_name,
max_model_len=2048,
dtype=dtype,
)
vllm_config = VllmConfig( vllm_config = VllmConfig(
model_config=ModelConfig( model_config=model_config,
model=model_name, scheduler_config=SchedulerConfig(
max_model_len=2048, max_num_seqs=1024,
dtype=dtype, max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
), ),
scheduler_config=SchedulerConfig(max_num_seqs=1024),
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
custom_ops=custom_ops_list, custom_ops=custom_ops_list,
@@ -368,7 +373,7 @@ def test_attention_quant_pattern(
# Run model with attn fusion enabled # Run model with attn fusion enabled
vllm_config.compilation_config.pass_config = PassConfig( vllm_config.compilation_config.pass_config = PassConfig(
enable_attn_fusion=True, enable_noop=True fuse_attn_quant=True, eliminate_noops=True
) )
with ( with (
set_current_vllm_config(vllm_config), set_current_vllm_config(vllm_config),
+2 -2
View File
@@ -51,7 +51,7 @@ def test_noop_elimination(dtype, num_tokens, hidden_size, buffer_size):
vllm_config = VllmConfig( vllm_config = VllmConfig(
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
pass_config=PassConfig(enable_noop=True), pass_config=PassConfig(eliminate_noops=True),
) )
) )
with vllm.config.set_current_vllm_config(vllm_config): with vllm.config.set_current_vllm_config(vllm_config):
@@ -99,7 +99,7 @@ def test_non_noop_slice_preserved():
vllm_config = VllmConfig( vllm_config = VllmConfig(
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
pass_config=PassConfig(enable_noop=True), pass_config=PassConfig(eliminate_noops=True),
) )
) )
with vllm.config.set_current_vllm_config(vllm_config): with vllm.config.set_current_vllm_config(vllm_config):
+5 -2
View File
@@ -64,8 +64,11 @@ def test_pass_manager_uuid(callable):
# UUID should be different due to config change # UUID should be different due to config change
config2 = copy.deepcopy(config) config2 = copy.deepcopy(config)
config2.compilation_config.pass_config.enable_fusion = ( config2.compilation_config.pass_config.fuse_norm_quant = (
not config2.compilation_config.pass_config.enable_fusion not config2.compilation_config.pass_config.fuse_norm_quant
)
config2.compilation_config.pass_config.fuse_act_quant = (
not config2.compilation_config.pass_config.fuse_act_quant
) )
pass_manager3 = PostGradPassManager() pass_manager3 = PostGradPassManager()
pass_manager3.configure(config2) pass_manager3.configure(config2)
+1 -1
View File
@@ -140,7 +140,7 @@ def test_qk_norm_rope_fusion(
custom_ops=custom_ops, custom_ops=custom_ops,
pass_config=PassConfig( pass_config=PassConfig(
enable_qk_norm_rope_fusion=True, enable_qk_norm_rope_fusion=True,
enable_noop=True, eliminate_noops=True,
), ),
), ),
) )
+1 -1
View File
@@ -168,7 +168,7 @@ def test_fusion_silu_and_mul_quant(
compilation_config=CompilationConfig( compilation_config=CompilationConfig(
mode=CompilationMode.VLLM_COMPILE, mode=CompilationMode.VLLM_COMPILE,
custom_ops=custom_ops, custom_ops=custom_ops,
pass_config=PassConfig(enable_fusion=True, enable_noop=True), pass_config=PassConfig(fuse_act_quant=True, eliminate_noops=True),
), ),
) )
+9 -7
View File
@@ -22,7 +22,14 @@ def get_model_args(
"num_speculative_tokens": 1, "num_speculative_tokens": 1,
"max_model_len": model_max_len, "max_model_len": model_max_len,
} }
eplb_config = {
"num_redundant_experts": tp_size,
"window_size": 128,
"step_interval": 1024,
"log_balancedness": False,
}
if use_async:
eplb_config["use_async"] = True
model_args = { model_args = {
"pretrained": model_name, "pretrained": model_name,
"dtype": "auto", "dtype": "auto",
@@ -31,15 +38,10 @@ def get_model_args(
"gpu_memory_utilization": 0.7, "gpu_memory_utilization": 0.7,
"speculative_config": speculative_config, "speculative_config": speculative_config,
"enable_expert_parallel": True, "enable_expert_parallel": True,
"num_redundant_experts": tp_size, "eplb_config": eplb_config,
"eplb_window_size": 128,
"eplb_step_interval": 1024,
"eplb_log_balancedness": False,
"enable_eplb": True, "enable_eplb": True,
"max_model_len": model_max_len, "max_model_len": model_max_len,
} }
if use_async:
model_args["eplb_config"] = {"use_async": True}
return model_args return model_args
+20 -14
View File
@@ -32,7 +32,8 @@ VLLM_MULTI_NODE = os.getenv("VLLM_MULTI_NODE", "0") == "1"
class ParallelSetup(NamedTuple): class ParallelSetup(NamedTuple):
tp_size: int tp_size: int
pp_size: int pp_size: int
enable_fusion: bool fuse_norm_quant: bool
fuse_act_quant: bool
eager_mode: bool eager_mode: bool
chunked_prefill: bool chunked_prefill: bool
@@ -66,7 +67,8 @@ class SPTestSettings:
ParallelSetup( ParallelSetup(
tp_size=tp_base, tp_size=tp_base,
pp_size=pp_multiplier * pp_base, pp_size=pp_multiplier * pp_base,
enable_fusion=False, fuse_norm_quant=False,
fuse_act_quant=False,
eager_mode=eager_mode_val, eager_mode=eager_mode_val,
chunked_prefill=chunked_prefill_val, chunked_prefill=chunked_prefill_val,
) )
@@ -97,7 +99,8 @@ class SPTestSettings:
ParallelSetup( ParallelSetup(
tp_size=tp_base, tp_size=tp_base,
pp_size=pp_multiplier * pp_base, pp_size=pp_multiplier * pp_base,
enable_fusion=False, fuse_norm_quant=False,
fuse_act_quant=False,
eager_mode=eager_mode_val, eager_mode=eager_mode_val,
chunked_prefill=chunked_prefill_val, chunked_prefill=chunked_prefill_val,
) )
@@ -126,7 +129,8 @@ class SPTestSettings:
ParallelSetup( ParallelSetup(
tp_size=tp_base, tp_size=tp_base,
pp_size=pp_base, pp_size=pp_base,
enable_fusion=fusion_val, fuse_norm_quant=fusion_val,
fuse_act_quant=fusion_val,
eager_mode=True, eager_mode=True,
chunked_prefill=False, chunked_prefill=False,
) )
@@ -162,7 +166,7 @@ def _compare_sp(
test_options: SPTestOptions, test_options: SPTestOptions,
num_gpus_available: int, num_gpus_available: int,
use_inductor_graph_partition: bool, use_inductor_graph_partition: bool,
enable_async_tp: bool, fuse_gemm_comms: bool,
*, *,
method: Literal["generate", "encode"], method: Literal["generate", "encode"],
is_multimodal: bool, is_multimodal: bool,
@@ -170,7 +174,8 @@ def _compare_sp(
( (
tp_size, tp_size,
pp_size, pp_size,
enable_fusion, fuse_norm_quant,
fuse_act_quant,
eager_mode, eager_mode,
chunked_prefill, chunked_prefill,
) = parallel_setup ) = parallel_setup
@@ -248,10 +253,11 @@ def _compare_sp(
"mode": CompilationMode.VLLM_COMPILE, "mode": CompilationMode.VLLM_COMPILE,
"compile_sizes": [4, 8], "compile_sizes": [4, 8],
"pass_config": { "pass_config": {
"enable_sequence_parallelism": True, "enable_sp": True,
"enable_async_tp": enable_async_tp, "fuse_gemm_comms": fuse_gemm_comms,
"enable_fusion": enable_fusion, "fuse_norm_quant": fuse_norm_quant,
"enable_noop": True, "fuse_act_quant": fuse_act_quant,
"eliminate_noops": True,
}, },
"use_inductor_graph_partition": use_inductor_graph_partition, "use_inductor_graph_partition": use_inductor_graph_partition,
} }
@@ -309,7 +315,7 @@ SP_TEST_MODELS = [
], ],
) )
@pytest.mark.parametrize("use_inductor_graph_partition", [True, False]) @pytest.mark.parametrize("use_inductor_graph_partition", [True, False])
@pytest.mark.parametrize("enable_async_tp", [False]) # TODO: enable async TP @pytest.mark.parametrize("fuse_gemm_comms", [False]) # TODO: enable async TP
@create_new_process_for_each_test() @create_new_process_for_each_test()
def test_tp_sp_generation( def test_tp_sp_generation(
model_id: str, model_id: str,
@@ -319,7 +325,7 @@ def test_tp_sp_generation(
test_options: SPTestOptions, test_options: SPTestOptions,
num_gpus_available, num_gpus_available,
use_inductor_graph_partition: bool, use_inductor_graph_partition: bool,
enable_async_tp: bool, fuse_gemm_comms: bool,
): ):
if use_inductor_graph_partition and not is_torch_equal_or_newer("2.9.0.dev"): 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+") pytest.skip("inductor graph partition is only available in PyTorch 2.9+")
@@ -328,7 +334,7 @@ def test_tp_sp_generation(
if ( if (
"fp8" in model_id.lower() "fp8" in model_id.lower()
and current_platform.get_device_capability() < (9, 0) and current_platform.get_device_capability() < (9, 0)
and (not enable_async_tp) and (not fuse_gemm_comms)
): ):
pytest.skip("FP8 reduction support begins with sm90 capable devices.") pytest.skip("FP8 reduction support begins with sm90 capable devices.")
@@ -340,7 +346,7 @@ def test_tp_sp_generation(
test_options, test_options,
num_gpus_available, num_gpus_available,
use_inductor_graph_partition, use_inductor_graph_partition,
enable_async_tp=enable_async_tp, fuse_gemm_comms=fuse_gemm_comms,
method="generate", method="generate",
is_multimodal=False, is_multimodal=False,
) )
+17 -8
View File
@@ -33,14 +33,16 @@ def test_worker_apply_lora(qwen3_lora_files):
lora_requests, lora_mapping lora_requests, lora_mapping
) )
model_config = ModelConfig(
MODEL_PATH,
seed=0,
dtype="float16",
max_model_len=127,
enforce_eager=True,
)
vllm_config = VllmConfig( vllm_config = VllmConfig(
model_config=ModelConfig( model_config=model_config,
MODEL_PATH,
seed=0,
dtype="float16",
max_model_len=127,
enforce_eager=True,
),
load_config=LoadConfig( load_config=LoadConfig(
download_dir=None, download_dir=None,
load_format="dummy", load_format="dummy",
@@ -50,7 +52,14 @@ def test_worker_apply_lora(qwen3_lora_files):
tensor_parallel_size=1, tensor_parallel_size=1,
data_parallel_size=1, data_parallel_size=1,
), ),
scheduler_config=SchedulerConfig("generate", 32, 32, 32), scheduler_config=SchedulerConfig(
max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
runner_type="generate",
max_num_batched_tokens=32,
max_num_seqs=32,
max_num_partial_prefills=32,
),
device_config=DeviceConfig("cuda"), device_config=DeviceConfig("cuda"),
cache_config=CacheConfig( cache_config=CacheConfig(
block_size=16, block_size=16,
@@ -315,3 +315,38 @@ def test_mistral_function_call_nested_json():
assert json.loads(parsed.tool_calls[0].function.arguments) == args_dict assert json.loads(parsed.tool_calls[0].function.arguments) == args_dict
# No additional content outside the tool call should be returned. # No additional content outside the tool call should be returned.
assert parsed.content is None assert parsed.content is None
# multiple calls
multiple_args_dict = [
{
"city": "Dallas",
"state": "TX",
"unit": "fahrenheit",
"sub_dict": {"foo": "bar", "inner": {"x": 1, "y": 2}},
},
{},
{"a": 0},
{"a": 1, "b": "c"},
]
names = ["get_current_weather", "get_current_weather_2", "random", "random_2"]
model_output = "".join(
[
f"{parser.bot_token}{name}{json.dumps(args)}"
for name, args in zip(names, multiple_args_dict)
]
)
parsed = parser.extract_tool_calls(model_output, None)
# Assertions: the tool call is detected and the full nested JSON is parsed
# without truncation.
assert parsed.tools_called
assert len(parsed.tool_calls) == len(multiple_args_dict)
for i, tool_call in enumerate(parsed.tool_calls):
assert MistralToolCall.is_valid_id(tool_call.id)
assert tool_call.function.name == names[i]
assert json.loads(tool_call.function.arguments) == multiple_args_dict[i]
# No additional content outside the tool call should be returned.
assert parsed.content is None
@@ -22,8 +22,11 @@ from vllm.multimodal import MULTIMODAL_REGISTRY, MultiModalDataDict
from vllm.multimodal.cache import MultiModalProcessorOnlyCache from vllm.multimodal.cache import MultiModalProcessorOnlyCache
from vllm.multimodal.inputs import MultiModalInputs from vllm.multimodal.inputs import MultiModalInputs
from vllm.multimodal.processing import BaseMultiModalProcessor, InputProcessingContext from vllm.multimodal.processing import BaseMultiModalProcessor, InputProcessingContext
from vllm.tokenizers import MistralTokenizer, cached_tokenizer_from_config from vllm.tokenizers import (
from vllm.transformers_utils.tokenizer import encode_tokens MistralTokenizer,
TokenizerLike,
cached_tokenizer_from_config,
)
from ....multimodal.utils import random_audio, random_image, random_video from ....multimodal.utils import random_audio, random_image, random_video
from ...registry import ( from ...registry import (
@@ -151,7 +154,7 @@ def get_text_token_prompts(
mm_data: MultiModalDataDict, mm_data: MultiModalDataDict,
): ):
dummy_inputs = processor.dummy_inputs dummy_inputs = processor.dummy_inputs
tokenizer = processor.info.get_tokenizer() tokenizer: TokenizerLike = processor.info.get_tokenizer()
model_config = processor.info.ctx.model_config model_config = processor.info.ctx.model_config
model_type = model_config.hf_config.model_type model_type = model_config.hf_config.model_type
@@ -188,10 +191,9 @@ def get_text_token_prompts(
assert isinstance(inputs.prompt, str) assert isinstance(inputs.prompt, str)
text_prompt = inputs.prompt text_prompt = inputs.prompt
token_prompt = encode_tokens( token_prompt = tokenizer.encode(
tokenizer,
text_prompt, text_prompt,
add_special_tokens=_ADD_SPECIAL_TOKENS_OVERRIDES.get(model_type), add_special_tokens=_ADD_SPECIAL_TOKENS_OVERRIDES.get(model_type, True),
) )
return text_prompt, token_prompt return text_prompt, token_prompt
@@ -5,7 +5,6 @@
import pytest import pytest
from vllm.multimodal import MULTIMODAL_REGISTRY from vllm.multimodal import MULTIMODAL_REGISTRY
from vllm.transformers_utils.tokenizer import encode_tokens
from ....conftest import ImageTestAssets from ....conftest import ImageTestAssets
from ...utils import build_model_context from ...utils import build_model_context
@@ -48,7 +47,7 @@ def test_processor_override(
] ]
} }
if tokenized_prompt: if tokenized_prompt:
prompt = encode_tokens(tokenizer, prompt) prompt = tokenizer.encode(prompt)
processed_inputs = processor.apply(prompt, mm_data, mm_processor_kwargs) processed_inputs = processor.apply(prompt, mm_data, mm_processor_kwargs)
mm_data = processed_inputs["mm_kwargs"].get_data() mm_data = processed_inputs["mm_kwargs"].get_data()
+19 -6
View File
@@ -6,12 +6,14 @@ from dataclasses import MISSING, Field, asdict, dataclass, field
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
from pydantic import ValidationError
from vllm.compilation.backends import VllmBackend from vllm.compilation.backends import VllmBackend
from vllm.config import ( from vllm.config import (
CompilationConfig, CompilationConfig,
ModelConfig, ModelConfig,
PoolerConfig, PoolerConfig,
SchedulerConfig,
VllmConfig, VllmConfig,
update_config, update_config,
) )
@@ -1021,17 +1023,17 @@ def test_vllm_config_explicit_overrides():
assert config.compilation_config.cudagraph_mode == CUDAGraphMode.NONE assert config.compilation_config.cudagraph_mode == CUDAGraphMode.NONE
# Explicit pass config flags to override defaults # Explicit pass config flags to override defaults
pass_config = PassConfig(enable_noop=True, enable_attn_fusion=True) pass_config = PassConfig(eliminate_noops=True, fuse_attn_quant=True)
compilation_config = CompilationConfig(pass_config=pass_config) compilation_config = CompilationConfig(pass_config=pass_config)
config = VllmConfig( config = VllmConfig(
optimization_level=OptimizationLevel.O0, optimization_level=OptimizationLevel.O0,
compilation_config=compilation_config, compilation_config=compilation_config,
) )
assert config.compilation_config.pass_config.enable_noop is True assert config.compilation_config.pass_config.eliminate_noops is True
assert config.compilation_config.pass_config.enable_attn_fusion is True assert config.compilation_config.pass_config.fuse_attn_quant is True
# Explicit cudagraph mode override on quantized model at O2 # Explicit cudagraph mode override on quantized model at O2
pass_config = PassConfig(enable_async_tp=True) pass_config = PassConfig(fuse_gemm_comms=True)
compilation_config = CompilationConfig( compilation_config = CompilationConfig(
cudagraph_mode=CUDAGraphMode.NONE, pass_config=pass_config cudagraph_mode=CUDAGraphMode.NONE, pass_config=pass_config
) )
@@ -1041,7 +1043,7 @@ def test_vllm_config_explicit_overrides():
compilation_config=compilation_config, compilation_config=compilation_config,
) )
assert config.compilation_config.cudagraph_mode == CUDAGraphMode.NONE assert config.compilation_config.cudagraph_mode == CUDAGraphMode.NONE
assert config.compilation_config.pass_config.enable_async_tp is True assert config.compilation_config.pass_config.fuse_gemm_comms is True
# Mode should still use default for O2 # Mode should still use default for O2
assert config.compilation_config.mode == CompilationMode.VLLM_COMPILE assert config.compilation_config.mode == CompilationMode.VLLM_COMPILE
@@ -1091,7 +1093,18 @@ def test_vllm_config_explicit_overrides():
compilation_config=compilation_config, compilation_config=compilation_config,
) )
# Explicit override should be respected # Explicit override should be respected
assert config.compilation_config.pass_config.enable_noop is False assert config.compilation_config.pass_config.eliminate_noops is False
# Other fields should still use defaults # Other fields should still use defaults
assert config.compilation_config.mode == CompilationMode.VLLM_COMPILE assert config.compilation_config.mode == CompilationMode.VLLM_COMPILE
assert config.compilation_config.cudagraph_mode == CUDAGraphMode.FULL_AND_PIECEWISE assert config.compilation_config.cudagraph_mode == CUDAGraphMode.FULL_AND_PIECEWISE
def test_scheduler_config_init():
with pytest.raises(ValidationError):
# Positional InitVars missing
# (InitVars cannot have defaults otherwise they will become attributes)
SchedulerConfig()
with pytest.raises(AttributeError):
# InitVar does not become an attribute
print(SchedulerConfig.default_factory().max_model_len)
+2
View File
@@ -185,6 +185,8 @@ def create_vllm_config(
max_num_seqs=max_num_seqs, max_num_seqs=max_num_seqs,
max_num_batched_tokens=max_num_batched_tokens, max_num_batched_tokens=max_num_batched_tokens,
enable_chunked_prefill=enable_chunked_prefill, enable_chunked_prefill=enable_chunked_prefill,
max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
) )
device_config = DeviceConfig() device_config = DeviceConfig()
+9 -2
View File
@@ -1128,7 +1128,11 @@ def test_estimate_max_model_len(model_id, max_model_len, want_estimated_max_len)
dtype="float16", dtype="float16",
max_model_len=max_model_len, max_model_len=max_model_len,
) )
scheduler_config = SchedulerConfig(max_num_batched_tokens=32768) scheduler_config = SchedulerConfig(
max_num_batched_tokens=32768,
max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
)
vllm_config = VllmConfig( vllm_config = VllmConfig(
model_config=model_config, model_config=model_config,
@@ -1163,7 +1167,10 @@ def test_get_max_concurrency_for_kv_cache_config():
max_model_len=max_model_len, max_model_len=max_model_len,
) )
scheduler_config = SchedulerConfig( scheduler_config = SchedulerConfig(
max_num_batched_tokens=1024, enable_chunked_prefill=True max_num_batched_tokens=1024,
enable_chunked_prefill=True,
max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
) )
vllm_config = VllmConfig( vllm_config = VllmConfig(
@@ -219,7 +219,17 @@ def test_priority_scheduling_blast(
vllm_config=scheduler.vllm_config, vllm_config=scheduler.vllm_config,
) )
scheduler.add_request(req) scheduler.add_request(req)
num_initial_requests = 2
for _ in range(num_initial_requests):
req = _create_random_request(
max_tokens_range=(1, max_output_tokens),
num_tokens_range=(1, max_input_tokens),
arrival_time_range=(0, 0),
priority_range=(4, 4),
num_mm_item_range=(0, 2),
vllm_config=scheduler.vllm_config,
)
scheduler.add_request(req)
for _ in range(20000): for _ in range(20000):
if len(scheduler.waiting) == 0: if len(scheduler.waiting) == 0:
num_new_requests = random.randint(0, 2) num_new_requests = random.randint(0, 2)
+7 -6
View File
@@ -1508,6 +1508,12 @@ def create_scheduler_with_priority(
Returns: Returns:
{class}`Scheduler` instance with priority scheduling {class}`Scheduler` instance with priority scheduling
""" """
model_config = ModelConfig(
model=model,
trust_remote_code=True,
dtype="float16",
seed=42,
)
if max_model_len is None: if max_model_len is None:
max_model_len = max_num_batched_tokens max_model_len = max_num_batched_tokens
scheduler_config = SchedulerConfig( scheduler_config = SchedulerConfig(
@@ -1517,14 +1523,9 @@ def create_scheduler_with_priority(
long_prefill_token_threshold=long_prefill_token_threshold, long_prefill_token_threshold=long_prefill_token_threshold,
disable_chunked_mm_input=disable_chunked_mm_input, disable_chunked_mm_input=disable_chunked_mm_input,
enable_chunked_prefill=True, enable_chunked_prefill=True,
is_encoder_decoder=model_config.is_encoder_decoder,
policy="priority", # Enable priority scheduling policy="priority", # Enable priority scheduling
) )
model_config = ModelConfig(
model=model,
trust_remote_code=True,
dtype="float16",
seed=42,
)
# Cache config, optionally force APC # Cache config, optionally force APC
cache_config = CacheConfig( cache_config = CacheConfig(
block_size=block_size, block_size=block_size,
+8 -7
View File
@@ -69,6 +69,13 @@ def create_scheduler(
Returns: Returns:
{class}`Scheduler` instance {class}`Scheduler` instance
""" """
model_config = ModelConfig(
model=model,
trust_remote_code=True,
dtype="float16",
seed=42,
skip_tokenizer_init=skip_tokenizer_init,
)
if max_model_len is None: if max_model_len is None:
max_model_len = max_num_batched_tokens max_model_len = max_num_batched_tokens
scheduler_config = SchedulerConfig( scheduler_config = SchedulerConfig(
@@ -79,13 +86,7 @@ def create_scheduler(
disable_chunked_mm_input=disable_chunked_mm_input, disable_chunked_mm_input=disable_chunked_mm_input,
enable_chunked_prefill=enable_chunked_prefill, enable_chunked_prefill=enable_chunked_prefill,
async_scheduling=async_scheduling, async_scheduling=async_scheduling,
) is_encoder_decoder=model_config.is_encoder_decoder,
model_config = ModelConfig(
model=model,
trust_remote_code=True,
dtype="float16",
seed=42,
skip_tokenizer_init=skip_tokenizer_init,
) )
# Cache config, optionally force APC # Cache config, optionally force APC
cache_config = CacheConfig( cache_config = CacheConfig(
@@ -40,7 +40,9 @@ def _create_vllm_config(
) -> MagicMock: ) -> MagicMock:
mock_config = MagicMock(spec=VllmConfig) mock_config = MagicMock(spec=VllmConfig)
mock_config.compilation_config = compilation_config mock_config.compilation_config = compilation_config
mock_config.scheduler_config = SchedulerConfig(max_num_seqs=max_num_seqs) mock_config.scheduler_config = SchedulerConfig.default_factory(
max_num_seqs=max_num_seqs,
)
mock_config.parallel_config = ParallelConfig() mock_config.parallel_config = ParallelConfig()
mock_config.speculative_config = None # No speculative decoding mock_config.speculative_config = None # No speculative decoding
if not lora_config: if not lora_config:
+7 -6
View File
@@ -484,12 +484,6 @@ def test_encoder_instance_zero_kv_cache(
vision encoder, so they don't need KV cache for text generation. vision encoder, so they don't need KV cache for text generation.
""" """
# Form vllm config # Form vllm config
scheduler_config = SchedulerConfig(
max_num_seqs=10,
max_num_batched_tokens=512,
max_model_len=512,
disable_hybrid_kv_cache_manager=True,
)
model_config = ModelConfig( model_config = ModelConfig(
model="llava-hf/llava-1.5-7b-hf", # Multimodal model model="llava-hf/llava-1.5-7b-hf", # Multimodal model
enforce_eager=True, enforce_eager=True,
@@ -497,6 +491,13 @@ def test_encoder_instance_zero_kv_cache(
dtype="float16", dtype="float16",
seed=42, seed=42,
) )
scheduler_config = SchedulerConfig(
max_num_seqs=10,
max_num_batched_tokens=512,
max_model_len=512,
disable_hybrid_kv_cache_manager=True,
is_encoder_decoder=model_config.is_encoder_decoder,
)
cache_config = CacheConfig( cache_config = CacheConfig(
block_size=16, block_size=16,
gpu_memory_utilization=gpu_memory_utilization, gpu_memory_utilization=gpu_memory_utilization,
+7 -6
View File
@@ -92,18 +92,19 @@ def create_vllm_config(
enable_permute_local_kv: bool = False, enable_permute_local_kv: bool = False,
) -> VllmConfig: ) -> VllmConfig:
"""Initialize VllmConfig For Testing.""" """Initialize VllmConfig For Testing."""
scheduler_config = SchedulerConfig(
max_num_seqs=max_num_seqs,
max_num_batched_tokens=max_num_batched_tokens,
max_model_len=max_model_len,
enable_chunked_prefill=enable_chunked_prefill,
)
model_config = ModelConfig( model_config = ModelConfig(
model=model, model=model,
trust_remote_code=True, trust_remote_code=True,
dtype="float16", dtype="float16",
seed=42, seed=42,
) )
scheduler_config = SchedulerConfig(
max_num_seqs=max_num_seqs,
max_num_batched_tokens=max_num_batched_tokens,
max_model_len=max_model_len,
enable_chunked_prefill=enable_chunked_prefill,
is_encoder_decoder=model_config.is_encoder_decoder,
)
# Cache config, optionally force APC # Cache config, optionally force APC
cache_config = CacheConfig( cache_config = CacheConfig(
block_size=block_size, block_size=block_size,
+4 -1
View File
@@ -66,7 +66,10 @@ def _create_proposer(
device_config=DeviceConfig(device=current_platform.device_type), device_config=DeviceConfig(device=current_platform.device_type),
parallel_config=ParallelConfig(), parallel_config=ParallelConfig(),
load_config=LoadConfig(), load_config=LoadConfig(),
scheduler_config=SchedulerConfig(), scheduler_config=SchedulerConfig(
max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
),
) )
return EagleProposer(vllm_config=vllm_config, device=current_platform.device_type) return EagleProposer(vllm_config=vllm_config, device=current_platform.device_type)
+4 -1
View File
@@ -51,7 +51,10 @@ def _create_mtp_proposer(num_speculative_tokens: int) -> EagleProposer:
device_config=DeviceConfig(device=current_platform.device_type), device_config=DeviceConfig(device=current_platform.device_type),
parallel_config=ParallelConfig(), parallel_config=ParallelConfig(),
load_config=LoadConfig(), load_config=LoadConfig(),
scheduler_config=SchedulerConfig(), scheduler_config=SchedulerConfig(
max_model_len=model_config.max_model_len,
is_encoder_decoder=model_config.is_encoder_decoder,
),
) )
return EagleProposer(vllm_config=vllm_config, device=current_platform.device_type) return EagleProposer(vllm_config=vllm_config, device=current_platform.device_type)
+6 -5
View File
@@ -26,16 +26,17 @@ from vllm.v1.worker.tpu_model_runner import (
def get_vllm_config(): def get_vllm_config():
scheduler_config = SchedulerConfig(
max_num_seqs=10,
max_num_batched_tokens=512,
max_model_len=512,
)
model_config = ModelConfig( model_config = ModelConfig(
model="facebook/opt-125m", model="facebook/opt-125m",
dtype="bfloat16", # TPUs typically use bfloat16 dtype="bfloat16", # TPUs typically use bfloat16
seed=42, seed=42,
) )
scheduler_config = SchedulerConfig(
max_num_seqs=10,
max_num_batched_tokens=512,
max_model_len=512,
is_encoder_decoder=model_config.is_encoder_decoder,
)
cache_config = CacheConfig( cache_config = CacheConfig(
block_size=16, block_size=16,
gpu_memory_utilization=0.9, gpu_memory_utilization=0.9,
+11 -9
View File
@@ -79,16 +79,17 @@ def initialize_kv_cache(runner: GPUModelRunner):
def get_vllm_config(): def get_vllm_config():
scheduler_config = SchedulerConfig(
max_num_seqs=10,
max_num_batched_tokens=512,
max_model_len=512,
)
model_config = ModelConfig( model_config = ModelConfig(
model="facebook/opt-125m", model="facebook/opt-125m",
dtype="float16", dtype="float16",
seed=42, seed=42,
) )
scheduler_config = SchedulerConfig(
max_num_seqs=10,
max_num_batched_tokens=512,
max_model_len=512,
is_encoder_decoder=model_config.is_encoder_decoder,
)
cache_config = CacheConfig( cache_config = CacheConfig(
block_size=BLOCK_SIZE, block_size=BLOCK_SIZE,
gpu_memory_utilization=0.9, gpu_memory_utilization=0.9,
@@ -784,14 +785,15 @@ def test_hybrid_attention_mamba_tensor_shapes(monkeypatch):
initialize_model_parallel(tensor_model_parallel_size=1) initialize_model_parallel(tensor_model_parallel_size=1)
torch.set_default_dtype(torch.float16) torch.set_default_dtype(torch.float16)
model_config = ModelConfig(
model="ibm-granite/granite-4.0-tiny-preview",
dtype="float16",
)
scheduler_config = SchedulerConfig( scheduler_config = SchedulerConfig(
max_num_seqs=10, max_num_seqs=10,
max_num_batched_tokens=512, max_num_batched_tokens=512,
max_model_len=512, max_model_len=512,
) is_encoder_decoder=model_config.is_encoder_decoder,
model_config = ModelConfig(
model="ibm-granite/granite-4.0-tiny-preview",
dtype="float16",
) )
cache_config = CacheConfig( cache_config = CacheConfig(
block_size=BLOCK_SIZE, block_size=BLOCK_SIZE,
+7 -6
View File
@@ -92,22 +92,23 @@ class PostGradPassManager(CustomGraphPass):
# Set the current vllm config to allow tracing CustomOp instances # Set the current vllm config to allow tracing CustomOp instances
with set_current_vllm_config(config, check_compile=False): with set_current_vllm_config(config, check_compile=False):
if self.pass_config.enable_noop: if self.pass_config.eliminate_noops:
self.passes += [NoOpEliminationPass(config)] self.passes += [NoOpEliminationPass(config)]
if self.pass_config.enable_sequence_parallelism: if self.pass_config.enable_sp:
self.passes += [SequenceParallelismPass(config)] self.passes += [SequenceParallelismPass(config)]
if self.pass_config.enable_async_tp: if self.pass_config.fuse_gemm_comms:
self.passes += [AsyncTPPass(config)] self.passes += [AsyncTPPass(config)]
if self.pass_config.enable_fi_allreduce_fusion: if self.pass_config.fuse_allreduce_rms:
self.passes += [AllReduceFusionPass(config)] self.passes += [AllReduceFusionPass(config)]
if self.pass_config.enable_fusion: if self.pass_config.fuse_norm_quant:
self.passes += [RMSNormQuantFusionPass(config)] self.passes += [RMSNormQuantFusionPass(config)]
if self.pass_config.fuse_act_quant:
self.passes += [ActivationQuantFusionPass(config)] self.passes += [ActivationQuantFusionPass(config)]
if self.pass_config.enable_attn_fusion: if self.pass_config.fuse_attn_quant:
self.passes += [AttnFusionPass(config)] self.passes += [AttnFusionPass(config)]
if self.pass_config.enable_qk_norm_rope_fusion: if self.pass_config.enable_qk_norm_rope_fusion:
+102 -18
View File
@@ -13,7 +13,7 @@ from pydantic.dataclasses import dataclass
import vllm.envs as envs import vllm.envs as envs
from vllm.compilation.inductor_pass import CallableInductorPass, InductorPass from vllm.compilation.inductor_pass import CallableInductorPass, InductorPass
from vllm.config.utils import config from vllm.config.utils import config, handle_deprecated
from vllm.logger import init_logger from vllm.logger import init_logger
from vllm.platforms import current_platform from vllm.platforms import current_platform
from vllm.utils.import_utils import resolve_obj_by_qualname from vllm.utils.import_utils import resolve_obj_by_qualname
@@ -105,18 +105,43 @@ class PassConfig:
improper state. improper state.
""" """
# New flags
fuse_norm_quant: bool = Field(default=None)
"""Fuse the custom RMSNorm + quant ops."""
fuse_act_quant: bool = Field(default=None)
"""Fuse the custom SiluMul + quant ops."""
fuse_attn_quant: bool = Field(default=None)
"""Fuse the custom attention + quant ops."""
eliminate_noops: bool = Field(default=None)
"""Eliminate no-op ops."""
enable_sp: bool = Field(default=None)
"""Enable sequence parallelism."""
fuse_gemm_comms: bool = Field(default=None)
"""Enable async TP."""
fuse_allreduce_rms: bool = Field(default=None)
"""Enable flashinfer allreduce fusion."""
# Deprecated flags
enable_fusion: bool = Field(default=None) enable_fusion: bool = Field(default=None)
"""Whether to enable the custom fusion (RMSNorm/SiluMul+quant) pass.""" """Deprecated in: v0.12.0. Use fuse_norm_quant and fuse_act_quant
instead. Will be removed in v0.13.0 or v1.0.0, whichever is sooner.
"""
enable_attn_fusion: bool = Field(default=None) enable_attn_fusion: bool = Field(default=None)
"""Whether to enable the custom attention+quant fusion pass.""" """Deprecated in: v0.12.0. Use fuse_attn_quant instead.
Will be removed in v0.13.0 or v1.0.0, whichever is sooner."""
enable_noop: bool = Field(default=None) enable_noop: bool = Field(default=None)
"""Whether to enable the custom no-op elimination pass.""" """Deprecated in: v0.12.0. Use eliminate_noops instead.
Will be removed in v0.13.0 or v1.0.0, whichever is sooner."""
enable_sequence_parallelism: bool = Field(default=None) enable_sequence_parallelism: bool = Field(default=None)
"""Whether to enable sequence parallelism.""" """Deprecated in: v0.12.0. Use enable_sp instead.
Will be removed in v0.13.0 or v1.0.0, whichever is sooner."""
enable_async_tp: bool = Field(default=None) enable_async_tp: bool = Field(default=None)
"""Whether to enable async TP.""" """Deprecated in: v0.12.0. Use fuse_gemm_comms instead.
Will be removed in v0.13.0 or v1.0.0, whichever is sooner."""
enable_fi_allreduce_fusion: bool = Field(default=None) enable_fi_allreduce_fusion: bool = Field(default=None)
"""Whether to enable flashinfer allreduce fusion.""" """Deprecated in: v0.12.0. Use fuse_allreduce_rms instead.
Will be removed in v0.13.0 or v1.0.0, whichever is sooner."""
fi_allreduce_fusion_max_size_mb: float | None = None fi_allreduce_fusion_max_size_mb: float | None = None
"""The threshold of the communicated tensor sizes under which """The threshold of the communicated tensor sizes under which
vllm should use flashinfer fused allreduce. Specified as a vllm should use flashinfer fused allreduce. Specified as a
@@ -136,7 +161,7 @@ class PassConfig:
}, },
}, where key is the device capability""" }, where key is the device capability"""
enable_qk_norm_rope_fusion: bool = False enable_qk_norm_rope_fusion: bool = False
"""Whether to enable the fused Q/K RMSNorm + RoPE pass.""" """Enable fused Q/K RMSNorm + RoPE pass."""
# TODO(luka) better pass enabling system. # TODO(luka) better pass enabling system.
@@ -174,6 +199,13 @@ class PassConfig:
return InductorPass.hash_dict(asdict(self)) return InductorPass.hash_dict(asdict(self))
@field_validator( @field_validator(
"fuse_norm_quant",
"fuse_act_quant",
"fuse_attn_quant",
"eliminate_noops",
"enable_sp",
"fuse_gemm_comms",
"fuse_allreduce_rms",
"enable_fusion", "enable_fusion",
"enable_attn_fusion", "enable_attn_fusion",
"enable_noop", "enable_noop",
@@ -190,18 +222,71 @@ class PassConfig:
return handler(value) return handler(value)
def __post_init__(self) -> None: def __post_init__(self) -> None:
if not self.enable_noop: # Handle deprecation and defaults
if self.enable_fusion:
# Map old flags to new flags and issue warnings
handle_deprecated(
self,
"enable_fusion",
["fuse_norm_quant", "fuse_act_quant"],
"v0.13.0 or v1.0.0, whichever is sooner",
)
handle_deprecated(
self,
"enable_attn_fusion",
"fuse_attn_quant",
"v0.13.0 or v1.0.0, whichever is sooner",
)
handle_deprecated(
self,
"enable_sequence_parallelism",
"enable_sp",
"v0.13.0 or v1.0.0, whichever is sooner",
)
handle_deprecated(
self,
"enable_async_tp",
"fuse_gemm_comms",
"v0.13.0 or v1.0.0, whichever is sooner",
)
handle_deprecated(
self,
"enable_fi_allreduce_fusion",
"fuse_allreduce_rms",
"v0.13.0 or v1.0.0, whichever is sooner",
)
handle_deprecated(
self,
"enable_noop",
"eliminate_noops",
"v0.13.0 or v1.0.0, whichever is sooner",
)
# Force old flags to None to ensure they are not used
self.enable_fusion = None
self.enable_attn_fusion = None
self.enable_noop = None
self.enable_sequence_parallelism = None
self.enable_async_tp = None
self.enable_fi_allreduce_fusion = None
if not self.eliminate_noops:
if self.fuse_norm_quant or self.fuse_act_quant:
logger.warning_once( logger.warning_once(
"Fusion enabled but reshape elimination disabled. " "Fusion enabled but reshape elimination disabled. "
"RMSNorm/SiluMul + quant (fp8) fusion might not work" "RMSNorm/SiluMul + quant (fp8) fusion might not work"
) )
if self.enable_attn_fusion: if self.fuse_attn_quant:
logger.warning_once( logger.warning_once(
"Fusion enabled but reshape elimination disabled. " "Fusion enabled but reshape elimination disabled. "
"Attention + quant (fp8) fusion might not work" "Attention + quant (fp8) fusion might not work"
) )
if self.enable_fi_allreduce_fusion: if self.fuse_allreduce_rms:
logger.warning_once( logger.warning_once(
"Fusion enabled but reshape elimination disabled. " "Fusion enabled but reshape elimination disabled. "
"Allreduce + rms norm + quant (fp8) fusion might not work" "Allreduce + rms norm + quant (fp8) fusion might not work"
@@ -873,7 +958,7 @@ class CompilationConfig:
self.set_splitting_ops_for_inductor_graph_partition() self.set_splitting_ops_for_inductor_graph_partition()
return return
if self.pass_config.enable_attn_fusion: if self.pass_config.fuse_attn_quant:
# here use_inductor_graph_partition is False # here use_inductor_graph_partition is False
self.set_splitting_ops_for_attn_fusion() self.set_splitting_ops_for_attn_fusion()
return return
@@ -915,12 +1000,12 @@ class CompilationConfig:
self.splitting_ops = list(self._attention_ops) self.splitting_ops = list(self._attention_ops)
def set_splitting_ops_for_attn_fusion(self): def set_splitting_ops_for_attn_fusion(self):
assert self.pass_config.enable_attn_fusion assert self.pass_config.fuse_attn_quant
if self.splitting_ops is None: if self.splitting_ops is None:
self.splitting_ops = [] self.splitting_ops = []
if self.cudagraph_mode.has_piecewise_cudagraphs(): if self.cudagraph_mode.has_piecewise_cudagraphs():
logger.warning_once( logger.warning_once(
"enable_attn_fusion is incompatible with piecewise " "fuse_attn_quant is incompatible with piecewise "
"cudagraph when use_inductor_graph_partition is off. " "cudagraph when use_inductor_graph_partition is off. "
"In this case, splitting_ops will be set to empty " "In this case, splitting_ops will be set to empty "
"list, and cudagraph_mode will be set to FULL. " "list, and cudagraph_mode will be set to FULL. "
@@ -931,8 +1016,7 @@ class CompilationConfig:
self.cudagraph_mode = CUDAGraphMode.FULL self.cudagraph_mode = CUDAGraphMode.FULL
assert not self.splitting_ops_contain_attention(), ( assert not self.splitting_ops_contain_attention(), (
"attention ops should not be in splitting_ops " "attention ops should not be in splitting_ops when fuse_attn_quant is True"
"when enable_attn_fusion is True"
) )
def splitting_ops_contain_attention(self) -> bool: def splitting_ops_contain_attention(self) -> bool:
@@ -1008,7 +1092,7 @@ class CompilationConfig:
self, uniform_decode_query_len: int, tensor_parallel_size: int self, uniform_decode_query_len: int, tensor_parallel_size: int
): ):
multiple_of = uniform_decode_query_len multiple_of = uniform_decode_query_len
if tensor_parallel_size > 1 and self.pass_config.enable_sequence_parallelism: if tensor_parallel_size > 1 and self.pass_config.enable_sp:
multiple_of = max(uniform_decode_query_len, tensor_parallel_size) multiple_of = max(uniform_decode_query_len, tensor_parallel_size)
if ( if (
multiple_of % uniform_decode_query_len != 0 multiple_of % uniform_decode_query_len != 0
+24 -18
View File
@@ -28,6 +28,19 @@ SchedulerPolicy = Literal["fcfs", "priority"]
class SchedulerConfig: class SchedulerConfig:
"""Scheduler configuration.""" """Scheduler configuration."""
max_model_len: InitVar[int]
"""Maximum length of a sequence (including prompt and generated text).
Note: This is stored in the ModelConfig, and is used only here to
provide fallbacks and validate other attributes."""
is_encoder_decoder: InitVar[bool]
"""True if the model is an encoder-decoder model.
Note: This is stored in the ModelConfig, and is used only here to
disable chunked prefill and prefix caching for encoder-decoder models.
"""
DEFAULT_MAX_NUM_BATCHED_TOKENS: ClassVar[int] = 2048 DEFAULT_MAX_NUM_BATCHED_TOKENS: ClassVar[int] = 2048
DEFAULT_MAX_NUM_SEQS: ClassVar[int] = 128 DEFAULT_MAX_NUM_SEQS: ClassVar[int] = 128
@@ -73,19 +86,6 @@ class SchedulerConfig:
is_multimodal_model: bool = False is_multimodal_model: bool = False
"""True if the model is multimodal.""" """True if the model is multimodal."""
max_model_len: InitVar[int] = 8192
"""Maximum length of a sequence (including prompt and generated text).
Note: This is stored in the ModelConfig, and is used only here to
provide fallbacks and validate other attributes."""
is_encoder_decoder: InitVar[bool] = False
"""True if the model is an encoder-decoder model.
Note: This is stored in the ModelConfig, and is used only here to
disable chunked prefill and prefix caching for encoder-decoder models.
"""
# TODO (ywang96): Make this configurable. # TODO (ywang96): Make this configurable.
max_num_encoder_input_tokens: int = Field(init=False) max_num_encoder_input_tokens: int = Field(init=False)
"""Multimodal encoder compute budget, only used in V1. """Multimodal encoder compute budget, only used in V1.
@@ -141,6 +141,17 @@ class SchedulerConfig:
while a larger value (e.g., 10) reduces host overhead and may increase throughput while a larger value (e.g., 10) reduces host overhead and may increase throughput
by batching multiple tokens before sending.""" by batching multiple tokens before sending."""
@staticmethod
def default_factory(**kwargs):
"""
Factory method to create `SchedulerConfig` with default values for `InitVar`s.
"""
if "max_model_len" not in kwargs:
kwargs["max_model_len"] = 8192
if "is_encoder_decoder" not in kwargs:
kwargs["is_encoder_decoder"] = False
return SchedulerConfig(**kwargs)
def get_scheduler_cls(self) -> type["SchedulerInterface"]: def get_scheduler_cls(self) -> type["SchedulerInterface"]:
if self.scheduler_cls is None: if self.scheduler_cls is None:
if self.async_scheduling: if self.async_scheduling:
@@ -284,8 +295,3 @@ class SchedulerConfig:
) )
return self return self
def __getattribute__(self, name: str) -> Any:
if name == "max_model_len" or name == "is_encoder_decoder":
raise AttributeError(f"{name} is an init-only parameter. ")
return object.__getattribute__(self, name)
+29
View File
@@ -19,6 +19,10 @@ import torch
from pydantic.fields import FieldInfo from pydantic.fields import FieldInfo
from typing_extensions import runtime_checkable from typing_extensions import runtime_checkable
from vllm.logger import init_logger
logger = init_logger(__name__)
if TYPE_CHECKING: if TYPE_CHECKING:
from _typeshed import DataclassInstance from _typeshed import DataclassInstance
else: else:
@@ -293,3 +297,28 @@ def get_hash_factors(config: ConfigT, ignored_factors: set[str]) -> dict[str, ob
def hash_factors(items: dict[str, object]) -> str: def hash_factors(items: dict[str, object]) -> str:
"""Return a SHA-256 hex digest of the canonical items structure.""" """Return a SHA-256 hex digest of the canonical items structure."""
return hashlib.sha256(json.dumps(items, sort_keys=True).encode()).hexdigest() return hashlib.sha256(json.dumps(items, sort_keys=True).encode()).hexdigest()
def handle_deprecated(
config: ConfigT,
old_name: str,
new_name_or_names: str | list[str],
removal_version: str,
) -> None:
old_val = getattr(config, old_name)
if old_val is None:
return
if isinstance(new_name_or_names, str):
new_names = [new_name_or_names]
else:
new_names = new_name_or_names
msg = (
f"{old_name} is deprecated and will be removed in {removal_version}. "
f"Use {', '.join(new_names)} instead."
)
logger.warning(msg)
for new_name in new_names:
setattr(config, new_name, old_val)
+48 -32
View File
@@ -83,22 +83,33 @@ IS_DENSE = False
# See https://github.com/vllm-project/vllm/issues/25689. # See https://github.com/vllm-project/vllm/issues/25689.
def enable_fusion(cfg: "VllmConfig") -> bool: def enable_norm_fusion(cfg: "VllmConfig") -> bool:
"""Returns True if RMS norm or quant FP8 is enabled.""" """Enable if either RMS norm or quant FP8 custom op is active;
otherwise Inductor handles fusion."""
return cfg.compilation_config.is_custom_op_enabled( return cfg.compilation_config.is_custom_op_enabled(
"rms_norm" "rms_norm"
) or cfg.compilation_config.is_custom_op_enabled("quant_fp8") ) or cfg.compilation_config.is_custom_op_enabled("quant_fp8")
def enable_act_fusion(cfg: "VllmConfig") -> bool:
"""Enable if either SiLU+Mul or quant FP8 custom op is active;
otherwise Inductor handles fusion."""
return cfg.compilation_config.is_custom_op_enabled(
"silu_and_mul"
) or cfg.compilation_config.is_custom_op_enabled("quant_fp8")
OPTIMIZATION_LEVEL_00 = { OPTIMIZATION_LEVEL_00 = {
"compilation_config": { "compilation_config": {
"pass_config": { "pass_config": {
"enable_noop": False, "eliminate_noops": False,
"enable_fusion": False, "fuse_norm_quant": False,
"enable_fi_allreduce_fusion": False, "fuse_act_quant": False,
"enable_attn_fusion": False, "fuse_allreduce_rms": False,
"enable_sequence_parallelism": False, "fuse_attn_quant": False,
"enable_async_tp": False, "enable_sp": False,
"fuse_gemm_comms": False,
}, },
"cudagraph_mode": CUDAGraphMode.NONE, "cudagraph_mode": CUDAGraphMode.NONE,
"use_inductor_graph_partition": False, "use_inductor_graph_partition": False,
@@ -107,12 +118,13 @@ OPTIMIZATION_LEVEL_00 = {
OPTIMIZATION_LEVEL_01 = { OPTIMIZATION_LEVEL_01 = {
"compilation_config": { "compilation_config": {
"pass_config": { "pass_config": {
"enable_noop": True, "eliminate_noops": True,
"enable_fusion": enable_fusion, "fuse_norm_quant": enable_norm_fusion,
"enable_fi_allreduce_fusion": False, "fuse_act_quant": enable_act_fusion,
"enable_attn_fusion": False, "fuse_allreduce_rms": False,
"enable_sequence_parallelism": False, "fuse_attn_quant": False,
"enable_async_tp": False, "enable_sp": False,
"fuse_gemm_comms": False,
}, },
"cudagraph_mode": CUDAGraphMode.PIECEWISE, "cudagraph_mode": CUDAGraphMode.PIECEWISE,
"use_inductor_graph_partition": False, "use_inductor_graph_partition": False,
@@ -121,12 +133,13 @@ OPTIMIZATION_LEVEL_01 = {
OPTIMIZATION_LEVEL_02 = { OPTIMIZATION_LEVEL_02 = {
"compilation_config": { "compilation_config": {
"pass_config": { "pass_config": {
"enable_noop": True, "eliminate_noops": True,
"enable_fusion": enable_fusion, "fuse_norm_quant": enable_norm_fusion,
"enable_fi_allreduce_fusion": False, "fuse_act_quant": enable_act_fusion,
"enable_attn_fusion": IS_QUANTIZED, "fuse_allreduce_rms": False,
"enable_sequence_parallelism": IS_DENSE, "fuse_attn_quant": IS_QUANTIZED,
"enable_async_tp": IS_DENSE, "enable_sp": IS_DENSE,
"fuse_gemm_comms": IS_DENSE,
}, },
"cudagraph_mode": CUDAGraphMode.FULL_AND_PIECEWISE, "cudagraph_mode": CUDAGraphMode.FULL_AND_PIECEWISE,
"use_inductor_graph_partition": False, "use_inductor_graph_partition": False,
@@ -135,12 +148,13 @@ OPTIMIZATION_LEVEL_02 = {
OPTIMIZATION_LEVEL_03 = { OPTIMIZATION_LEVEL_03 = {
"compilation_config": { "compilation_config": {
"pass_config": { "pass_config": {
"enable_noop": True, "eliminate_noops": True,
"enable_fusion": enable_fusion, "fuse_norm_quant": enable_norm_fusion,
"enable_fi_allreduce_fusion": False, "fuse_act_quant": enable_act_fusion,
"enable_attn_fusion": IS_QUANTIZED, "fuse_allreduce_rms": False,
"enable_sequence_parallelism": IS_DENSE, "fuse_attn_quant": IS_QUANTIZED,
"enable_async_tp": IS_DENSE, "enable_sp": IS_DENSE,
"fuse_gemm_comms": IS_DENSE,
}, },
"cudagraph_mode": CUDAGraphMode.FULL_AND_PIECEWISE, "cudagraph_mode": CUDAGraphMode.FULL_AND_PIECEWISE,
"use_inductor_graph_partition": False, "use_inductor_graph_partition": False,
@@ -170,7 +184,9 @@ class VllmConfig:
"""Cache configuration.""" """Cache configuration."""
parallel_config: ParallelConfig = Field(default_factory=ParallelConfig) parallel_config: ParallelConfig = Field(default_factory=ParallelConfig)
"""Parallel configuration.""" """Parallel configuration."""
scheduler_config: SchedulerConfig = Field(default_factory=SchedulerConfig) scheduler_config: SchedulerConfig = Field(
default_factory=SchedulerConfig.default_factory,
)
"""Scheduler configuration.""" """Scheduler configuration."""
device_config: DeviceConfig = Field(default_factory=DeviceConfig) device_config: DeviceConfig = Field(default_factory=DeviceConfig)
"""Device configuration.""" """Device configuration."""
@@ -643,9 +659,9 @@ class VllmConfig:
# async tp is built on top of sequence parallelism # async tp is built on top of sequence parallelism
# and requires it to be enabled. # and requires it to be enabled.
if self.compilation_config.pass_config.enable_async_tp: if self.compilation_config.pass_config.fuse_gemm_comms:
self.compilation_config.pass_config.enable_sequence_parallelism = True self.compilation_config.pass_config.enable_sp = True
if self.compilation_config.pass_config.enable_sequence_parallelism: if self.compilation_config.pass_config.enable_sp:
if "-rms_norm" in self.compilation_config.custom_ops: if "-rms_norm" in self.compilation_config.custom_ops:
logger.warning( logger.warning(
"RMS norm force disabled, sequence parallelism might break" "RMS norm force disabled, sequence parallelism might break"
@@ -795,7 +811,7 @@ class VllmConfig:
# Do this after all the updates to compilation_config.mode # Do this after all the updates to compilation_config.mode
self.compilation_config.set_splitting_ops_for_v1() self.compilation_config.set_splitting_ops_for_v1()
if self.compilation_config.pass_config.enable_sequence_parallelism: if self.compilation_config.pass_config.enable_sp:
# With pipeline parallelism or dynamo partitioning, # With pipeline parallelism or dynamo partitioning,
# native rms norm tracing errors due to incorrect residual shape. # native rms norm tracing errors due to incorrect residual shape.
# Use custom rms norm to unblock. In the future, # Use custom rms norm to unblock. In the future,
@@ -1060,7 +1076,7 @@ class VllmConfig:
if ( if (
self.parallel_config.tensor_parallel_size > 1 self.parallel_config.tensor_parallel_size > 1
and self.compilation_config.pass_config.enable_sequence_parallelism and self.compilation_config.pass_config.enable_sp
): ):
cudagraph_capture_sizes = self.update_sizes_for_sequence_parallelism( cudagraph_capture_sizes = self.update_sizes_for_sequence_parallelism(
cudagraph_capture_sizes cudagraph_capture_sizes
-14
View File
@@ -420,10 +420,6 @@ class EngineArgs:
) )
_api_process_count: int = ParallelConfig._api_process_count _api_process_count: int = ParallelConfig._api_process_count
_api_process_rank: int = ParallelConfig._api_process_rank _api_process_rank: int = ParallelConfig._api_process_rank
num_redundant_experts: int = EPLBConfig.num_redundant_experts
eplb_window_size: int = EPLBConfig.window_size
eplb_step_interval: int = EPLBConfig.step_interval
eplb_log_balancedness: bool = EPLBConfig.log_balancedness
max_parallel_loading_workers: int | None = ( max_parallel_loading_workers: int | None = (
ParallelConfig.max_parallel_loading_workers ParallelConfig.max_parallel_loading_workers
) )
@@ -1581,16 +1577,6 @@ class EngineArgs:
) )
self.disable_nccl_for_dp_synchronization = True self.disable_nccl_for_dp_synchronization = True
# Forward the deprecated CLI args to the EPLB config.
if self.num_redundant_experts is not None:
self.eplb_config.num_redundant_experts = self.num_redundant_experts
if self.eplb_window_size is not None:
self.eplb_config.window_size = self.eplb_window_size
if self.eplb_step_interval is not None:
self.eplb_config.step_interval = self.eplb_step_interval
if self.eplb_log_balancedness is not None:
self.eplb_config.log_balancedness = self.eplb_log_balancedness
parallel_config = ParallelConfig( parallel_config = ParallelConfig(
pipeline_parallel_size=self.pipeline_parallel_size, pipeline_parallel_size=self.pipeline_parallel_size,
tensor_parallel_size=self.tensor_parallel_size, tensor_parallel_size=self.tensor_parallel_size,
+1 -1
View File
@@ -37,7 +37,7 @@ from vllm.inputs.data import PromptType
from vllm.logger import init_logger from vllm.logger import init_logger
from vllm.model_executor.models import SupportsTranscription from vllm.model_executor.models import SupportsTranscription
from vllm.outputs import RequestOutput from vllm.outputs import RequestOutput
from vllm.transformers_utils.tokenizer import get_tokenizer from vllm.tokenizers import get_tokenizer
from vllm.utils.import_utils import PlaceholderModule from vllm.utils.import_utils import PlaceholderModule
try: try:
@@ -80,7 +80,7 @@ class MistralToolParser(ToolParser):
self.tool_call_regex = re.compile(r"\[{.*}\]", re.DOTALL) self.tool_call_regex = re.compile(r"\[{.*}\]", re.DOTALL)
if _is_fn_name_regex_support(self.model_tokenizer): if _is_fn_name_regex_support(self.model_tokenizer):
self.fn_name_regex = re.compile( self.fn_name_regex = re.compile(
r"([a-zA-Z0-9_-]+)(\{[\s\S]*?\})(?=\s*$|,|\s)?", re.DOTALL r"([a-zA-Z0-9_-]+)(\{[\s\S]*?\}+)", re.DOTALL
) )
else: else:
self.fn_name_regex = None self.fn_name_regex = None
+2 -2
View File
@@ -33,7 +33,7 @@ class RenderConfig:
`0` yields an empty list (and skips embeds). `0` yields an empty list (and skips embeds).
`-1` maps to `model_config.max_model_len`.""" `-1` maps to `model_config.max_model_len`."""
add_special_tokens: bool | None = True add_special_tokens: bool = True
"""Whether to add model-specific special tokens during tokenization.""" """Whether to add model-specific special tokens during tokenization."""
cache_salt: str | None = None cache_salt: str | None = None
@@ -315,7 +315,7 @@ class CompletionRenderer(BaseRenderer):
text: str, text: str,
max_length: int | None, max_length: int | None,
truncate_prompt_tokens: int | None, truncate_prompt_tokens: int | None,
add_special_tokens: bool | None, add_special_tokens: bool,
cache_salt: str | None, cache_salt: str | None,
) -> EngineTokensPrompt: ) -> EngineTokensPrompt:
"""Tokenize text input asynchronously.""" """Tokenize text input asynchronously."""
+1 -1
View File
@@ -19,7 +19,7 @@ from vllm.inputs import TokensPrompt
from vllm.model_executor.models.interfaces import supports_score_template from vllm.model_executor.models.interfaces import supports_score_template
from vllm.multimodal.inputs import MultiModalDataDict from vllm.multimodal.inputs import MultiModalDataDict
from vllm.outputs import PoolingRequestOutput from vllm.outputs import PoolingRequestOutput
from vllm.transformers_utils.tokenizer import TokenizerLike from vllm.tokenizers import TokenizerLike
ScoreContentPartParam: TypeAlias = ( ScoreContentPartParam: TypeAlias = (
ChatCompletionContentPartImageParam | ChatCompletionContentPartImageEmbedsParam ChatCompletionContentPartImageParam | ChatCompletionContentPartImageEmbedsParam
@@ -346,11 +346,16 @@ class DeepSeekMTP(nn.Module, SupportsPP, DeepseekV2MixtureOfExperts):
# Use expert_params_mapping to locate the destination # Use expert_params_mapping to locate the destination
# param and delegate to its expert-aware weight_loader # param and delegate to its expert-aware weight_loader
# with expert_id. # with expert_id.
is_expert_weight = False
for mapping in expert_params_mapping: for mapping in expert_params_mapping:
param_name, weight_name, expert_id, shard_id = mapping param_name, weight_name, expert_id, shard_id = mapping
if weight_name not in chunk_name: if weight_name not in chunk_name:
continue continue
# Anyway, this is an expert weight and should not be
# attempted to load as other weights later
is_expert_weight = True
# Do not modify `name` since the loop may continue here # Do not modify `name` since the loop may continue here
# Instead, create a new variable # Instead, create a new variable
name_mapped = chunk_name.replace(weight_name, param_name) name_mapped = chunk_name.replace(weight_name, param_name)
@@ -377,6 +382,12 @@ class DeepSeekMTP(nn.Module, SupportsPP, DeepseekV2MixtureOfExperts):
loaded_params.add(name_mapped) loaded_params.add(name_mapped)
break break
else: else:
if is_expert_weight:
# We've checked that this is an expert weight
# However it's not mapped locally to this rank
# So we simply skip it
continue
# Skip loading extra bias for GPTQ models. # Skip loading extra bias for GPTQ models.
if name.endswith(".bias") and name not in params_dict: if name.endswith(".bias") and name not in params_dict:
continue continue
+10 -5
View File
@@ -1135,6 +1135,8 @@ class DeepseekV2DecoderLayer(nn.Module):
dim == 0 for dim in (qk_nope_head_dim, qk_rope_head_dim) dim == 0 for dim in (qk_nope_head_dim, qk_rope_head_dim)
) )
self.use_mha = use_mha
if use_mha: if use_mha:
attn_cls = DeepseekAttention attn_cls = DeepseekAttention
elif model_config.use_mla: elif model_config.use_mla:
@@ -1196,11 +1198,14 @@ class DeepseekV2DecoderLayer(nn.Module):
hidden_states = self.input_layernorm(hidden_states) hidden_states = self.input_layernorm(hidden_states)
else: else:
hidden_states, residual = self.input_layernorm(hidden_states, residual) hidden_states, residual = self.input_layernorm(hidden_states, residual)
hidden_states = self.self_attn(
positions=positions, attn_kwargs = {
hidden_states=hidden_states, "positions": positions,
llama_4_scaling=llama_4_scaling, "hidden_states": hidden_states,
) }
if not self.use_mha:
attn_kwargs["llama_4_scaling"] = llama_4_scaling
hidden_states = self.self_attn(**attn_kwargs)
if ( if (
not isinstance(self.self_attn, DeepseekAttention) not isinstance(self.self_attn, DeepseekAttention)
+1
View File
@@ -338,6 +338,7 @@ class Idefics3MultiModalProcessor(BaseMultiModalProcessor[Idefics3ProcessingInfo
prompt_ids = self._apply_hf_processor_tokens_only(prompt_ids) prompt_ids = self._apply_hf_processor_tokens_only(prompt_ids)
return BatchFeature(dict(input_ids=[prompt_ids]), tensor_type="pt") return BatchFeature(dict(input_ids=[prompt_ids]), tensor_type="pt")
mm_kwargs = {"input_data_format": "channels_last", **mm_kwargs}
processed_outputs = super()._call_hf_processor( processed_outputs = super()._call_hf_processor(
prompt, prompt,
mm_data, mm_data,
+10 -15
View File
@@ -75,7 +75,6 @@ from vllm.multimodal.profiling import BaseDummyInputsBuilder
from vllm.sequence import IntermediateTensors from vllm.sequence import IntermediateTensors
from vllm.tokenizers import TokenizerLike, cached_tokenizer_from_config from vllm.tokenizers import TokenizerLike, cached_tokenizer_from_config
from vllm.transformers_utils.configs.radio import RadioConfig from vllm.transformers_utils.configs.radio import RadioConfig
from vllm.transformers_utils.tokenizer import encode_tokens
from vllm.utils.tensor_schema import TensorSchema, TensorShape from vllm.utils.tensor_schema import TensorSchema, TensorShape
from .utils import _merge_multimodal_embeddings from .utils import _merge_multimodal_embeddings
@@ -454,14 +453,12 @@ class NanoNemotronVLProcessor(BaseNanoNemotronVLProcessor):
# Pre-tokenize special tokens for video processing # Pre-tokenize special tokens for video processing
# to avoid repeated tokenization # to avoid repeated tokenization
self._img_start_token_ids = encode_tokens( self._img_start_token_ids = tokenizer.encode(
tokenizer, IMG_START, add_special_tokens=False IMG_START, add_special_tokens=False
) )
self._img_end_token_ids = encode_tokens( self._img_end_token_ids = tokenizer.encode(IMG_END, add_special_tokens=False)
tokenizer, IMG_END, add_special_tokens=False self._img_context_token_ids = tokenizer.encode(
) IMG_CONTEXT, add_special_tokens=False
self._img_context_token_ids = encode_tokens(
tokenizer, IMG_CONTEXT, add_special_tokens=False
) )
@property @property
@@ -1179,14 +1176,12 @@ class NemotronH_Nano_VL_V2(
# Pre-tokenize special tokens for video processing # Pre-tokenize special tokens for video processing
# to avoid repeated tokenization # to avoid repeated tokenization
tokenizer = cached_tokenizer_from_config(vllm_config.model_config) tokenizer = cached_tokenizer_from_config(vllm_config.model_config)
self._img_start_token_ids = encode_tokens( self._img_start_token_ids = tokenizer.encode(
tokenizer, IMG_START, add_special_tokens=False IMG_START, add_special_tokens=False
) )
self._img_end_token_ids = encode_tokens( self._img_end_token_ids = tokenizer.encode(IMG_END, add_special_tokens=False)
tokenizer, IMG_END, add_special_tokens=False self._img_context_token_ids = tokenizer.encode(
) IMG_CONTEXT, add_special_tokens=False
self._img_context_token_ids = encode_tokens(
tokenizer, IMG_CONTEXT, add_special_tokens=False
) )
def pixel_shuffle(self, x, scale_factor=0.5): def pixel_shuffle(self, x, scale_factor=0.5):
@@ -88,7 +88,6 @@ from vllm.multimodal.processing import (
) )
from vllm.multimodal.profiling import BaseDummyInputsBuilder from vllm.multimodal.profiling import BaseDummyInputsBuilder
from vllm.sequence import IntermediateTensors from vllm.sequence import IntermediateTensors
from vllm.transformers_utils.tokenizer import encode_tokens
from vllm.utils.tensor_schema import TensorSchema, TensorShape from vllm.utils.tensor_schema import TensorSchema, TensorShape
from .interfaces import ( from .interfaces import (
@@ -591,7 +590,7 @@ class Qwen2_5OmniThinkerMultiModalProcessor(
tokenization_kwargs=tokenization_kwargs, tokenization_kwargs=tokenization_kwargs,
) )
tokenizer = self.info.get_tokenizer() tokenizer = self.info.get_tokenizer()
prompt_ids = encode_tokens(tokenizer, prompt) prompt_ids = tokenizer.encode(prompt)
else: else:
prompt_ids = self._apply_hf_processor_tokens_only(prompt) prompt_ids = self._apply_hf_processor_tokens_only(prompt)
+8 -11
View File
@@ -25,7 +25,6 @@ from typing_extensions import TypeVar, assert_never
from vllm.logger import init_logger from vllm.logger import init_logger
from vllm.tokenizers import TokenizerLike from vllm.tokenizers import TokenizerLike
from vllm.transformers_utils.processor import cached_processor_from_config from vllm.transformers_utils.processor import cached_processor_from_config
from vllm.transformers_utils.tokenizer import decode_tokens, encode_tokens
from vllm.utils.collection_utils import flatten_2d_lists, full_groupby from vllm.utils.collection_utils import flatten_2d_lists, full_groupby
from vllm.utils.func_utils import get_allowed_kwarg_only_overrides from vllm.utils.func_utils import get_allowed_kwarg_only_overrides
from vllm.utils.jsontree import JSONTree, json_map_leaves from vllm.utils.jsontree import JSONTree, json_map_leaves
@@ -80,9 +79,9 @@ def _cached_encode(
tokenizer: TokenizerLike, tokenizer: TokenizerLike,
text: str, text: str,
*, *,
add_special_tokens: bool | None = None, add_special_tokens: bool = True,
) -> list[int]: ) -> list[int]:
return encode_tokens(tokenizer, text, add_special_tokens=add_special_tokens) return tokenizer.encode(text, add_special_tokens=add_special_tokens)
@lru_cache(maxsize=2048) @lru_cache(maxsize=2048)
@@ -90,11 +89,9 @@ def _cached_decode(
tokenizer: TokenizerLike, tokenizer: TokenizerLike,
token_ids: tuple[int, ...], token_ids: tuple[int, ...],
*, *,
skip_special_tokens: bool | None = None, skip_special_tokens: bool = False,
) -> str: ) -> str:
return decode_tokens( return tokenizer.decode(list(token_ids), skip_special_tokens=skip_special_tokens)
tokenizer, list(token_ids), skip_special_tokens=skip_special_tokens
)
def _seq2text( def _seq2text(
@@ -110,7 +107,7 @@ def _seq2text(
raise ValueError("You cannot decode tokens when `skip_tokenizer_init=True`") raise ValueError("You cannot decode tokens when `skip_tokenizer_init=True`")
if not use_cache: if not use_cache:
return decode_tokens(tokenizer, seq) return tokenizer.decode(seq)
return _cached_decode(tokenizer, tuple(seq)) return _cached_decode(tokenizer, tuple(seq))
@@ -126,7 +123,7 @@ def _seq2tokens(
raise ValueError("You cannot encode text when `skip_tokenizer_init=True`") raise ValueError("You cannot encode text when `skip_tokenizer_init=True`")
if not use_cache: if not use_cache:
return encode_tokens(tokenizer, seq, add_special_tokens=False) return tokenizer.encode(seq, add_special_tokens=False)
return _cached_encode(tokenizer, seq, add_special_tokens=False) return _cached_encode(tokenizer, seq, add_special_tokens=False)
@@ -2198,8 +2195,8 @@ class EncDecMultiModalProcessor(BaseMultiModalProcessor[_I]):
tokenizer = self.info.get_tokenizer() tokenizer = self.info.get_tokenizer()
decoder_prompt_raw = self.create_decoder_prompt(prompt, mm_data) decoder_prompt_raw = self.create_decoder_prompt(prompt, mm_data)
if isinstance(decoder_prompt_raw, str): if isinstance(decoder_prompt_raw, str):
decoder_prompt_ids = encode_tokens( decoder_prompt_ids = tokenizer.encode(
tokenizer, decoder_prompt_raw, add_special_tokens=False decoder_prompt_raw, add_special_tokens=False
) )
else: else:
decoder_prompt_ids = decoder_prompt_raw decoder_prompt_ids = decoder_prompt_raw
+4
View File
@@ -4,6 +4,8 @@
import warnings import warnings
from typing import Any from typing import Any
from typing_extensions import deprecated
from vllm.logger import init_logger from vllm.logger import init_logger
from vllm.tokenizers import TokenizerLike from vllm.tokenizers import TokenizerLike
@@ -73,6 +75,7 @@ def __getattr__(name: str):
raise AttributeError(f"module {__name__!r} has no attribute {name!r}") raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
@deprecated("Will be removed in v0.13. Please use `tokenizer.decode()` instead.")
def decode_tokens( def decode_tokens(
tokenizer: TokenizerLike, tokenizer: TokenizerLike,
token_ids: list[int], token_ids: list[int],
@@ -94,6 +97,7 @@ def decode_tokens(
return tokenizer.decode(token_ids, **kw_args) return tokenizer.decode(token_ids, **kw_args)
@deprecated("Will be removed in v0.13. Please use `tokenizer.encode()` instead.")
def encode_tokens( def encode_tokens(
tokenizer: TokenizerLike, tokenizer: TokenizerLike,
text: str, text: str,
+10 -14
View File
@@ -137,31 +137,30 @@ class PriorityRequestQueue(RequestQueue):
""" """
A priority queue that supports heap operations. A priority queue that supports heap operations.
Requests with a smaller value of `priority` are processed first. Respects the ordering defined in the Request class, where
requests with a smaller value of `priority` are processed first.
If multiple requests have the same priority, the one with the earlier If multiple requests have the same priority, the one with the earlier
`arrival_time` is processed first. `arrival_time` is processed first.
""" """
def __init__(self) -> None: def __init__(self) -> None:
self._heap: list[tuple[int, float, Request]] = [] self._heap: list[Request] = []
def add_request(self, request: Request) -> None: def add_request(self, request: Request) -> None:
"""Add a request to the queue according to priority policy.""" """Add a request to the queue according to priority policy."""
heapq.heappush(self._heap, (request.priority, request.arrival_time, request)) heapq.heappush(self._heap, request)
def pop_request(self) -> Request: def pop_request(self) -> Request:
"""Pop a request from the queue according to priority policy.""" """Pop a request from the queue according to priority policy."""
if not self._heap: if not self._heap:
raise IndexError("pop from empty heap") raise IndexError("pop from empty heap")
_, _, request = heapq.heappop(self._heap) return heapq.heappop(self._heap)
return request
def peek_request(self) -> Request: def peek_request(self) -> Request:
"""Peek at the next request in the queue without removing it.""" """Peek at the next request in the queue without removing it."""
if not self._heap: if not self._heap:
raise IndexError("peek from empty heap") raise IndexError("peek from empty heap")
_, _, request = self._heap[0] return self._heap[0]
return request
def prepend_request(self, request: Request) -> None: def prepend_request(self, request: Request) -> None:
"""Add a request to the queue according to priority policy. """Add a request to the queue according to priority policy.
@@ -180,15 +179,13 @@ class PriorityRequestQueue(RequestQueue):
def remove_request(self, request: Request) -> None: def remove_request(self, request: Request) -> None:
"""Remove a specific request from the queue.""" """Remove a specific request from the queue."""
self._heap = [(p, t, r) for p, t, r in self._heap if r != request] self._heap.remove(request)
heapq.heapify(self._heap) heapq.heapify(self._heap)
def remove_requests(self, requests: Iterable[Request]) -> None: def remove_requests(self, requests: Iterable[Request]) -> None:
"""Remove multiple specific requests from the queue.""" """Remove multiple specific requests from the queue."""
requests_to_remove = set(requests) requests_to_remove = requests if isinstance(requests, set) else set(requests)
self._heap = [ self._heap = [r for r in self._heap if r not in requests_to_remove]
(p, t, r) for p, t, r in self._heap if r not in requests_to_remove
]
heapq.heapify(self._heap) heapq.heapify(self._heap)
def __bool__(self) -> bool: def __bool__(self) -> bool:
@@ -203,8 +200,7 @@ class PriorityRequestQueue(RequestQueue):
"""Iterate over the queue according to priority policy.""" """Iterate over the queue according to priority policy."""
heap_copy = self._heap[:] heap_copy = self._heap[:]
while heap_copy: while heap_copy:
_, _, request = heapq.heappop(heap_copy) yield heapq.heappop(heap_copy)
yield request
def __reversed__(self) -> Iterator[Request]: def __reversed__(self) -> Iterator[Request]:
"""Iterate over the queue in reverse priority order.""" """Iterate over the queue in reverse priority order."""
+13
View File
@@ -227,6 +227,19 @@ class Request:
events, self.events = self.events, [] events, self.events = self.events, []
return events return events
def __lt__(self, other: "Request") -> bool:
"""
Compare two requests based on priority, arrival time, and request ID.
Used in priority scheduling.
"""
if self.priority != other.priority:
return self.priority < other.priority
if self.arrival_time != other.arrival_time:
return self.arrival_time < other.arrival_time
if self.request_id != other.request_id:
return self.request_id < other.request_id
return id(self) < id(other)
class RequestStatus(enum.IntEnum): class RequestStatus(enum.IntEnum):
"""Status of a request.""" """Status of a request."""
+6 -2
View File
@@ -110,7 +110,7 @@ class MinPLogitsProcessor(LogitsProcessor):
# Identify valid tokens using threshold comparison # Identify valid tokens using threshold comparison
invalid_token_mask = probability_values < adjusted_min_p invalid_token_mask = probability_values < adjusted_min_p
# Apply mask using boolean indexing # Apply mask using boolean indexing
logits[invalid_token_mask] = -float("inf") logits.masked_fill_(invalid_token_mask, -float("inf"))
return logits return logits
@@ -178,6 +178,10 @@ class MinTokensLogitsProcessor(LogitsProcessor):
self._device_tensor([], torch.int32), self._device_tensor([], torch.int32),
) )
self.neg_inf_tensor = torch.tensor(
-float("inf"), dtype=torch.float32, device=self.device
)
def is_argmax_invariant(self) -> bool: def is_argmax_invariant(self) -> bool:
"""By censoring stop tokens, min-tokens can change the outcome """By censoring stop tokens, min-tokens can change the outcome
of the argmax operation in greedy sampling.""" of the argmax operation in greedy sampling."""
@@ -229,7 +233,7 @@ class MinTokensLogitsProcessor(LogitsProcessor):
def apply(self, logits: torch.Tensor) -> torch.Tensor: def apply(self, logits: torch.Tensor) -> torch.Tensor:
if self.min_toks: if self.min_toks:
# Inhibit EOS token for requests which have not reached min length # Inhibit EOS token for requests which have not reached min length
logits[self.logits_slice] = -float("inf") logits.index_put_(self.logits_slice, self.neg_inf_tensor)
return logits return logits
+2 -5
View File
@@ -2417,10 +2417,7 @@ class GPUModelRunner(
# Pad tokens to multiple of tensor_parallel_size when # Pad tokens to multiple of tensor_parallel_size when
# enabled collective fusion for SP # enabled collective fusion for SP
tp_size = self.vllm_config.parallel_config.tensor_parallel_size tp_size = self.vllm_config.parallel_config.tensor_parallel_size
if ( if self.compilation_config.pass_config.enable_sp and tp_size > 1:
self.compilation_config.pass_config.enable_sequence_parallelism
and tp_size > 1
):
return round_up(num_scheduled_tokens, tp_size) return round_up(num_scheduled_tokens, tp_size)
return num_scheduled_tokens return num_scheduled_tokens
@@ -4000,7 +3997,7 @@ class GPUModelRunner(
num_reqs=num_reqs_padded, num_reqs=num_reqs_padded,
max_query_len=max_query_len, max_query_len=max_query_len,
ubatch_slices=ubatch_slices, ubatch_slices=ubatch_slices,
for_cudagraph_capture=True, for_cudagraph_capture=is_graph_capturing,
) )
with self.maybe_dummy_run_with_lora( with self.maybe_dummy_run_with_lora(
+1 -1
View File
@@ -552,7 +552,7 @@ class Worker(WorkerBase):
if ( if (
parallel_config.pipeline_parallel_size > 1 parallel_config.pipeline_parallel_size > 1
and compilation_config.pass_config.enable_sequence_parallelism and compilation_config.pass_config.enable_sp
and forward_pass and forward_pass
): ):
# currently only supported by V1 GPUModelRunner # currently only supported by V1 GPUModelRunner
+1 -1
View File
@@ -342,7 +342,7 @@ def is_residual_scattered_for_sp(
partition), SP is always applied partition), SP is always applied
- Otherwise, SP is only applied for specific shapes in compile_sizes - Otherwise, SP is only applied for specific shapes in compile_sizes
""" """
if not vllm_config.compilation_config.pass_config.enable_sequence_parallelism: if not vllm_config.compilation_config.pass_config.enable_sp:
return False return False
tp = vllm_config.parallel_config.tensor_parallel_size tp = vllm_config.parallel_config.tensor_parallel_size