Repository navigation
perf(moe): split hybrid decode routes inside the ensure kernel - #685
Merged
Merged
Conversation
3 of 10 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
After
_ensure_experts_hybrid_kernelrewrites a layer's routes to cache slots, hybrid decode built the GPU and CPU inputs with torch ops on every MoE layer: a clone of the ids, a>= 0compare, twotorch.where, aclamp_min(0)for MoE kernels withoutsupports_inactive_slots, and withcollect_statsthree sums and eight in-place adds inrecord_decode_stats_hybrid. The ensure kernel now does this in the same launch:CLAMP: CPU routes get slot 0 instead of -1 when the GPU kernel reads every route's slot.STATS: the hybrid missing / fetched / active / calls counters and their per-layer copies. Thestat_*tensors become views of one buffer, so the kernel takes them as two pointers;decode_miss_statsanddecode_miss_stats_per_layerread them as before.ensure_experts_hybridnow takes the router weights and returnsHybridRoutes(gpu_slots, gpu_w, cpu_ids)._decode_hybridis its only caller, so the path without the split goes away:record_decode_stats_hybrid, the CPU reference_ensure_experts_hybrid_cpu, the two tests intests/moe/test_hybrid_fetch.pythat drove the kernel without the split, and the split-rule test there that only checked its own reference helper are removed.This is independent of #670. Both change
_decode_hybrid, in different hunks; a trial merge of the two branches merges without conflicts.Validation
H100 80GB HBM3, Xeon Platinum 8480+, torch 2.14.1+cu130.
tests/): the same 300 random decode steps (3 layers, 32 experts, 40 slots, top-8, batch 1 and 4, fetch fraction 0.5, clamp on and off, fp32 and bf16 weights) through main's torch split withrecord_decode_stats_hybridand throughHybridRoutes, in two processes. GPU slots, CPU ids, GPU weights,slot_for_idandid_of_slotare equal after every step; the totals and per-layer stats are equal at the end.tests/moe tests/engine/test_moe_cpu_layers.pyon 930cc18: 155 passed, 6 skipped. Main gives 157 passed on this machine; the difference is the two removed tests. 47aa1a1 then drops one more test, which ran only Python code; the 2 tests left intests/moe/test_hybrid_fetch.pypass.bench_decode_moe.py --backend hybrid --greedy --decode 512 --cache-rate 0.25, ABBA against main (9c635a1), tok/s, measured on the first commit (13a4887):Output text sha1 matches main in every run. On the final commit, one Qwen3.6-35B-A3B-FP8 hybrid run decodes at 111.08 tok/s with the same output sha1.
tests/e2e/test_aime.pywith AIME25 problem 1 and the hybrid strategy passes on both models;moe_collect_statson, the texts,decode_miss_statsanddecode_miss_stats_per_layerequal main's; with the cpu strategy the texts equal main's;bench_decode_moe.py --backend cpu,hybrid --greedy --decode 512 --cache-rate 0.25): output sha1 matches main's for hybrid and 51afda3's (the base of refactor(cpu-moe): split the executor into weight formats and gpu sync backends #670) for cpu on both models.Not covered: ROCm.