From e044277d8b2d00fc511fa255a432351edf39f0a3 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 30 Sep 2026 17:08:50 -0700 Subject: [PATCH] patches: glm53-dflash-01 v3 -- declare supports_eagle3 as a class attribute v2 (inheriting SupportsEagle3 as a base) taught the real lesson: the isinstance check PASSES and the class then dies at creation with 'Cannot create a consistent method resolution order (MRO) for bases ...' -- GLM's outer wrapper already inherits vLLM Protocols (SupportsPP, MixtureOfExperts, HasInnerState, IsHybrid) whose ordering is incompatible with appending another Protocol base. v3 avoids the MRO entirely: declare supports_eagle3: ClassVar[Literal[True]] = True as a class attribute on Glm5NextForCausalLM. Runtime-checkable Protocols do presence-based isinstance, so the bare flag satisfies supports_eagle3(model) without touching the MRO. The aux-layer plumbing stays on the trunk via EagleModelMixin. base 008eeaa2... -> patched 4c9a632b..., apply-verified against the pinned image (patch -p1 reproduces the sha256 and matches the mounted dflash-patch file byte for byte). --- .../glm53-dflash-01-aux-hidden-states.patch | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) 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