DFlash2: fetched incoai/GLM-5.3-Flash-DFlash2 (2,342,169,800 B, sha256 matches the
Hub LFS oid) and tried --speculative-config {"method":"dflash","model":"/draft"}.
Config and drafter are accepted; the worker dies with 'Model does not support
EAGLE3 interface' - so the only gap is the target-side aux-hidden-state contract
(set_aux_hidden_state_layers + per-layer capture + the two-value forward return,
as deepseek_v2.py demonstrates twice in this image). Recorded the exact interface,
the GLM-specific unknown (what the single-stream state entering layer k means for
an mHC multi-stream trunk) and the honest expectation: no speedup on a
token-proportional pointwise bound.
fp8 KV: recorded the deciding measurement - the fork's KV reserve model is
dtype-blind (the fp8 boot printed the identical 1760 MiB / 13600 B-per-token plan),
so fp8 cannot buy capacity even if the gfx12 MLA path were rewritten. Verdict: do
not spend effort there.
Compile blocker narrowed from 'a latent GLM bug' to dynamo's name map: the
KeyError is thrown by torch/_dynamo/output_graph.py's nn_modules lookup (:3000,
registered :1259/:1384, _modules[..] prefixes stripped :1225), i.e. the compiler
cannot resolve a submodule by name while tracing the decoder layer. Next step is
TORCHDYNAMO_VERBOSE=1, with the note that the scratch launcher resets ENVARGS.
tests/run.sh: 362 seams pass.
80 lines
4.7 KiB
Diff
80 lines
4.7 KiB
Diff
# glm53-compile-03-fullgraph-optout.patch — let torch.compile split the graph instead
|
|
# of failing on a break.
|
|
#
|
|
# STATUS: WIP — third of three patches in the "compile the GLM trunk" changelist.
|
|
# With 01+02+03 the model TRACES, then hits the NEXT blocker (below). The set does not
|
|
# yet boot the engine; nothing in scripts/ mounts it.
|
|
#
|
|
# THE BREAK: with 01+02 mounted the worker dies with
|
|
#
|
|
# RuntimeError: Graph breaks are not supported with aot compile.
|
|
# Please use torch.compile(fullgraph=True).
|
|
#
|
|
# because vllm/compilation/wrapper.py calls torch.compile(..., fullgraph=True, ...) and
|
|
# this build has AOT compile on by default (VLLM_USE_AOT_COMPILE). The GLM trunk cannot
|
|
# satisfy fullgraph: its indexer metadata path syncs to the host —
|
|
# models/glm5next/amd/sparse_indexer.py:263 int(positions[...].max().item()) + 1
|
|
# models/glm5next/amd/sparse_indexer.py:419 lmax = int(decode_metadata.decode_lens.max().item())
|
|
# — and a .item() inside a captured graph is not expressible.
|
|
#
|
|
# WHAT WAS VERIFIED (in-image, torch 2.11.0+rocm10.0, torch.compile(backend="eager")):
|
|
#
|
|
# fullgraph=True suppress_errors=False -> RAISE Unsupported
|
|
# fullgraph=True suppress_errors=True -> RAISE Unsupported <-- suppress_errors
|
|
# does NOT cover breaks
|
|
# fullgraph=False suppress_errors=False -> ok (traceable segments compiled by
|
|
# inductor, the rest runs eagerly;
|
|
# numerics unchanged)
|
|
#
|
|
# So breaks must be TOLERATED, not suppressed: the traceable mass still fuses. This
|
|
# patch makes the fullgraph requirement opt-out via VLLM_COMPILE_FULLGRAPH=0 (default 1,
|
|
# so every other model keeps stock behaviour), and the run also needs
|
|
# VLLM_USE_AOT_COMPILE=0 because AOT compile refuses breaks outright.
|
|
#
|
|
# TARGET: vllm/compilation/wrapper.py (inside the pinned image)
|
|
# base sha256 969961dca41c78385212e985cfc0c57ef067f4a2d7490c73c658c600a1b95cac
|
|
# patched sha256 732363bb1a1367772f13c60a655c678e7e2e9e56186677b14238f5e84cac31b3
|
|
# (the file already imports os; the patch does not add a second import)
|
|
#
|
|
# NEXT BLOCKER — NOT FIXED HERE. With 01+02+03 and
|
|
# R4D_GLM_COMPILE=1 VLLM_COMPILE_FULLGRAPH=0 VLLM_USE_AOT_COMPILE=0 the trunk traces
|
|
# ("Dynamo bytecode transform time: 1.08 s") and then the worker dies during profile_run
|
|
# on the decode forward:
|
|
#
|
|
# KeyError: 'in_proj_qkvbfg_a'
|
|
# model.py:748 Glm5NextModel.forward hidden_states, residual, post, comb = layer(...)
|
|
# model.py:456 Glm5NextDecoderLayer.forward
|
|
#
|
|
# `in_proj_qkvbfg_a` is the KDA layer's merged column-parallel projection
|
|
# (models/glm5next/common/kda.py:217, called at :407) — and it is also a name in the
|
|
# load_weights shard table (model.py:780-785), i.e. a real submodule attribute name,
|
|
# not an arbitrary string.
|
|
#
|
|
# WHERE IT IS THROWN (established 2026-09-30 by reading the full traceback, since the
|
|
# report line is inside dynamo-rewritten code): torch/_dynamo keeps a name -> module map
|
|
# and looks it up by name — output_graph.py:1259 / :1384 register into `nn_modules`,
|
|
# :3000 does `self.nn_modules[node.target]` (a bare-name KeyError when absent), and
|
|
# :1225 documents stripping "_buffers[..]/_parameters[..]/_modules[..]" from those
|
|
# names. So the compiler is failing to RESOLVE A SUBMODULE BY NAME while tracing the
|
|
# GLM decoder layer. Whether the root cause is the fork's module tree (something
|
|
# dynamo cannot register statically) or dynamo's own registration is NOT yet settled.
|
|
#
|
|
# NEXT DEBUG STEP: re-run with TORCHDYNAMO_VERBOSE=1 (torch offers it in the error
|
|
# itself: "Set TORCHDYNAMO_VERBOSE=1 for the internal stack trace") to get the internal
|
|
# frame that computed the name. NOTE the launcher gotcha that wasted one boot:
|
|
# /home/dank/serve_glm_autoround.sh RESETS ENVARGS (it is initialized empty near the
|
|
# top and only the COMPILE_PATCH branch appends), so an outer `ENVARGS=... bash ...`
|
|
# is silently dropped — add the var inside the script or to the branch itself.
|
|
--- a/vllm/compilation/wrapper.py
|
|
+++ b/vllm/compilation/wrapper.py
|
|
@@ fullgraph opt-out (env VLLM_COMPILE_FULLGRAPH=0) @@
|
|
+# FORK-LOCAL (patch: fullgraph opt-out). torch.compile(fullgraph=True) turns any
|
|
+# dynamo graph break into a hard failure; suppress_errors does NOT cover breaks
|
|
+# (verified in-image, torch 2.11+rocm10.0). With VLLM_COMPILE_FULLGRAPH=0 the
|
|
+# traceable segments are still compiled by inductor and the untraceable ones run
|
|
+# eagerly, which is what a model with device-sync metadata (the GLM-5.3-Flash
|
|
+# indexer) needs. Default 1 keeps stock behaviour for every other model.
|
|
+_FULLGRAPH = os.environ.get("VLLM_COMPILE_FULLGRAPH", "1") == "1"
|
|
- fullgraph=True,
|
|
+ fullgraph=_FULLGRAPH,
|