A high-throughput and memory-efficient inference and serving engine for LLMs
Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git
Synced Nov 4, 06:15 UTC
Fix some legacy checkpoints with deprecated `rope_type` values (#41734)
Signed-off-by: Harry Mellor <19981378+hmellor@users.noreply.github.com>
Harry Mellor committed
May 6, 2026 at 12:13 UTC
d8deb5b7ade403ae36feda6f71898a61ac0bda6e
1 file changed
+56
-54
vllm/transformers_utils/config.py
+56
-54
@@ -401,6 +401,57 @@ def set_default_rope_theta(config: PretrainedConfig, default_theta: float) -> No
401
config.rope_parameters["rope_theta"] = default_theta
402
403
404
+def patch_legacy_rope_type(rope_parameters: dict[str, Any] | None) -> None:
405
+ """Patch legacy RoPE type fields for backwards compatibility with
406
+ older custom models which would otherwise fail to load."""
407
+
408
+ # No RoPE parameters to patch
409
+ if rope_parameters is None:
410
+ return
411
+
412
+ def _patch_legacy_rope_type(rope_parameters: dict[str, Any]) -> None:
413
+ # Case 1: Both legacy and modern fields present - check for conflicts
414
+ if "rope_type" in rope_parameters and "type" in rope_parameters:
415
+ rope_type = rope_parameters["rope_type"]
416
+ rope_type_legacy = rope_parameters["type"]
417
+ if (rope_type_legacy == "su" and rope_type == "longrope") or (
418
+ rope_type_legacy == "mrope" and rope_type == "default"
419
+ ):
420
+ pass # No action needed
421
+ elif rope_type != rope_type_legacy:
422
+ raise ValueError(
423
+ f"Found conflicts between 'rope_type={rope_type}' (modern "
424
+ f"field) and 'type={rope_type_legacy}' (legacy field). "
425
+ "You should only specify one of them."
426
+ )
427
+ # Case 2: Only legacy field present - patch to modern format with warning
428
+ if "rope_type" not in rope_parameters and "type" in rope_parameters:
429
+ rope_parameters["rope_type"] = rope_parameters["type"]
430
+ logger.info("Replacing legacy 'type' key with 'rope_type'")
431
+ # Case 3: No rope_type field at all - cannot determine RoPE type, raise error
432
+ if "rope_type" not in rope_parameters:
433
+ raise ValueError("rope_parameters should have a 'rope_type' key")
434
+ # Patch legacy rope_type values with warning
435
+ if rope_parameters["rope_type"] == "su":
436
+ rope_parameters["rope_type"] = "longrope"
437
+ logger.warning("Replacing legacy rope_type 'su' with 'longrope'")
438
+ elif rope_parameters["rope_type"] == "mrope":
439
+ if "mrope_section" not in rope_parameters:
440
+ raise ValueError(
441
+ "Legacy rope_type 'mrope' requires "
442
+ "'mrope_section' in rope_parameters"
443
+ )
444
+ rope_parameters["rope_type"] = "default"
445
+ logger.warning("Replacing legacy rope_type 'mrope' with 'default'")
446
+
447
+ # Handle nested rope_parameters in interleaved sliding attention models
448
+ if is_rope_parameters_nested(rope_parameters):
449
+ for rope_parameters_layer_type in rope_parameters.values():
450
+ _patch_legacy_rope_type(rope_parameters_layer_type)
451
+ else:
452
+ _patch_legacy_rope_type(rope_parameters)
453
+
454
+
455
def patch_rope_parameters(config: PretrainedConfig) -> None:
456
"""Provide backwards compatibility for RoPE."""
457
from vllm.config.utils import getattr_iter
@@ -415,15 +466,9 @@ def patch_rope_parameters(config: PretrainedConfig) -> None:
466
467
if Version(version("transformers")) < Version("5.0.0"):
468
# Transformers v4 installed, legacy config fields may be present.
418
- existing_rp = getattr(config, "rope_parameters", None)
419
- if isinstance(existing_rp, dict) and is_rope_parameters_nested(existing_rp):
420
- # Interleaved-attention models (e.g. Laguna-XS.2) ship a nested
421
- # {layer_type: {...}} rope_parameters that the model code indexes
422
- # by layer_type. The per-layer-type sub-dicts already carry the
423
- # correct rope_theta / partial_rotary_factor / ompe (the converter
424
- # places top-level legacy fields inside full_attention), so don't
425
- # merge top-level fields here — that would shadow the per-type
426
- # values and break sliding-attention layers.
469
+ if is_rope_parameters_nested(getattr(config, "rope_parameters", {})):
470
+ # Loading nested rope_parameters (from Transformers v5) in Transformers v4.
471
+ # Skip legacy patching since it should already be in the correct format.
472
pass
473
else:
474
if (rope_scaling := getattr(config, "rope_scaling", None)) is not None:
@@ -441,6 +486,7 @@ def patch_rope_parameters(config: PretrainedConfig) -> None:
486
config.rope_parameters["partial_rotary_factor"] = partial_rotary_factor
487
if ompe is not None:
488
config.rope_parameters["original_max_position_embeddings"] = ompe
489
+ patch_legacy_rope_type(getattr(config, "rope_parameters", None))
490
elif rope_theta is not None or getattr(config, "rope_parameters", None):
491
# Transformers v5 installed
492
# Patch these fields in case they used non-standard names
@@ -449,54 +495,10 @@ def patch_rope_parameters(config: PretrainedConfig) -> None:
495
if partial_rotary_factor is not None:
496
config.partial_rotary_factor = partial_rotary_factor
497
# Standardize and validate RoPE parameters
498
+ patch_legacy_rope_type(getattr(config, "rope_parameters", None))
499
config.standardize_rope_params()
500
config.validate_rope()
501
455
- # No RoPE parameters to patch
456
- if getattr(config, "rope_parameters", None) is None:
457
- return
458
-
459
- # Handle nested rope_parameters in interleaved sliding attention models
460
- if is_rope_parameters_nested(config.rope_parameters):
461
- for rope_parameters_layer_type in config.rope_parameters.values():
462
- patch_rope_parameters_dict(rope_parameters_layer_type)
463
- else:
464
- patch_rope_parameters_dict(config.rope_parameters)
465
-
466
-
467
-def patch_rope_parameters_dict(rope_parameters: dict[str, Any]) -> None:
468
- if "rope_type" in rope_parameters and "type" in rope_parameters:
469
- rope_type = rope_parameters["rope_type"]
470
- rope_type_legacy = rope_parameters["type"]
471
- if (rope_type_legacy == "su" and rope_type == "longrope") or (
472
- rope_type_legacy == "mrope" and rope_type == "default"
473
- ):
474
- pass # No action needed
475
- elif rope_type != rope_type_legacy:
476
- raise ValueError(
477
- f"Found conflicts between 'rope_type={rope_type}' (modern "
478
- f"field) and 'type={rope_type_legacy}' (legacy field). "
479
- "You should only specify one of them."
480
- )
481
-
482
- if "rope_type" not in rope_parameters and "type" in rope_parameters:
483
- rope_parameters["rope_type"] = rope_parameters["type"]
484
- logger.info("Replacing legacy 'type' key with 'rope_type'")
485
-
486
- if "rope_type" not in rope_parameters:
487
- raise ValueError("rope_parameters should have a 'rope_type' key")
488
-
489
- if rope_parameters["rope_type"] == "su":
490
- rope_parameters["rope_type"] = "longrope"
491
- logger.warning("Replacing legacy rope_type 'su' with 'longrope'")
492
- elif rope_parameters["rope_type"] == "mrope":
493
- if "mrope_section" not in rope_parameters:
494
- raise ValueError(
495
- "Legacy rope_type 'mrope' requires 'mrope_section' in rope_parameters"
496
- )
497
- rope_parameters["rope_type"] = "default"
498
- logger.warning("Replacing legacy rope_type 'mrope' with 'default'")
499
-
502
503
def _uses_mrope(config: PretrainedConfig) -> bool:
504
rope_parameters = getattr(config, "rope_parameters", None)