[Common][PyTorch] Add QB router histogram paths - #3395
Open
harryzhou2000 wants to merge 4 commits into
Open
Conversation
Signed-off-by: Harry Zhou <hhanyu@nvidia.com>
Contributor
Greptile SummaryThe PR adds opt-in Quantile Balancing to the fused sigmoid MoE router, including Top-(k+1) cutoff selection and caller-owned histogram accumulation.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant Python as PyTorch router
participant Binding as C++ binding
participant Core as CUDA router
participant Histogram as Caller histogram
User->>Python: fused_topk(..., QB arguments)
Python->>Python: validate/cache bin bounds
Python->>Binding: QB forward
Binding->>Core: Top-(k+1) sigmoid routing
Core->>Core: retain Top-k and derive cutoff
Core->>Histogram: accumulate expert/bin counts
Core-->>Binding: probabilities and routes
Binding-->>User: probabilities and routing output
Reviews (4): Last reviewed commit: "[Common][PyTorch] Validate QB bounds in ..." | Re-trigger Greptile |
Signed-off-by: Harry Zhou <hhanyu@nvidia.com>
Signed-off-by: Harry Zhou <hhanyu@nvidia.com>
Signed-off-by: Harry Zhou <hhanyu@nvidia.com>
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
Add opt-in Quantile Balancing (QB) support to the fused sigmoid router used by
Kimi-K3-style MoE models. The router now has statically dispatched QB specializations that
select Top-(k+1), retain the actual Top-k routes, and accumulate the per-expert histogram
needed by the QB bias update without materializing a
[num_tokens, num_experts]bin-indextensor.
The existing non-QB specialization and API behavior are unchanged when the three QB
arguments are omitted.
Type of change
Quantile Balancing math
This implementation follows the
Kimi K3 Technical Report, Section 2.3.3, Eqs. (13)-(14), and Appendices C-D.
Let
mbe the number of tokens in the global training step,Ethe number of experts, andkthe number of experts routed per token. Perfect balance gives every expert the targetload
The exact derivation assumes
qis integral and that cutoff ties do not occur; the practicalhistogram recovery below uses
ceil(q), and TE supplies deterministic cutoff tie handling.Routing and the token-side cutoff
For token
iand expertj, the raw router score and biased selection score at steptareThe bias is used only for expert selection. Mixture weights omit it, as in report Eq. (13):
To derive the next bias, QB selects
Top-(k+1)underu^(t). The firstkexperts are theactual routes; the
(k+1)-th score is the token-side cutoffAn expert must exceed
alpha_i^(t)to enter tokeni's Top-k. The report assumes no ties.This implementation makes ties deterministic by discarding the largest expert ID among equal
cutoff candidates, leaving exactly
koutput routes.Expert-side quantile update
Hold the cutoffs from the current forward pass fixed and consider a candidate next-step bias
bhat_j^(t+1). Its implied load for expertjisSetting this count to
qmeans exactlyqvalues of the marging_ij = s_ij - alpha_i^(t)exceed-bhat_j^(t+1). Therefore report Eq. (14) givesAppendix D expresses the same update using the required bias
Indeed,
s_ij + bhat_j^(t+1) > alpha_i^(t)iffbhat_j^(t+1) > r_ij.Negating the margin reverses its ordering, so the update is equivalently
This explains both QB-specific router operations. Top-(k+1) exposes the token's current
competition boundary, while subtracting the raw score converts that boundary into the exact
bias threshold for each token/expert pair. A histogram of raw scores alone would discard the
token-local boundary created by the competing experts.
In particular, the histogram quantity is
alpha_i - s_ij, notalpha_i - (s_ij + b_j):alpha_iis a biased cutoff, buts_ijis the raw sigmoid score.An underloaded expert consequently receives a relatively larger recovered bias, while an
overloaded expert receives a smaller one.
The report mean-centers the recovered biases,
because adding one common constant to every bias shifts every biased score and cutoff equally
and does not change Top-k. The update takes effect only in the next training step, so the
batch is never routed with a bias derived from itself.
Histogram approximation
The exact update would retain
m * Erequired biases. Instead, forBuniform bins withbounds
[L, U], this PR accumulatesAppendix D proves a natural per-step range. Since sigmoid scores are in
(0, 1)and thecutoff is one current biased score,
The report uses
B=1000, all-reduces the per-expertH[E, B]counts once per step, selectsthe first bin whose cumulative count reaches
ceil(q), and interpolates within it. Ifbeta_jis that bin's zero-based index,c_jis its preceding cumulative count,h_jis itsown count, and
w = (U-L)/B, Appendix D recoversThe result is then mean-centered. Its quantile error is bounded by one bin width. Counts
accumulate exactly across ranks and microbatches, so this recovers the pooled-global-batch
quantile rather than an average of per-rank quantiles.
TE receives
[L, U]as a caller-owned CUDA tensor and only performs Top-(k+1), exact Top-koutput, and local histogram accumulation. Histogram all-reduce, within-bin interpolation,
bias update/centering, and next-step bounds update remain caller responsibilities.
Changes
NVTEQBHistogramModeand C/PyTorch entry points for QB routing.qb_histogram,qb_bin_bounds, andqb_histogram_modeare all provided.are non-differentiable, while selected sigmoid probabilities use the existing gradient.
forward/backward parity, deterministic cutoff ties, bin clamping, accumulation across
microbatches, and argument validation.
Histogram implementation choices
two_kernelwrites one FP32 cutoff per token. A second kernel rereads the existing FP32 rawscores, accumulates eight experts' bins in shared memory per CTA, and issues global atomics
only for nonzero shared bins. With
B=1000, its dynamic shared-memory footprint is about32 KB per CTA. This mode adds a launch, a
4 * num_tokens-byte cutoff buffer, and a read ofthe
[T, E]score tensor, but substantially combines contended updates before global memory.fused_atomickeepsalpha_iin the router warp and directly issues one global int32 atomicper token/expert pair in the router epilogue. It avoids the cutoff store, second launch, and
score reread, but global contention can become configuration-dependent. The caller-owned
histogram is only
4 * E * Bbytes (3.584 MB for 896 experts and 1000 bins); neither modecreates a
4 * T * E-byte bin-index buffer.Both are compile-time QB specializations, so ordinary routing does not execute QB conditionals,
Top-(k+1), or histogram atomics.
Performance
Measured on an NVIDIA B300 SXM6 AC with the NVIDIA PyTorch 26.06 container,
nvidia-cutlass-dsl==4.5.0, andnvidia-cudnn-frontend==1.26.0. Each case uses896 experts, Top-16, 1,000 histogram bins, FP32 logits, 100 warmups, 500 timed calls per
sample, and ten CUDA-event samples. The table reports median latency in milliseconds.
The fused-atomic implementation takes 7.3% to 20.9% of the PyTorch QB latency
(4.8x to 13.6x faster). Relative to TE's existing no-QB router, the QB feature costs
18.0% to 34.8%; this includes both Top-(k+1) selection and histogram atomics. Relative to
the two-kernel QB path, fused atomic is 0.7% to 23.3% faster in every measured case. The
two modes are retained because larger expert/bin counts or different score distributions can
change global-atomic contention.
The performance comparison includes four implementations: the pure-PyTorch QB reference,
the existing TE router without QB, QB
two_kernel, and QBfused_atomic. Every case checksroute, probability, and histogram correctness before timing. The TE-no-QB comparison isolates
the feature cost; the PyTorch-QB comparison shows the value of avoiding framework-level
intermediates and launches.
Validation
The focused QB matrix passes:
The entire fused-router test file passes:
The same B300 run also passed an actual CUDA tensor smoke test and confirmed that the loaded
extension exports both QB modes and all three opt-in Python arguments. Targeted pre-commit
checks (Python formatting, clang-format, whitespace, EOF, merge-conflict, large-file, and
Python-version checks) pass on the seven changed files.
Build configuration:
Checklist