Repository navigation
[#20540][perf] Kimi K3 MoE decode: router GEMM and routing kernel on a router stream - #20541
Draft
lucifer1004 wants to merge 2 commits into
Draft
lucifer1004 wants to merge 2 commits into
lucifer1004 wants to merge 2 commits into
Conversation
…to its own op trtllm::mxe2m1_moe_routing runs the routing kernel of mxe4m3_mxe2m1_block_scale_moe_runner into a workspace from trtllm::mxe2m1_moe_routing_workspace; the runner's run_moe_routed takes that workspace and skips its own routing (get_tile reports the tile the workspace must be computed for). The Python op records the tile and routing inputs per (gemm1 weights, num_tokens) and, with KIMI_K3_MOE_PRE_ROUTING=1, takes a pre-routing launched on another stream after joining its event; it routes itself when anything differs. Signed-off-by: Zihua Wu <13583761+lucifer1004@users.noreply.github.com>
… router stream With KIMI_K3_MOE_ROUTER_STREAM=1, multi-stream decode runs the router GEMM on its own stream beside the latent down projection, and the shared experts start after it on the shared stream. With KIMI_K3_MOE_PRE_ROUTING=1 the routing kernel of the MXFP4 TRTLLM-Gen MoE also runs on the router stream and the MoE op joins it after quantizing its input. Signed-off-by: Zihua Wu <13583761+lucifer1004@users.noreply.github.com>
This was referenced Oct 19, 2026
This branch has not been deployed
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.
Description
Fixes #20540.
Kimi K3 decode with the MXFP4 TRTLLM-Gen MoE ran the router GEMM, the latent down projection, the input quantization, the routing kernel and FC1 / FC2 in order on the main stream. This PR lets the router GEMM and the routing kernel run on their own stream. Both are opt-in for now.
Commit 1: routing as its own op (
mxFp4BlockScaleMoe.cpp,trtllm_gen_custom_ops.py,cpp_custom_ops.py)trtllm::mxe2m1_moe_routing_workspaceallocates the routing outputs that FC1 / FC2 / finalize read.trtllm::mxe2m1_moe_routingruns the same routing kernel the runner runs, on the current stream.run_moe_routed, which takes that workspace and skips its routing, andget_tile, which reports the tile the workspace must be computed for. The runner checks that tile.mxe4m3_mxe2m1_block_scale_moe_runner(KIMI_K3_MOE_PRE_ROUTING=1):mxe2m1_pre_routing_prepare/mxe2m1_pre_routing_launchlet a caller launch the routing on another stream for a recorded shape;KIMI_K3_MOE_PRE_ROUTING_MAX_TOKENS(default 8) limits pre-routing to small decode batches.Commit 2: Kimi K3 MoE router stream (
modeling_kimi_linear.py,utils.py)KIMI_K3_MOE_ROUTER_STREAM=1, the model creates one more aux stream (AuxStreamType.MoeRouter).KimiK3MoERuntimethen uses_forward_router_streamin multi-stream decode when none of the latent stream, deferred shared all-reduce or fused router+down projection applies (those are CuteDSL / MegaMoE configurations):_reduce_routed_latentand used by both paths.Performance, Rubin, TP8 across 2 nodes (MNNVL), Kimi K3 with speculative decoding, MoE TP8, CUDA graphs, single request, decode step time. Measured with the same code on our integration branch:
Outputs are byte-identical for the router stream alone. With pre-routing, MoE outputs are bit-identical to the op routing itself, and our accuracy gates were unchanged.
Moving the routing alone, with the shared experts still behind it on one stream, was neutral to slightly negative in a whole-layer microbenchmark: the shared GEMMs then overlap FC1 / FC2. That is why the shared experts start on their own stream. Above 8 tokens per rank the same contention made pre-routing slower, hence the default token limit.
Relation to other work:
Open design question: the hand-off from the model to the op goes through module-level dicts keyed by the expert weight pointer, so the MoE / ConfigurableMoE call signatures stay unchanged. Passing the prepared routing explicitly through
ConfigurableMoE.forwardwould be cleaner. Happy to change it if reviewers prefer that.Test Coverage
tests/unittest/_torch/thop/serial/test_moe_mxe2m1_pre_routing.py(SM100 family; collected by theunittest/_torch/thop/serialentries ofl0_b200.yml/l0_b300.yml):tests/unittest/_torch/modeling/test_kimi_linear_modeling.py(CPU): the router stream is a separate aux stream when enabled. The existing registry test covers the default.test_moe_mxe2m1_pre_routing.py: 16 passed, 0 skipped (on main: the ops do not exist);test_kimi_linear_modeling.py: 3 passed (on main the new test fails);test_custom_ops.py -k test_register_fake: passed (both new ops have fake implementations).PR Checklist