diff --git a/scripts/patches/glm53-dflash-01-aux-hidden-states.patch b/scripts/patches/glm53-dflash-01-aux-hidden-states.patch index 5308233..88933ff 100644 --- a/scripts/patches/glm53-dflash-01-aux-hidden-states.patch +++ b/scripts/patches/glm53-dflash-01-aux-hidden-states.patch @@ -18,12 +18,19 @@ # # THE CONTRACT (read out of this image, not assumed): # * interfaces.py:1663 -- `supports_eagle3: ClassVar[Literal[True]] = True`. THE FLAG -# IS A REQUIRED MEMBER FOR `isinstance`: satisfying the Protocol with methods alone -# still raises the same RuntimeError -- v1 of this patch did exactly that and the boot -# failed identically. INHERIT the Protocol instead. That is the idiom in this image -# (LagunaForCausalLM, MiMoV2FlashForCausalLM and DFlashLagunaForCausalLM all list -# SupportsEagle3 among their bases) and it brings the flag, SupportsEagleBase's -# has_own_lm_head/has_own_embed_tokens, AND working non-stub defaults for both methods. +# IS A REQUIRED MEMBER for runtime-checkable presence-based isinstance, so v1 +# (methods only) failed identically. BUT v2 (inheriting the Protocol) taught the +# sharper lesson: adding SupportsEagle3 to Glm5NextForCausalLM's bases passes +# isinstance and then dies at class creation with +# "Cannot create a consistent method resolution order (MRO) for bases ..." +# -- because GLM's outer wrapper already inherits vLLM Protocols that are NOT +# Protocol-derived mixins in a compatible order. The fix that avoids the MRO +# entirely: declare the flag as a class attribute on the wrapper: +# supports_eagle3: ClassVar[Literal[True]] = True +# which satisfies presence-based isinstance without touching the MRO, and pairs +# with the EagleModelMixin on the trunk that supplies the real aux-layer plumbing. +# (SupportsEagleBase's has_own_lm_head/has_own_embed_tokens default to False, which +# is what a wrapper that delegates embed/lm_head to its trunk wants.) # * interfaces.py:1673-1719 -- the inherited defaults unwrap # `holder = getattr(parent_ref, "model", parent_ref)`, assert # `isinstance(holder, EagleModelMixin)`, set `holder._set_aux_hidden_state_layers`, and @@ -50,12 +57,12 @@ # # TARGET: vllm/models/glm5next/common/model.py (inside the pinned image) # base sha256 008eeaa2a07e091465319f86900b5a321d921238723ccbe22e6b9e971e1d2b28 -# patched sha256 5eea89c51d4ab37ef823526286b5103e39996802ca08aa1934f6373fc4728062 +# patched sha256 4c9a632b5173fdefe0672b810b54f91b88ed65decf0f4a76fde92527970bee8e # # APPLY: `patch -p1` from the vllm package root, or bind-mount the patched file over # site-packages (which is what a scratch-launcher DFLASH_PATCH=1 does). ---- a/vllm/models/glm5next/common/model.py -+++ b/vllm/models/glm5next/common/model.py +--- orig/vllm/models/glm5next/common/model.py 2026-09-30 15:57:08.910029614 -0700 ++++ new/vllm/models/glm5next/common/model.py 2026-09-30 17:04:20.104521484 -0700 @@ -95,6 +95,12 @@ logger = init_logger(__name__) @@ -103,17 +110,12 @@ return hidden_states def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: -@@ -935,7 +950,12 @@ - - +@@ -937,6 +952,8 @@ class Glm5NextForCausalLM( -- nn.Module, HasInnerState, SupportsPP, MixtureOfExperts, IsHybrid -+ nn.Module, -+ HasInnerState, -+ SupportsPP, -+ MixtureOfExperts, -+ IsHybrid, -+ SupportsEagle3, + nn.Module, HasInnerState, SupportsPP, MixtureOfExperts, IsHybrid ): ++ supports_eagle3: ClassVar[Literal[True]] = True ++ def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__() + self.model_config = vllm_config.model_config