From 7560d40543f7504bafd3fe289041d3ab05db2c3e Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 30 Sep 2026 17:24:56 -0700 Subject: [PATCH] patches: glm53-dflash-01 v4 -- all three SupportsEagle3 members on the wrapper The v4 window boot named the real presence-check rule: isinstance against a runtime_checkable Protocol walks __protocol_attrs__ (which includes members inherited from BASE protocols) and getattr_static()s each one off the instance, breaking on the first missing attribute. SupportsEagleBase declares has_own_lm_head/has_own_embed_tokens as plain instance-var annotations, so v3's bare supports_eagle3 flag still failed. Replicated in-image with stock typing: flag-only class -> False; flag + the two base members -> True. v4 declares all three on Glm5NextForCausalLM: supports_eagle3: ClassVar[Literal[True]] = True has_own_lm_head: bool = False has_own_embed_tokens: bool = False (False is correct for the two: the wrapper delegates embed/lm_head to its trunk. The MRO-safe attribute path is kept from v3.) base 008eeaa2... -> patched 60f27aad..., apply-verified against the pinned image (patch -p1 reproduces the sha256 and matches the mounted file). --- .../glm53-dflash-01-aux-hidden-states.patch | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/scripts/patches/glm53-dflash-01-aux-hidden-states.patch b/scripts/patches/glm53-dflash-01-aux-hidden-states.patch index 88933ff..aaba9eb 100644 --- a/scripts/patches/glm53-dflash-01-aux-hidden-states.patch +++ b/scripts/patches/glm53-dflash-01-aux-hidden-states.patch @@ -29,8 +29,16 @@ # 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.) +# CAUGHT LATE BY ANOTHER BOOT: the presence check walks ALL `__protocol_attrs__` +# INCLUDING base-protocol members (typing._ProtocolMeta.__instancecheck__ loops +# `getattr_static(instance, attr)` over every member and breaks on the first +# AttributeError). SupportsEagleBase declares `has_own_lm_head: bool = False` and +# `has_own_embed_tokens: bool = False` (plain instance-var annotations), so the +# flag ALONE still fails isinstance -- replicated in-image with stock typing +# (flag-only class -> False; flag + the two base members -> True). v4 therefore +# declares all three on the wrapper: supports_eagle3, has_own_lm_head, +# has_own_embed_tokens. False is the right value for the two: the wrapper +# delegates embed/lm_head to its trunk. # * 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 @@ -47,7 +55,8 @@ # carries the already-summed single-stream state -- its non-mHC branch re-splits # `residual = hidden_states` inside the layer -- so this is the equivalent of # deepseek_v2's `hidden_states + residual`); the conditional tuple return; and -# SupportsEagle3 among Glm5NextForCausalLM's bases. +# the three SupportsEagle3 member attributes on Glm5NextForCausalLM (the flag plus +# SupportsEagleBase's two defaults). # # HONEST SCOPE: this makes the interface PRESENT, which is exactly what the engine # checks -- it does not make drafts GOOD, and per the measured profile it is not a @@ -57,12 +66,12 @@ # # TARGET: vllm/models/glm5next/common/model.py (inside the pinned image) # base sha256 008eeaa2a07e091465319f86900b5a321d921238723ccbe22e6b9e971e1d2b28 -# patched sha256 4c9a632b5173fdefe0672b810b54f91b88ed65decf0f4a76fde92527970bee8e +# patched sha256 60f27aad36ab9610d335bd0d9a2e177d8e26b6af1e81b3a31adf5f5cca8cab68 # # 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). --- 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 ++++ new/vllm/models/glm5next/common/model.py 2026-09-30 17:22:36.124257958 -0700 @@ -95,6 +95,12 @@ logger = init_logger(__name__) @@ -110,11 +119,13 @@ return hidden_states def load_weights(self, weights: Iterable[tuple[str, torch.Tensor]]) -> set[str]: -@@ -937,6 +952,8 @@ +@@ -937,6 +952,10 @@ class Glm5NextForCausalLM( nn.Module, HasInnerState, SupportsPP, MixtureOfExperts, IsHybrid ): + supports_eagle3: ClassVar[Literal[True]] = True ++ has_own_lm_head: bool = False ++ has_own_embed_tokens: bool = False + def __init__(self, *, vllm_config: VllmConfig, prefix: str = ""): super().__init__()