diff --git a/.github/vllm-release-tag.commit b/.github/vllm-release-tag.commit index 420000f9594e..7fdbfd64bbdc 100644 --- a/.github/vllm-release-tag.commit +++ b/.github/vllm-release-tag.commit @@ -1 +1 @@ -v0.32.0 +v0.33.0 diff --git a/Dockerfile b/Dockerfile index 2a84ccbbb366..e307632dacbf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -32,7 +32,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" RUN if [ -n "$VLLM_COMMIT" ]; then \ diff --git a/Dockerfile.310p b/Dockerfile.310p index 8b849b4017e8..dcc41f89bf09 100644 --- a/Dockerfile.310p +++ b/Dockerfile.310p @@ -30,7 +30,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" RUN if [ -n "$VLLM_COMMIT" ]; then \ diff --git a/Dockerfile.310p.openEuler b/Dockerfile.310p.openEuler index 61be55c37dbb..7aa48cd0bf6d 100644 --- a/Dockerfile.310p.openEuler +++ b/Dockerfile.310p.openEuler @@ -29,7 +29,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" RUN if [ -n "$VLLM_COMMIT" ]; then \ diff --git a/Dockerfile.a3 b/Dockerfile.a3 index 3fa9b1893544..025a477a1c98 100644 --- a/Dockerfile.a3 +++ b/Dockerfile.a3 @@ -35,7 +35,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" RUN if [ -n "$VLLM_COMMIT" ]; then \ diff --git a/Dockerfile.a3.openEuler b/Dockerfile.a3.openEuler index 1f16b5d84ae9..615e7501030e 100644 --- a/Dockerfile.a3.openEuler +++ b/Dockerfile.a3.openEuler @@ -32,7 +32,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" RUN if [ -n "$VLLM_COMMIT" ]; then \ diff --git a/Dockerfile.a5 b/Dockerfile.a5 index 9b25add6e761..89e758ebf12f 100644 --- a/Dockerfile.a5 +++ b/Dockerfile.a5 @@ -35,7 +35,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" ARG CARGO_BUILD_JOBS=16 diff --git a/Dockerfile.a5.openEuler b/Dockerfile.a5.openEuler index 31603c685c5a..be7aa237f9a6 100644 --- a/Dockerfile.a5.openEuler +++ b/Dockerfile.a5.openEuler @@ -32,7 +32,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" ARG CARGO_BUILD_JOBS=16 diff --git a/Dockerfile.openEuler b/Dockerfile.openEuler index 0bf28f92c95d..47ffd648a2dd 100644 --- a/Dockerfile.openEuler +++ b/Dockerfile.openEuler @@ -32,7 +32,7 @@ RUN python3 -m pip install 'modelscope<1.38' 'ray>=2.47.1,<=2.48.0' 'protobuf>3. # Install vLLM ARG VLLM_REPO=https://github.com/vllm-project/vllm.git -ARG VLLM_TAG=v0.32.0 +ARG VLLM_TAG=v0.33.0 ARG VLLM_COMMIT="" ARG PYTORCH_INDEX_URL="https://download.pytorch.org/whl/cpu/" RUN if [ -n "$VLLM_COMMIT" ]; then \ diff --git a/README.md b/README.md index 5847fb4179be..bb9f079ed58e 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Below are the maintained branches: | Branch | Status | Note | |------------------|--------------|--------------------------------------| -| main | Maintained | CI commitment for vLLM main branch and vLLM v0.32.0 tag | +| main | Maintained | CI commitment for vLLM main branch and vLLM v0.33.0 tag | | releases/v0.13.0 | Maintained | Only bug fixes are allowed, and no new release tags anymore. | | releases/v0.18.0 | Maintained | CI commitment for vLLM 0.18.0 version | | releases/v0.23.0 | Maintained | CI commitment for vLLM 0.23.0 version | diff --git a/README.zh.md b/README.zh.md index e75e642e5d2a..4c14a0491d0e 100644 --- a/README.zh.md +++ b/README.zh.md @@ -100,7 +100,7 @@ vllm-ascend有主干分支和开发分支。 | 分支 | 状态 | 备注 | |------------------|--------------|----------------------| -| main | Maintained | 基于vLLM main分支和vLLM最新版本(v0.32.0)CI看护 | +| main | Maintained | 基于vLLM main分支和vLLM最新版本(v0.33.0)CI看护 | | releases/v0.13.0 | Maintained | 只允许Bug修复,不会再发布新版本 | | releases/v0.18.0 | Maintained | 基于vLLM v0.18.0版本CI看护 | | releases/v0.23.0 | Maintained | 基于vLLM v0.23.0版本CI看护 | diff --git a/release_notes/fragments/20627.yaml b/release_notes/fragments/20627.yaml new file mode 100644 index 000000000000..8bac79ceec6d --- /dev/null +++ b/release_notes/fragments/20627.yaml @@ -0,0 +1,4 @@ +pr: 20627 +entries: + - category: dependency + text: Updated vLLM release compatibility and Dockerfile defaults to v0.33.0 while retaining support for the verified vLLM main baseline. diff --git a/tests/e2e/common/rlhf/weight_transfer/weight_source.py b/tests/e2e/common/rlhf/weight_transfer/weight_source.py index f6e896003bad..4a024b72364a 100644 --- a/tests/e2e/common/rlhf/weight_transfer/weight_source.py +++ b/tests/e2e/common/rlhf/weight_transfer/weight_source.py @@ -18,7 +18,6 @@ from vllm.distributed.weight_transfer.base import ParamMeta, WeightSource from tests.e2e.common.rlhf.weight_transfer.case import WeightUpdateModelCase -from vllm_ascend.utils import vllm_version_is def expand_fused_expert_params(name: str, shape: tuple[int, ...]) -> list[tuple[str, tuple[int, ...]]]: @@ -82,11 +81,6 @@ def _apply_hf_overrides(config, overrides: dict[str, Any]) -> None: FIXED_WEIGHT_SEED = 20260915 -def _source_metadata(func): - """vLLM main (#63256) requires a cached property; v0.32.0 still calls it.""" - return func if vllm_version_is("0.32.0") else cached_property(func) - - class FixedRandomWeightSource(WeightSource): """Generate every reduced-model parameter deterministically on demand. @@ -190,7 +184,7 @@ def _make_tensor(self, name: str, shape: tuple[int, ...], dtype: torch.dtype = t return tensor.uniform_(0.9, 1.1) return tensor.uniform_(-0.02, 0.02) - @_source_metadata + @cached_property def metadata(self) -> list[ParamMeta]: return [ParamMeta(name, dtype, shape) for name, shape, dtype in self._parameters] @@ -199,11 +193,9 @@ def __iter__(self): for name, shape, dtype in self._parameters: yield name, self._make_tensor(name, shape, dtype) - if not vllm_version_is("0.32.0"): - - def iter_full(self) -> Iterator[tuple[str, torch.Tensor]]: - """vLLM main drives updates through `iter_full()` instead of `__iter__`.""" - yield from self.__iter__() + def iter_full(self) -> Iterator[tuple[str, torch.Tensor]]: + """vLLM drives updates through `iter_full()`.""" + yield from self.__iter__() @property def case_id(self) -> str: @@ -247,8 +239,7 @@ def packed_buffer_size_for(source: FixedRandomWeightSource) -> int: raises ``ValueError: Tensor ... exceeds buffer_size_bytes``. Keep the 1 GiB floor and add 128 MiB of headroom above the largest tensor. """ - # `metadata` is a method on v0.32.0 and a cached property on main. - metadata = source.metadata() if vllm_version_is("0.32.0") else source.metadata + metadata = source.metadata max_tensor_bytes = max(math.prod(meta.shape) * meta.dtype.itemsize for meta in metadata) return max(max_tensor_bytes + 128 * 2**20, 2**30) diff --git a/tests/e2e/nightly/single_node/ops/singlecard_ops/triton/test_num_nans.py b/tests/e2e/nightly/single_node/ops/singlecard_ops/triton/test_num_nans.py index 4dd2d5470c61..d3d5d35b1730 100644 --- a/tests/e2e/nightly/single_node/ops/singlecard_ops/triton/test_num_nans.py +++ b/tests/e2e/nightly/single_node/ops/singlecard_ops/triton/test_num_nans.py @@ -48,7 +48,7 @@ # AttributeError. Setting VLLM_VERSION makes ``vllm_version_is`` use it instead # of ``vllm.__version__``. This must happen before the first ``vllm_ascend`` # import below, and it must not override an explicitly exported value. -os.environ.setdefault("VLLM_VERSION", "0.32.0") +os.environ.setdefault("VLLM_VERSION", "0.33.0") from vllm_ascend.device.device_config import get_ascend_device_type from vllm_ascend.device.hardware import AscendDeviceType diff --git a/tests/e2e/pull_request/one_card/test_gumbel_sampling.py b/tests/e2e/pull_request/one_card/test_gumbel_sampling.py index 689051a8eed5..d4d291308a17 100644 --- a/tests/e2e/pull_request/one_card/test_gumbel_sampling.py +++ b/tests/e2e/pull_request/one_card/test_gumbel_sampling.py @@ -604,7 +604,7 @@ def test_dspark_uses_ascend_gumbel(self): speculator.temperature = torch.tensor([0.5, 1.5], device=DEVICE) speculator.seeds = torch.tensor([3, 7], dtype=torch.int64, device=DEVICE) speculator._step_cols = torch.arange(2, dtype=torch.int32, device=DEVICE) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): # The release tree keeps the raw per-step draft-logits tensor. speculator.draft_logits = torch.zeros(2, 2, 1031, device=DEVICE) draft_logits = speculator.draft_logits diff --git a/tests/ut/attention/test_batch_invariance_support.py b/tests/ut/attention/test_batch_invariance_support.py index 501011e26092..63b961affe22 100644 --- a/tests/ut/attention/test_batch_invariance_support.py +++ b/tests/ut/attention/test_batch_invariance_support.py @@ -5,7 +5,7 @@ vLLM #60271 ("Check batch-invariance support for every attention backend") added a hard check in ``vllm/v1/worker/gpu/attn_utils.init_attn_backend`` on main: ``VLLM_BATCH_INVARIANT`` mode now rejects any attention backend whose -``supports_batch_invariance()`` returns False. Both v0.32.0 and verified main +``supports_batch_invariance()`` returns False. Both v0.33.0 and verified main enforce this check, so Ascend advertises support in both lanes. """ diff --git a/tests/ut/attention/test_flash_attn.py b/tests/ut/attention/test_flash_attn.py index ce8f2e49b862..dd1648409734 100644 --- a/tests/ut/attention/test_flash_attn.py +++ b/tests/ut/attention/test_flash_attn.py @@ -501,7 +501,7 @@ def test_only_undersized_draft_swa_pages_drop_inherited_padding( expected_padding = None if recover else original.page_size_padded assert spec.page_size_bytes == (expected_padding or natural_page) assert spec.page_size_padded == expected_padding - # v0.32.0 has no draft marker; check propagation when upstream supports it. + # Both supported versions propagate the draft marker. if hasattr(original, "is_draft"): assert spec.is_draft is is_draft assert config.cache_config.skip_page_size_padded == padding diff --git a/tests/ut/attention/test_gqa_dcp_split.py b/tests/ut/attention/test_gqa_dcp_split.py index 7728be42d3ce..7c4c6a29b62b 100644 --- a/tests/ut/attention/test_gqa_dcp_split.py +++ b/tests/ut/attention/test_gqa_dcp_split.py @@ -17,7 +17,6 @@ ) from vllm_ascend.attention.context_parallel.common_cp import CPKVScope, use_history_current_split_decode from vllm_ascend.compilation.updatable_graph import ContextSource, GraphUpdateTask, SharedSource, UpdatableGraph -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.spec_decode.target_dependent_ar.speculator import AscendTargetDependentARSpeculator @@ -311,11 +310,8 @@ def merge(*args, **kwargs): def test_v2_draft_steps_update_history_and_current_independently(interleave): speculator = object.__new__(AscendTargetDependentARSpeculator) speculator.attn_architecture = "GQA" - if vllm_version_is("0.32.0"): - speculator.max_model_len = 32 - else: - # vLLM main exposes max_model_len as a read-only view of vllm_config. - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) + # vLLM main exposes max_model_len as a read-only view of vllm_config. + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) speculator.use_dcp = True prepare_local = MagicMock( side_effect=lambda lengths: get_dcp_local_seq_lens( @@ -358,11 +354,8 @@ def test_v2_graph_shared_source_preserves_steps_layers_and_padding(is_prefill, c ) speculator.input_batch = SimpleNamespace(num_reqs=2, seq_lens_np=[13, 31]) speculator.num_speculative_steps = 3 - if vllm_version_is("0.32.0"): - speculator.max_model_len = 32 - else: - # vLLM main exposes max_model_len as a read-only view of vllm_config. - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) + # vLLM main exposes max_model_len as a read-only view of vllm_config. + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) query = (4, 2, 1) if is_prefill else (1, 1, 1) steps = [ { diff --git a/tests/ut/attention/test_mla_v1.py b/tests/ut/attention/test_mla_v1.py index 2a227fef7a32..c5dfec6ee0d0 100644 --- a/tests/ut/attention/test_mla_v1.py +++ b/tests/ut/attention/test_mla_v1.py @@ -1947,9 +1947,8 @@ def test_qkv_a_fused_output_gate_disables_mlapo(self, mock_get_current_vllm_conf """Kimi-K3 fuses its gate as a third QKV-A shard; MLAPO cannot carry it.""" mock_get_current_vllm_config.return_value = self.impl.vllm_config self.impl.fused_qkv_a_proj.output_sizes = [64, 32, 128] - # Only vLLM main builds the three-shard QKV-A-gate projection; release - # v0.32.0 keeps a separate gate and a two-shard projection. - gate_fused = not vllm_version_is("0.32.0") + # Both supported Kimi AMD implementations use the three-shard layout. + gate_fused = True impl = self._rebuild_impl() @@ -2807,13 +2806,8 @@ def test_process_weights_after_loading_refreshes_prolog_v3_weights(self, mock_fo def test_process_weights_after_loading_rebinds_incompatible_value(self, mock_format_cast): """An incompatible reload must rebind instead of raising from ``copy_``. - ``replace_parameter(..., prefer_copy=True)`` reuses the stored storage - only while shape, dtype and device still match. The hand-rolled - ``copy_`` it replaced was unconditional, so a re-derived value that - stopped being compatible aborted the whole weight-update transaction - with a ``RuntimeError``. That failure mode is the only behaviour this - change alters, so it is the part of the contract the unit tests have to - pin down. + v0.33.0 rebinds an incompatible value; main can copy a smaller value + into the parameter's existing storage. Both must accept the new shape. """ layer = MagicMock(spec=LinearBase) layer.input_size_per_partition = 10 @@ -2843,7 +2837,7 @@ def test_process_weights_after_loading_rebinds_incompatible_value(self, mock_for self.impl.process_weights_after_loading(torch.bfloat16) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): # A re-derived value that no longer fits rebinds the parameter. self.assertNotEqual(self.impl.W_UV.data_ptr(), w_uv_ptr) else: @@ -3695,10 +3689,6 @@ def test_split_fused_qkv_lora_plain_layout_has_no_gate(): torch.testing.assert_close(kv_no_split, qkv_lora[:, 4:]) -@pytest.mark.skipif( - vllm_version_is("0.32.0"), - reason="gate-fused QKV-A layout is vLLM main only", -) def test_split_fused_qkv_lora_peels_kimi_output_gate(): """A gate-fused layout returns the trailing shard separately from q/kv.""" qkv_lora = torch.arange(15, dtype=torch.float32).reshape(1, 15) diff --git a/tests/ut/attention/test_sfa_v1.py b/tests/ut/attention/test_sfa_v1.py index 3d28012de278..e50b2555e811 100644 --- a/tests/ut/attention/test_sfa_v1.py +++ b/tests/ut/attention/test_sfa_v1.py @@ -1293,13 +1293,8 @@ def test_process_weights_after_loading_rebinds_incompatible_value( ): """An incompatible reload must rebind instead of raising from ``copy_``. - ``replace_parameter(..., prefer_copy=True)`` reuses the stored storage - only while shape, dtype and device still match. The hand-rolled - ``copy_`` it replaced was unconditional, so a re-derived value that - stopped being compatible aborted the whole weight-update transaction - with a ``RuntimeError``. That failure mode is the only behaviour this - change alters, so it is the part of the contract the unit tests have to - pin down. + v0.33.0 rebinds an incompatible value; main can copy a smaller value + into the parameter's existing storage. Both must accept the new shape. """ layer = self._setup_kv_b_proj() mock_format_cast.return_value = layer.weight @@ -1320,7 +1315,7 @@ def test_process_weights_after_loading_rebinds_incompatible_value( self.impl.process_weights_after_loading(torch.bfloat16) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): # A re-derived value that no longer fits rebinds the parameter. self.assertNotEqual(self.impl.W_UV.data_ptr(), w_uv_ptr) else: diff --git a/tests/ut/core/test_kv_cache_interface.py b/tests/ut/core/test_kv_cache_interface.py index f123c231046b..942071c9adf4 100644 --- a/tests/ut/core/test_kv_cache_interface.py +++ b/tests/ut/core/test_kv_cache_interface.py @@ -7,6 +7,10 @@ import pytest import torch from vllm.v1.core.block_pool import BlockPool + +# vLLM #61183 moved `is_kv_cache_spec_uniform` to `kv_cache_planning` on main; +# the v0.33.0 lane still ships it in `kv_cache_utils`. +from vllm.v1.core.kv_cache_planning import is_kv_cache_spec_uniform from vllm.v1.core.single_type_kv_cache_manager import CircularBufferManager, register_all_kvcache_specs from vllm.v1.kv_cache_interface import ( CircularBufferSpec, @@ -28,14 +32,6 @@ supports_bounded_replay, supports_component_major_mla_pd, ) -from vllm_ascend.utils import vllm_version_is - -# vLLM #61183 moved `is_kv_cache_spec_uniform` to `kv_cache_planning` on main; -# the v0.32.0 lane still ships it in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import is_kv_cache_spec_uniform -else: - from vllm.v1.core.kv_cache_planning import is_kv_cache_spec_uniform def _mla_spec(): diff --git a/tests/ut/distributed/ascend_store/test_request_lifecycle.py b/tests/ut/distributed/ascend_store/test_request_lifecycle.py index 0bf2713b2960..0edac77c58e2 100644 --- a/tests/ut/distributed/ascend_store/test_request_lifecycle.py +++ b/tests/ut/distributed/ascend_store/test_request_lifecycle.py @@ -38,7 +38,6 @@ KVCacheStoreRecvingThread, KVCacheStoreSendingThread, ) -from vllm_ascend.utils import vllm_version_is def aligned_buffer(size): @@ -350,11 +349,10 @@ def run_request(req_id, tokens, expected_hit, expected_local=0): scheduler.update_from_output(output, result) if drafts: expected_computed = computed_before_update - len(drafts) + accepted - if not vllm_version_is("0.32.0"): - # vLLM main trims ``num_computed_tokens`` to cover only the - # tokens actually kept when a request stops mid token-list. - appended = request.num_output_tokens - output_tokens_before_update - expected_computed -= (accepted + 1) - appended + # vLLM main trims ``num_computed_tokens`` to cover only the + # tokens actually kept when a request stops mid token-list. + appended = request.num_output_tokens - output_tokens_before_update + expected_computed -= (accepted + 1) - appended assert request.num_computed_tokens == expected_computed if speculative_method: scheduler.update_draft_token_ids( @@ -434,7 +432,7 @@ def run_request(req_id, tokens, expected_hit, expected_local=0): # pure full-attention dspark layout sees the doubled local prefix hit. only_full_attention = isinstance(plan.kv_cache_groups[0].kv_cache_spec, FullAttentionSpec) mixed_local = 128 - if not vllm_version_is("0.32.0") and speculative_method == "dspark" and only_full_attention: + if speculative_method == "dspark" and only_full_attention: mixed_local = 256 run_request("mixed-local-remote", list(range(513)), 512, expected_local=mixed_local) assert scheduler.reset_prefix_cache() diff --git a/tests/ut/distributed/kv_transfer/kv_p2p/test_mooncake_connector.py b/tests/ut/distributed/kv_transfer/kv_p2p/test_mooncake_connector.py index dcc6de552a7d..43a345b1fb13 100644 --- a/tests/ut/distributed/kv_transfer/kv_p2p/test_mooncake_connector.py +++ b/tests/ut/distributed/kv_transfer/kv_p2p/test_mooncake_connector.py @@ -18,6 +18,13 @@ import zmq from vllm.config import KVTransferConfig from vllm.utils.network_utils import make_zmq_path + +# vLLM #61183 moved these KV-cache planning helpers to `kv_cache_planning` on +# main; the v0.33.0 lane still ships them in `kv_cache_utils`. +from vllm.v1.core.kv_cache_planning import ( + get_kv_cache_config_from_groups, + is_kv_cache_spec_uniform, +) from vllm.v1.kv_cache_interface import ( FullAttentionSpec, KVCacheGroupSpec, @@ -52,20 +59,7 @@ transfer_groups_need_independent_block_ids, zmq_ctx, ) -from vllm_ascend.utils import get_kv_cache_tensor_layers, vllm_version_is - -# vLLM #61183 moved these KV-cache planning helpers to `kv_cache_planning` on -# main; the v0.32.0 lane still ships them in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import ( - get_kv_cache_config_from_groups, - is_kv_cache_spec_uniform, - ) -else: - from vllm.v1.core.kv_cache_planning import ( - get_kv_cache_config_from_groups, - is_kv_cache_spec_uniform, - ) +from vllm_ascend.utils import get_kv_cache_tensor_layers GET_META_MSG = b"get_meta_msg" DONE_RECVING_MSG = b"done_recving_msg" diff --git a/tests/ut/distributed/weight_transfer/test_hccl_engine.py b/tests/ut/distributed/weight_transfer/test_hccl_engine.py index 08b94053e1b8..84ef5fd4e71e 100644 --- a/tests/ut/distributed/weight_transfer/test_hccl_engine.py +++ b/tests/ut/distributed/weight_transfer/test_hccl_engine.py @@ -221,7 +221,7 @@ def pack(**kwargs): patch.object(engine, "_checked_iter", return_value=iter(pairs)), patch(f"{namespace}.packed_broadcast_producer", side_effect=pack), ): - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): engine._broadcast(pairs, []) else: # Main passes the metadata slice and the broadcasting group rank. @@ -267,7 +267,7 @@ def source(): iter_source = MagicMock() iter_source.iter_full.return_value = source() iter_source.__iter__.return_value = source() - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): with patch.object(torch, "npu", SimpleNamespace(device=lambda _: nullcontext()), create=True): engine._broadcast(iter_source, []) else: @@ -322,15 +322,15 @@ def test_worker_update_binds_assigned_device_for_base_sync(): def test_send_reuses_real_upstream_round_trip(sender): engine = _trainer(sender) param = ParamMeta(name="w", dtype=torch.float32, shape=(1,)) - if vllm_version_is("0.32.0"): - engine.source.metadata.return_value = [] + if vllm_version_is("0.33.0"): + engine.source.metadata = [] else: # vLLM main exposes WeightSource.metadata as a property and sends one # slice per broadcasting rank. engine.source.metadata = [param] with patch.object(engine, "_broadcast") as broadcast, patch.object(engine, "_post_send_sync") as sync: engine.send_weights() - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): broadcast.assert_called_once_with(engine.source, []) else: broadcast.assert_called_once_with([param], 0) diff --git a/tests/ut/models/minimax_m3/test_msa_m3.py b/tests/ut/models/minimax_m3/test_msa_m3.py index 4cf317786c05..079250747e6e 100644 --- a/tests/ut/models/minimax_m3/test_msa_m3.py +++ b/tests/ut/models/minimax_m3/test_msa_m3.py @@ -984,7 +984,7 @@ def test_a5_indexer_forward_keeps_triton_decode_branch() -> None: def test_triton_indexer_forward_accepts_single_return_value() -> None: - """v0.32.0 keeps the upstream single-tensor decode contract.""" + """Accept the single-tensor indexer decode result.""" impl = object.__new__(AscendMiniMaxM3IndexerImpl) torch.nn.Module.__init__(impl) impl.num_index_heads = 1 diff --git a/tests/ut/models/qwen4_exp/test_qsa_layerwise_hooks.py b/tests/ut/models/qwen4_exp/test_qsa_layerwise_hooks.py index 1182a6fc28ee..361b4ac8c6d0 100644 --- a/tests/ut/models/qwen4_exp/test_qsa_layerwise_hooks.py +++ b/tests/ut/models/qwen4_exp/test_qsa_layerwise_hooks.py @@ -39,7 +39,7 @@ class Indexer: def __call__(self, *args, **kwargs): order.append("indexer_update") selected = torch.zeros(2, self.output_width, dtype=torch.int32) - return selected if vllm_version_is("0.32.0") else (selected, None) + return selected if vllm_version_is("0.33.0") else (selected, None) owner = SimpleNamespace( layer_name="main", diff --git a/tests/ut/models/qwen4_exp/test_qsa_upstream_abi.py b/tests/ut/models/qwen4_exp/test_qsa_upstream_abi.py index 4db51d33cb01..9862a85e5d2c 100644 --- a/tests/ut/models/qwen4_exp/test_qsa_upstream_abi.py +++ b/tests/ut/models/qwen4_exp/test_qsa_upstream_abi.py @@ -48,7 +48,7 @@ def test_fused_prepare_upstream_abi_materializes_qkv_and_gate(monkeypatch) -> No selected = torch.zeros((2, 3), dtype=torch.int32) # Main's indexer returns (selection, prepared main outputs). - indexer = Mock(return_value=selected if vllm_version_is("0.32.0") else (selected, None)) + indexer = Mock(return_value=selected if vllm_version_is("0.33.0") else (selected, None)) indexer.output_width = 3 indexer.raw_key_cache = SimpleNamespace(prefix=side_prefix) layer.indexer = indexer @@ -84,7 +84,7 @@ def test_fused_prepare_upstream_abi_materializes_qkv_and_gate(monkeypatch) -> No torch.testing.assert_close(update_args[1], projected_k.view(2, 1, 4)) torch.testing.assert_close(update_args[2], projected_v.view(2, 1, 4)) assert layer.impl.forward_qsa.call_count + layer.impl.forward.call_count == 1 - forward_call = layer.impl.forward_qsa if vllm_version_is("0.32.0") else layer.impl.forward + forward_call = layer.impl.forward_qsa if vllm_version_is("0.33.0") else layer.impl.forward forward_args = forward_call.call_args.args torch.testing.assert_close(forward_args[1], projected_q.view(2, 2, 4)) diff --git a/tests/ut/models/test_deepseek_v41_cache.py b/tests/ut/models/test_deepseek_v41_cache.py index 04dfe7d11726..4f1dbcb14fa1 100644 --- a/tests/ut/models/test_deepseek_v41_cache.py +++ b/tests/ut/models/test_deepseek_v41_cache.py @@ -18,7 +18,10 @@ import torch_npu from vllm.config import set_current_vllm_config from vllm.transformers_utils.configs.deepseek_v41 import DeepseekV41Config -from vllm.v1.core import kv_cache_utils + +# vLLM #61183 moved the KV-cache planning helpers to `kv_cache_planning` on +# main; the v0.33.0 lane still ships them in `kv_cache_utils`. +from vllm.v1.core import kv_cache_planning, kv_cache_utils from vllm.v1.kv_cache_interface import CircularBufferSpec from tests.deepseek_v41_utils import ( @@ -57,19 +60,8 @@ ) from vllm_ascend.models.deepseek_v41.compressor import DeepseekV41Compressor from vllm_ascend.models.deepseek_v41.model import AscendDeepseekV41SWACache, build_layer_plan -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.device_metadata import DeviceMetadataStage -# vLLM #61183 moved the KV-cache planning helpers to `kv_cache_planning` on -# main; the v0.32.0 lane still ships them in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core import kv_cache_utils as kv_cache_planning -else: - from vllm.v1.core import kv_cache_planning - -# v0.32.0 keeps the two-argument admission API; verified main requires a builder. -_UPSTREAM_MAX_MEMORY_TAKES_BUILDER = not vllm_version_is("0.32.0") - def _pool_bytes_per_block(runtime, groups): """vLLM #57169 added a leading ``vllm_config`` argument on main.""" @@ -84,8 +76,6 @@ def _max_memory_usage_bytes_from_groups(runtime, groups): the upstream formula; that formula sizes the pool through the builder hook, so feed it the Ascend V4.1 per-block cost. """ - if not _UPSTREAM_MAX_MEMORY_TAKES_BUILDER: - return kv_cache_planning._max_memory_usage_bytes_from_groups(runtime, groups) builder = MagicMock() builder._get_pool_bytes_per_block.return_value = get_deepseek_v41_pool_bytes_per_block(groups) return kv_cache_planning._max_memory_usage_bytes_from_groups(builder, runtime, groups) diff --git a/tests/ut/models/test_glm5next_recoverssm_metadata.py b/tests/ut/models/test_glm5next_recoverssm_metadata.py index 47c8aa450177..d388fc21ce8d 100644 --- a/tests/ut/models/test_glm5next_recoverssm_metadata.py +++ b/tests/ut/models/test_glm5next_recoverssm_metadata.py @@ -94,7 +94,7 @@ def test_upstream_context_creation_uses_ascend_patch_and_caches(monkeypatch): assert args == (layers,) assert kwargs["spec_query_len"] == 6 assert kwargs["max_num_reqs"] == 12 - # vLLM main forwards the commit backend; 0.32.0 does not. + # Both supported versions use the Triton commit backend. assert kwargs.get("backend", "triton") == "triton" diff --git a/tests/ut/models/test_kimi_k3_adapter.py b/tests/ut/models/test_kimi_k3_adapter.py index 578381055364..0dd5c84b8269 100644 --- a/tests/ut/models/test_kimi_k3_adapter.py +++ b/tests/ut/models/test_kimi_k3_adapter.py @@ -22,7 +22,6 @@ AscendK3DSparkModel, ) from vllm_ascend.quantization.methods.w8a8.w8a8_mxfp8 import AscendW8A8MXFP8DynamicLinearMethod -from vllm_ascend.utils import vllm_version_is def test_kimi_disabling_mlapo_refreshes_projection_nz_management(): @@ -744,10 +743,6 @@ def test_k3_dspark_pp_mapper_keeps_frozen_embed_but_drops_heads(monkeypatch): assert pp_mapper._map_name(name) == upstream_mapper._map_name(name) -@pytest.mark.skipif( - vllm_version_is("0.32.0"), - reason="The AMD specialized-decode hooks we inherit are main-only.", -) def test_kimi_lm_initializes_specialized_decode(monkeypatch): from vllm.models.kimi_k3.amd.specialized_decode import runtime @@ -786,10 +781,6 @@ def __init__(self, **kwargs): assert model.specialized_decode is None -@pytest.mark.skipif( - vllm_version_is("0.32.0"), - reason="The AMD specialized-decode hooks we inherit are main-only.", -) def test_kimi_lm_uses_ascend_hybrid_model_state(): from vllm_ascend.worker.v2.model_states.mamba_hybrid import AscendMambaHybridModelState @@ -799,10 +790,6 @@ def test_kimi_lm_uses_ascend_hybrid_model_state(): assert model.get_model_state_cls() is AscendMambaHybridModelState -@pytest.mark.skipif( - vllm_version_is("0.32.0"), - reason="Upstream passes the specialized-decode step only on main.", -) def test_kimi_model_forwards_specialized_decode_step(monkeypatch): seen = {} step = object() diff --git a/tests/ut/models/test_qwen4_exp_cache_config.py b/tests/ut/models/test_qwen4_exp_cache_config.py index db6683dcf5a5..19f0a3275dc8 100644 --- a/tests/ut/models/test_qwen4_exp_cache_config.py +++ b/tests/ut/models/test_qwen4_exp_cache_config.py @@ -6,6 +6,7 @@ import torch from vllm.config import KVTransferConfig from vllm.model_executor.models import ModelRegistry +from vllm.v1.core.kv_cache_planning import DefaultKVCacheConfigBuilder from vllm.v1.kv_cache_interface import ( CircularBufferSpec, FullAttentionSpec, @@ -543,6 +544,7 @@ def test_qwen4_cache_admission_matches_shared_planner_allocation() -> None: max_in_flight_tokens=4096, ) required_bytes = _ascend_max_memory_usage_bytes_from_groups( + DefaultKVCacheConfigBuilder(), vllm_config, groups, ) @@ -609,7 +611,7 @@ def required_blocks(group_list) -> int: gdn_blocks_each = required_blocks(gdn_groups[:1]) blocks_before = required_blocks(groups) - bytes_before = _ascend_max_memory_usage_bytes_from_groups(vllm_config, groups) + bytes_before = _ascend_max_memory_usage_bytes_from_groups(DefaultKVCacheConfigBuilder(), vllm_config, groups) merged = _merge_mamba_state_groups(groups, 13) @@ -630,7 +632,7 @@ def required_blocks(group_list) -> int: owner.spec.real_page_size_bytes for owner in probe.owners if owner.role == PLE ) - bytes_after = _ascend_max_memory_usage_bytes_from_groups(vllm_config, merged) + bytes_after = _ascend_max_memory_usage_bytes_from_groups(DefaultKVCacheConfigBuilder(), vllm_config, merged) assert bytes_after == blocks_after * pool_block_bytes assert bytes_before - bytes_after == 33 * gdn_blocks_each * pool_block_bytes @@ -820,7 +822,7 @@ def test_compressed_qsa_builder_and_cache_use_matching_pages(monkeypatch, manage from vllm_ascend.models.qwen4_exp import qsa - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): import vllm.models.qwen4_exp.common.qsa_cache as qsa_module # type: ignore[import-not-found] QSARawKeyCache = qsa_module.QSAKeyStateCache diff --git a/tests/ut/models/test_qwen4_exp_soc_gating.py b/tests/ut/models/test_qwen4_exp_soc_gating.py index 1e08f8dcce08..9907204d51f5 100644 --- a/tests/ut/models/test_qwen4_exp_soc_gating.py +++ b/tests/ut/models/test_qwen4_exp_soc_gating.py @@ -90,7 +90,7 @@ def gbsa(*args, **kwargs): monkeypatch.setattr(ascend_qsa, "qsa_gbsa_attention", gbsa) impl: Any = _make_impl() - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): result = impl.forward_qsa( layer=layer, query=torch.zeros(1, 2, 2), diff --git a/tests/ut/patch/platform/test_packed_kv_cache_compat.py b/tests/ut/patch/platform/test_packed_kv_cache_compat.py index 82defbc550ba..50ada6aa4312 100644 --- a/tests/ut/patch/platform/test_packed_kv_cache_compat.py +++ b/tests/ut/patch/platform/test_packed_kv_cache_compat.py @@ -4,50 +4,11 @@ from types import SimpleNamespace from unittest.mock import MagicMock, patch -import pytest - from vllm_ascend.patch.platform import patch_kv_cache_utils as cache_patch -@pytest.mark.parametrize("use_fallback", [False, True]) -def test_packed_groups_use_matching_eagle_annotation_api(use_fallback): - config = SimpleNamespace() - specs = {"layer": object()} - groups = [object()] - - def annotate(config_arg, specs_arg, groups_arg, *, use_trailing_layer_fallback): - assert use_trailing_layer_fallback is use_fallback - - predicate = MagicMock(return_value=use_fallback) - annotator = MagicMock(side_effect=annotate) - warning = MagicMock() - upstream = SimpleNamespace( - _annotate_eagle_groups=annotator, - _warn_if_unannotated_eagle_mamba=warning, - _uses_trailing_mtp_layers=predicate, - ) - with ( - patch.object(cache_patch, "_kv_cache_planning", upstream), - patch.object(cache_patch, "vllm_version_is", lambda version: version == "0.32.0"), - patch.object(cache_patch, "is_deepseek_v41_cache", return_value=True), - patch.object(cache_patch, "group_cache_specs", return_value=specs), - patch.object(cache_patch, "make_cache_groups", return_value=groups), - ): - assert cache_patch._ascend_get_packed_kv_cache_groups(config, specs) is groups - - predicate.assert_called_once_with(config) - assert annotator.call_args.args == (config, specs, groups) - warning.assert_called_once_with(config, groups) - - -def test_packed_groups_skip_eagle_annotation_on_main(): - """The version gate leaves the API main no longer ships untouched. - - vLLM #42309 drops ``_annotate_eagle_groups``/``_uses_trailing_mtp_layers`` - from main and annotates EAGLE groups in ``get_kv_cache_configs`` instead. - The packed-group hook must therefore stay hands-off on the main lane even - when the live module exposes the helpers. - """ +def test_packed_groups_leave_eagle_annotation_to_upstream(): + """Both supported planners annotate EAGLE groups in get_kv_cache_configs.""" config = SimpleNamespace() specs = {"layer": object()} groups = [object()] @@ -60,7 +21,6 @@ def test_packed_groups_skip_eagle_annotation_on_main(): ) with ( patch.object(cache_patch, "_kv_cache_planning", upstream), - patch.object(cache_patch, "vllm_version_is", lambda version: False), patch.object(cache_patch, "is_deepseek_v41_cache", return_value=True), patch.object(cache_patch, "group_cache_specs", return_value=specs), patch.object(cache_patch, "make_cache_groups", return_value=groups), diff --git a/tests/ut/patch/platform/test_patch_pp_mtp.py b/tests/ut/patch/platform/test_patch_pp_mtp.py index d49b991b23e5..6e8cfae1efd0 100644 --- a/tests/ut/patch/platform/test_patch_pp_mtp.py +++ b/tests/ut/patch/platform/test_patch_pp_mtp.py @@ -416,9 +416,9 @@ def test_pp_mtp_spec_token_id_edge_cases(): _update_pp_mtp_spec_token_ids(scheduler, scheduler_output, model_runner_output) assert finished.spec_token_ids == ["keep"] assert empty_sampled.spec_token_ids == [] - # Main trims to the validated prefix plus one lookahead token; 0.32.0 returns + # Main trims to the validated prefix plus one lookahead token; 0.33.0 returns # only the validated prefix. - assert advancing.spec_token_ids == ([401] if vllm_version_is("0.32.0") else [401, 402]) + assert advancing.spec_token_ids == ([401] if vllm_version_is("0.33.0") else [401, 402]) def test_pp_mtp_spec_tokens_remain_unconstrained_during_reasoning(monkeypatch): diff --git a/tests/ut/patch/platform/test_prefix_cache_cp_patches.py b/tests/ut/patch/platform/test_prefix_cache_cp_patches.py index fef7297cfaac..9968f11d6589 100644 --- a/tests/ut/patch/platform/test_prefix_cache_cp_patches.py +++ b/tests/ut/patch/platform/test_prefix_cache_cp_patches.py @@ -51,15 +51,11 @@ group_and_unify_kv_cache_specs, ) from vllm_ascend.patch.platform.patch_mamba_manager import AscendMambaManager -from vllm_ascend.utils import vllm_version_is # vLLM #60043 removed the leftover `mamba_cache_mode="all"` path and now asserts # that prefix caching requires `mamba_cache_mode="align"` in both supported lanes. _MAMBA_CACHING_MODE = "align" -# v0.32.0 keeps the two-argument admission API; verified main requires a builder. -_UPSTREAM_MAX_MEMORY_TAKES_BUILDER = not vllm_version_is("0.32.0") - def test_packed_cache_reuses_global_capacity_and_records_recycled_state_pages(): register_all_kvcache_specs(None) @@ -922,19 +918,11 @@ def test_deepseek_v4_main_restores_ascend_shared_tuple_planner(monkeypatch) -> N assert result.num_blocks == 7 assert result.kv_cache_tensors == [planned_tensor] - if _UPSTREAM_MAX_MEMORY_TAKES_BUILDER: - # vLLM #42309 threads the KVCacheConfigBuilder through admission on - # main; the DSV4 shared-tuple branch does not read it. - needed_memory = kv_cache_utils_patch._ascend_max_memory_usage_bytes_from_groups( - MagicMock(), - vllm_config, - kv_cache_config.kv_cache_groups, - ) - else: - needed_memory = kv_cache_utils_patch._ascend_max_memory_usage_bytes_from_groups( - vllm_config, - kv_cache_config.kv_cache_groups, - ) + needed_memory = kv_cache_utils_patch._ascend_max_memory_usage_bytes_from_groups( + MagicMock(), + vllm_config, + kv_cache_config.kv_cache_groups, + ) full_spec = kv_cache_config.kv_cache_groups[0].kv_cache_spec assert isinstance(full_spec, UniformTypeKVCacheSpecs) layer_tuple_bytes = sum(spec.page_size_bytes for spec in full_spec.kv_cache_specs.values()) diff --git a/tests/ut/patch/worker/patch_common/test_patch_distributed.py b/tests/ut/patch/worker/patch_common/test_patch_distributed.py index e63b579ed0d2..f29ddce42e26 100644 --- a/tests/ut/patch/worker/patch_common/test_patch_distributed.py +++ b/tests/ut/patch/worker/patch_common/test_patch_distributed.py @@ -190,7 +190,7 @@ def __init__(self, **kwargs): npu_communicator_module.NPUCommunicator = FakeNPUCommunicator utils_module.create_hccl_pg_options = MagicMock(return_value=shared_hccl_options) # The patch only uses this to decide whether to set ``cpu_timeout`` (vLLM - # main) or leave it to the upstream base class (0.32.0); no test here + # main) or leave it to the upstream base class (0.33.0); no test here # asserts on that branch. utils_module.vllm_version_is = lambda _target: False diff --git a/tests/ut/patch/worker/test_patch_mm_input_norm.py b/tests/ut/patch/worker/test_patch_mm_input_norm.py index 7e75a33d6f18..9e6756edfc88 100644 --- a/tests/ut/patch/worker/test_patch_mm_input_norm.py +++ b/tests/ut/patch/worker/test_patch_mm_input_norm.py @@ -13,24 +13,9 @@ from vllm.model_executor.model_loader.dummy_loader import DummyModelLoader from vllm.model_executor.model_loader.sharded_state_loader import ShardedStateLoader -from vllm_ascend.patch.worker.patch_mm_input_norm import patch_mm_input_norm - -@pytest.fixture(params=[True, False], ids=["v032-persistent", "upstream-nonpersistent"]) -def norm(request, monkeypatch): - original_init = FusedMMInputNorm.__init__ - - def init(self, *args, **kwargs): - original_init(self, *args, **kwargs) - # Exercise both upstream contracts even when CI already has #62767. - for name in ("weight", "bias"): - self.register_buffer(name, getattr(self, name), persistent=request.param) - - monkeypatch.setattr(FusedMMInputNorm, "__init__", init) - patch_mm_input_norm() - patched_init = FusedMMInputNorm.__init__ - patch_mm_input_norm() - assert FusedMMInputNorm.__init__ is patched_init +@pytest.fixture +def norm(): # Config construction must not initialize Ascend logging or device state. with patch("vllm_ascend.platform.NPUPlatform.check_and_update_config"): vllm_config = VllmConfig() diff --git a/tests/ut/patch/worker/test_patch_v2_gumbel.py b/tests/ut/patch/worker/test_patch_v2_gumbel.py index bb178581182d..71fe5a2a85b6 100644 --- a/tests/ut/patch/worker/test_patch_v2_gumbel.py +++ b/tests/ut/patch/worker/test_patch_v2_gumbel.py @@ -53,7 +53,7 @@ def test_dspark_sample_logits_dispatch(monkeypatch, probabilistic): speculator.temperature = torch.tensor([0.5, 1.5]) speculator.seeds = torch.tensor([3, 7]) speculator._step_cols = torch.arange(2, dtype=torch.int32) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): # vLLM main (#63554) forwards the draft-logits cache shard to the sampler. speculator.draft_logits = ( # type: ignore[assignment] torch.empty(2, 2, 3) if probabilistic else None @@ -99,7 +99,7 @@ def test_dspark_sample_logits_dispatch(monkeypatch, probabilistic): torch.testing.assert_close(args[4], sample_pos - 1) assert kwargs["apply_temperature"] is True assert kwargs["is_drafting"] is True - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): assert kwargs["logits_cache"] is speculator.draft_logits else: assert kwargs["logits_cache"] is speculator.draft_logits.values # type: ignore[attr-defined] diff --git a/tests/ut/simple_kv_offload/test_simple_kv_offload.py b/tests/ut/simple_kv_offload/test_simple_kv_offload.py index 489b11fbb069..87db5c52deb9 100644 --- a/tests/ut/simple_kv_offload/test_simple_kv_offload.py +++ b/tests/ut/simple_kv_offload/test_simple_kv_offload.py @@ -23,7 +23,6 @@ SimpleCPUOffloadNPUWorker, _flatten_kv_value, ) -from vllm_ascend.utils import vllm_version_is def test_factory_registration_uses_consolidated_package( @@ -235,10 +234,6 @@ def launch_copy(self, *args, **kwargs) -> None: assert store_event.recorded_stream is current_stream -@pytest.mark.skipif( - vllm_version_is("0.32.0"), - reason="get_simple_cpu_offload_num_cpu_blocks is a main-only RPC", -) def test_npu_worker_reports_aligned_cpu_blocks( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -262,10 +257,6 @@ def test_npu_worker_reports_aligned_cpu_blocks( assert worker.get_simple_cpu_offload_num_cpu_blocks() == 8 -@pytest.mark.skipif( - vllm_version_is("0.32.0"), - reason="get_simple_cpu_offload_num_cpu_blocks is a main-only RPC", -) def test_npu_worker_reports_no_cpu_blocks_without_transfer_group( monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -278,10 +269,6 @@ def test_npu_worker_reports_no_cpu_blocks_without_transfer_group( assert worker.get_simple_cpu_offload_num_cpu_blocks() is None -@pytest.mark.skipif( - vllm_version_is("0.32.0"), - reason="get_simple_cpu_offload_num_cpu_blocks is a main-only RPC", -) def test_npu_worker_reports_no_cpu_blocks_without_connector( monkeypatch: pytest.MonkeyPatch, ) -> None: diff --git a/tests/ut/spec_decode/test_dflash2_v2.py b/tests/ut/spec_decode/test_dflash2_v2.py index 66951316278a..897db0b90cc1 100644 --- a/tests/ut/spec_decode/test_dflash2_v2.py +++ b/tests/ut/spec_decode/test_dflash2_v2.py @@ -31,7 +31,6 @@ import vllm_ascend.worker.v2.spec_decode.dflash.speculator as dflash_module from vllm_ascend.ops.vocab_parallel_embedding import VocabParallelMode -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.spec_decode import init_speculator from vllm_ascend.worker.v2.spec_decode.dflash.speculator import AscendDFlashSpeculator from vllm_ascend.worker.v2.spec_decode.dflash2.speculator import ( @@ -168,11 +167,8 @@ def test_v2_flash_attn_uses_exact_lengths_after_rejection_and_reordering(monkeyp kv_spec = FullAttentionSpec(block_size=128, num_kv_heads=1, head_size=128, dtype=torch.bfloat16) speculator = AscendDFlash2Speculator.__new__(AscendDFlash2Speculator) speculator.arange_np = torch.arange(5, dtype=torch.int32).numpy() - if vllm_version_is("0.32.0"): - speculator.max_model_len = 1024 - else: - # vLLM main exposes max_model_len as a read-only view of vllm_config. - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=1024)) + # vLLM main exposes max_model_len as a read-only view of vllm_config. + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=1024)) speculator.draft_max_seq_len = 1024 speculator.dcp_size = 1 speculator.input_buffers = SimpleNamespace( @@ -611,7 +607,7 @@ def test_dflash_input_preparation_keeps_physical_and_kernel_block_sizes_separate kernel.assert_called_once_with(*inputs, num_reqs_override=None, kv_cache_block_size=128) -@pytest.mark.skipif(vllm_version_is("0.32.0"), reason="main-only num_reqs_override") +@pytest.mark.skipif(False, reason="main-only num_reqs_override") def test_dflash_input_preparation_forwards_num_reqs_override(monkeypatch): """vLLM main (#58984) forwards the DP-synced request count positionally.""" kernel = MagicMock() diff --git a/tests/ut/spec_decode/test_dspark_pcp_dp_sync.py b/tests/ut/spec_decode/test_dspark_pcp_dp_sync.py index 16c5b7186c9f..79cf45397d97 100644 --- a/tests/ut/spec_decode/test_dspark_pcp_dp_sync.py +++ b/tests/ut/spec_decode/test_dspark_pcp_dp_sync.py @@ -37,7 +37,7 @@ def test_dspark_global_requests_do_not_reuse_local_pcp_dp_capacity(monkeypatch, idx_mapping=torch.arange(draft_reqs), is_prefilling_np=np.zeros(draft_reqs, dtype=np.bool_), ) - sync_kwargs = {} if vllm_version_is("0.32.0") else {"max_query_len": None} + sync_kwargs = {} if vllm_version_is("0.33.0") else {"max_query_len": None} target_sync = DPSyncState( num_tokens_across_dp=torch.tensor([20, 20]), uniform_token_count=5, eager=False, num_reqs=4, **sync_kwargs ) @@ -87,7 +87,7 @@ def test_dspark_syncs_finished_proposals_only_without_upstream_hook( spec.vllm_config = SimpleNamespace(parallel_config=SimpleNamespace()) spec.draft_logits = torch.arange(24, dtype=torch.float32).reshape(6, 2, 2) if probabilistic else None original_logits = spec.draft_logits.clone() if probabilistic else None - batch = SimpleNamespace(idx_mapping=torch.tensor([4, 1]), is_prefilling_np=np.zeros(2, dtype=np.bool_)) + batch = SimpleNamespace(num_reqs=2, idx_mapping=torch.tensor([4, 1]), is_prefilling_np=np.zeros(2, dtype=np.bool_)) local_tokens = torch.tensor([[9, 8], [7, 6]]) shared_tokens = torch.tensor([[1, 2], [3, 4]]) shared_logits = torch.full((2, 2, 2), 0.5) diff --git a/tests/ut/spec_decode/test_dspark_speculator.py b/tests/ut/spec_decode/test_dspark_speculator.py index 08c784f15020..6825ef12ffd8 100644 --- a/tests/ut/spec_decode/test_dspark_speculator.py +++ b/tests/ut/spec_decode/test_dspark_speculator.py @@ -18,7 +18,6 @@ AscendQwen3DSparkForCausalLM, process_weight, ) -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.spec_decode.dspark.speculator import ( AscendDSparkSpeculator, ) @@ -203,8 +202,6 @@ def _context_speculator(monkeypatch, group_ids=(0, 1), layer_map=(1, 0)): ) spec.attn_architecture, spec.use_dcp = "MLA", False spec.device = torch.device("cpu") - if vllm_version_is("0.32.0"): - spec.max_model_len = 16 spec.speculative_config = object() spec.vllm_config = SimpleNamespace( model_config=SimpleNamespace(get_hidden_size=lambda: 4, max_model_len=16), diff --git a/tests/ut/spec_decode/test_dspark_valid_kv_lengths.py b/tests/ut/spec_decode/test_dspark_valid_kv_lengths.py index 301d94d5a95b..37e50a547cf4 100644 --- a/tests/ut/spec_decode/test_dspark_valid_kv_lengths.py +++ b/tests/ut/spec_decode/test_dspark_valid_kv_lengths.py @@ -14,7 +14,6 @@ from vllm.v1.worker.gpu.spec_decode.dspark.speculator import DSparkSpeculator import vllm_ascend.worker.v2.spec_decode.dspark.speculator as speculator_module -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.spec_decode.dspark.speculator import AscendDSparkSpeculator @@ -25,11 +24,8 @@ def _spec(lengths, *, architecture="MLA", use_dcp=False): spec.use_dcp = use_dcp spec.input_buffers = SimpleNamespace(seq_lens=torch.tensor(lengths, dtype=torch.int32), positions=object()) spec.target_input_buffers = SimpleNamespace(seq_lens_cpu=torch.tensor([99999], dtype=torch.int32)) - if vllm_version_is("0.32.0"): - spec.max_model_len = 131072 - else: - # vLLM main exposes max_model_len as a read-only view of vllm_config. - spec.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=131072)) + # vLLM main exposes max_model_len as a read-only view of vllm_config. + spec.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=131072)) return spec diff --git a/tests/ut/spec_decode/test_mla_dspark.py b/tests/ut/spec_decode/test_mla_dspark.py index 9224a05369df..4c3e4bba9ec7 100644 --- a/tests/ut/spec_decode/test_mla_dspark.py +++ b/tests/ut/spec_decode/test_mla_dspark.py @@ -63,7 +63,7 @@ def test_dspark_without_pcp_reuses_target_sync(monkeypatch): monkeypatch.setattr(shared, "build_attn_metadata_wrapper", nullcontext) monkeypatch.setattr(shared, "build_attn_metadata_factory", lambda *a, **kw: nullcontext()) # Without PCP, both models use the same request layout. - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): target_sync = DPSyncState( # type: ignore[call-arg] num_tokens_across_dp=torch.tensor([4, 4]), uniform_token_count=1, eager=False, num_reqs=4 ) diff --git a/tests/ut/test_compressed_prefix_cache.py b/tests/ut/test_compressed_prefix_cache.py index eca8fee6c8ad..7d9714d9eecd 100644 --- a/tests/ut/test_compressed_prefix_cache.py +++ b/tests/ut/test_compressed_prefix_cache.py @@ -8,6 +8,10 @@ from vllm.sampling_params import SamplingParams from vllm.utils.hashing import sha256 from vllm.v1.core.block_pool import BlockPool + +# vLLM #61183 moved `is_kv_cache_spec_uniform` to `kv_cache_planning` on main; +# the v0.33.0 lane still ships it in `kv_cache_utils`. +from vllm.v1.core.kv_cache_planning import is_kv_cache_spec_uniform from vllm.v1.core.kv_cache_utils import ( BlockHashListWithBlockSize, get_block_hash, @@ -31,14 +35,6 @@ from vllm_ascend.patch.platform.patch_kv_cache_coordinator import ( AscendHybridKVCacheCoordinator, ) -from vllm_ascend.utils import vllm_version_is - -# vLLM #61183 moved `is_kv_cache_spec_uniform` to `kv_cache_planning` on main; -# the v0.32.0 lane still ships it in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import is_kv_cache_spec_uniform -else: - from vllm.v1.core.kv_cache_planning import is_kv_cache_spec_uniform pytestmark = pytest.mark.cpu_test diff --git a/tests/ut/worker/test_dcp_speculator_metadata_v2.py b/tests/ut/worker/test_dcp_speculator_metadata_v2.py index df541ae823ab..729a9ad629be 100644 --- a/tests/ut/worker/test_dcp_speculator_metadata_v2.py +++ b/tests/ut/worker/test_dcp_speculator_metadata_v2.py @@ -19,7 +19,6 @@ from vllm_ascend.attention.attention_v1 import AscendAttentionState from vllm_ascend.attention.context_parallel import sfa_cp from vllm_ascend.attention.context_parallel.sfa_cp import AscendSFADCPMetadata, AscendSFADCPMetadataBuilder -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.dcp_utils import DCPManager from vllm_ascend.worker.v2 import attn_utils from vllm_ascend.worker.v2.spec_decode.dspark.speculator import AscendDSparkSpeculator @@ -94,9 +93,6 @@ def _speculator(monkeypatch, kind, architecture, width, padded, step, use_dcp=Tr spec.dcp_manager = manager # vLLM main (#56723) reads speculator.dcp_size in _build_attn_metadata. spec.dcp_size = config.parallel_config.decode_context_parallel_size - # vLLM main exposes max_model_len as a read-only view of vllm_config. - if vllm_version_is("0.32.0"): - spec.max_model_len = 128 spec.draft_max_seq_len = 128 spec.num_query_per_req = width spec.vllm_config = spec.draft_vllm_config = config diff --git a/tests/ut/worker/test_mla_dcp_metadata_v2.py b/tests/ut/worker/test_mla_dcp_metadata_v2.py index 5cfbcd6b76fb..61d3d9953ced 100644 --- a/tests/ut/worker/test_mla_dcp_metadata_v2.py +++ b/tests/ut/worker/test_mla_dcp_metadata_v2.py @@ -9,7 +9,6 @@ import torch from vllm_ascend.attention.context_parallel.mla_cp import AscendMLADCPDecodeMetadata -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.dcp_utils import DCPManager from vllm_ascend.worker.v2 import attn_utils from vllm_ascend.worker.v2.spec_decode.target_dependent_ar.speculator import AscendTargetDependentARSpeculator @@ -116,11 +115,8 @@ def test_full_draft_steps_refresh_local_lengths_without_aliasing(size, rank, int speculator = object.__new__(AscendTargetDependentARSpeculator) speculator.attn_architecture = "MLA" speculator.use_dcp = True - if vllm_version_is("0.32.0"): - speculator.max_model_len = 128 - else: - # vLLM main exposes max_model_len as a read-only view of vllm_config. - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=128)) + # vLLM main exposes max_model_len as a read-only view of vllm_config. + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=128)) speculator.dcp_manager = _manager(size, rank, interleave) speculator.draft_vllm_config = SimpleNamespace( parallel_config=SimpleNamespace(decode_context_parallel_size=size, cp_kv_cache_interleave_size=interleave) diff --git a/tests/ut/worker/test_model_runner_v2.py b/tests/ut/worker/test_model_runner_v2.py index 762018e6f152..769c873c7991 100644 --- a/tests/ut/worker/test_model_runner_v2.py +++ b/tests/ut/worker/test_model_runner_v2.py @@ -27,7 +27,6 @@ from vllm_ascend.attention.attention_v1 import AscendAttentionBackend from vllm_ascend.attention.fa_v1 import AscendFlashAttentionBackend from vllm_ascend.attention.mla_v1 import AscendMLABackend, AscendMLAImpl -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.input_batch import AscendInputBatch, AscendInputBuffers from vllm_ascend.worker.v2.model_runner import NPUModelRunner from vllm_ascend.worker.v2.pcp_manager import AscendPCPManager @@ -488,7 +487,7 @@ def test_prepare_inputs_preserves_pcp_tokens_and_forwards_graph_padding(): # prepare_inputs keeps the real global PCP batch when it is larger than the # graph descriptor, and forwards the whole descriptor through the retained - # PCPManager API (vLLM #57980), also retained in v0.32.0. + # PCPManager API (vLLM #57980), also retained in v0.33.0. assert len(padding_assignments) == 2 assert ast.unparse(padding_assignments[0].value) == "max(num_tokens, batch_desc.num_tokens)" assert ast.unparse(padding_assignments[1].value) == "global_graph_num_reqs * batch_desc.uniform_token_count" @@ -960,7 +959,7 @@ def test_pcp_dummy_refreshes_captured_buffers_after_real_batch(num_reqs, num_tok dummy = AscendInputBatch.make_dummy(num_reqs, num_tokens, runner.input_buffers) # execute_model stages dummy inputs before preparing attention metadata. - stage_name = "prepare_inputs_to_capture" if vllm_version_is("0.32.0") else "prepare_inputs_for_capture_or_profile" + stage_name = "prepare_inputs_for_capture_or_profile" staged = getattr(manager, stage_name)(dummy) block_tables, slots = runner.prepare_dummy_attn(staged) diff --git a/tests/ut/worker/test_model_runner_v2_finegrained_tp.py b/tests/ut/worker/test_model_runner_v2_finegrained_tp.py index 43cd63e99052..6ee1c8dd8658 100644 --- a/tests/ut/worker/test_model_runner_v2_finegrained_tp.py +++ b/tests/ut/worker/test_model_runner_v2_finegrained_tp.py @@ -224,8 +224,8 @@ def test_dispatch_tail_canary_matches_upstream_sample(with_grammar, with_draft, expected_calls = 2 if with_grammar else 1 assert len(upstream_calls) == expected_calls assert override_calls == upstream_calls - if with_grammar and with_draft and vllm_version_is("0.32.0"): - # 0.32.0 exposes the permissive-row mask as the fourth sampler argument; + if with_grammar and with_draft and vllm_version_is("0.33.0"): + # 0.33.0 exposes the permissive-row mask as the fourth sampler argument; # main feeds it through the scheduler/draft-token handler instead. invalid_drafts = runner.rejection_sampler.call_args.args[3] assert invalid_drafts.tolist() == [False, False, True] diff --git a/tests/ut/worker/test_model_runner_v2_kv_cache.py b/tests/ut/worker/test_model_runner_v2_kv_cache.py index 340b3cea8bad..eacfefa08110 100644 --- a/tests/ut/worker/test_model_runner_v2_kv_cache.py +++ b/tests/ut/worker/test_model_runner_v2_kv_cache.py @@ -103,7 +103,7 @@ def test_initialize_builds_aux_output_connector_when_enabled(): # The initializer deep-copies the config, so assert against the resolved one # (identity shortcut) instead of comparing the original object by value. - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): get_aux.assert_called_once_with(runner.model, runner.vllm_config, runner.kv_cache_config) else: # Main creates the connector without the KV-cache config and diff --git a/tests/ut/worker/test_mtp_pcp_speculator_v2.py b/tests/ut/worker/test_mtp_pcp_speculator_v2.py index 12b3064e96b2..6c9efa1e6129 100644 --- a/tests/ut/worker/test_mtp_pcp_speculator_v2.py +++ b/tests/ut/worker/test_mtp_pcp_speculator_v2.py @@ -356,7 +356,7 @@ def test_propose_renegotiates_pcp_draft_dp_sync(pcp_enabled, mismatch, dummy_run speculator.pcp_manager = object() if pcp_enabled else None input_batch = object() attn_metadata = {"mtp": _mla_pcp_decode_metadata(4, [4, 8])} - sync_kwargs = {} if vllm_version_is("0.32.0") else {"max_query_len": None} + sync_kwargs = {} if vllm_version_is("0.33.0") else {"max_query_len": None} dp_sync = DPSyncState( num_tokens_across_dp=torch.tensor([64, 64]), uniform_token_count=4, eager=True, num_reqs=16, **sync_kwargs ) diff --git a/tests/ut/worker/test_pcp_manager_v2.py b/tests/ut/worker/test_pcp_manager_v2.py index de4a2a86183d..fb5d592f8bca 100644 --- a/tests/ut/worker/test_pcp_manager_v2.py +++ b/tests/ut/worker/test_pcp_manager_v2.py @@ -34,7 +34,6 @@ from vllm_ascend.attention.context_parallel.common_cp import is_pcp_decode_sharding_enabled from vllm_ascend.platform import _setup_worker_and_scheduler -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2 import states as states_module from vllm_ascend.worker.v2.aclgraph_utils import ModelAclGraphManager from vllm_ascend.worker.v2.input_batch import AscendInputBatch, AscendInputBuffers @@ -1189,7 +1188,7 @@ def test_cpp_dummy_is_partitioned_instead_of_staged(): local_batch = _make_local_pcp_batch() # vLLM main renamed the upstream staging hook; patch and call the live name. - stage_name = "prepare_inputs_to_capture" if vllm_version_is("0.32.0") else "prepare_inputs_for_capture_or_profile" + stage_name = "prepare_inputs_for_capture_or_profile" with ( patch.object(PCPManager, stage_name) as stage, patch.object(manager, "partition_batch", return_value=local_batch) as partition, @@ -1211,7 +1210,7 @@ def test_capture_input_without_cpp_marker_uses_staging_path(): legacy_batch = SimpleNamespace() staged_batch = _make_local_pcp_batch() - stage_name = "prepare_inputs_to_capture" if vllm_version_is("0.32.0") else "prepare_inputs_for_capture_or_profile" + stage_name = "prepare_inputs_for_capture_or_profile" with ( patch.object(PCPManager, stage_name, return_value=staged_batch) as stage, patch.object(manager, "partition_batch") as partition, @@ -1372,9 +1371,7 @@ def test_is_target_attn_groups_excludes_draft_only_groups(draft_pcp_size) -> Non def _get_draft_input_buffers(manager, buffers, num_tokens): - """Call the live upstream signature; vLLM main also returns the MoE padding mask.""" - if vllm_version_is("0.32.0"): - return manager.get_draft_input_buffers(buffers) + """Both supported upstream versions return the MoE padding mask.""" return manager.get_draft_input_buffers(buffers, num_tokens)[0] diff --git a/tests/ut/worker/test_v2_dummy_padding.py b/tests/ut/worker/test_v2_dummy_padding.py index 30995f2d6a2c..709a4f715e34 100644 --- a/tests/ut/worker/test_v2_dummy_padding.py +++ b/tests/ut/worker/test_v2_dummy_padding.py @@ -13,7 +13,6 @@ from vllm.v1.worker.utils import get_uniform_decode_token_count from vllm_ascend.attention.attention_v1 import AscendAttentionState -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.aclgraph_utils import ModelAclGraphManager from vllm_ascend.worker.v2.input_batch import AscendInputBatch, AscendInputBuffers from vllm_ascend.worker.v2.model_runner import NPUModelRunner @@ -140,7 +139,7 @@ def test_mixed_dp_dummy_keeps_graphs_and_reuses_sync(buffers, runner, draft_mode cpu_group = object() def other_rank_votes(votes, group): - # v0.32.0 passes ``group=cpu_group``; main's ``cpu_all_reduce_`` does not. + # cpu_all_reduce_ already binds the CPU group. assert group is None or group is cpu_group # The other ranks decode real requests with the same query width. votes[0, 1:] = torch.tensor([2 * uniform, 3 * uniform, uniform]) @@ -171,16 +170,10 @@ def execute_dummy(num_tokens, **kwargs): return None, None extra_collective_patch: AbstractContextManager[Any] - if vllm_version_is("0.32.0"): - # v0.32.0 collects through ``dist.all_reduce(votes, group=cpu_group)``. - dp_group = SimpleNamespace(cpu_group=cpu_group) - collective = Mock(side_effect=other_rank_votes) - extra_collective_patch = patch("vllm.v1.worker.gpu.dp_utils.dist.all_reduce", collective) - else: - # vLLM main collects through ``get_dp_group().cpu_all_reduce_(votes)``. - collective = Mock(side_effect=lambda votes: other_rank_votes(votes, None)) - dp_group = SimpleNamespace(cpu_all_reduce_=collective) - extra_collective_patch = nullcontext() + # vLLM main collects through ``get_dp_group().cpu_all_reduce_(votes)``. + collective = Mock(side_effect=lambda votes: other_rank_votes(votes, None)) + dp_group = SimpleNamespace(cpu_all_reduce_=collective) + extra_collective_patch = nullcontext() with ( patch.object(GPUModelRunner, "_dummy_run", side_effect=execute_dummy), diff --git a/tests/ut/worker/test_worker_v2.py b/tests/ut/worker/test_worker_v2.py index f180d2981498..d1361e759da2 100644 --- a/tests/ut/worker/test_worker_v2.py +++ b/tests/ut/worker/test_worker_v2.py @@ -85,20 +85,12 @@ def test_triton_warmup_failure_prevents_capture(use_v2): class TestNPUWorkerV2(TestBase): def test_worker_imports_planning_helpers_from_supported_lane(self): - from vllm_ascend.utils import vllm_version_is - from vllm_ascend.worker import worker - - if vllm_version_is("0.32.0"): - from vllm.v1.core import kv_cache_utils as planning + from vllm.v1.core import kv_cache_planning as planning + from vllm.v1.core.kv_cache_config_builder import get_kv_cache_config_builder - self.assertIs(worker.get_kv_cache_groups, planning.get_kv_cache_groups) - else: - from vllm.v1.core import kv_cache_planning as planning - from vllm.v1.core.kv_cache_config_builder import get_kv_cache_config_builder + from vllm_ascend.worker import worker - # On main the grouping is resolved through the platform's - # pluggable KVCacheConfigBuilder, installed in worker.py. - self.assertIs(worker.get_kv_cache_config_builder, get_kv_cache_config_builder) + self.assertIs(worker.get_kv_cache_config_builder, get_kv_cache_config_builder) self.assertIs(worker.unify_hybrid_kv_cache_specs, planning.unify_hybrid_kv_cache_specs) def test_get_encoder_cudagraph_stats_is_serializable(self): diff --git a/tests/ut/worker/v2/test_speculator.py b/tests/ut/worker/v2/test_speculator.py index b675a7cef20e..e1ea10039963 100644 --- a/tests/ut/worker/v2/test_speculator.py +++ b/tests/ut/worker/v2/test_speculator.py @@ -19,7 +19,6 @@ from vllm_ascend.attention.mla_v1 import AscendMLABackend from vllm_ascend.attention.sfa_v1 import AscendSFABackend from vllm_ascend.distributed.eplb.tensor_ops import make_allgather_mask -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.input_batch import AscendInputBuffers from vllm_ascend.worker.v2.spec_decode.target_dependent_ar.speculator import ( AscendTargetDependentARSpeculator, @@ -31,10 +30,7 @@ def test_calc_next_seq_lens_cpu(): """Test calculation of the next CPU sequence lengths.""" speculator = AscendTargetDependentARSpeculator.__new__(AscendTargetDependentARSpeculator) - if vllm_version_is("0.32.0"): - speculator.max_model_len = 100 - else: - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=100)) + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=100)) seq_lens_cpu = torch.tensor([10, 20, 98, 66], dtype=torch.int32) result = speculator._calc_next_seq_lens_cpu(seq_lens_cpu, num_reqs=3, num_reqs_padded=4, step=3) expected = torch.tensor([13, 23, 100, 0], dtype=torch.int32) @@ -246,9 +242,8 @@ def test_prefill_filters_target_only_metadata(): CUDAGraphMode.NONE, None, ] - if not vllm_version_is("0.32.0"): - # vLLM main added `skip_sample` and forwards it to the upstream _prefill. - expected_args.append(False) + # vLLM main added `skip_sample` and forwards it to the upstream _prefill. + expected_args.append(False) parent_prefill.assert_called_once_with(*expected_args) @@ -260,11 +255,7 @@ def test_prefill_forwards_skip_sample_on_main(): speculator.draft_attn_layer_names = {"draft"} with patch.object(TargetDependentARSpeculator, "_prefill") as parent_prefill: speculator._prefill(2, 4, attn_metadata, None, None, skip_sample=True) - if vllm_version_is("0.32.0"): - assert "skip_sample" not in parent_prefill.call_args.kwargs - assert len(parent_prefill.call_args.args) == 7 - else: - assert parent_prefill.call_args.args[-1] is True + assert parent_prefill.call_args.args[-1] is True def test_build_uniform_attn_metadata_sets_decode_only(): @@ -474,10 +465,7 @@ def test_update_decode_attn_metadata_gqa(): """Test updating decode attention metadata for GQA.""" speculator = AscendTargetDependentARSpeculator.__new__(AscendTargetDependentARSpeculator) speculator.attn_architecture = "GQA" - if vllm_version_is("0.32.0"): - speculator.max_model_len = 32 - else: - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) speculator.use_dcp = False metadata = SimpleNamespace( seq_lens_cpu=torch.zeros(4, dtype=torch.int32), @@ -516,10 +504,7 @@ def test_build_fia_params_decode(): speculator.draft_attn_layer_names = {"draft"} speculator.input_batch = SimpleNamespace(num_reqs=2, seq_lens_np=np.array([10, 29])) speculator.num_speculative_steps = 3 - if vllm_version_is("0.32.0"): - speculator.max_model_len = 30 - else: - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=30)) + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=30)) result = speculator.build_fia_params(3, {"draft": metadata}, False) assert len(result) == 2 assert result[0]["actual_seq_lengths"] == [1, 2, 3] @@ -688,10 +673,7 @@ def test_update_decode_attn_metadata_mla_with_dcp(): """Test MLA decode metadata updates with DCP enabled.""" speculator = AscendTargetDependentARSpeculator.__new__(AscendTargetDependentARSpeculator) speculator.attn_architecture = "MLA" - if vllm_version_is("0.32.0"): - speculator.max_model_len = 32 - else: - speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) + speculator.vllm_config = SimpleNamespace(model_config=SimpleNamespace(max_model_len=32)) speculator.use_dcp = True local_seq_lens = torch.tensor([6, 11, 0], dtype=torch.int32) diff --git a/vllm_ascend/_310p/worker_310p.py b/vllm_ascend/_310p/worker_310p.py index 80c4106acf3f..0ae3e7eaff7b 100644 --- a/vllm_ascend/_310p/worker_310p.py +++ b/vllm_ascend/_310p/worker_310p.py @@ -24,17 +24,13 @@ from vllm.utils.mem_utils import MemorySnapshot, memory_profiling from vllm.utils.torch_utils import set_random_seed # noqa: E402 +# KV-cache planning lives in kv_cache_planning on both supported versions. +from vllm.v1.core.kv_cache_planning import get_kv_cache_groups + from vllm_ascend._310p.kv_cache_sharing import get_310p_shared_cache_slots -from vllm_ascend.utils import is_rc_device, vllm_version_is +from vllm_ascend.utils import is_rc_device from vllm_ascend.worker.worker import NPUWorker, init_workspace_manager -# vLLM #61183 moved `get_kv_cache_groups` to `kv_cache_planning` on main; the -# v0.32.0 lane still ships it in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import get_kv_cache_groups -else: - from vllm.v1.core.kv_cache_planning import get_kv_cache_groups - class NPUWorker310(NPUWorker): def _scale_kv_cache_memory_for_multi_group(self, available_memory: int) -> int: diff --git a/vllm_ascend/ascend_config.py b/vllm_ascend/ascend_config.py index 821deb648037..5519f0bf560c 100644 --- a/vllm_ascend/ascend_config.py +++ b/vllm_ascend/ascend_config.py @@ -895,7 +895,7 @@ def derive_and_validate(self, vllm_config: VllmConfig) -> AscendConfig: ) = self._parse_sparse_li_layers_from_quant_config(quant_config, ("W8A8_MXFP8",)) self._sparse_li_layer_filter_enabled = self._has_sparse_li_layer_config(quant_config) # vLLM #60517 removed the torch.compile-based sequence-parallelism pass - # (and `PassConfig.enable_sp`) in both v0.32.0 and verified main. + # (and `PassConfig.enable_sp`) in both v0.33.0 and verified main. enable_sp_by_pass = False self.enable_sp_by_pass = vc.model_config is not None and not vc.model_config.enforce_eager and enable_sp_by_pass diff --git a/vllm_ascend/attention/mla_v1.py b/vllm_ascend/attention/mla_v1.py index 02db136c561a..093003e65ab1 100644 --- a/vllm_ascend/attention/mla_v1.py +++ b/vllm_ascend/attention/mla_v1.py @@ -87,7 +87,6 @@ enable_sfa, is_pd_decode_recompute_scheduler_enabled, maybe_trans_nz, - vllm_version_is, weak_ref_tensors, ) from vllm_ascend.worker.npu_input_batch import NPUInputBatch @@ -1017,20 +1016,13 @@ def __init__( self.kv_b_proj = kwargs["kv_b_proj"] self.o_proj = kwargs["o_proj"] self.g_proj = kwargs.get("g_proj") - # vLLM main fuses Kimi-K3's output gate into the QKV-A projection as a - # trailing shard, making its per-rank layout ``[q_a | kv_a | gate]`` and - # dropping the standalone ``g_proj``. Release v0.32.0 keeps the separate - # ``g_proj`` and a two-shard projection. - if vllm_version_is("0.32.0"): - self.qkv_a_gate_fused = False - self.use_output_gate = self.g_proj is not None - else: - # The plain MLA projection also only has the two latent shards, so - # the shard count identifies the fused layout without importing the - # Kimi-specific linear class. - fused_output_sizes = getattr(self.fused_qkv_a_proj, "output_sizes", None) - self.qkv_a_gate_fused = fused_output_sizes is not None and len(fused_output_sizes) == 3 - self.use_output_gate = self.g_proj is not None or self.qkv_a_gate_fused + # Both supported Kimi AMD implementations can append an output-gate shard. + # The plain MLA projection also only has the two latent shards, so + # the shard count identifies the fused layout without importing the + # Kimi-specific linear class. + fused_output_sizes = getattr(self.fused_qkv_a_proj, "output_sizes", None) + self.qkv_a_gate_fused = fused_output_sizes is not None and len(fused_output_sizes) == 3 + self.use_output_gate = self.g_proj is not None or self.qkv_a_gate_fused self.use_mla_rope = kwargs.get("use_mla_rope", True) self.vllm_config = get_current_vllm_config() self.use_pcp = self.vllm_config.parallel_config.prefill_context_parallel_size > 1 @@ -1312,23 +1304,13 @@ def process_weights_after_loading(self, act_dtype: torch.dtype): # scenario the graph is captured once, so every later weight update # reload has to refresh the stored tensors in place instead of # rebinding the attributes to freshly allocated tensors. - # `replace_parameter(..., prefer_copy=True)` does exactly that on - # v0.32.0: it copies into the existing storage while the new value stays - # compatible, and rebinds only when shape/dtype/device actually - # changes. vLLM main (#62326) dropped `prefer_copy` and keeps the - # parameter object by default. This mirrors how upstream vLLM refreshes - # `MLAAttention.W_UV`/`W_UK_T`, and unlike a plain `copy_` it cannot - # raise on a shape mismatch. + # replace_parameter preserves the parameter object and compatible storage. w_uv = W_UV.transpose(0, 1).contiguous() # (L, N, V) -> (N, L, V) w_uk_t = W_UK.permute(1, 2, 0).contiguous() # (L, N, P) -> (N, P, L) if self.dcp_q_replicate_enabled: w_uk_t = get_dcp_group().all_gather(w_uk_t, dim=0) - if vllm_version_is("0.32.0"): - replace_parameter(self, "W_UV", w_uv, prefer_copy=True) - replace_parameter(self, "W_UK_T", w_uk_t, prefer_copy=True) - else: - replace_parameter(self, "W_UV", w_uv) - replace_parameter(self, "W_UK_T", w_uk_t) + replace_parameter(self, "W_UV", w_uv) + replace_parameter(self, "W_UK_T", w_uk_t) self.mlapo_W_UK_T = self.W_UK_T if self.enable_mlapo: @@ -3268,53 +3250,33 @@ def mla_preprocess_decode(self, q_c, kv_no_split, kv_cache, attn_metadata, writt current_k_pe=current_k_pe, ) - # vLLM main fuses Kimi-K3's output gate into the trailing shard of the - # QKV-A projection; v0.32.0 never has that shard, so the release lane keeps - # the original two-way ``[q_a | kv_a]`` split. - if vllm_version_is("0.32.0"): + @property + def _fused_qkv_a_kv_end(self) -> int | None: + """End offset of the KV-A shard inside the fused QKV-A projection. - @property - def _fused_qkv_a_kv_end(self) -> int | None: - """v0.32.0 keeps the plain two-shard QKV-A projection.""" + Kimi-K3 appends its output gate after ``[q_a | kv_a]``. ``None`` means + the plain two-shard layout, where the KV-A shard runs to the end. + """ + if not getattr(self, "qkv_a_gate_fused", False): return None + return self.q_lora_rank + self.kv_lora_rank + self.qk_rope_head_dim - def _split_fused_qkv_lora(self, qkv_lora: torch.Tensor): - """Split the plain ``[q_a | kv_a]`` QKV-A projection.""" - q_c, kv_no_split = qkv_lora.split( - [self.q_lora_rank, self.kv_lora_rank + self.qk_rope_head_dim], - dim=-1, - ) - return q_c, kv_no_split, None - - else: - - @property - def _fused_qkv_a_kv_end(self) -> int | None: - """End offset of the KV-A shard inside the fused QKV-A projection. - - Kimi-K3 appends its output gate after ``[q_a | kv_a]``. ``None`` means - the plain two-shard layout, where the KV-A shard runs to the end. - """ - if not getattr(self, "qkv_a_gate_fused", False): - return None - return self.q_lora_rank + self.kv_lora_rank + self.qk_rope_head_dim - - def _split_fused_qkv_lora(self, qkv_lora: torch.Tensor): - """Split the fused QKV-A projection into ``q_c`` and ``kv_no_split``. - - Kimi-K3 appends its output gate as a trailing shard; when that layout is - detected the gate is peeled off first and returned so the caller can - apply it after attention. ``None`` is returned for the plain layout. - """ - gate = None - kv_end = self._fused_qkv_a_kv_end - if kv_end is not None: - qkv_lora, gate = qkv_lora.split([kv_end, qkv_lora.shape[-1] - kv_end], dim=-1) - q_c, kv_no_split = qkv_lora.split( - [self.q_lora_rank, self.kv_lora_rank + self.qk_rope_head_dim], - dim=-1, - ) - return q_c, kv_no_split, gate + def _split_fused_qkv_lora(self, qkv_lora: torch.Tensor): + """Split the fused QKV-A projection into ``q_c`` and ``kv_no_split``. + + Kimi-K3 appends its output gate as a trailing shard; when that layout is + detected the gate is peeled off first and returned so the caller can + apply it after attention. ``None`` is returned for the plain layout. + """ + gate = None + kv_end = self._fused_qkv_a_kv_end + if kv_end is not None: + qkv_lora, gate = qkv_lora.split([kv_end, qkv_lora.shape[-1] - kv_end], dim=-1) + q_c, kv_no_split = qkv_lora.split( + [self.q_lora_rank, self.kv_lora_rank + self.qk_rope_head_dim], + dim=-1, + ) + return q_c, kv_no_split, gate def _mla_preprocess(self, layer_name, hidden_states, kv_cache, attn_metadata): # MLA Preprocess: diff --git a/vllm_ascend/attention/sfa_v1.py b/vllm_ascend/attention/sfa_v1.py index e35965e4639d..5de780b06039 100644 --- a/vllm_ascend/attention/sfa_v1.py +++ b/vllm_ascend/attention/sfa_v1.py @@ -76,7 +76,6 @@ is_mtp_layer, is_rl_weight_update_enabled, maybe_trans_nz, - vllm_version_is, ) from vllm_ascend.weight_switch import ParallelOProjection, WeightSwitchConfig @@ -981,25 +980,11 @@ def process_weights_after_loading(self, act_dtype: torch.dtype): W_UK, W_UV = kv_b_proj_weight.split([self.qk_nope_head_dim, self.v_head_dim], dim=-1) - # NOTE: `W_UK`/`W_UV` must live at a stable address: in graph + RL - # scenario the graph is captured once, so every later weight update - # reload has to refresh the stored tensors in place instead of - # rebinding the attributes to freshly allocated tensors. - # `replace_parameter(..., prefer_copy=True)` does exactly that on - # v0.32.0: it copies into the existing storage while the new value stays - # compatible, and rebinds only when shape/dtype/device actually - # changes. vLLM main (#62326) dropped `prefer_copy` and keeps the - # parameter object by default. This mirrors how upstream vLLM refreshes - # `MLAAttention.W_UV`/`W_UK_T`, and unlike a plain `copy_` it cannot - # raise on a shape mismatch. + # replace_parameter preserves the parameter object and compatible storage on both supported versions. w_uv = W_UV.transpose(0, 1).contiguous() # (L, N, V) -> (N, L, V) w_uk_t = W_UK.permute(1, 2, 0).contiguous() # (L, N, P) -> (N, P, L) - if vllm_version_is("0.32.0"): - replace_parameter(self, "W_UV", w_uv, prefer_copy=True) - replace_parameter(self, "W_UK_T", w_uk_t, prefer_copy=True) - else: - replace_parameter(self, "W_UV", w_uv) - replace_parameter(self, "W_UK_T", w_uk_t) + replace_parameter(self, "W_UV", w_uv) + replace_parameter(self, "W_UK_T", w_uk_t) # Dispose kv_b_proj since it is replaced by W_UV and W_UK_T to save memory. # RL keeps it: it is the only source of W_UV/W_UK_T, so every weight diff --git a/vllm_ascend/core/dyntra_lb_scheduler.py b/vllm_ascend/core/dyntra_lb_scheduler.py index 773751a5c7f3..178d9f11a4db 100644 --- a/vllm_ascend/core/dyntra_lb_scheduler.py +++ b/vllm_ascend/core/dyntra_lb_scheduler.py @@ -30,7 +30,6 @@ from vllm.v1.utils import record_function_or_nullcontext from vllm_ascend.ascend_config import DyntraLBConfig -from vllm_ascend.utils import vllm_version_is if TYPE_CHECKING: from vllm.v1.core.sched.scheduler import Scheduler as _SchedulerBase @@ -594,9 +593,7 @@ def schedule(self, throttle_prefills: bool = False) -> SchedulerOutput: break if new_blocks is None: - if not vllm_version_is("0.32.0") and ( - self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED - ): + if self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED: # The request was the lowest-priority running request and # preempted itself. The requests after it have higher # priority and may still fit; it was removed from diff --git a/vllm_ascend/core/recompute_scheduler.py b/vllm_ascend/core/recompute_scheduler.py index 21702e156217..ad1a723b54eb 100644 --- a/vllm_ascend/core/recompute_scheduler.py +++ b/vllm_ascend/core/recompute_scheduler.py @@ -46,7 +46,7 @@ DyntraLBPolicyMixin, print_scheduler_summary, ) -from vllm_ascend.utils import get_ascend_config, vllm_version_is +from vllm_ascend.utils import get_ascend_config def _normalize_encoder_schedule_result( @@ -432,9 +432,7 @@ def schedule(self, throttle_prefills: bool = False) -> SchedulerOutput: break if new_blocks is None: - if not vllm_version_is("0.32.0") and ( - self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED - ): + if self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED: # The request was the lowest-priority running request and # preempted itself. The requests after it have higher # priority and may still fit; it was removed from diff --git a/vllm_ascend/core/scheduler_profiling_chunk.py b/vllm_ascend/core/scheduler_profiling_chunk.py index 863fa708ec96..c374a902d041 100644 --- a/vllm_ascend/core/scheduler_profiling_chunk.py +++ b/vllm_ascend/core/scheduler_profiling_chunk.py @@ -46,7 +46,6 @@ from vllm.v1.utils import record_function_or_nullcontext from vllm_ascend.core.profiling_chunk_predictor import ProfilingChunkManager -from vllm_ascend.utils import vllm_version_is class ProfilingChunkScheduler(Scheduler): @@ -527,9 +526,7 @@ def schedule(self, throttle_prefills: bool = False) -> SchedulerOutput: # noqa: break if new_blocks is None: - if not vllm_version_is("0.32.0") and ( - self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED - ): + if self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED: # The request was the lowest-priority running request and # preempted itself. The requests after it have higher # priority and may still fit; it was removed from diff --git a/vllm_ascend/distributed/weight_transfer/hccl_engine.py b/vllm_ascend/distributed/weight_transfer/hccl_engine.py index 357f912c2e62..ca71afa58ebf 100644 --- a/vllm_ascend/distributed/weight_transfer/hccl_engine.py +++ b/vllm_ascend/distributed/weight_transfer/hccl_engine.py @@ -295,7 +295,7 @@ def send_weights(self) -> None: self._release_group() raise - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): def _broadcast(self, source: WeightSource, meta: list[ParamMeta]) -> None: with torch.npu.device(self.device): diff --git a/vllm_ascend/distributed/weight_transfer/npu_ipc_engine.py b/vllm_ascend/distributed/weight_transfer/npu_ipc_engine.py index 5f9dd16b5c11..12b91c34e82f 100644 --- a/vllm_ascend/distributed/weight_transfer/npu_ipc_engine.py +++ b/vllm_ascend/distributed/weight_transfer/npu_ipc_engine.py @@ -25,7 +25,6 @@ packed_npu_ipc_consumer, packed_npu_ipc_producer, ) -from vllm_ascend.utils import vllm_version_is if TYPE_CHECKING: from vllm.distributed.weight_transfer.base import ( @@ -268,9 +267,8 @@ def _post_send_sync() -> None: def _send_packed(self, source: "WeightSource") -> None: """Send weights in bounded-memory chunks (packed mode).""" - # vLLM main replaced `WeightSource.__iter__` with `iter_full()`; - # v0.32.0 still iterates the source directly. - iterator = iter(source) if vllm_version_is("0.32.0") else source.iter_full() + # Both supported versions drive the WeightSource iter_full protocol. + iterator = source.iter_full() for chunk in packed_npu_ipc_producer( iterator=iterator, npu_uuid=self.npu_uuid, diff --git a/vllm_ascend/ec_manager/score_ec_manager.py b/vllm_ascend/ec_manager/score_ec_manager.py index c8fc5c4313c9..e712d522ba1e 100644 --- a/vllm_ascend/ec_manager/score_ec_manager.py +++ b/vllm_ascend/ec_manager/score_ec_manager.py @@ -6,8 +6,6 @@ from vllm.v1.core.encoder_cache_manager import EncoderCacheManager from vllm.v1.request import Request -from vllm_ascend.utils import vllm_version_is - if TYPE_CHECKING: from vllm.config import VllmConfig @@ -110,10 +108,9 @@ def create_manager( def __init__(self, cache_size: int, vllm_config: "VllmConfig"): super().__init__(cache_size) - if not vllm_version_is("0.32.0"): - # vLLM main keeps per-mm_hash refcounts for a request's cached - # inputs; the pinned release tree tracks only the input ids. - self.request_hash_refs: dict[str, dict[str, int]] = {} + # vLLM main keeps per-mm_hash refcounts for a request's cached + # inputs; the pinned release tree tracks only the input ids. + self.request_hash_refs: dict[str, dict[str, int]] = {} config = ScoreEncoderCacheConfig.from_dict(vllm_config.ec_manager_config.manager_config) # ---------------- NPU cache ---------------- @@ -306,14 +303,11 @@ def check_and_update_cache(self, request: Request, input_id: int) -> bool: if mm_hash in self.npu_cache: ent.clock = self.max_clock - if vllm_version_is("0.32.0"): - self.request_cached_ids.setdefault(request.request_id, set()).add(input_id) - else: - cached_ids = self.request_cached_ids.setdefault(request.request_id, set()) - if input_id not in cached_ids: - cached_ids.add(input_id) - hash_refs = self.request_hash_refs.setdefault(request.request_id, {}) - hash_refs[mm_hash] = hash_refs.get(mm_hash, 0) + 1 + cached_ids = self.request_cached_ids.setdefault(request.request_id, set()) + if input_id not in cached_ids: + cached_ids.add(input_id) + hash_refs = self.request_hash_refs.setdefault(request.request_id, {}) + hash_refs[mm_hash] = hash_refs.get(mm_hash, 0) + 1 return True def on_request(self): @@ -421,46 +415,36 @@ def allocate(self, request: Request, input_id: int) -> None: self.cpu_cache[mm_hash] = cache_entry self.cached[mm_hash].add(request_id) - if vllm_version_is("0.32.0"): - self.request_cached_ids.setdefault(request_id, set()).add(input_id) - else: - cached_ids = self.request_cached_ids.setdefault(request_id, set()) - if input_id not in cached_ids: - cached_ids.add(input_id) - hash_refs = self.request_hash_refs.setdefault(request_id, {}) - hash_refs[mm_hash] = hash_refs.get(mm_hash, 0) + 1 + cached_ids = self.request_cached_ids.setdefault(request_id, set()) + if input_id not in cached_ids: + cached_ids.add(input_id) + hash_refs = self.request_hash_refs.setdefault(request_id, {}) + hash_refs[mm_hash] = hash_refs.get(mm_hash, 0) + 1 def free_encoder_input(self, request: Request, input_id: int) -> None: req_id = request.request_id mm_hash = request.mm_features[input_id].identifier - if vllm_version_is("0.32.0"): - if req_id in self.request_cached_ids: - self.request_cached_ids[req_id].discard(input_id) - if not self.request_cached_ids[req_id]: - del self.request_cached_ids[req_id] - else: - cached_ids = self.request_cached_ids.get(req_id) - if cached_ids is not None and input_id in cached_ids: - cached_ids.remove(input_id) - hash_refs = self.request_hash_refs.setdefault(req_id, {}) - refs = hash_refs.get(mm_hash, 0) - if refs <= 1: - hash_refs.pop(mm_hash, None) - else: - hash_refs[mm_hash] = refs - 1 - if not cached_ids: - del self.request_cached_ids[req_id] - if not hash_refs: - self.request_hash_refs.pop(req_id, None) + cached_ids = self.request_cached_ids.get(req_id) + if cached_ids is not None and input_id in cached_ids: + cached_ids.remove(input_id) + hash_refs = self.request_hash_refs.setdefault(req_id, {}) + refs = hash_refs.get(mm_hash, 0) + if refs <= 1: + hash_refs.pop(mm_hash, None) + else: + hash_refs[mm_hash] = refs - 1 + if not cached_ids: + del self.request_cached_ids[req_id] + if not hash_refs: + self.request_hash_refs.pop(req_id, None) # The mm_hash not in cache or the req_id set is empty if not self.cached.get(mm_hash, None): return - if not vllm_version_is("0.32.0"): - # A request that still holds another input with the same mm_hash - # keeps the entry alive (vLLM main's refcounted release fix). - if mm_hash in self.request_hash_refs.get(req_id, ()): - return + # A request that still holds another input with the same mm_hash + # keeps the entry alive (vLLM main's refcounted release fix). + if mm_hash in self.request_hash_refs.get(req_id, ()): + return self.cached[mm_hash].discard(req_id) if self.cached[mm_hash]: return @@ -554,8 +538,7 @@ def reset(self) -> None: """ self.cached.clear() self.request_cached_ids.clear() - if not vllm_version_is("0.32.0"): - self.request_hash_refs.clear() + self.request_hash_refs.clear() self.freeable.clear() self.promoting.clear() self.cpu_get_encoder_mm_hashes.clear() diff --git a/vllm_ascend/models/deepseek_v4/compressor.py b/vllm_ascend/models/deepseek_v4/compressor.py index 3aa7bf9c4275..32ed6166b359 100644 --- a/vllm_ascend/models/deepseek_v4/compressor.py +++ b/vllm_ascend/models/deepseek_v4/compressor.py @@ -28,7 +28,9 @@ import torch from torch import nn -from transformers import DeepseekV2Config, DeepseekV3Config + +# DeepseekV4Config is provided by Transformers on both supported versions. +from transformers import DeepseekV2Config, DeepseekV3Config, DeepseekV4Config from vllm.config import CacheConfig, VllmConfig from vllm.model_executor.layers.layernorm import RMSNorm from vllm.model_executor.layers.linear import ReplicatedLinear @@ -38,17 +40,8 @@ from vllm_ascend.core.kv_cache_interface import AscendSlidingWindowMLASpec from vllm_ascend.device.hardware_profile import HardwareCapability, get_current_hardware_profile -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.device_metadata import DeviceMetadataStage, wait_for_device_metadata -# vLLM #61392 switched DeepseekV4Config to the upstream Transformers class on -# main; the v0.32.0 lane still ships it under -# `vllm.transformers_utils.configs.deepseek_v4`. -if vllm_version_is("0.32.0"): - from vllm.transformers_utils.configs.deepseek_v4 import DeepseekV4Config # type: ignore[import-not-found] -else: - from transformers import DeepseekV4Config - class AscendCompressorStateCache(CompressorStateCache): def __init__( diff --git a/vllm_ascend/models/deepseek_v4/indexer.py b/vllm_ascend/models/deepseek_v4/indexer.py index be3cc3e5354d..2463839d4f71 100644 --- a/vllm_ascend/models/deepseek_v4/indexer.py +++ b/vllm_ascend/models/deepseek_v4/indexer.py @@ -31,7 +31,9 @@ import torch.nn.functional as F import torch_npu from torch import nn -from transformers import DeepseekV2Config, DeepseekV3Config + +# DeepseekV4Config is provided by Transformers on both supported versions. +from transformers import DeepseekV2Config, DeepseekV3Config, DeepseekV4Config from vllm.config import CacheConfig, VllmConfig from vllm.model_executor.layers.linear import ReplicatedLinear from vllm.model_executor.layers.quantization import QuantizationConfig @@ -48,18 +50,9 @@ ) from vllm_ascend.utils import ( npu_stream_switch, - vllm_version_is, ) from vllm_ascend.worker.device_metadata import DeviceMetadataStage, wait_for_device_metadata -# vLLM #61392 switched DeepseekV4Config to the upstream Transformers class on -# main; the v0.32.0 lane still ships it under -# `vllm.transformers_utils.configs.deepseek_v4`. -if vllm_version_is("0.32.0"): - from vllm.transformers_utils.configs.deepseek_v4 import DeepseekV4Config # type: ignore[import-not-found] -else: - from transformers import DeepseekV4Config - def hadamard_linear(x: torch.Tensor, hadamard: torch.Tensor) -> tuple[torch.Tensor, tuple[int, ...], int]: x_shape = x.shape diff --git a/vllm_ascend/models/deepseek_v4/mm_preprocess.py b/vllm_ascend/models/deepseek_v4/mm_preprocess.py index 18bf48cd3d63..64b23b606fd0 100644 --- a/vllm_ascend/models/deepseek_v4/mm_preprocess.py +++ b/vllm_ascend/models/deepseek_v4/mm_preprocess.py @@ -29,7 +29,9 @@ import numpy as np import torch from PIL import Image, ImageOps -from transformers import BatchFeature + +# DeepseekV4Config is provided by Transformers on both supported versions. +from transformers import BatchFeature, DeepseekV4Config from vllm.config.multimodal import BaseDummyOptions, ImageDummyOptions from vllm.inputs import MultiModalDataDict from vllm.multimodal.inputs import MultiModalFieldConfig, MultiModalKwargsItems @@ -47,16 +49,6 @@ PlaceholderFeaturesInfo, ) -from vllm_ascend.utils import vllm_version_is - -# vLLM #61392 switched DeepseekV4Config to the upstream Transformers class on -# main; the v0.32.0 lane still ships it under -# `vllm.transformers_utils.configs.deepseek_v4`. -if vllm_version_is("0.32.0"): - from vllm.transformers_utils.configs.deepseek_v4 import DeepseekV4Config # type: ignore[import-not-found] -else: - from transformers import DeepseekV4Config - IMAGE_START, IMAGE_PAD, IMAGE, IMAGE_NEW_LINE, IMAGE_END = range(5) COMPRESS_PAD_TO = 4 diff --git a/vllm_ascend/models/deepseek_v4/model.py b/vllm_ascend/models/deepseek_v4/model.py index 81959b79123c..ce28d9bd26b3 100644 --- a/vllm_ascend/models/deepseek_v4/model.py +++ b/vllm_ascend/models/deepseek_v4/model.py @@ -32,7 +32,11 @@ import torch.nn.functional as F import vllm.envs as envs from torch import nn -from transformers import DeepseekV2Config, DeepseekV3Config + +# vLLM #61392 switched DeepseekV4Config to the upstream Transformers class on +# main; the v0.33.0 lane still ships it under +# `vllm.transformers_utils.configs.deepseek_v4`. +from transformers import DeepseekV2Config, DeepseekV3Config, DeepseekV4Config from vllm._aiter_ops import rocm_aiter_ops from vllm.compilation.decorators import support_torch_compile from vllm.config import CacheConfig, ParallelConfig, VllmConfig @@ -97,7 +101,6 @@ enable_custom_op, extract_dsv4_layer_index, get_dsv4_compress_ratio, - vllm_version_is, ) from vllm_ascend.worker.v2.pp_transport import ( PPTransportDataType, @@ -108,14 +111,6 @@ make_empty_intermediate_tensors as make_pp_empty_intermediate_tensors, ) -# vLLM #61392 switched DeepseekV4Config to the upstream Transformers class on -# main; the v0.32.0 lane still ships it under -# `vllm.transformers_utils.configs.deepseek_v4`. -if vllm_version_is("0.32.0"): - from vllm.transformers_utils.configs.deepseek_v4 import DeepseekV4Config # type: ignore[import-not-found] -else: - from transformers import DeepseekV4Config - sequence_parallel_chunk = sp_shard @@ -341,8 +336,7 @@ def __init__( # vLLM main folded `num_hash_layers` into the per-layer `mlp_layer_types`; # judge Hash-MoE per layer (it need not be a contiguous prefix) and fall - # back to the legacy count on the v0.32.0 lane, which has no - # `mlp_layer_types`. + # back to the legacy count for checkpoints without `mlp_layer_types`. if is_draft_layer: self.hash = False else: @@ -702,18 +696,17 @@ def __init__( if config is None: config = vllm_config.model_config.hf_config - if not vllm_version_is("0.32.0"): - # vLLM #61392 folded `compress_ratios` into `layer_types`; the - # Ascend helpers and the KV-store metadata still index the legacy - # field, so restore it. - if getattr(config, "compress_ratios", None) is None: - # `vllm.transformers_utils.deepseek_v4_utils` only exists on - # main (added by #61392), so keep the import lazy. - from vllm.transformers_utils.deepseek_v4_utils import get_compress_ratios - - compress_ratios = get_compress_ratios(config) - if compress_ratios: - config.compress_ratios = list(compress_ratios) + # vLLM #61392 folded `compress_ratios` into `layer_types`; the + # Ascend helpers and the KV-store metadata still index the legacy + # field, so restore it. + if getattr(config, "compress_ratios", None) is None: + # `vllm.transformers_utils.deepseek_v4_utils` only exists on + # main (added by #61392), so keep the import lazy. + from vllm.transformers_utils.deepseek_v4_utils import get_compress_ratios + + compress_ratios = get_compress_ratios(config) + if compress_ratios: + config.compress_ratios = list(compress_ratios) cache_config = vllm_config.cache_config quant_config = vllm_config.quant_config parallel_config = vllm_config.parallel_config diff --git a/vllm_ascend/models/deepseek_v41/cache_config.py b/vllm_ascend/models/deepseek_v41/cache_config.py index b737660f8b96..9c6e4497d562 100644 --- a/vllm_ascend/models/deepseek_v41/cache_config.py +++ b/vllm_ascend/models/deepseek_v41/cache_config.py @@ -6,6 +6,9 @@ import torch from vllm.config import VllmConfig + +# Both supported versions expose planning helpers in kv_cache_planning. +from vllm.v1.core.kv_cache_planning import may_override_num_blocks from vllm.v1.kv_cache_interface import ( CircularBufferSpec, KVCacheConfig, @@ -23,14 +26,6 @@ HardwareCapability, get_current_hardware_profile, ) -from vllm_ascend.utils import vllm_version_is - -# vLLM #61183 moved `may_override_num_blocks` to `kv_cache_planning` on main; -# the v0.32.0 lane still ships it in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import may_override_num_blocks -else: - from vllm.v1.core.kv_cache_planning import may_override_num_blocks STATE_RING_ROWS = 32 diff --git a/vllm_ascend/models/glm5next/cache_config.py b/vllm_ascend/models/glm5next/cache_config.py index d87a64071b25..1cd24fc7cc25 100644 --- a/vllm_ascend/models/glm5next/cache_config.py +++ b/vllm_ascend/models/glm5next/cache_config.py @@ -14,6 +14,12 @@ from vllm.config import VllmConfig from vllm.model_executor.models.utils import extract_layer_index from vllm.utils.torch_utils import get_dtype_size + +# Both supported versions expose planning helpers in kv_cache_planning. +from vllm.v1.core.kv_cache_planning import ( + create_kv_cache_group_specs, + may_override_num_blocks, +) from vllm.v1.kv_cache_interface import ( KVCacheConfig, KVCacheGroupSpec, @@ -30,20 +36,6 @@ get_kv_cache_compression_ratio, get_storage_block_size, ) -from vllm_ascend.utils import vllm_version_is - -# vLLM #61183 moved these helpers to `kv_cache_planning` on main; the v0.32.0 -# lane still ships them in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import ( - create_kv_cache_group_specs, - may_override_num_blocks, - ) -else: - from vllm.v1.core.kv_cache_planning import ( - create_kv_cache_group_specs, - may_override_num_blocks, - ) @dataclass(frozen=True) diff --git a/vllm_ascend/models/glm5next/kda.py b/vllm_ascend/models/glm5next/kda.py index d68139b4be3b..5283da0bd42d 100644 --- a/vllm_ascend/models/glm5next/kda.py +++ b/vllm_ascend/models/glm5next/kda.py @@ -35,7 +35,6 @@ from vllm_ascend.models.glm5next.recoverssm_config import use_glm_recoverssm from vllm_ascend.ops.gdn_attn_builder import AscendGDNHostMetadataBackend from vllm_ascend.ops.triton.kda.recoverssm import kda_recoverssm_verify -from vllm_ascend.utils import vllm_version_is class Glm5NextGDNHostMetadataBackend(AscendGDNHostMetadataBackend): @@ -217,8 +216,6 @@ def get_state_dtype( self.cache_config.mamba_ssm_cache_dtype, ) if self.use_recoverssm: - if vllm_version_is("0.32.0"): - return MambaStateDtypeCalculator.append_kda_recoverssm_record(dtypes, self.model_config.dtype) # vLLM main moved KDA RecoverSSM records out of the KV cache and # removed the calculator helper, but Ascend still packs the # float32 correction and activation key/gate records into the page. @@ -240,10 +237,6 @@ def get_state_shape( num_spec=self.num_spec, ) if self.use_recoverssm: - if vllm_version_is("0.32.0"): - return MambaStateShapeCalculator.append_kda_recoverssm_record( - shapes, self.num_heads, self.head_dim, self.tp_size, self.num_spec + 1 - ) # One checkpoint per request plus compact update records, matching # the layout the Ascend commit context allocates from. local_num_heads = divide(self.num_heads, self.tp_size) diff --git a/vllm_ascend/models/glm5next/model.py b/vllm_ascend/models/glm5next/model.py index f6aa39299a9e..f5ef283eb020 100644 --- a/vllm_ascend/models/glm5next/model.py +++ b/vllm_ascend/models/glm5next/model.py @@ -80,7 +80,7 @@ from vllm.sequence import IntermediateTensors from vllm.utils.torch_utils import get_kv_cache_torch_dtype -from vllm_ascend.utils import pad_sequence_parallel_tokens, vllm_version_is +from vllm_ascend.utils import pad_sequence_parallel_tokens from .attention import Glm5NextMLAAttention from .kda import Glm5NextLinearAttention, get_kda_parallel_size @@ -775,13 +775,10 @@ def load_weights(self, weights: Iterable[tuple[Any, ...]]) -> set[str]: params_dict = dict(self.named_parameters()) loaded_params: set[str] = set() - if vllm_version_is("0.32.0"): - _pending_wk_fp8: dict = {} - else: - # Reordering loaders can split an FP8 indexer wk weight/scale pair - # across load_weights() calls; keep the pending buffer on the model. - _pending_wk_fp8 = getattr(self, "_pending_indexer_wk_fp8", {}) - self._pending_indexer_wk_fp8 = _pending_wk_fp8 + # Reordering loaders can split an FP8 indexer wk weight/scale pair + # across load_weights() calls; keep the pending buffer on the model. + _pending_wk_fp8 = getattr(self, "_pending_indexer_wk_fp8", {}) + self._pending_indexer_wk_fp8 = _pending_wk_fp8 for args in weights: name, loaded_weight = args[:2] @@ -938,8 +935,6 @@ def get_mamba_state_dtype_from_config( vllm_config.cache_config.mamba_ssm_cache_dtype, ) if use_glm_recoverssm(vllm_config): - if vllm_version_is("0.32.0"): - return MambaStateDtypeCalculator.append_kda_recoverssm_record(dtypes, vllm_config.model_config.dtype) # vLLM main moved KDA RecoverSSM records out of the KV cache and # removed the calculator helper, but Ascend still packs them in. return (*dtypes, torch.float32, get_kv_cache_torch_dtype("auto", vllm_config.model_config.dtype)) @@ -961,10 +956,6 @@ def get_mamba_state_shape_from_config( num_spec=num_spec, ) if use_glm_recoverssm(vllm_config): - if vllm_version_is("0.32.0"): - return MambaStateShapeCalculator.append_kda_recoverssm_record( - shapes, hf_config.linear_num_heads, hf_config.linear_head_dim, tp_size, num_spec + 1 - ) local_num_heads = divide(hf_config.linear_num_heads, tp_size) spec_query_len = num_spec + 1 return ( diff --git a/vllm_ascend/models/glm5next/mtp.py b/vllm_ascend/models/glm5next/mtp.py index cbe741cedb63..59be61df071d 100644 --- a/vllm_ascend/models/glm5next/mtp.py +++ b/vllm_ascend/models/glm5next/mtp.py @@ -27,7 +27,7 @@ from vllm.utils.torch_utils import direct_register_custom_op from vllm_ascend.ops.triton.linearnorm.fused_eh_norm import fused_eh_norm -from vllm_ascend.utils import is_rot_weight_used, vllm_version_is +from vllm_ascend.utils import is_rot_weight_used from .model import ( Glm5NextDecoderLayer, @@ -346,13 +346,10 @@ def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: params_dict = dict(self.named_parameters()) loaded_params: set[str] = set() - if vllm_version_is("0.32.0"): - _pending_wk_fp8: dict = {} - else: - # Reordering loaders can split an FP8 indexer wk weight/scale pair - # across load_weights() calls; keep the pending buffer on the model. - _pending_wk_fp8 = getattr(self, "_pending_indexer_wk_fp8", {}) - self._pending_indexer_wk_fp8 = _pending_wk_fp8 + # Reordering loaders can split an FP8 indexer wk weight/scale pair + # across load_weights() calls; keep the pending buffer on the model. + _pending_wk_fp8 = getattr(self, "_pending_indexer_wk_fp8", {}) + self._pending_indexer_wk_fp8 = _pending_wk_fp8 for name, loaded_weight in weights: if "rotary_emb.inv_freq" in name: continue diff --git a/vllm_ascend/models/kimi_k3.py b/vllm_ascend/models/kimi_k3.py index 741713d95677..7262c008f635 100644 --- a/vllm_ascend/models/kimi_k3.py +++ b/vllm_ascend/models/kimi_k3.py @@ -91,7 +91,7 @@ from vllm_ascend.ops.kimi_kda import AscendKimiK3DeltaAttention # type: ignore[import-untyped] from vllm_ascend.ops.linear_op import KimiOProjMMReduceScatterOp from vllm_ascend.quantization.methods.w8a8.w8a8_mxfp8 import AscendW8A8MXFP8DynamicLinearMethod -from vllm_ascend.utils import get_rotation_path, is_950, vllm_version_is +from vllm_ascend.utils import get_rotation_path, is_950 from vllm_ascend.worker.v2.pp_transport import ( PPTransportDataType, add_pp_transport_tensors, @@ -929,14 +929,6 @@ def forward( **kwargs, ) -> torch.Tensor | IntermediateTensors | tuple[torch.Tensor, list[torch.Tensor]]: if self.config.attn_res_block_size is None: - if vllm_version_is("0.32.0"): - return super().forward( - input_ids=input_ids, - positions=positions, - intermediate_tensors=intermediate_tensors, - inputs_embeds=inputs_embeds, - **kwargs, - ) return super().forward( input_ids=input_ids, positions=positions, @@ -1131,15 +1123,11 @@ class AscendKimiLinearForCausalLM(UpstreamKimiLinearForCausalLM, KimiMixtureOfEx def __init__(self, *, vllm_config: VllmConfig, prefix: str = "") -> None: nn.Module.__init__(self) - if vllm_version_is("0.32.0"): - # v0.32.0 predates the AMD specialized-decode hooks we inherit. - pass - else: - from vllm.models.kimi_k3.amd.specialized_decode.runtime import ( - specialized_decode_config, - ) + from vllm.models.kimi_k3.amd.specialized_decode.runtime import ( + specialized_decode_config, + ) - self.init_specialized_decode(specialized_decode_config(vllm_config)) + self.init_specialized_decode(specialized_decode_config(vllm_config)) self.model_config = vllm_config.model_config self.vllm_config = vllm_config self.config = self.model_config.hf_config @@ -1177,19 +1165,17 @@ def set_moe_parameters(self) -> None: def set_dspark_aux_capture_materialized(self, enabled: bool) -> None: self.model.dspark_aux_capture_materialized = enabled - if not vllm_version_is("0.32.0"): + def get_model_state_cls(self): + """Use the Ascend hybrid state instead of the inherited ROCm one. - def get_model_state_cls(self): - """Use the Ascend hybrid state instead of the inherited ROCm one. - - vLLM main lets the AMD Kimi class provide its own model state; that - state builds upstream attention metadata, which is invalid on NPU. - """ - from vllm_ascend.worker.v2.model_states.mamba_hybrid import ( - AscendMambaHybridModelState, - ) + vLLM main lets the AMD Kimi class provide its own model state; that + state builds upstream attention metadata, which is invalid on NPU. + """ + from vllm_ascend.worker.v2.model_states.mamba_hybrid import ( + AscendMambaHybridModelState, + ) - return AscendMambaHybridModelState + return AscendMambaHybridModelState class AscendKimiK3MultiModalProjector(KimiK25MultiModalProjector): diff --git a/vllm_ascend/models/qwen4_exp/cpu_length_sync.py b/vllm_ascend/models/qwen4_exp/cpu_length_sync.py index 079a0fe32c47..cb3bc1852573 100644 --- a/vllm_ascend/models/qwen4_exp/cpu_length_sync.py +++ b/vllm_ascend/models/qwen4_exp/cpu_length_sync.py @@ -24,7 +24,7 @@ def can_skip_qwen_cpu_length_sync(runner: Any) -> bool: # main renamed the QSA side-cache module and its builder/backend; the # release tree still ships qsa_cache.py. - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): import vllm.models.qwen4_exp.common.qsa_cache as qsa_cache # type: ignore[import-not-found] QSAIndexerMetadataBuilder = qsa_cache.QSAMetadataBuilder diff --git a/vllm_ascend/models/qwen4_exp/qsa.py b/vllm_ascend/models/qwen4_exp/qsa.py index b2ac62f5221b..2517a687f89e 100644 --- a/vllm_ascend/models/qwen4_exp/qsa.py +++ b/vllm_ascend/models/qwen4_exp/qsa.py @@ -51,7 +51,7 @@ from .gbsa import GBSA_PAGE_SIZE, qsa_gbsa_attention from .lightning_indexer import qsa_select_paged_tokens_lightning -if vllm_version_is("0.32.0"): +if vllm_version_is("0.33.0"): import vllm.models.qwen4_exp.amd.indexer_qsa as upstream_indexer # type: ignore[import-not-found] import vllm.models.qwen4_exp.common.qsa_cache as qsa_indexer # type: ignore[import-not-found] @@ -64,7 +64,7 @@ # The upstream backend class is renamed per tree; the class definition below # carries the resulting valid-type/misc ignores. -if vllm_version_is("0.32.0"): +if vllm_version_is("0.33.0"): UpstreamQSABackend = upstream_qsa.Qwen4ExpQSAFlashAttentionBackend # type: ignore[attr-defined] else: UpstreamQSABackend = upstream_qsa.Qwen4ExpQSABackend # type: ignore[attr-defined] @@ -266,7 +266,7 @@ def normalize_compressed_keys( first_positions, ) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): def forward( # type: ignore[misc, override] self, @@ -450,7 +450,7 @@ class AscendQSAImpl: supports_dcp = False supports_pcp = False - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): def __init__(self, *args: object, **kwargs: object) -> None: del kwargs @@ -499,7 +499,7 @@ def do_kv_cache_update( _store_qsa_cache_rows(key_cache, slot_mapping, key) _store_qsa_cache_rows(value_cache, slot_mapping, value) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): def forward_qsa( self, @@ -716,7 +716,7 @@ def supported_kv_cache_layouts(cls) -> tuple[KVCacheLayout, ...]: # structure, cache specifications and weight mapping in upstream vLLM. upstream_indexer.apply_qsa_rope = apply_qsa_rope upstream_qsa.QSAIndexer = AscendQSAIndexer -if vllm_version_is("0.32.0"): +if vllm_version_is("0.33.0"): upstream_qsa.Qwen4ExpQSAFlashAttentionImpl = AscendQSAImpl # type: ignore[attr-defined] upstream_qsa.Qwen4ExpQSAFlashAttentionBackend = AscendQSABackend # type: ignore[attr-defined] else: @@ -784,7 +784,7 @@ def _run_qsa( raise RuntimeError("Fused QSA preparation requires an output gate") gate.copy_(projected_gate.view_as(gate)) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): selected = cast( torch.Tensor, self.indexer( # type: ignore[call-arg] @@ -817,7 +817,7 @@ def _run_qsa( # name and signature follow the tree's upstream ABI. impl: Any = self.impl with attention_transfer_window(): - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): impl.forward_qsa( self, query, diff --git a/vllm_ascend/observability/runtime_guard/hooks.py b/vllm_ascend/observability/runtime_guard/hooks.py index 29772c0c334c..873a028a47ad 100644 --- a/vllm_ascend/observability/runtime_guard/hooks.py +++ b/vllm_ascend/observability/runtime_guard/hooks.py @@ -41,13 +41,13 @@ from types import SimpleNamespace from typing import Any +from vllm.distributed.kv_transfer.kv_connector.v1.base import KVConnectorOutput from vllm.distributed.parallel_state import get_tp_group from vllm.v1.outputs import AsyncModelRunnerOutput, ModelRunnerOutput from vllm.v1.worker.gpu.async_utils import AsyncOutput from vllm_ascend.logger import init_logger_ascend from vllm_ascend.observability.runtime_guard.processor import SamplePhaseResult -from vllm_ascend.utils import vllm_version_is logger = init_logger_ascend(__name__) @@ -345,12 +345,6 @@ def get_output(self) -> ModelRunnerOutput: _safe_check_after_sample(self._runner, output) return output - # vLLM main makes ``get_kv_connector_output`` abstract on - # ``AsyncModelRunnerOutput``: it salvages the step's KV output when - # ``get_output`` fails. v0.32.0 neither declares nor calls it, so the - # release lane needs no override. - if not vllm_version_is("0.32.0"): - from vllm.distributed.kv_transfer.kv_connector.v1.base import KVConnectorOutput - - def get_kv_connector_output(self) -> KVConnectorOutput | None: - return self._inner.get_kv_connector_output() + # Both supported versions require get_kv_connector_output on async outputs. + def get_kv_connector_output(self) -> KVConnectorOutput | None: + return self._inner.get_kv_connector_output() diff --git a/vllm_ascend/ops/gdn.py b/vllm_ascend/ops/gdn.py index 60a1ec3a6a52..31e0a3ed15a5 100644 --- a/vllm_ascend/ops/gdn.py +++ b/vllm_ascend/ops/gdn.py @@ -51,7 +51,6 @@ from vllm_ascend.ops.triton.fla.utils import clear_ssm_states from vllm_ascend.ops.triton.mamba.causal_conv1d import causal_conv1d_update_varlen, extract_last_width from vllm_ascend.ops.triton.mamba.state_index import gather_ssm_states, scatter_ssm_states_ -from vllm_ascend.utils import vllm_version_is _PACKED_CONV_WEIGHT_NAME = "ascend_conv1d_weight" @@ -90,21 +89,12 @@ def _pack_conv_weights(conv1d: nn.Module) -> None: .to(device=packed_param.device, dtype=packed_param.dtype) .contiguous() ) - # vLLM main (#62326) keeps the parameter object by default and drops - # `prefer_copy`; v0.32.0 still requires `prefer_copy=True`. - if vllm_version_is("0.32.0"): - replace_parameter( - conv1d, - _PACKED_CONV_WEIGHT_NAME, - packed_weight, - prefer_copy=True, - ) - else: - replace_parameter( - conv1d, - _PACKED_CONV_WEIGHT_NAME, - packed_weight, - ) + # replace_parameter preserves the parameter object on both supported versions. + replace_parameter( + conv1d, + _PACKED_CONV_WEIGHT_NAME, + packed_weight, + ) def initialize_packed_conv_weight(layer: nn.Module) -> None: diff --git a/vllm_ascend/ops/gdn_attn_builder.py b/vllm_ascend/ops/gdn_attn_builder.py index 9cd768ff52d3..c9fd78435fdc 100644 --- a/vllm_ascend/ops/gdn_attn_builder.py +++ b/vllm_ascend/ops/gdn_attn_builder.py @@ -40,7 +40,6 @@ prepare_update_chunk_offsets, ) from vllm_ascend.ops.triton.mamba.gdn_prepare import prepare_gdn -from vllm_ascend.utils import vllm_version_is _GDN_CHUNK_SIZE = 64 # Keep this aligned with solve_tril.LARGE_BLOCK_T in ops/triton/fla/solve_tril.py. @@ -835,16 +834,8 @@ def build( # type: ignore[override] query_start_loc_cpu = m.query_start_loc_cpu mamba_cache_mode = self.vllm_config.cache_config.mamba_cache_mode mamba_block_table = m.block_table_tensor - # vLLM #58737 derives num_reqs from the block table and asserts that - # seq_lens has the same number of rows. Ascend's unpadded() intentionally - # keeps the padded block-table rows, so on vLLM main pass only the real - # request rows. v0.32.0's align path already derives its output rows from - # seq_lens, so the result is unchanged there. - if ( - not vllm_version_is("0.32.0") - and mamba_cache_mode != "none" - and mamba_block_table.shape[0] != m.seq_lens.shape[0] - ): + # Restrict recurrent state lookup to real request rows. + if mamba_cache_mode != "none" and mamba_block_table.shape[0] != m.seq_lens.shape[0]: mamba_block_table = mamba_block_table[: m.seq_lens.shape[0]] block_table_tensor = mamba_get_block_table_tensor( mamba_block_table, diff --git a/vllm_ascend/ops/kimi_kda.py b/vllm_ascend/ops/kimi_kda.py index 1d94f4a13323..40f25667030e 100644 --- a/vllm_ascend/ops/kimi_kda.py +++ b/vllm_ascend/ops/kimi_kda.py @@ -42,7 +42,7 @@ from vllm_ascend.quantization.methods.w8a8.w8a8_mxfp8 import ( AscendW8A8MXFP8DynamicLinearMethod, ) -from vllm_ascend.utils import npu_stream_switch, vllm_version_is +from vllm_ascend.utils import npu_stream_switch _PACKED_CONV_WEIGHT_NAME = "ascend_conv1d_weight" _F_PROJ_SHARD_ID = 1 @@ -435,21 +435,12 @@ def _pack_conv_weights(self) -> None: .to(device=packed_param.device, dtype=packed_param.dtype) .contiguous() ) - # vLLM main (#62326) keeps the parameter object by default and drops - # `prefer_copy`; v0.32.0 still requires `prefer_copy=True`. - if vllm_version_is("0.32.0"): - replace_parameter( - self, - _PACKED_CONV_WEIGHT_NAME, - packed_weight, - prefer_copy=True, - ) - else: - replace_parameter( - self, - _PACKED_CONV_WEIGHT_NAME, - packed_weight, - ) + # replace_parameter preserves the parameter object on both supported versions. + replace_parameter( + self, + _PACKED_CONV_WEIGHT_NAME, + packed_weight, + ) def _run_recurrent( self, diff --git a/vllm_ascend/ops/kimi_mla.py b/vllm_ascend/ops/kimi_mla.py index e3293011196a..45d1b76c84df 100644 --- a/vllm_ascend/ops/kimi_mla.py +++ b/vllm_ascend/ops/kimi_mla.py @@ -15,7 +15,7 @@ class AscendKimiK3MultiHeadLatentAttention(AscendMultiHeadLatentAttention, KimiK so Python runs the Ascend initializer on the replacement instance. """ - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): # vLLM #60110 added this flag and reads it in the upstream # process_weights_after_loading hook. The AMD initializer never runs on # Ascend, so expose the fold as disabled. diff --git a/vllm_ascend/ops/linear.py b/vllm_ascend/ops/linear.py index 0f26ee9404a7..625965909aaa 100644 --- a/vllm_ascend/ops/linear.py +++ b/vllm_ascend/ops/linear.py @@ -42,7 +42,7 @@ from vllm_ascend.device.hardware_profile import HardwareCapability, WeightLayoutPolicy, get_current_hardware_profile from vllm_ascend.ops.linear_op import get_parallel_op, get_replicated_op -from vllm_ascend.utils import maybe_trans_nz, vllm_version_is +from vllm_ascend.utils import maybe_trans_nz from vllm_ascend.weight_switch import WeightSwitchGatherSpec, WeightSwitchMixin @@ -115,10 +115,7 @@ def process_weights_after_loading(self, layer: torch.nn.Module) -> None: # keep the captured graph's weight reference to the updated weight # during RL weight updates. vLLM main (#62326) dropped `prefer_copy` # and keeps the parameter object by default. - if vllm_version_is("0.32.0"): - replace_parameter(layer, "weight_fp32", new_fp32, prefer_copy=True) - else: - replace_parameter(layer, "weight_fp32", new_fp32) + replace_parameter(layer, "weight_fp32", new_fp32) if "conv1d" not in layer.prefix and not skip_weight_nz_conversion: # 310P torch_npu rejects FRACTAL_NZ matmul when the weight-side # matrix has n=1 or k=1. Keep scalar gates such as Qwen MoE's diff --git a/vllm_ascend/ops/triton/docs/prepare_dflash_inputs.md b/vllm_ascend/ops/triton/docs/prepare_dflash_inputs.md index d73d3b4f964f..723f921a8eb4 100644 --- a/vllm_ascend/ops/triton/docs/prepare_dflash_inputs.md +++ b/vllm_ascend/ops/triton/docs/prepare_dflash_inputs.md @@ -3,13 +3,13 @@ ## Description - **Function**: Prepares the metadata and fixed-capacity buffers required by DFlash speculative decoding on Ascend NPU. For each request, the operator converts the current target-model token span into draft-model context KV positions/slots, constructs the next DFlash query tokens and query slots, builds sampling mappings, copies per-request sampling state, and pads graph-visible buffers. -- **Supported vLLM ABI**: vLLM 0.32.0 `prepare_dflash_inputs`, including +- **Supported vLLM ABI**: vLLM 0.33.0 `prepare_dflash_inputs`, including `cp_rank`, `cp_size`, and `cp_interleave` for rank-local DCP KV slots. - **Implementation**: - `vllm_ascend/ops/triton/spec_decode/prepare_dflash_inputs.py` contains the 2-D Triton kernel and launcher `prepare_dflash_inputs_triton`. - `vllm_ascend/worker/v2/spec_decode/dflash/speculator.py` provides the - vLLM 0.32.0 `prepare_dflash_inputs` wrapper. + vLLM 0.33.0 `prepare_dflash_inputs` wrapper. - **Formula**: - Request context range: `ctx_start = query_start_loc[req]`, @@ -97,7 +97,7 @@ ## Constraints - The operator is inference-only and requires Ascend NPU Triton execution. -- The optimized kernel implements the vLLM 0.32.0 DFlash ABI and the same +- The optimized kernel implements the vLLM 0.33.0 DFlash ABI and the same rank-local DCP slot mapping as main's scalar implementation. - Multimodal inputs (including M-RoPE positions) are not supported by this optimized path. It derives KV slots from scalar token positions; multimodal inputs require the target slot mapping and linear token indices (see [#9340](https://github.com/vllm-project/vllm-ascend/pull/9340)). - `input_batch.num_reqs > 0` and `input_batch.num_reqs <= max_num_reqs`. @@ -118,7 +118,7 @@ ## Upstream Compatibility -The worker wrapper preserves the vLLM 0.32.0 positional signature and forwards +The worker wrapper preserves the vLLM 0.33.0 positional signature and forwards DFlash and DCP inputs to the optimized 2-D launcher. The Ascend speculator binds `kv_cache_block_size` from `self.vllm_config.cache_config.block_size` when setting attention and passes it as a keyword-only argument. Multimodal diff --git a/vllm_ascend/ops/triton/sample/categorical_sample.py b/vllm_ascend/ops/triton/sample/categorical_sample.py index 972a5df47585..673d2e07b54f 100644 --- a/vllm_ascend/ops/triton/sample/categorical_sample.py +++ b/vllm_ascend/ops/triton/sample/categorical_sample.py @@ -425,7 +425,7 @@ def _categorical_sample_main( logits_cache_source: torch.Tensor | None = None, logits_cache_row_mapping: torch.Tensor | None = None, ) -> torch.Tensor: - # 0.32.0 has `logits_cache_source` (only watermarking supplies a separate + # 0.33.0 has `logits_cache_source` (only watermarking supplies a separate # source); main adds the per-row mapping for batch-sharded caches. The NPU # kernels support neither. if logits_cache_row_mapping is not None: diff --git a/vllm_ascend/patch/__init__.py b/vllm_ascend/patch/__init__.py index 40a3f139038a..66dce0e664bb 100644 --- a/vllm_ascend/patch/__init__.py +++ b/vllm_ascend/patch/__init__.py @@ -217,7 +217,7 @@ # Why: # GLM-5.3 always generates reasoning. This compatibility fallback # normalizes thinking=False and enable_thinking=False to prevent -# reasoning from leaking into content; v0.32.0 also handles this +# reasoning from leaking into content; v0.33.0 also handles this # upstream through PR #56994. # How: # Detect the GLM-5.3 template using the upstream signature and normalize @@ -258,9 +258,8 @@ # vLLM #44243 has landed in the supported upstream version, so this # override is kept only for the drop exemption of entry 2; remove it # together with entry 2 once upstream exposes the PD role. -# 2. `get_kv_cache_config_from_groups` (in `vllm.v1.core.kv_cache_utils` on -# v0.32.0; moved to `vllm.v1.core.kv_cache_planning` on main by vLLM -# #61183), +# 2. `get_kv_cache_config_from_groups` (in `vllm.v1.core.kv_cache_planning` +# on both supported versions, vLLM #61183), # `HybridKVCacheCoordinator.find_longest_cache_hit` and # `...find_longest_cache_hit_per_group` # Why: @@ -301,22 +300,17 @@ # Future Plan: # Remove this patch once upstream vLLM supports hybrid KV cache + CP for # non-CUDA backends, or exposes a platform hook for this behavior. -# 2. `vllm.v1.core.kv_cache_utils.get_kv_cache_groups`, -# `...get_kv_cache_config_from_groups`, +# 2. `vllm.v1.core.kv_cache_planning.get_kv_cache_config_from_groups`, # `..._max_memory_usage_bytes_from_groups`, `..._pool_bytes_per_block` # Why: -# The v0.32.0 release lane has no pluggable `KVCacheConfigBuilder`, so -# the Ascend DSV4/DSV4.1, GLM-Next, Kimi-K3 DSpark, and TurboQuant -# planning rules must stay module-level monkey patches there. +# Ascend cache layouts need platform-specific materialization and memory +# accounting. # How: -# Keep the planning patches applied from this file. Main resolves -# grouping through `vllm_ascend.core.kv_cache_config_builder`, selected -# by `NPUPlatform.get_kv_cache_config_builder_cls`; its default -# materialization delegates back to these patched functions. -# Related PR (if no, explain why): +# Both supported versions select AscendKVCacheConfigBuilder through +# NPUPlatform. Its default materialization delegates to the patched +# planning functions. +# Related PR: # https://github.com/vllm-project/vllm/pull/53558 -# Future Plan: -# Remove them when vllm-ascend stops supporting v0.32.0. # # ** 11. File: platform/patch_mamba_block_aligned_split.py** # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -729,7 +723,7 @@ # # 3. `xgrammar.GrammarCompiler.compile_json_schema` # Why: -# vLLM #58067 (included in v0.32.0 and verified main) passes +# vLLM #58067 (included in v0.33.0 and verified main) passes # `separators=(",", ":")` when `disable_any_whitespace` is set. The # xgrammar releases shipped with Ascend (0.2.7/0.2.8) mishandle it: the # stricter grammar makes small models loop on `","` until `max_tokens` @@ -1132,22 +1126,9 @@ # fused attention preparation. # # -# ** 11. File: worker/patch_mm_input_norm.py ** -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# 1. `vllm.model_executor.layers.fusion.mm_input_norm.FusedMMInputNorm` -# Why: -# v0.32.0 persists processor-derived normalization buffers, so legacy -# sharded checkpoints fail with missing visual.input_norm.weight/bias. -# Dummy loading can also overwrite these constants. -# How: -# Wrap construction once and register weight/bias as nonpersistent -# buffers, preserving device normalization and strict weight validation. -# Applying this on upstream main with the fix retains the same behavior. -# Related PR: -# https://github.com/vllm-project/vllm/pull/62767 -# Future Plan: -# Remove when all supported vLLM baselines contain commit -# 90c4a1a73eecea0428ee4303ad96c9fdeaac3f80 (or an equivalent backport). +# ** 11. File: worker/patch_mm_input_norm.py (removed) ** +# Both vLLM v0.33.0 and verified main include #62767 and keep the +# processor-derived normalization buffers nonpersistent. # # ** 12. File: worker/patch_ascend_ops.py** # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/vllm_ascend/patch/platform/__init__.py b/vllm_ascend/patch/platform/__init__.py index 52be23ec8d4c..504835973ba3 100644 --- a/vllm_ascend/patch/platform/__init__.py +++ b/vllm_ascend/patch/platform/__init__.py @@ -79,8 +79,7 @@ # # ** File: platform/patch_kv_cache_utils.py ** # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# 1. `vllm.v1.core.kv_cache_utils` (v0.32.0) / -# `vllm.v1.core.kv_cache_planning` (main, vLLM #61183) +# 1. `vllm.v1.core.kv_cache_planning` (both supported versions, vLLM #61183) # Why: # vLLM's generic KV-cache planner cannot represent GLM-Next's cache # topology, where MLA and compressed indexer caches share block IDs while @@ -95,12 +94,10 @@ # Remove this patch when upstream's generic KV-cache layout supports the # Ascend GLM-Next cache topology. # -# On main, Ascend grouping and pool accounting live in -# `vllm_ascend.core.kv_cache_config_builder`, which the platform selects -# through `NPUPlatform.get_kv_cache_config_builder_cls`; its default -# materialization delegates back to the patched planning functions -# applied by this file. The v0.32.0 lane, which has no pluggable -# builder, applies the same rules directly from this file. +# On both supported versions, Ascend grouping and pool accounting live +# in AscendKVCacheConfigBuilder, which the platform selects through +# NPUPlatform.get_kv_cache_config_builder_cls. Its default materialization +# delegates to the patched planning functions in this file. # # ** File: platform/patch_mamba_config.py ** # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/vllm_ascend/patch/platform/patch_balance_schedule.py b/vllm_ascend/patch/platform/patch_balance_schedule.py index 88c4a306ffd3..5ddd915d109d 100644 --- a/vllm_ascend/patch/platform/patch_balance_schedule.py +++ b/vllm_ascend/patch/platform/patch_balance_schedule.py @@ -78,7 +78,6 @@ from vllm.v1.utils import record_function_or_nullcontext from vllm_ascend.ascend_config import init_ascend_config -from vllm_ascend.utils import vllm_version_is def _balance_scheduling_enabled(vllm_config) -> bool: @@ -346,9 +345,7 @@ def schedule(self, throttle_prefills: bool = False) -> SchedulerOutput: break if new_blocks is None: - if not vllm_version_is("0.32.0") and ( - self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED - ): + if self.policy == SchedulingPolicy.PRIORITY and request.status == RequestStatus.PREEMPTED: # The request was the lowest-priority running request and # preempted itself. The requests after it have higher # priority and may still fit; it was removed from diff --git a/vllm_ascend/patch/platform/patch_kv_cache_coordinator.py b/vllm_ascend/patch/platform/patch_kv_cache_coordinator.py index d7a99ffd773a..a0b8e5d1f8e3 100644 --- a/vllm_ascend/patch/platform/patch_kv_cache_coordinator.py +++ b/vllm_ascend/patch/platform/patch_kv_cache_coordinator.py @@ -35,7 +35,6 @@ ) from vllm_ascend.core.kv_cache_interface import is_prefix_cacheable -from vllm_ascend.utils import vllm_version_is _orig_get_kv_cache_coordinator = vllm.v1.core.kv_cache_coordinator.get_kv_cache_coordinator @@ -151,23 +150,14 @@ def __init__( # type: ignore[misc] self.scheduler_block_size, kv_cache_config, ) - if vllm_version_is("0.32.0"): - self.block_pool = BlockPool( - num_gpu_blocks=kv_cache_config.num_blocks, - enable_caching=enable_caching, - hash_block_size=hash_block_size, - enable_kv_cache_events=enable_kv_cache_events, - metrics_collector=metrics_collector, - ) - else: - self.block_pool = BlockPool( - num_gpu_blocks=kv_cache_config.num_blocks, - enable_caching=enable_caching, - hash_block_size=hash_block_size, - enable_kv_cache_events=enable_kv_cache_events, - metrics_collector=metrics_collector, - num_hash_lookahead_tokens=num_hash_lookahead_tokens, - ) + self.block_pool = BlockPool( + num_gpu_blocks=kv_cache_config.num_blocks, + enable_caching=enable_caching, + hash_block_size=hash_block_size, + enable_kv_cache_events=enable_kv_cache_events, + metrics_collector=metrics_collector, + num_hash_lookahead_tokens=num_hash_lookahead_tokens, + ) # KV cache group indices that get the EAGLE last-block drop. self.eagle_group_ids: set[int] = { # type: ignore[no-redef] @@ -185,8 +175,7 @@ def __init__( # type: ignore[misc] } # vLLM main (#61589) reads this base-class attribute in cache_blocks(); # lookahead hashes clear the drop while keeping the groups flagged. - if not vllm_version_is("0.32.0"): - self.drop_eagle_group_ids = self.eagle_group_ids if use_eagle else set() + self.drop_eagle_group_ids = self.eagle_group_ids if use_eagle else set() extra_mgr_kwargs: dict = {"scheduler_block_size": scheduler_block_size} extra_mgr_kwargs["needs_kv_cache_zeroing"] = kv_cache_config.needs_kv_cache_zeroing @@ -588,10 +577,8 @@ def get_kv_cache_coordinator( # type: ignore[misc] orig_kwargs["scheduler_block_size"] = scheduler_block_size orig_kwargs["num_prefill_lookahead"] = num_prefill_lookahead orig_kwargs["allow_partial_hash_hits"] = allow_partial_hash_hits - # vLLM main (#61589) added lookahead block hashes; v0.32.0's upstream - # coordinator has no such parameter. - if not vllm_version_is("0.32.0"): - orig_kwargs["num_hash_lookahead_tokens"] = num_hash_lookahead_tokens + # Both supported versions accept lookahead hash tokens. + orig_kwargs["num_hash_lookahead_tokens"] = num_hash_lookahead_tokens return _orig_get_kv_cache_coordinator(**orig_kwargs) return AscendHybridKVCacheCoordinator(**hybrid_kwargs) # type: ignore[call-arg] diff --git a/vllm_ascend/patch/platform/patch_kv_cache_utils.py b/vllm_ascend/patch/platform/patch_kv_cache_utils.py index 48c83e03922b..740847f28acf 100644 --- a/vllm_ascend/patch/platform/patch_kv_cache_utils.py +++ b/vllm_ascend/patch/platform/patch_kv_cache_utils.py @@ -6,10 +6,13 @@ from dataclasses import replace from typing import Any +# Both supported versions use the KV-cache planner and builder API from #61183/#42309. +import vllm.v1.core.kv_cache_planning as _kv_cache_planning import vllm.v1.core.kv_cache_utils from vllm.config import VllmConfig from vllm.logger import logger from vllm.utils.math_utils import cdiv, round_up +from vllm.v1.core.kv_cache_planning import _approximate_gcd, may_override_num_blocks from vllm.v1.kv_cache_interface import ( FullAttentionSpec, KVCacheConfig, @@ -52,17 +55,6 @@ from vllm_ascend.quantization.methods.kv_cache.turboquant import cache as tq_cache from vllm_ascend.utils import vllm_version_is -# vLLM #61183 moved the KV-cache planning helpers out of -# `vllm.v1.core.kv_cache_utils` into `vllm.v1.core.kv_cache_planning` on main. -# The v0.32.0 lane still ships them in `kv_cache_utils`, so resolve the live -# module by version and import/patch the planning symbols from there. -if vllm_version_is("0.32.0"): - import vllm.v1.core.kv_cache_utils as _kv_cache_planning - from vllm.v1.core.kv_cache_utils import _approximate_gcd, may_override_num_blocks -else: - import vllm.v1.core.kv_cache_planning as _kv_cache_planning - from vllm.v1.core.kv_cache_planning import _approximate_gcd, may_override_num_blocks - _KIMI_K3_TARGET_LAYER_PREFIX = "language_model.model.layers." _KIMI_K3_DRAFT_LAYER_PREFIX = "model.layers." _orig_resolve_kv_cache_block_sizes = vllm.v1.core.kv_cache_utils.resolve_kv_cache_block_sizes @@ -496,23 +488,6 @@ def _ascend_get_packed_kv_cache_groups( assert _orig_get_packed_kv_cache_groups is not None return _orig_get_packed_kv_cache_groups(vllm_config, kv_cache_spec) groups = _get_kv_cache_groups_uniform_groups(grouped_specs) - # The v0.32.0 lane annotates EAGLE groups on this packed hook, because - # ``get_kv_cache_groups`` returns packed groups before running its own - # annotation. vLLM #42309 drops ``_annotate_eagle_groups``/ - # ``_uses_trailing_mtp_layers`` from main and inlines the annotation into - # ``get_kv_cache_configs`` keyed on ``spec.is_draft``, so only call the API - # on the release lane. - if vllm_version_is("0.32.0"): - _kv_cache_planning._annotate_eagle_groups( - vllm_config, - kv_cache_spec, - groups, - use_trailing_layer_fallback=_kv_cache_planning._uses_trailing_mtp_layers(vllm_config), - ) - _kv_cache_planning._warn_if_unannotated_eagle_mamba( - vllm_config, - groups, - ) return groups @@ -672,85 +647,36 @@ def _ascend_pool_bytes_per_block( # type: ignore[misc] return sum(page_sizes) * num_layer_tuples -# vLLM #42309 threads the platform's ``KVCacheConfigBuilder`` through KV cache -# admission on main, so ``_max_memory_usage_bytes_from_groups`` gained a leading -# ``builder`` argument. The v0.32.0 lane keeps the pre-#42309 two-argument -# signature. -if vllm_version_is("0.32.0"): - - def _ascend_max_memory_usage_bytes_from_groups( - vllm_config: VllmConfig, - kv_cache_groups: list[KVCacheGroupSpec], - ) -> int: - """Keep the pre-#51718 DSV4 admission formula for its shared tuples.""" - if tq_cache.uses_turboquant_groups(kv_cache_groups): - return tq_cache.max_memory_usage(vllm_config, kv_cache_groups) - if _get_glm5_next_cache_layout(kv_cache_groups) is not None: - return get_glm5_next_max_memory_usage(vllm_config, kv_cache_groups) - qwen_bytes = get_qwen4_exp_max_memory_usage(vllm_config, kv_cache_groups) - if qwen_bytes is not None: - return qwen_bytes - if not _is_deepseek_v4_groups(kv_cache_groups): - return _orig_max_memory_usage_bytes_from_groups(vllm_config, kv_cache_groups) - - assert all(isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) for group in kv_cache_groups) - full_mla_spec = kv_cache_groups[0].kv_cache_spec - assert isinstance(full_mla_spec, UniformTypeKVCacheSpecs) - layer_tuple_bytes = sum(_page_sizes(full_mla_spec)) - num_layer_tuples = max( - _get_max_layers_per_page_size(group.kv_cache_spec) - for group in kv_cache_groups - if isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) - ) - return sum( - num_layer_tuples * group.kv_cache_spec.max_memory_usage_pages(vllm_config) * layer_tuple_bytes - for group in kv_cache_groups - if isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) - ) - -else: - - def _ascend_max_memory_usage_bytes_from_groups(*args: Any) -> int: # type: ignore[misc] - """Keep the pre-#51718 DSV4 admission formula for its shared tuples. +def _ascend_max_memory_usage_bytes_from_groups( + builder: Any, + vllm_config: VllmConfig, + kv_cache_groups: list[KVCacheGroupSpec], +) -> int: + """Keep Ascend admission accounting with the upstream builder API.""" + if tq_cache.uses_turboquant_groups(kv_cache_groups): + return tq_cache.max_memory_usage(vllm_config, kv_cache_groups) + if _get_glm5_next_cache_layout(kv_cache_groups) is not None: + return get_glm5_next_max_memory_usage(vllm_config, kv_cache_groups) + qwen_bytes = get_qwen4_exp_max_memory_usage(vllm_config, kv_cache_groups) + if qwen_bytes is not None: + return qwen_bytes + if not _is_deepseek_v4_groups(kv_cache_groups): + return _orig_max_memory_usage_bytes_from_groups(builder, vllm_config, kv_cache_groups) - vLLM #42309 threads a ``KVCacheConfigBuilder`` through KV cache - admission on main, so the call becomes - ``(builder, vllm_config, kv_cache_groups)``, while main checkouts - predating #42309 still call ``(vllm_config, kv_cache_groups)``. - ``vllm_version_is`` cannot separate two main dev builds, so dispatch on - the argument count. - """ - if len(args) == 3: - builder, vllm_config, kv_cache_groups = args - else: - builder = None - vllm_config, kv_cache_groups = args - if tq_cache.uses_turboquant_groups(kv_cache_groups): - return tq_cache.max_memory_usage(vllm_config, kv_cache_groups) - if _get_glm5_next_cache_layout(kv_cache_groups) is not None: - return get_glm5_next_max_memory_usage(vllm_config, kv_cache_groups) - qwen_bytes = get_qwen4_exp_max_memory_usage(vllm_config, kv_cache_groups) - if qwen_bytes is not None: - return qwen_bytes - if not _is_deepseek_v4_groups(kv_cache_groups): - if builder is None: - return _orig_max_memory_usage_bytes_from_groups(vllm_config, kv_cache_groups) - return _orig_max_memory_usage_bytes_from_groups(builder, vllm_config, kv_cache_groups) - - assert all(isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) for group in kv_cache_groups) - full_mla_spec = kv_cache_groups[0].kv_cache_spec - assert isinstance(full_mla_spec, UniformTypeKVCacheSpecs) - layer_tuple_bytes = sum(_page_sizes(full_mla_spec)) - num_layer_tuples = max( - _get_max_layers_per_page_size(group.kv_cache_spec) - for group in kv_cache_groups - if isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) - ) - return sum( - num_layer_tuples * group.kv_cache_spec.max_memory_usage_pages(vllm_config) * layer_tuple_bytes - for group in kv_cache_groups - if isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) - ) + assert all(isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) for group in kv_cache_groups) + full_mla_spec = kv_cache_groups[0].kv_cache_spec + assert isinstance(full_mla_spec, UniformTypeKVCacheSpecs) + layer_tuple_bytes = sum(_page_sizes(full_mla_spec)) + num_layer_tuples = max( + _get_max_layers_per_page_size(group.kv_cache_spec) + for group in kv_cache_groups + if isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) + ) + return sum( + num_layer_tuples * group.kv_cache_spec.max_memory_usage_pages(vllm_config) * layer_tuple_bytes + for group in kv_cache_groups + if isinstance(group.kv_cache_spec, UniformTypeKVCacheSpecs) + ) def _get_ascend_kv_cache_groups( diff --git a/vllm_ascend/patch/platform/patch_pp_mtp.py b/vllm_ascend/patch/platform/patch_pp_mtp.py index a784fd775ebd..222481ee9f28 100644 --- a/vllm_ascend/patch/platform/patch_pp_mtp.py +++ b/vllm_ascend/patch/platform/patch_pp_mtp.py @@ -228,7 +228,7 @@ def _update_pp_mtp_spec_token_ids(scheduler, scheduler_output, model_runner_outp request.spec_token_ids = [] continue - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): validated = scheduler.structured_output_manager.validate_tokens(request, spec_token_ids[req_index]) else: validated = scheduler.structured_output_manager.trim_spec_tokens(request, spec_token_ids[req_index]) diff --git a/vllm_ascend/patch/platform/patch_speculative_config.py b/vllm_ascend/patch/platform/patch_speculative_config.py index 6bfe6a33de36..7fb7cad3eb99 100644 --- a/vllm_ascend/patch/platform/patch_speculative_config.py +++ b/vllm_ascend/patch/platform/patch_speculative_config.py @@ -10,7 +10,7 @@ from vllm.config.speculative import SpeculativeConfig from vllm.transformers_utils.configs.speculators import SpeculatorsConfig -from vllm_ascend.utils import is_deepseek_v41, is_gqa_pcp_dcp_config, vllm_version_is +from vllm_ascend.utils import is_deepseek_v41, is_gqa_pcp_dcp_config _orig_post_init = SpeculativeConfig.__post_init__ _orig_hf_config_override = SpeculativeConfig.hf_config_override @@ -87,7 +87,7 @@ def _normalize_legacy_qwen3_dspark_config( hf_config: PretrainedConfig, transformers_mtp_overrides: dict[str, Any] | None = None, ) -> PretrainedConfig: - if not vllm_version_is("0.32.0") and transformers_mtp_overrides is not None: + if transformers_mtp_overrides is not None: # The Transformers MTP draft is built from the target config: upstream # applies the overrides and none of the checkpoint rewrites below apply. return _orig_hf_config_override( # type: ignore[call-arg] diff --git a/vllm_ascend/patch/platform/patch_structured_output.py b/vllm_ascend/patch/platform/patch_structured_output.py index c78c366d1555..46ad417c8260 100644 --- a/vllm_ascend/patch/platform/patch_structured_output.py +++ b/vllm_ascend/patch/platform/patch_structured_output.py @@ -163,7 +163,7 @@ def accept_tokens(self: Any, request_id: str, tokens: list[int]) -> bool: def _patch_xgrammar_disable_any_whitespace() -> None: """Ignore xgrammar's ``separators`` argument on both supported vLLM lanes. - vLLM #58067 (present in v0.32.0 and verified main) passes + vLLM #58067 (present in v0.33.0 and verified main) passes ``separators=(",", ":")`` to ``GrammarCompiler.compile_json_schema`` when ``disable_any_whitespace`` is set. The xgrammar releases shipped with Ascend (0.2.7/0.2.8) mishandle it: the resulting grammar lets small models @@ -198,5 +198,5 @@ def compile_json_schema(self: Any, schema: Any, *args: Any, **kwargs: Any) -> An _patch_sampling_params_validation() _patch_structured_output_manager() _patch_outlines_accept_tokens() -# vLLM #58067 is present in both v0.32.0 and verified main. +# vLLM #58067 is present in both v0.33.0 and verified main. _patch_xgrammar_disable_any_whitespace() diff --git a/vllm_ascend/patch/worker/__init__.py b/vllm_ascend/patch/worker/__init__.py index 26e6ce567ea0..3b99659ddaa2 100644 --- a/vllm_ascend/patch/worker/__init__.py +++ b/vllm_ascend/patch/worker/__init__.py @@ -33,7 +33,6 @@ import vllm_ascend.patch.worker.patch_kv_cache_dtype # noqa # Apply before model construction on every device, including 310P. -import vllm_ascend.patch.worker.patch_mm_input_norm # noqa import vllm_ascend.patch.worker.patch_distributed # noqa import vllm_ascend.patch.worker.patch_minimax_m2 # noqa diff --git a/vllm_ascend/patch/worker/patch_attn_utils.py b/vllm_ascend/patch/worker/patch_attn_utils.py index fed8ac8d504a..53ba569016e0 100644 --- a/vllm_ascend/patch/worker/patch_attn_utils.py +++ b/vllm_ascend/patch/worker/patch_attn_utils.py @@ -27,10 +27,10 @@ def _get_ascend_sfa_indexer_backend(_self): # vLLM main (#63384) moved OLMoE to the Transformers backend, whose -# `vllm_attention_forward` bakes a layout-dependent `aten.view`. v0.32.0 still +# `vllm_attention_forward` bakes a layout-dependent `aten.view`. v0.33.0 still # uses the native OLMoE implementation, where this mismatch cannot happen, so # the release lane gets none of this patch. -if not vllm_version_is("0.32.0"): +if not vllm_version_is("0.33.0"): _VLLM_ATTENTION_IMPL = "vllm" @cache diff --git a/vllm_ascend/patch/worker/patch_distributed.py b/vllm_ascend/patch/worker/patch_distributed.py index b6bc4bae8560..b1d31947207e 100644 --- a/vllm_ascend/patch/worker/patch_distributed.py +++ b/vllm_ascend/patch/worker/patch_distributed.py @@ -27,7 +27,7 @@ from vllm_ascend.distributed.device_communicators.npu_communicator import NPUCommunicator from vllm_ascend.patch.worker._hccl_pg_registry import HcclPgKey, HcclPgRegistry, make_hccl_pg_key -from vllm_ascend.utils import create_hccl_pg_options, vllm_version_is +from vllm_ascend.utils import create_hccl_pg_options _HCCL_PG_REGISTRY = HcclPgRegistry() logger = logging.getLogger(__name__) @@ -121,8 +121,7 @@ def __init__( # type: ignore[misc] self.torch_distributed_backend = torch_distributed_backend # vLLM main keeps the CPU group timeout for cpu_all_reduce_; this patch # reimplements GroupCoordinator.__init__ without calling super(). - if not vllm_version_is("0.32.0"): - self.cpu_timeout = get_cpu_distributed_timeout_or_none() + self.cpu_timeout = get_cpu_distributed_timeout_or_none() self._acquired_hccl_keys: list[HcclPgKey] = [] # type: ignore[no-redef] self._unshared_hccl_groups: list[object] = [] # type: ignore[no-redef] self.use_device_communicator = use_device_communicator diff --git a/vllm_ascend/patch/worker/patch_kimi_k25.py b/vllm_ascend/patch/worker/patch_kimi_k25.py index da363ae7a0be..0c72e3401d12 100644 --- a/vllm_ascend/patch/worker/patch_kimi_k25.py +++ b/vllm_ascend/patch/worker/patch_kimi_k25.py @@ -26,8 +26,8 @@ from vllm_ascend.device.hardware_profile import HardwareCapability, get_current_hardware_profile from vllm_ascend.utils import vllm_version_is -if vllm_version_is("0.32.0"): - # 0.32.0 decorates its torch-compiled `get_rope_shape` with a first-call +if vllm_version_is("0.33.0"): + # 0.33.0 decorates its torch-compiled `get_rope_shape` with a first-call # warmup; main removed both the decorator and the compile wrapper. import vllm.model_executor.models.kimi_k25_vit as kimi_k25_vit # type: ignore[import-not-found] @@ -47,7 +47,7 @@ def get_rope_shape(org, interpolation_mode, shape): ) -if vllm_version_is("0.32.0"): +if vllm_version_is("0.33.0"): # Keep the release lane's first-call warmup; the Ascend function is plain, # so on main the decorator no longer exists and nothing is dropped. get_rope_shape = get_rope_shape_decorate(get_rope_shape) diff --git a/vllm_ascend/patch/worker/patch_mm_input_norm.py b/vllm_ascend/patch/worker/patch_mm_input_norm.py deleted file mode 100644 index 2f5a51095c2b..000000000000 --- a/vllm_ascend/patch/worker/patch_mm_input_norm.py +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Ascend project -"""Backport the buffer persistence fix from vLLM #62767 to v0.32.0.""" - -from functools import wraps - -from vllm.model_executor.layers.fusion.mm_input_norm import FusedMMInputNorm - - -def patch_mm_input_norm() -> None: - original_init = FusedMMInputNorm.__init__ - if getattr(original_init, "_ascend_nonpersistent_norm", False): - return - - @wraps(original_init) - def init(self, *args, **kwargs) -> None: - original_init(self, *args, **kwargs) - # These constants come from the processor, not the checkpoint. Keep - # their values/device while excluding them from sharded/dummy loading. - self.register_buffer("weight", self.weight, persistent=False) - self.register_buffer("bias", self.bias, persistent=False) - - init._ascend_nonpersistent_norm = True # type: ignore[attr-defined] - FusedMMInputNorm.__init__ = init - - -patch_mm_input_norm() diff --git a/vllm_ascend/patch/worker/patch_model_runner.py b/vllm_ascend/patch/worker/patch_model_runner.py index 1f88d4fd7779..830d644c5d4c 100644 --- a/vllm_ascend/patch/worker/patch_model_runner.py +++ b/vllm_ascend/patch/worker/patch_model_runner.py @@ -215,7 +215,7 @@ def initialize_kv_cache( # vLLM main carries routed-experts output through the AuxOutput # connector, which the V2 NPUModelRunner relies on via super(). if self.vllm_config.aux_output_config.enabled: - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): self.aux_output_connector = upstream.get_aux_output_connector( # type: ignore[call-arg] self.model, self.vllm_config, kv_cache_config ) diff --git a/vllm_ascend/patch/worker/patch_uva.py b/vllm_ascend/patch/worker/patch_uva.py index 79c6baa4005a..4423a7ed1683 100644 --- a/vllm_ascend/patch/worker/patch_uva.py +++ b/vllm_ascend/patch/worker/patch_uva.py @@ -258,7 +258,7 @@ def copy_chunks_to_uva(self, chunks: Sequence, n: int) -> torch.Tensor: vllm.v1.worker.gpu.buffer_utils.UvaBuffer = UvaBufferWrapper -if not vllm_version_is("0.32.0"): +if not vllm_version_is("0.33.0"): def _copy_chunks_to_uva(self, chunks: Sequence, n: int) -> torch.Tensor: buf = self._next_buf(n) diff --git a/vllm_ascend/platform.py b/vllm_ascend/platform.py index 5b961ff9b381..3a21232df6ac 100644 --- a/vllm_ascend/platform.py +++ b/vllm_ascend/platform.py @@ -65,7 +65,6 @@ refresh_block_size, update_cudagraph_capture_sizes, enable_sp, - vllm_version_is, ) if TYPE_CHECKING: @@ -604,21 +603,20 @@ def check_and_update_config(cls, vllm_config: VllmConfig) -> None: # vLLM #61392 folds `compress_ratios` into `layer_types`/`compress_rates`. # Restore the legacy field before any runner/model/cache component reads # it (e.g. NPUModelRunner.__init__ setting `use_compress`). - if not vllm_version_is("0.32.0"): - from vllm.transformers_utils.deepseek_v4_utils import get_compress_ratios - - seen: set[int] = set() - for config in ( - getattr(vllm_config.model_config, "hf_config", None), - getattr(vllm_config.model_config, "hf_text_config", None), - ): - if config is None or id(config) in seen: - continue - seen.add(id(config)) - if getattr(config, "compress_ratios", None) is None: - ratios = get_compress_ratios(config) - if ratios: - config.compress_ratios = list(ratios) + from vllm.transformers_utils.deepseek_v4_utils import get_compress_ratios + + seen: set[int] = set() + for config in ( + getattr(vllm_config.model_config, "hf_config", None), + getattr(vllm_config.model_config, "hf_text_config", None), + ): + if config is None or id(config) in seen: + continue + seen.add(id(config)) + if getattr(config, "compress_ratios", None) is None: + ratios = get_compress_ratios(config) + if ratios: + config.compress_ratios = list(ratios) _validate_model_runner_config(vllm_config) cls._validate_indexer_pp_config(vllm_config) diff --git a/vllm_ascend/quantization/methods/kv_cache/turboquant/cache.py b/vllm_ascend/quantization/methods/kv_cache/turboquant/cache.py index c19caaafa04f..67022001d237 100644 --- a/vllm_ascend/quantization/methods/kv_cache/turboquant/cache.py +++ b/vllm_ascend/quantization/methods/kv_cache/turboquant/cache.py @@ -11,6 +11,9 @@ from vllm.logger import logger from vllm.utils.math_utils import round_up from vllm.utils.torch_utils import get_dtype_size + +# Both supported versions expose planning helpers in kv_cache_planning. +from vllm.v1.core.kv_cache_planning import may_override_num_blocks from vllm.v1.kv_cache_interface import ( KVCacheGroupSpec, KVCacheSpec, @@ -18,17 +21,8 @@ UniformTypeKVCacheSpecs, ) -from vllm_ascend.utils import vllm_version_is - from . import SLOT_BYTES, TURBOQUANT_CACHE_DTYPE -# vLLM #61183 moved `may_override_num_blocks` to `kv_cache_planning` on main; -# the v0.32.0 lane still ships it in `kv_cache_utils`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import may_override_num_blocks -else: - from vllm.v1.core.kv_cache_planning import may_override_num_blocks - # PA attention's fast copy path requires aligned page starts. Preserve the # integral compact-row stride used by the scatter update path as well. PHYSICAL_STRIDE_ALIGNMENT = 256 diff --git a/vllm_ascend/worker/utils.py b/vllm_ascend/worker/utils.py index 89bc461352e6..aaa0b5d38b92 100644 --- a/vllm_ascend/worker/utils.py +++ b/vllm_ascend/worker/utils.py @@ -59,7 +59,7 @@ def copy_kv_cache_blocks_inplace( # Main keys on that geometry; the release lane keys on (device, address). key = ( (tensor.device, data_ptr) - if vllm_version_is("0.32.0") + if vllm_version_is("0.33.0") else (tensor.device, data_ptr, tuple(tensor.shape), tuple(tensor.stride()), tensor.element_size()) ) if key in seen_tensors: diff --git a/vllm_ascend/worker/v1/model_runner.py b/vllm_ascend/worker/v1/model_runner.py index 5584227654e7..2480a20fed04 100644 --- a/vllm_ascend/worker/v1/model_runner.py +++ b/vllm_ascend/worker/v1/model_runner.py @@ -205,7 +205,6 @@ model_uses_kpool_indexer, set_potential_max_tokens, should_skip_allreduce_across_dp_group, - vllm_version_is, weak_ref_tensor, weak_ref_tensors, ) @@ -263,15 +262,6 @@ from vllm_ascend.sample.rejection_sampler import AscendRejectionSampler -# vLLM #61701 removed Medusa/MLP speculator support on main; the v0.32.0 lane -# still ships `AscendMedusaProposer`. Keep the name for the drafter type union -# on both lanes, but on main never resolve it at runtime: the dispatch below -# short-circuits on the version first, and the config rejects `method="medusa"` -# before a proposer could be constructed. -if vllm_version_is("0.32.0"): - from vllm_ascend.worker.v1.spec_decode.medusa_proposer import AscendMedusaProposer # type: ignore[import-not-found] - - if TYPE_CHECKING: import xgrammar as xgr # type: ignore[import-untyped] from vllm.v1.core.sched.output import GrammarOutput, SchedulerOutput @@ -761,7 +751,6 @@ def _set_up_drafter(self): | AscendDSparkProposer | AscendGemma4Proposer | AscendSuffixDecodingProposer - | AscendMedusaProposer | AscendExtractHiddenStatesProposer | None ) = None @@ -2082,16 +2071,6 @@ def propose_draft_token_ids( self._num_valid_draft_tokens, batch_size, ) - elif vllm_version_is("0.32.0") and isinstance(self.drafter, AscendMedusaProposer): - draft_token_ids = self.drafter.propose( - # Dynamic SD: forward the scheduled K (equals the configured - # maximum when the feature is disabled). - scheduler_output.num_spec_tokens_to_schedule, - valid_sampled_token_ids, - sampling_metadata, - spec_decode_metadata, - sample_hidden_states, - ) elif self.speculative_config.uses_extract_hidden_states(): # Handle extract_hidden_states method assert isinstance(self.drafter, AscendExtractHiddenStatesProposer) diff --git a/vllm_ascend/worker/v1/spec_decode/__init__.py b/vllm_ascend/worker/v1/spec_decode/__init__.py index 7e62fd4f6766..44b8fafec8a2 100644 --- a/vllm_ascend/worker/v1/spec_decode/__init__.py +++ b/vllm_ascend/worker/v1/spec_decode/__init__.py @@ -18,7 +18,6 @@ # -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v1.spec_decode.dflash2_proposer import AscendDflash2Proposer, is_dflash2_draft from vllm_ascend.worker.v1.spec_decode.dflash_proposer import AscendDflashProposer from vllm_ascend.worker.v1.spec_decode.draft_proposer import AscendDraftModelProposer @@ -37,11 +36,6 @@ from vllm_ascend.worker.v1.spec_decode.step3p5 import AscendStep3p5MTPProposer from vllm_ascend.worker.v1.spec_decode.suffix_proposer import AscendSuffixDecodingProposer -# vLLM #61701 removed Medusa (and MLP speculator) support on main; the v0.32.0 -# lane still ships `AscendMedusaProposer`. -if vllm_version_is("0.32.0"): - from vllm_ascend.worker.v1.spec_decode.medusa_proposer import AscendMedusaProposer - def get_spec_decode_method(method, vllm_config, device, runner): if method == "ngram": @@ -51,11 +45,7 @@ def get_spec_decode_method(method, vllm_config, device, runner): elif method == "suffix": return AscendSuffixDecodingProposer(vllm_config, runner) elif method == "medusa": - if vllm_version_is("0.32.0"): - return AscendMedusaProposer(vllm_config, device) - raise ValueError( - "Medusa speculative decoding was removed in vLLM (vLLM #61701) and is only supported on the v0.32.0 lane." - ) + raise ValueError("Medusa speculative decoding was removed in vLLM (vLLM #61701).") elif method == "dspark": return AscendDSparkProposer(vllm_config, device, runner) elif method == "mtp" and vllm_config.speculative_config.use_gemma4_mtp(): diff --git a/vllm_ascend/worker/v1/spec_decode/llm_base_proposer.py b/vllm_ascend/worker/v1/spec_decode/llm_base_proposer.py index 81df0dfb17e4..aea2d2c8cbf0 100644 --- a/vllm_ascend/worker/v1/spec_decode/llm_base_proposer.py +++ b/vllm_ascend/worker/v1/spec_decode/llm_base_proposer.py @@ -1222,7 +1222,7 @@ def _propose( self.query_start_loc_group[0][: num_reqs_padded + 1].copy_(common_attn_metadata.query_start_loc) self.query_start_loc_group[0][num_reqs_padded + 1 :].fill_(0) common_attn_metadata.query_start_loc = self.query_start_loc_group[0][: num_reqs_padded + 1] - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): # seq_lens/query_start_loc were replaced above; drop cached layouts. common_attn_metadata.invalidate_cached_layout() # type: ignore[attr-defined] @@ -2080,7 +2080,7 @@ def attn_update_stack_num_spec_norm( # sequence length to 1 to minimize their overheads in attention. exceeds_mask = common_attn_metadata.seq_lens[:batch_size] > self.max_model_len common_attn_metadata.seq_lens[:batch_size].masked_fill_(exceeds_mask, 1) - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): # seq_lens was advanced in place above; drop cached layouts. common_attn_metadata.invalidate_cached_layout() # type: ignore[attr-defined] if common_attn_metadata.seq_lens_cpu is not None: diff --git a/vllm_ascend/worker/v2/attn_utils.py b/vllm_ascend/worker/v2/attn_utils.py index 65f049558d7a..8435ee63c596 100644 --- a/vllm_ascend/worker/v2/attn_utils.py +++ b/vllm_ascend/worker/v2/attn_utils.py @@ -131,7 +131,7 @@ if TYPE_CHECKING: from vllm_ascend.worker.v2.pcp_manager import AscendPCPAttentionContext -if vllm_version_is("0.32.0"): +if vllm_version_is("0.33.0"): import vllm.models.qwen4_exp.common.qsa_cache as qsa_cache # type: ignore[import-not-found] QSAMetadataBuilder = qsa_cache.QSAMetadataBuilder @@ -371,13 +371,8 @@ def get_kv_cache_spec(vllm_config: VllmConfig) -> dict[str, KVCacheSpec]: spec = AscendFlashAttentionBackend.customize_spec(spec) if type(spec) is FullAttentionSpec and is_c8_mxfp_kv_quant(vllm_config): spec = mxfp_cache_spec(spec) - # vLLM #42309 annotates EAGLE groups from ``spec.is_draft``, tagged on - # the spec while specs are built. The v0.32.0 lane has no ``is_draft`` - # field and annotates EAGLE groups through the packed hook, so only main - # propagates the flag here; without it no group is flagged as the draft - # model's and the coordinator fallback treats the target groups as - # EAGLE groups too. - if not vllm_version_is("0.32.0") and getattr(attn_module, "is_draft_layer", False): + # Both supported planners identify EAGLE groups through spec.is_draft. + if getattr(attn_module, "is_draft_layer", False): spec = replace(spec, is_draft=True) kv_cache_spec[layer_name] = spec if isinstance(spec, AttentionSpec) and getattr(attn_module, "align_kv_cache_with_mamba", True): diff --git a/vllm_ascend/worker/v2/model_runner.py b/vllm_ascend/worker/v2/model_runner.py index e1cb6b8072af..9c5a0a9fb9d2 100644 --- a/vllm_ascend/worker/v2/model_runner.py +++ b/vllm_ascend/worker/v2/model_runner.py @@ -1126,8 +1126,8 @@ def sample(self, hidden_states, input_batch, grammar_output): grammar_output.structured_output_request_ids, grammar_output.grammar_bitmask, ) - if vllm_version_is("0.32.0"): - # 0.32.0 rejects drafts verified against a permissive grammar + if vllm_version_is("0.33.0"): + # 0.33.0 rejects drafts verified against a permissive grammar # row; main moved that bookkeeping into the scheduler and the # draft-token handler. import vllm.v1.worker.gpu.structured_outputs as structured_outputs # type: ignore[import-not-found] @@ -1145,7 +1145,7 @@ def sample(self, hidden_states, input_batch, grammar_output): # Rejection sampling for spec decoding. assert self.rejection_sampler is not None assert self.speculator is not None - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): sampler_output = self.rejection_sampler( logits, input_batch, @@ -1371,8 +1371,7 @@ def postprocess_sampled( query_start_loc, ) else: - # Main hands non-last PP ranks the drafts received from the last - # rank; 0.32.0 has no such argument, hence the None-only path above. + # Non-last PP ranks receive drafts from the last rank on both versions. super().postprocess_sampled( idx_mapping, sampled_tokens, diff --git a/vllm_ascend/worker/v2/pcp_manager.py b/vllm_ascend/worker/v2/pcp_manager.py index 8531a4c88ed2..124b8c8e27b5 100644 --- a/vllm_ascend/worker/v2/pcp_manager.py +++ b/vllm_ascend/worker/v2/pcp_manager.py @@ -39,7 +39,6 @@ from vllm_ascend.attention.context_parallel.common_cp import is_pcp_decode_sharding_enabled from vllm_ascend.ops.rotary_embedding import update_cos_sin -from vllm_ascend.utils import vllm_version_is from vllm_ascend.worker.v2.attn_utils import build_attn_state from vllm_ascend.worker.v2.input_batch import AscendInputBatch, AscendInputBuffers @@ -117,7 +116,7 @@ def __init__( dcp_world_size=dcp_world_size, dcp_rank=dcp_rank, cp_interleave=cp_interleave, - **({} if vllm_version_is("0.32.0") else {"moe_gathers_tokens": moe_gathers_tokens}), + moe_gathers_tokens=moe_gathers_tokens, ) # PCP supplies its own output buffers to compute_slot_mappings, so their # dtype must match Ascend block-table slots for cache-write operators. @@ -370,45 +369,24 @@ def _finalize_partition( # vLLM main renamed ``PCPManager.prepare_inputs_to_capture`` to # ``prepare_inputs_for_capture_or_profile`` so the capture path also expands # ``is_padding`` to the rows the MoE routes. - if vllm_version_is("0.32.0"): - - def prepare_inputs_to_capture( - self, - input_batch: AscendInputBatch, - ) -> AscendInputBatch: - """Stage ordinary dummies, but partition CPP's global prefill dummy.""" - if not getattr(input_batch, "is_cpp_profile", False): - staged = super().prepare_inputs_to_capture(input_batch) - assert isinstance(staged, AscendInputBatch) - return staged - - # The parent implementation only copies a dummy into PCP-local buffers. - # CPP instead supplies a global prompt, so use the real prefill splitter - # before those buffers are overwritten with the rank-local layout. - return self.partition_batch( - input_batch, - BatchExecutionDescriptor(CUDAGraphMode.NONE, input_batch.num_tokens, None), - ) - else: - - def prepare_inputs_for_capture_or_profile( # type: ignore[misc] - self, - input_batch: AscendInputBatch, - ) -> AscendInputBatch: - """Stage ordinary dummies, but partition CPP's global prefill dummy.""" - if not getattr(input_batch, "is_cpp_profile", False): - staged = super().prepare_inputs_for_capture_or_profile(input_batch) - assert isinstance(staged, AscendInputBatch) - return staged - - # The parent implementation only copies a dummy into PCP-local buffers. - # CPP instead supplies a global prompt, so use the real prefill splitter - # before those buffers are overwritten with the rank-local layout. - return self.partition_batch( - input_batch, - BatchExecutionDescriptor(CUDAGraphMode.NONE, input_batch.num_tokens, None), - ) + def prepare_inputs_for_capture_or_profile( # type: ignore[misc] + self, + input_batch: AscendInputBatch, + ) -> AscendInputBatch: + """Stage ordinary dummies, but partition CPP's global prefill dummy.""" + if not getattr(input_batch, "is_cpp_profile", False): + staged = super().prepare_inputs_for_capture_or_profile(input_batch) + assert isinstance(staged, AscendInputBatch) + return staged + + # The parent implementation only copies a dummy into PCP-local buffers. + # CPP instead supplies a global prompt, so use the real prefill splitter + # before those buffers are overwritten with the rank-local layout. + return self.partition_batch( + input_batch, + BatchExecutionDescriptor(CUDAGraphMode.NONE, input_batch.num_tokens, None), + ) def _pad_hidden_restore_idx(self, global_batch: AscendInputBatch) -> None: """Extend restore indices to the global padded extent. @@ -608,8 +586,8 @@ def restore_for_sampling( return hidden_states, aux_hidden_states, global_batch def get_draft_input_buffers( - self, input_buffers: InputBuffers, num_tokens: int | None = None - ) -> InputBatch | InputBuffers | tuple[InputBatch | InputBuffers, torch.Tensor]: + self, input_buffers: InputBuffers, num_tokens: int + ) -> tuple[InputBatch | InputBuffers, torch.Tensor]: """Stage rank-local draft prefill inputs at the draft's own addresses. Draft graphs are captured against the speculator's input buffers, @@ -620,9 +598,7 @@ def get_draft_input_buffers( """ local_batch = self.draft_prefill_batch if local_batch is None: - if vllm_version_is("0.32.0"): - return input_buffers - return super().get_draft_input_buffers(input_buffers, num_tokens) # type: ignore[call-arg] + return super().get_draft_input_buffers(input_buffers, num_tokens) num_staged_tokens = local_batch.num_tokens_after_padding self._draft_input_ids_stash[:num_staged_tokens].copy_(input_buffers.input_ids[:num_staged_tokens]) self._draft_positions_stash[:num_staged_tokens].copy_(input_buffers.positions[:num_staged_tokens]) @@ -631,8 +607,6 @@ def get_draft_input_buffers( input_buffers.input_ids[:num_staged_tokens].copy_(local_batch.input_ids[:num_staged_tokens]) input_buffers.positions[:num_staged_tokens].copy_(local_batch.positions[:num_staged_tokens]) input_buffers.is_padding[:num_staged_tokens].copy_(local_batch.is_padding[:num_staged_tokens]) - if vllm_version_is("0.32.0"): - return input_buffers return input_buffers, local_batch.is_padding def restore_draft_prefill( diff --git a/vllm_ascend/worker/v2/spec_decode/dflash/speculator.py b/vllm_ascend/worker/v2/spec_decode/dflash/speculator.py index 6c52900a83cf..19206dbaa4e2 100644 --- a/vllm_ascend/worker/v2/spec_decode/dflash/speculator.py +++ b/vllm_ascend/worker/v2/spec_decode/dflash/speculator.py @@ -126,7 +126,7 @@ def prepare_with_block_size( class AscendDFlashSpeculator(LmheadTPDraftSamplingMixin, DFlashSpeculator): - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): def supports_batch_sharded_draft_logits(self) -> bool: # NPU draft-logits kernels index the cache by request state. diff --git a/vllm_ascend/worker/v2/spec_decode/dspark/speculator.py b/vllm_ascend/worker/v2/spec_decode/dspark/speculator.py index 48254b27bd40..70c124f2b377 100644 --- a/vllm_ascend/worker/v2/spec_decode/dspark/speculator.py +++ b/vllm_ascend/worker/v2/spec_decode/dspark/speculator.py @@ -16,6 +16,7 @@ # This file is a part of the vllm-ascend project. # from collections.abc import Mapping, Sequence +from contextlib import contextmanager from typing import Any, cast import numpy as np @@ -64,7 +65,7 @@ class AscendDSparkSpeculator(LmheadTPDraftSamplingMixin, DSparkSpeculator): # override, upstream sampling logic untouched). _lmhead_tp_sample_draft_supported = True - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): def supports_batch_sharded_draft_logits(self) -> bool: # NPU draft-logits kernels index the cache by request state. @@ -75,6 +76,7 @@ def __init__(self, vllm_config: VllmConfig, device: torch.device): super().__init__(vllm_config, device) self._lmhead_tp_validate_draft_sampling() self.input_batch: InputBatch | None = None + self._draft_metadata_num_reqs: int | None = None self.attn_architecture: str | None = None self.use_flashmla: bool = False self._init_dcp() @@ -296,12 +298,28 @@ def _prepare_draft_dcp_metadata_inputs( max_model_len=self.max_model_len, ) + # TODO: Remove this helper and build_draft_attn_metadatas once tiling + # eliminates replay-time metadata rebuilding. The rebuild currently needs + # this count because it cannot access the effective num_reqs from upstream propose(). + @contextmanager + def _draft_metadata_request_count(self, num_reqs: int): + previous = getattr(self, "_draft_metadata_num_reqs", None) + self._draft_metadata_num_reqs = num_reqs + try: + yield + finally: + self._draft_metadata_num_reqs = previous + # Graph capture builds metadata from the padded request shape. def build_draft_attn_metadatas(self, num_reqs_padded, seq_lens_cpu_upper_bound): assert self.input_batch is not None + num_reqs = getattr(self, "_draft_metadata_num_reqs", None) + if num_reqs is None: + num_reqs = self.input_batch.num_reqs + assert 0 <= num_reqs <= num_reqs_padded, "draft requests exceed graph capacity" num_tokens_padded = num_reqs_padded * self.num_query_per_req seq_lens_cpu, is_prefilling = self._prepare_draft_dcp_metadata_inputs( - self.input_batch.num_reqs, num_reqs_padded, self.num_query_per_req + num_reqs, num_reqs_padded, self.num_query_per_req ) with ( build_attn_metadata_wrapper(), @@ -322,7 +340,7 @@ def build_draft_attn_metadatas(self, num_reqs_padded, seq_lens_cpu_upper_bound): num_reqs=num_reqs_padded, ) attn_metadata = self._build_uniform_attn_metadata( - num_reqs=self.input_batch.num_reqs, + num_reqs=num_reqs, batch_desc=batch_desc, num_query_per_req=self.num_query_per_req, seq_lens_cpu_upper_bound=seq_lens_cpu_upper_bound, @@ -432,15 +450,22 @@ def propose( # TODO: Remove this guard once main2main includes upstream vLLM # #54856 (facd9a74a1), which resets the profiling DP counts. sync_state = None + # Upstream trims DP dummy draft requests before selecting its graph, + # while input_batch still describes the padded target batch. Replay + # metadata must use the same count without mutating the target batch. + num_draft_reqs = input_batch.num_reqs + if dummy_run and sync_state is not None: + num_draft_reqs = min(num_draft_reqs, sync_state.num_reqs) seq_lens_cpu = None is_prefilling = torch.from_numpy(self.input_batch.is_prefilling_np) if self.use_dcp and self.attn_architecture in ("GQA", "MLA") and not (dummy_run and skip_attn_for_dummy_run): # DSpark drafts one block with a fixed step; zero unused request slots # before upstream selects the padded batch size and slices this view. seq_lens_cpu, is_prefilling = self._prepare_draft_dcp_metadata_inputs( - input_batch.num_reqs, self.max_num_reqs, self.num_query_per_req + num_draft_reqs, self.max_num_reqs, self.num_query_per_req ) with ( + self._draft_metadata_request_count(num_draft_reqs), build_attn_metadata_wrapper(), build_attn_metadata_factory( self.input_buffers.positions, diff --git a/vllm_ascend/worker/v2/spec_decode/lmhead_tp_utils.py b/vllm_ascend/worker/v2/spec_decode/lmhead_tp_utils.py index c610941bc9cd..1e144cbfbd70 100644 --- a/vllm_ascend/worker/v2/spec_decode/lmhead_tp_utils.py +++ b/vllm_ascend/worker/v2/spec_decode/lmhead_tp_utils.py @@ -6,7 +6,7 @@ import torch -from vllm_ascend.utils import lmhead_tp_enable, lmhead_tp_max_num_logits, lmhead_tp_pad_rows, vllm_version_is +from vllm_ascend.utils import lmhead_tp_enable, lmhead_tp_max_num_logits, lmhead_tp_pad_rows class LmheadTPDraftSamplingMixin: @@ -61,82 +61,22 @@ def _lmhead_tp_validate_draft_sampling(self) -> None: "read the request mapping and write those buffers out of bounds." ) - if vllm_version_is("0.32.0"): - - def sample_draft( - self, - hidden_states: torch.Tensor, - positions: torch.Tensor, - idx_mapping: torch.Tensor, - temperature: torch.Tensor, - seeds: torch.Tensor, - draft_step: torch.Tensor, - draft_logits: torch.Tensor | None, - ): - if not lmhead_tp_enable(): - return super().sample_draft( # type: ignore[misc] - hidden_states, positions, idx_mapping, temperature, seeds, draft_step, draft_logits - ) - if draft_logits is not None: - raise NotImplementedError( - "lmhead TP does not support draft_sample_method='probabilistic': " - "the gumbel path writes into fixed-size draft buffers that cannot " - "hold the group-aligned padding rows." - ) - num_logits = hidden_states.shape[0] - # Shared pad primitive (the runner's sample() pads the target head the - # same way); zero rows carry no draft token and are trimmed back off. - padded = lmhead_tp_pad_rows( - hidden_states, - self._lmhead_tp_max_num_logits(), - "max_num_reqs * (num_speculative_steps + 1)", - ) - out = super().sample_draft( # type: ignore[misc] - padded, positions, idx_mapping, temperature, seeds, draft_step, draft_logits - ) - return out[:num_logits] - - else: - # vLLM #59554 added `num_steps` to `Speculator.sample_draft`; DFlash - # passes it so the draft watermarker can key its draw by the step count. - def sample_draft( # type: ignore[misc] - self, - hidden_states: torch.Tensor, - positions: torch.Tensor, - idx_mapping: torch.Tensor, - temperature: torch.Tensor, - seeds: torch.Tensor, - draft_step: torch.Tensor, - draft_logits: torch.Tensor | None, - num_steps: int = 1, - ): - if not lmhead_tp_enable(): - return super().sample_draft( # type: ignore[misc] - hidden_states, - positions, - idx_mapping, - temperature, - seeds, - draft_step, - draft_logits, - num_steps=num_steps, - ) - if draft_logits is not None: - raise NotImplementedError( - "lmhead TP does not support draft_sample_method='probabilistic': " - "the gumbel path writes into fixed-size draft buffers that cannot " - "hold the group-aligned padding rows." - ) - num_logits = hidden_states.shape[0] - # Shared pad primitive (the runner's sample() pads the target head the - # same way); zero rows carry no draft token and are trimmed back off. - padded = lmhead_tp_pad_rows( + # vLLM #59554 added `num_steps` to `Speculator.sample_draft`; DFlash + # passes it so the draft watermarker can key its draw by the step count. + def sample_draft( # type: ignore[misc] + self, + hidden_states: torch.Tensor, + positions: torch.Tensor, + idx_mapping: torch.Tensor, + temperature: torch.Tensor, + seeds: torch.Tensor, + draft_step: torch.Tensor, + draft_logits: torch.Tensor | None, + num_steps: int = 1, + ): + if not lmhead_tp_enable(): + return super().sample_draft( # type: ignore[misc] hidden_states, - self._lmhead_tp_max_num_logits(), - "max_num_reqs * (num_speculative_steps + 1)", - ) - out = super().sample_draft( # type: ignore[misc] - padded, positions, idx_mapping, temperature, @@ -145,4 +85,28 @@ def sample_draft( # type: ignore[misc] draft_logits, num_steps=num_steps, ) - return out[:num_logits] + if draft_logits is not None: + raise NotImplementedError( + "lmhead TP does not support draft_sample_method='probabilistic': " + "the gumbel path writes into fixed-size draft buffers that cannot " + "hold the group-aligned padding rows." + ) + num_logits = hidden_states.shape[0] + # Shared pad primitive (the runner's sample() pads the target head the + # same way); zero rows carry no draft token and are trimmed back off. + padded = lmhead_tp_pad_rows( + hidden_states, + self._lmhead_tp_max_num_logits(), + "max_num_reqs * (num_speculative_steps + 1)", + ) + out = super().sample_draft( # type: ignore[misc] + padded, + positions, + idx_mapping, + temperature, + seeds, + draft_step, + draft_logits, + num_steps=num_steps, + ) + return out[:num_logits] diff --git a/vllm_ascend/worker/v2/spec_decode/multi_module_mtp/speculator.py b/vllm_ascend/worker/v2/spec_decode/multi_module_mtp/speculator.py index 50abeaf2bf46..737ac8713c04 100644 --- a/vllm_ascend/worker/v2/spec_decode/multi_module_mtp/speculator.py +++ b/vllm_ascend/worker/v2/spec_decode/multi_module_mtp/speculator.py @@ -51,7 +51,7 @@ class AscendMultiModuleMTPSpeculator(MultiModuleMTPSpeculator): UpdatableGraph attention-parameter updates on replay). """ - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): def supports_batch_sharded_draft_logits(self) -> bool: # NPU draft-logits kernels index the cache by request state. diff --git a/vllm_ascend/worker/v2/spec_decode/rejection_sampler_utils.py b/vllm_ascend/worker/v2/spec_decode/rejection_sampler_utils.py index 1023453faa8c..8a4117d42f9e 100644 --- a/vllm_ascend/worker/v2/spec_decode/rejection_sampler_utils.py +++ b/vllm_ascend/worker/v2/spec_decode/rejection_sampler_utils.py @@ -352,7 +352,7 @@ def rejection_sample( # An explicit flag bypasses configuration lookup for standalone callers. if use_fp64: raise NotImplementedError("FP64 rejection sampling is not supported on NPU.") - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): draft_logits_row_mapping = None if draft_logits_num_shards != 1: # vLLM main (#63554) can shard the draft logits cache across TP ranks; @@ -403,14 +403,8 @@ def rejection_sample( num_logits, vocab_size = target_logits.shape has_draft_logits = draft_logits is not None - # vLLM main renamed the `num_speculative_steps` argument of the logits-stats - # kernels to `num_logits` and moved bonus-token detection into - # `_is_bonus_logit`, which masks its look-ahead load with the total logit - # count. Passing `num_speculative_steps` there makes the kernels treat every - # logit after the first one as a bonus token and return early, leaving the - # `new_empty` block-statistics buffers uninitialized. v0.32.0 still expects - # `num_speculative_steps`. - stats_num_logits = num_speculative_steps if vllm_version_is("0.32.0") else num_logits + # Both upstream kernels detect bonus rows using the total logit count. + stats_num_logits = num_logits if draft_logits is None: # When draft_logits is None, create a dummy tensor so that Triton @@ -433,7 +427,7 @@ def rejection_sample( target_local_sumexp = target_logits.new_empty(num_logits, vocab_num_blocks, dtype=torch.float32) draft_local_max = target_logits.new_empty(num_logits, vocab_num_blocks, dtype=torch.float32) draft_local_sumexp = target_logits.new_empty(num_logits, vocab_num_blocks, dtype=torch.float32) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): _compute_block_stats_kernel[(num_logits, vocab_num_blocks)]( target_local_argmax, target_local_argmax.stride(0), @@ -515,7 +509,7 @@ def rejection_sample( if use_block_verification: cumulative_log_p = target_logits.new_empty(num_logits, dtype=torch.float32) - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): _compute_cumulative_log_p_kernel[(num_reqs,)]( cumulative_log_p, target_logits, @@ -569,7 +563,7 @@ def rejection_sample( if has_draft_logits: local_residual_mass = target_logits.new_empty(num_logits, vocab_num_blocks, dtype=torch.float32) if num_logits > 1: - if vllm_version_is("0.32.0"): + if vllm_version_is("0.33.0"): _compute_local_residual_mass_kernel[(num_logits - 1, vocab_num_blocks)]( local_residual_mass, local_residual_mass.stride(0), diff --git a/vllm_ascend/worker/v2/spec_decode/standalone_ar/speculator.py b/vllm_ascend/worker/v2/spec_decode/standalone_ar/speculator.py index 5abf093c097b..b54138945391 100644 --- a/vllm_ascend/worker/v2/spec_decode/standalone_ar/speculator.py +++ b/vllm_ascend/worker/v2/spec_decode/standalone_ar/speculator.py @@ -19,7 +19,7 @@ class AscendStandaloneARSpeculator(StandaloneARSpeculator): - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): def supports_batch_sharded_draft_logits(self) -> bool: # NPU draft-logits kernels index the cache by request state. diff --git a/vllm_ascend/worker/v2/spec_decode/target_dependent_ar/speculator.py b/vllm_ascend/worker/v2/spec_decode/target_dependent_ar/speculator.py index 5b040cc345c5..4b50fd54c4ed 100644 --- a/vllm_ascend/worker/v2/spec_decode/target_dependent_ar/speculator.py +++ b/vllm_ascend/worker/v2/spec_decode/target_dependent_ar/speculator.py @@ -82,7 +82,7 @@ class AscendTargetDependentARSpeculator(LmheadTPDraftSamplingMixin, TargetDepend model_state: "AscendModelState" - if not vllm_version_is("0.32.0"): + if not vllm_version_is("0.33.0"): def supports_batch_sharded_draft_logits(self) -> bool: # NPU draft-logits kernels index the cache by request state. @@ -489,29 +489,18 @@ def _prefill( name: metadata for name, metadata in attn_metadata.items() if name in self.draft_attn_layer_names } - if vllm_version_is("0.32.0"): - super()._prefill( - num_reqs, - num_tokens, - attn_metadata, - slot_mappings, - num_tokens_across_dp, - cudagraph_runtime_mode, - mm_inputs, - ) - else: - # vLLM main forwards `skip_sample` so the drafter KV stays in sync - # without sampling when num_speculative_tokens == 0. - super()._prefill( - num_reqs, - num_tokens, - attn_metadata, - slot_mappings, - num_tokens_across_dp, - cudagraph_runtime_mode, - mm_inputs, - skip_sample, - ) + # vLLM main forwards `skip_sample` so the drafter KV stays in sync + # without sampling when num_speculative_tokens == 0. + super()._prefill( + num_reqs, + num_tokens, + attn_metadata, + slot_mappings, + num_tokens_across_dp, + cudagraph_runtime_mode, + mm_inputs, + skip_sample, + ) def _build_attn_metadata( self, diff --git a/vllm_ascend/worker/worker.py b/vllm_ascend/worker/worker.py index 2f1f180ab8ec..851c351f40b0 100644 --- a/vllm_ascend/worker/worker.py +++ b/vllm_ascend/worker/worker.py @@ -56,6 +56,8 @@ from vllm.utils.mem_constants import GiB_bytes from vllm.utils.mem_utils import MemorySnapshot, format_gib, memory_profiling from vllm.utils.torch_utils import STR_DTYPE_TO_TORCH_DTYPE +from vllm.v1.core.kv_cache_config_builder import get_kv_cache_config_builder +from vllm.v1.core.kv_cache_planning import unify_hybrid_kv_cache_specs from vllm.v1.core.sched.output import GrammarOutput, SchedulerOutput from vllm.v1.kv_cache_interface import ( AttentionSpec, @@ -115,26 +117,14 @@ register_ascend_fla_customop, register_device_print, setup_ascend_local_comm_res, - vllm_version_is, ) -# vLLM #61183 moved the planning helpers on main; v0.32.0 keeps them -# in kv_cache_utils, so importing the main-only module breaks worker startup. -# Main resolves grouping through the platform's `KVCacheConfigBuilder`. -if vllm_version_is("0.32.0"): - from vllm.v1.core.kv_cache_utils import ( - get_kv_cache_groups, - unify_hybrid_kv_cache_specs, - ) -else: - from vllm.v1.core.kv_cache_config_builder import get_kv_cache_config_builder - from vllm.v1.core.kv_cache_planning import unify_hybrid_kv_cache_specs - - def get_kv_cache_groups( - vllm_config: VllmConfig, - kv_cache_spec: dict[str, KVCacheSpec], - ) -> list[KVCacheGroupSpec]: - return get_kv_cache_config_builder(vllm_config).get_kv_cache_groups(vllm_config, kv_cache_spec) + +def get_kv_cache_groups( + vllm_config: VllmConfig, + kv_cache_spec: dict[str, KVCacheSpec], +) -> list[KVCacheGroupSpec]: + return get_kv_cache_config_builder(vllm_config).get_kv_cache_groups(vllm_config, kv_cache_spec) torch._dynamo.trace_rules.clear_lru_cache() # noqa: E402 @@ -1199,22 +1189,16 @@ def get_kv_connector_handshake_metadata( return {(pp_rank, tp_rank): metadata} def get_simple_cpu_offload_num_cpu_blocks(self) -> int | None: - if vllm_version_is("0.32.0"): - # v0.32.0's engine core never issues this RPC, and the upstream - # `._find_simple_cpu_offload_connector` / `get_aligned_num_cpu_blocks` - # helpers do not exist on that lane. - return None - else: - from vllm.distributed.kv_transfer.kv_connector.v1.simple_cpu_offload_connector import ( # noqa: E501 - _find_simple_cpu_offload_connector, - ) + from vllm.distributed.kv_transfer.kv_connector.v1.simple_cpu_offload_connector import ( # noqa: E501 + _find_simple_cpu_offload_connector, + ) - if not has_kv_transfer_group(): - return None - connector = _find_simple_cpu_offload_connector(get_kv_transfer_group()) - if connector is None: - return None - return connector.get_aligned_num_cpu_blocks() + if not has_kv_transfer_group(): + return None + connector = _find_simple_cpu_offload_connector(get_kv_transfer_group()) + if connector is None: + return None + return connector.get_aligned_num_cpu_blocks() def _get_layerwise_kv_cache_memory_info( self, @@ -1396,10 +1380,9 @@ def profile( logger.debug("Starting torch profiler with trace name: %s", trace_name) # Else: profiler already initialized. Restart profiling but keep the # original trace name from the first initialization. - if not vllm_version_is("0.32.0"): - # vLLM main supports per-session profiler kwargs; the release - # wrapper has no slot for them. - self.profiler.set_profiler_kwargs(profiler_kwargs) + # vLLM main supports per-session profiler kwargs; the release + # wrapper has no slot for them. + self.profiler.set_profiler_kwargs(profiler_kwargs) self.profiler.start(delay_iterations=delay_iterations, max_iterations=max_iterations) else: if self.profiler is None: