Skip to content

fix(models): compute shared experts before in-place routed experts - #463

Merged
jason-fxz merged 1 commit into
FlashML-org:mainfrom
taking-lying-flat:fix/glm-shared-expert-input
Sep 14, 2026
Merged

jason-fxz merged 1 commit into
FlashML-org:mainfrom
taking-lying-flat:fix/glm-shared-expert-input

Conversation

@taking-lying-flat

@taking-lying-flat taking-lying-flat commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

BF16 prefill and resident decode overwrite hidden_states with the routed expert output. GLM-4 MoE, GLM MoE DSA, GLM5 Next and MiniMax-M3 currently evaluate their shared experts afterwards, producing R(x) + S(R(x)) instead of R(x) + S(x).

Compute each shared branch before routed_forward, preserving the kernel's existing memory reuse, and document the input mutation contract on both routed entry points.

Local validation (the regression script is retained outside this PR):

  • The same tests give 16 failed, 8 passed on unmodified main (08d728d) and 24 passed with this change: 16 CPU cases with mutating/non-mutating expert implementations, and 8 real BF16 GPU cases covering resident prefill and decode against a PyTorch routed-expert reference.
  • NVIDIA RTX A1000 Laptop GPU (4 GiB), Intel Core i7-12800HX, NVIDIA driver 595.84, Ubuntu 26.04.1; PyTorch 2.11.0 and Triton 3.6.0.
  • Checkpoint: none; tiny randomly initialized blocks. Full-checkpoint parity was not tested.
  • git diff --check passes.

Exact local test command, run from the checkout's python/ directory:

uv run --no-project --python /tmp/freetoken-glm-shared-venv/bin/python python -m pytest /tmp/freetoken-glm-shared-validation/test_shared_expert_input.py -q --tb=short

@taking-lying-flat
taking-lying-flat force-pushed the fix/glm-shared-expert-input branch from 06db1f2 to 1cc51e3 Compare September 14, 2026 00:28
@jason-fxz

Copy link
Copy Markdown
Collaborator

Confirmed: fused_experts_impl writes the routed sum back into hidden_states (bf16 experts, resident both phases / offload prefill), so these four blocks fed R(x) to the shared expert; computing the shared branch first is the right minimal fix and the NVFP4/FP8 paths stay bit-identical. Merging.

@jason-fxz
jason-fxz merged commit e0886cc into FlashML-org:main Sep 14, 2026
@taking-lying-flat

Copy link
Copy Markdown
Contributor Author

Confirmed: fused_experts_impl writes the routed sum back into hidden_states (bf16 experts, resident both phases / offload prefill), so these four blocks fed R(x) to the shared expert; computing the shared branch first is the right minimal fix and the NVFP4/FP8 paths stay bit-identical. Merging.

How Can I. contact you

@jason-fxz

Copy link
Copy Markdown
Collaborator

email?

Confirmed: fused_experts_impl writes the routed sum back into hidden_states (bf16 experts, resident both phases / offload prefill), so these four blocks fed R(x) to the shared expert; computing the shared branch first is the right minimal fix and the NVFP4/FP8 paths stay bit-identical. Merging.

How Can I. contact you

@taking-lying-flat

Copy link
Copy Markdown
Contributor Author

email?

Confirmed: fused_experts_impl writes the routed sum back into hidden_states (bf16 experts, resident both phases / offload prefill), so these four blocks fed R(x) to the shared expert; computing the shared branch first is the right minimal fix and the NVFP4/FP8 paths stay bit-identical. Merging.

How Can I. contact you

yeap

@jason-fxz

Copy link
Copy Markdown
Collaborator

you can find it in my GitHub profile

danielamadori pushed a commit to danielamadori/DFlash-FreeToken that referenced this pull request Sep 15, 2026
nomanoma121 pushed a commit to nomanoma121/My-FreeToken that referenced this pull request Sep 16, 2026
… stack

Upstream FlashML-org#454 serves images on the Qwen families: requests carry MMItems whose placeholder rows
hold content pad ids (so the radix cache keys them by content), the tokenizer precomputes 3-axis
rope positions, and the engine encodes on the GPU from pinned host banks right before the LM
forward. Kai had its own image path (a CPU vision tower in the tokenizer worker, per-request
cos/sin tables, image prompts kept out of the prefix cache and scheduled alone). The two cannot
coexist -- they define Req, Batch, UserMsg and the rope differently -- so this merge takes
upstream's and removes Kai's: vision_cpu.py, mrope.py, tokenizer/mm_host.py,
tokenizer/qwen_vl_lite.py, the scheduler's _encode_multimodal and rope tables, the data:-only
image_url renderer, and their tests.

What Kai keeps is adapted to the new shape:
- --spec-mtp: the verify-window graph, the draft-head chain graph and the eager draft and
  check-step batches carry [3, n] rope positions (logical + the request's mrope_delta) on an
  mrope model; the draft head embeds the placeholder token where an image row's successor is a
  content pad id past the vocab.
- --prefill-mixer-pieces: a piece takes its columns of the 3-axis positions; an image chunk
  splits like a text one (its soft tokens are in the stream before the pieces run).
- --prefill-chunk-budget: the transient probe feeds 3-axis positions, like upstream's warmup.
- PLE on disk: the hash windows go through upstream's placeholder restore, the verify window's
  drafts included.
- The pipeline window, --dense-quant and --host-embedding config paths sit on upstream's
  active_encoders / hf_config stripping; the loader passes include_mtp and include_vision.
- A chunk checkpoint and --prefix-disk-cache no longer exclude image requests: their ids now
  name the image.

FlashML-org#462 fixes the W4A16_NVFP4 input_scale wait Kai had fixed in e4ffedf, more completely (it also
infers W4A16 from config_groups and skips a stored input_scale the scheme does not declare);
upstream's modelopt.py is taken as is and Kai's duplicate test is dropped. FlashML-org#463 does not touch a
model Kai runs (qwen3_5_moe and qwen4_exp already compute the shared expert first).

The merge base is upstream 9535656: the history rewrite of 2026-09-13 dropped GitHub's
signature from the previous sync's upstream commits, so git would otherwise take fb7f732.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
trcwebdesign pushed a commit to trcwebdesign/FreeToken that referenced this pull request Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants