diff --git a/python/sglang/srt/utils/hf_transformers_patches.py b/python/sglang/srt/utils/hf_transformers_patches.py index dbf9726a0..17a394190 100644 --- a/python/sglang/srt/utils/hf_transformers_patches.py +++ b/python/sglang/srt/utils/hf_transformers_patches.py @@ -136,41 +136,18 @@ def _ensure_gguf_version(): def _patch_rope_parameters_validation(): - """Fix rope_parameters validation for unregistered model types. + """Guard ``standardize_rope_params()`` against missing + ``max_position_embeddings``. - For unregistered model types (e.g. ``deepseek_v32``), the generic - ``PretrainedConfig`` lacks a ``rope_parameters`` field so the conversion - that injects ``rope_theta`` from the top-level config is skipped. - Additionally, ``standardize_rope_params()`` accesses + For ``PretrainedConfig``, ``standardize_rope_params()`` accesses ``self.max_position_embeddings`` during ``__post_init__`` before extra kwargs are set as attributes, causing ``AttributeError``. - Fix: (1) patch ``from_dict`` to inject ``rope_theta`` into - ``rope_scaling``, (2) guard ``standardize_rope_params`` against missing + Fix: guard ``standardize_rope_params`` against missing ``max_position_embeddings``. - - TODO(upstream): remove once unregistered model types handle rope - standardization correctly in transformers. """ from transformers import PretrainedConfig - original = PretrainedConfig.from_dict.__func__ - - @classmethod # type: ignore[misc] - def patched(cls, config_dict, **kwargs): - rope_scaling = config_dict.get("rope_scaling") - rope_theta = config_dict.get("rope_theta") - if ( - isinstance(rope_scaling, dict) - and rope_theta is not None - and "rope_theta" not in rope_scaling - ): - config_dict = config_dict.copy() - config_dict["rope_scaling"] = {**rope_scaling, "rope_theta": rope_theta} - return original(cls, config_dict, **kwargs) - - PretrainedConfig.from_dict = patched - # standardize_rope_params accesses self.max_position_embeddings before # __post_init__ sets extra kwargs — skip when the attribute is absent. if hasattr(PretrainedConfig, "standardize_rope_params"): diff --git a/test/registered/unit/utils/test_hf_transformers.py b/test/registered/unit/utils/test_hf_transformers.py index b29839d0e..81b0122d5 100644 --- a/test/registered/unit/utils/test_hf_transformers.py +++ b/test/registered/unit/utils/test_hf_transformers.py @@ -480,6 +480,15 @@ class TestPatchRemovedSymbols(unittest.TestCase): class TestPatchRopeParametersValidation(unittest.TestCase): + # ----------------------------------------------------------------------- + # Test ``rope_theta`` injection into ``rope_scaling``. + # + # Upstream `transformers.PretrainedConfig` now natively handles this + # logic. While the manual injection patch has been removed, these + # test cases are retained to ensure regression testing of the + # configuration's injection behavior. + # ----------------------------------------------------------------------- + def test_injects_rope_theta_into_rope_scaling(self): config_dict = { "model_type": "llama",