Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions tests/kernels/core/test_apply_rotary_emb.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def get_test_cases() -> list[RotaryEmbeddingTestCase]:
Ernie4_5_VLRotaryEmbedding,
)
from vllm.model_executor.layers.rotary_embedding.mrope import MRotaryEmbedding
from vllm.model_executor.layers.rotary_embedding.xdrope import XDRotaryEmbedding

common_kwargs = {
"head_size": 128,
Expand Down Expand Up @@ -77,20 +76,6 @@ def get_test_cases() -> list[RotaryEmbeddingTestCase]:
expect_forward_native=False,
expect_forward=True,
),
# XDRotaryEmbedding tests
RotaryEmbeddingTestCase(
name="XDRotaryEmbedding.forward",
rope_class=XDRotaryEmbedding,
rope_kwargs={
**common_kwargs,
"scaling_alpha": 1.0,
"xdrope_section": [16, 16, 16, 16],
},
method_name="forward",
positions_shape=(4, 32), # 4D for P/W/H/T
expect_forward_native=False,
expect_forward=True,
),
# Ernie4_5_VLRotaryEmbedding tests
RotaryEmbeddingTestCase(
name="Ernie4_5_VLRotaryEmbedding.forward_native",
Expand Down
19 changes: 19 additions & 0 deletions tests/models/transformers/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,3 +769,22 @@ class Attention(nn.Module):

with pytest.raises(ValueError, match="Cannot resolve attention scaling expression"):
fuser.scale(Attention())


class _ImageOnlyMRoPEModel:
"""`get_rope_index` without `video_grid_thw` or `**kwargs` (e.g. HunYuanVL)."""

def get_rope_index(self, input_ids, image_grid_thw):
seq_len = input_ids.shape[-1]
positions = torch.arange(seq_len).view(1, 1, -1).expand(4, 1, -1)
return positions, torch.tensor([0])


def test_get_mrope_input_positions_omits_unsupported_grid_kwargs():
"""Optional grids the model can't accept must not be passed when empty."""
mixin = SimpleNamespace(model=_ImageOnlyMRoPEModel())

positions, delta = MultiModalMixin.get_mrope_input_positions(mixin, [1, 2, 3], [])

assert positions.shape == (4, 3)
assert delta == 0
48 changes: 48 additions & 0 deletions tests/transformers_utils/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
from vllm.transformers_utils import config as config_module
from vllm.transformers_utils.config import (
get_safetensors_params_metadata,
mrope_num_dims,
patch_legacy_rope_type,
try_get_generation_config,
uses_mrope,
)
from vllm.transformers_utils.configs.glm5_next import (
Glm5NextConfig,
Expand Down Expand Up @@ -176,3 +178,49 @@ def test_safetensors_metadata_of_repo_without_safetensors():
assert get_safetensors_params_metadata("some/pytorch-only-model") == {}

get_safetensors_metadata.assert_called_once()


@pytest.mark.parametrize(
("section_key", "mrope_section", "expected_num_dims"),
[
("mrope_section", [16, 24, 24], 3),
("mrope_section", [16, 16, 16, 16], 4),
# Interleaved M-RoPE takes 2 sections but still consumes 3D positions
("mrope_section", [32, 32], 3),
# HunYuan-VL checkpoints ship the section under its legacy name
("xdrope_section", [16, 16, 16, 16], 4),
],
)
def test_mrope_num_dims(section_key, mrope_section, expected_num_dims):
config = PretrainedConfig()
config.rope_parameters = {"rope_type": "default", section_key: mrope_section}

assert uses_mrope(config)
assert mrope_num_dims(config) == expected_num_dims


@pytest.mark.parametrize("section_name", ["mrope_section", "xdrope_section"])
def test_mrope_num_dims_from_config_attribute(section_name):
"""Some configs expose the section as an attribute rather than under
`rope_parameters`."""
config = PretrainedConfig()
setattr(config, section_name, [16, 16, 16, 16])

assert uses_mrope(config)
assert mrope_num_dims(config) == 4


def test_mrope_num_dims_from_nested_rope_parameters():
"""Sections nested by layer type must be found, not silently defaulted."""
config = PretrainedConfig()
config.rope_parameters = {
"full_attention": {"mrope_section": [16, 16, 16, 16]},
"linear_attention": {"rope_type": "default"},
}

assert uses_mrope(config)
assert mrope_num_dims(config) == 4


def test_mrope_num_dims_without_mrope():
assert mrope_num_dims(PretrainedConfig()) == 0
18 changes: 0 additions & 18 deletions tests/v1/core/test_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,24 +105,6 @@ def _mm_feature_mixed(offset: int, length: int) -> MultiModalFeatureSpec:
)


def test_strip_covered_mm_data_xdrope() -> None:
"""XD-RoPE models (e.g. HunyuanOCR) compute positions the same way, so a
covered item must keep its grid dims: stripping them made the worker index
an empty ``image_grid_thw`` and crash the engine on the second request with
an identical prompt."""
covered = _mm_feature_mixed(offset=0, length=100)
uncovered = _mm_feature_mixed(offset=300, length=100)

stripped = strip_covered_mm_data(
[covered, uncovered], num_computed_tokens=250, uses_xdrope=True
)

assert stripped[0].data is not None
assert list(stripped[0].data.keys()) == ["image_grid_thw"]
assert stripped[1].data is not None
assert set(stripped[1].data.keys()) == {"pixel_values", "image_grid_thw"}


def test_strip_covered_mm_data_mrope() -> None:
"""For M-RoPE models, covered items keep their keep_on_cpu metadata fields
(the worker needs them to compute positions); payload fields are dropped."""
Expand Down
10 changes: 3 additions & 7 deletions vllm/config/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
get_sentence_transformer_tokenizer_config,
is_encoder_decoder,
is_rope_parameters_nested,
mrope_num_dims,
try_get_dense_modules,
try_get_generation_config,
try_get_tokenizer_config,
uses_mrope,
uses_xdrope_dim,
)
from vllm.transformers_utils.model_arch_config_convertor import (
MODEL_ARCH_CONFIG_CONVERTORS,
Expand Down Expand Up @@ -1850,12 +1850,8 @@ def uses_mrope(self) -> bool:
return uses_mrope(self.hf_config)

@property
def uses_xdrope_dim(self) -> int:
return uses_xdrope_dim(self.hf_config)

@property
def uses_xdrope(self) -> bool:
return self.uses_xdrope_dim > 0
def mrope_num_dims(self) -> int:
return mrope_num_dims(self.hf_config)

@property
def is_multimodal_model(self) -> bool:
Expand Down
13 changes: 0 additions & 13 deletions vllm/model_executor/layers/rotary_embedding/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
from .ntk_scaling_rope import NTKScalingRotaryEmbedding
from .phi3_long_rope_scaled_rope import Phi3LongRoPEScaledRotaryEmbedding
from .telechat3_scaling_rope import TeleChat3RoPEScaledRotaryEmbedding
from .xdrope import XDRotaryEmbedding
from .yarn_scaling_rope import YaRNScalingRotaryEmbedding

_ROPE_DICT: dict[tuple[Any, ...], RotaryEmbedding] = {}
Expand Down Expand Up @@ -228,18 +227,6 @@ def get_rope(
raise ValueError(
"Dynamic rope scaling must contain either 'alpha' or 'factor' field"
)
elif scaling_type == "xdrope":
scaling_alpha = rope_parameters["alpha"]
rotary_emb = XDRotaryEmbedding(
head_size,
rotary_dim,
max_position,
base,
is_neox_style,
scaling_alpha,
dtype,
xdrope_section=rope_parameters["xdrope_section"],
)
elif scaling_type == "yarn":
scaling_factor = rope_parameters["factor"]
original_max_position = rope_parameters["original_max_position_embeddings"]
Expand Down
172 changes: 0 additions & 172 deletions vllm/model_executor/layers/rotary_embedding/xdrope.py

This file was deleted.

Loading
Loading