Repository navigation
Conversation
|
/bot run |
|
PR_Github #77887 [ run ] triggered by Bot. Commit: |
|
PR_Github #77887 [ run ] completed with state
|
|
/bot run --disable-fail-fast |
|
PR_Github #77904 [ run ] triggered by Bot. Commit: |
|
PR_Github #77904 [ run ] completed with state
|
|
/bot run --disable-fail-fast |
… step-loop runtime hooks Adds the modeling_v2 target minimax_m3_nvfp4__sm_103__tp4 (GB300, TP4, Eagle3 one-model speculation) and the executor seams it opts into. - Runtime hooks (off unless a model declares them): packed step inputs, skipped unchanged H2D uploads, a private graph metadata pool, sampler greedy-token and step-fold paths, MSA runtime policy, and rank-merged autotuned tactics. Greedy-only outputs are kept only when nothing reads the logits (no guided decoder, non-empty batch). - TP4 decode target: fused attention with long-context selection, a pre-wait-staged NVFP4 QKV/indexer producer and index scorer, multicast all-reduce + RMSNorm boundaries with the MoE finalize folded in, MXFP8 GEMVs, CuTe DSL MoE engines, an exact greedy and sampled verify, a fused draft loop, and lossless 12-bit coded BF16 target and draft heads. - Explicit dispatch: every covered shape is a certified catalog cell; under modeling_v2: require a covered shape that cannot run raises. Every item is on by default with one constant that turns it off; no environment reads. - Numerics match stock up to summation order; the long-context selector breaks >1024-way score ties by its contract (smaller block). Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
Pick the row source explicitly, raise when neither logits nor greedy tokens are present, and assert logits before the fast greedy kernel. Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
Adds the modeling_v2 target minimax_m3_nvfp4__sm_103__tp8 (GB300, 8 ranks over two trays, tensor-parallel attention and experts, one-model Eagle3 or no speculation) and routes world = tp = moe_tp = 8 to it; the tp4 branch of the router is unchanged. - Decode path: the tp4 target's exact decode path at the TP8 geometry, plus the TP8 items: the 1..8-token MoE engine at expert width 384 (logits replicated 32x at <= 4 tokens), an 8-head one-launch long-context sparse decode staged before its grid wait at <= 8 rows, a fused index score + top-16 select for spans of <= 2 requests, the producer releasing its dependents on entry, the long-row select's early release at <= 8 rows, the TP8 MXFP8 GEMV table, fixed-tactic low-M BF16 GEMMs for the drafter linears, the drafter decode's KV split capped at 16K for one request, BF16 target and draft heads, and the drafter fc forked beside the verify head. - Isolation: the target imports nothing from the tp4 target; the MoE engine and the MX GEMV op it changes are its own copies inside the target. The two new kernels are compiled ops (cpp/tensorrt_llm/kernels/minimaxM3Tp8, trtllm::minimax_m3_tp8_*). A drift test pins the files copied unchanged from the tp4 target. - fmha/flashinfer_trtllm_gen.py applies a layer's KV-split cap (msa_decode.dense_decode_max_seq_len); a no-op unless a layer sets one. - Same contract as the tp4 target: every kernel a catalog entry with CELLS and a torch reference, dispatch.py listing each fast path's rows, a covered shape that cannot run raising under modeling_v2: require, kernels built before warmup, every item on by default with one constant to turn it off. - Numerics match stock up to summation order (BF16 heads and drafter, NVFP4 experts, MXFP8 projections). Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
CUtensorMap already carries its own alignment, which is stricter than 64 bytes in newer CUDA toolkits; clang-hosted nvcc rejects the weaker alignas with "alignment cannot be set to less than the default alignment" (SBSA build). Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
306e8da to
bb8674c
Compare
|
/bot run --disable-fail-fast |
|
PR_Github #77987 [ run ] triggered by Bot. Commit: |
|
PR_Github #77987 [ run ] completed with state
|
Resolve two additive conflicts with the Qwen4-exp modeling_v2 target by keeping both router entries and both routing tests. Port the sampler's greedy_tokens_usable to main's request_row_params after the TorchSampler strategy refactor (NVIDIA#20188) removed _request_strategy. Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
- Register fake implementations for the new step_inputs_scatter and MiniMax-M3 router, low-M GEMM, producer and allreduce-norm ops. - Give the warmup tests' stand-in engines the default runtime hooks the decoder runner now reads. - Leave the identity table unset in the piecewise-attention metadata mock. - Stub the eager K/V view resolution only while the runtime-policy fixture builds its manager, so the pool-view tests still exercise get_buffers. Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #78201 [ run ] triggered by Bot. Commit: |
|
PR_Github #78201 [ run ] completed with state
|
Restructure the minimax_m3_nvfp4__sm_103__tp4 and __tp8 targets into the flat layout the modeling_v2 exemplars use, with no change to what they compute. Each target owns its own copy of every file (the targets share no code): * modeling.py: the dispatch tables (FAST_PATHS, row ranges, miss/uncovered policy), the flat core, PrefillTarget / DecodeTarget, the one-model Eagle3 drafter and worker, the step fold, runtime hooks and the shell. The core selects the target on num_contexts alone: every pure generation step is DecodeTarget's (its decode kernels up to 48 tokens, its own generic layers for wider steps or embeddings), every step with context rows PrefillTarget's. The two targets share no body: each owns its layer, attention and MoE compositions, and its step_args is the one projection of the MSA metadata its forward reads (DecodeTarget states num_contexts=0 / num_ctx_tokens=0). Shared module-level code is limited to single-call op adapters that read no step metadata. * weights.py: the language-model and drafter weight tables (host-side TP slicing, consumed checkpoint keys released during the load; at TP8 the 4 KV / index heads are duplicated on rank pairs as the built-in loader does). * ops/: catalog entries with certified cells for every call the model makes; kernel wrappers route through their entries. The MSA and drafter attention entries carry a numeric reference and GPU tests that drive every cell against real caches and prepared metadata. * kernels/: the CuTe DSL GEMV, MoE engine and embedding+first-norm kernels move into each target (the old shared cute_dsl_kernels/minimax_m3 copy is removed); capacity annotations on every constant. * The legacy dispatch/layers/linears/runtime/spec_fold/spec_worker modules are removed; the unit tests are ported to the flat targets. * The unfused QKV / index projection runtime (fuse_qkv_index_projection=False, FP8 indexer, FP8 or NVFP4 main KV) runs as the built-in model does. Routing (models/minimax_m3/routing.py) now declines what the targets do not build or run, so modeling_v2="auto" falls back to the built-in model and "require" names the missed criterion: * Eagle3 drafters other than the targets' one-layer drafter (read from the drafter checkpoint's config.json). * Runtimes other than MSA with an FP8 indexer and an FP8 or NVFP4 main KV cache. The resolver hands routing modules that set ROUTES_ON_RUNTIME a RuntimeFacts (sparse attention config and the KV cache quantization the engine will run with); only MiniMax-M3 sets it. _validate_runtime stays as the backstop. Adds a whole-model accuracy test under modeling_v2="require" (GSM8K without speculation, and with one-model Eagle3 plus a chat-GSM8K acceptance probe), on the 4-GPU GB300 list (TP4) and the 2-node GB300 list (TP8). Bitwise identical to the previous targets on GB300 (tokens and per-step outputs on every rank, no speculation and Eagle3, fused and unfused projections, TP4 and TP8, including pure generation steps wider than the decode kernels' 48 tokens). Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
Resolve cache_manager.py: keep the decode shortcuts and pooled views, and the HND main KV storage with the strided NHD view from NVIDIA#20159. Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #78786 [ run ] triggered by Bot. Commit: |
|
PR_Github #78786 [ run ] completed with state
|
Conflicts: - sampler.py: the stable greedy path keeps the forward's greedy tokens (rows_cuda) and takes main's removal of the two-model d2t check and the d2t argument of fast_greedy_sample_kernel. Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #80708 [ run ] triggered by Bot. Commit: |
|
PR_Github #80708 [ run ] completed with state
|
Measured on GB300 with NVIDIA#20306's CI wheel (its MiniMax-M3 TP4 modeling_v2 target) against the built-in model in the same wheel, the gen worker's median device step time per decode iteration was 6.07 vs 10.44 ms at concurrency 1 and 47.48 vs 45.56 ms at concurrency 64. So the con1 lane sets `modeling_v2: auto`, and the con64 lane pins `off`. Main has no MiniMax-M3 route, so `auto` runs the built-in model today (same step time as with the option unset) and the lane picks the target up once it is on main. Signed-off-by: chenfeiz0326 <203214996+chenfeiz0326@users.noreply.github.com>
|
Automatically added "ci: full pre-merge approved" because this PR has satisfied the required GitHub review approvals. Unresolved review conversations and other required checks remain independent merge requirements. |
Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
…sh executor tests Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #80966 [ run ] triggered by Bot. Commit: |
Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #80996 [ run ] triggered by Bot. Commit: |
|
PR_Github #80966 [ run ] completed with state |
|
PR_Github #80996 [ run ] completed with state
|
@coderabbitai summary
Description
At small decode batches, a speculative MiniMax-M3 NVFP4 step on GB300 at TP4/TP8 is bound by many small kernels, the boundaries between them, and host work between CUDA graph replays. This PR adds two
modeling_v2targets for that configuration,minimax_m3_nvfp4__sm_103__tp4andminimax_m3_nvfp4__sm_103__tp8, plus the executor seams they need. It has two main parts: the TP4 target with the runtime hooks, and the TP8 target. The router picks the target for the matching checkpoint and hardware,modeling_v2: requiremakes it mandatory, and every kernel it adds is a catalog entry with a torch reference and unit tests.Step-loop runtime hooks
The hooks are
RuntimeHooksintensorrt_llm/_torch/pyexecutor/runtime_hooks.py; a model declares them throughruntime_hooks_of(model). Every hook defaults to off and no in-tree model declares one, so existing models are unchanged. There are nollm_argschanges.step_inputs.py, with thetrtllm::step_inputs_scatterop): copies made between replays are staged and issued as one upload plus one scatter. The scatter applies host copies first, then device copies, both in recording order.h2d_cache.py): metadata copies whose values the destination already holds are skipped.mxfp8_quantize_autotuned,flashinfer_mxfp8_gemm_cute_dsl, and asplit_kargument on the CuTe DSL index scorer.Greedy-only outputs (greedy tokens without logits) are kept only when nothing downstream reads the logits. An executor-side guided decoder turns them off.
The TP4 decode target
A pure generation step of up to 48 tokens runs a fused decode path. Prefill, mixed steps and wider steps take the generic layer path.
Explicit dispatch.
dispatch.pylists the row range each fast path serves. Every covered row count is a certified cell of the entry that serves it. Undermodeling_v2: require, a covered shape whose precondition is missing raises; it never falls back silently. Every item is on by default and has one constant that turns it off. The target reads no environment variables.Kernels. The kernels are compiled ops (
cpp/tensorrt_llm/kernels/minimaxM3,trtllm::minimax_m3_*) and CuTe DSL modules. Nothing compiles at runtime from source strings, and every compile happens before warmup.Numerics. Weights and activations keep stock M3's precisions; the drafter and both LM heads run in BF16 over the full vocabulary. Results differ from stock only by floating-point summation order, so at most a few BF16 units in the last place. The greedy verify reproduces stock's acceptance bit for bit, and the MoE-finalize adds the shared expert in stock's order.
One known difference: the long-context block selector breaks score ties toward the smaller block, as its contract says. The in-tree selector instead takes tied blocks in atomic arrival order when more than 1024 blocks tie exactly.
The one change outside the target and the executor seams is a small hook in
fmha/msa_decode.py. It lets a layer cap the dense decode's KV-split length, and it is a no-op unless a layer sets the cap.The TP8 decode target
minimax_m3_nvfp4__sm_103__tp8serves the same checkpoint on 8 GB300s across two trays (attention and experts both tensor-parallel 8). It runs the TP4 target's exact decode path at the TP8 geometry, plus:minimaxM3Tp8/sparseDecodeLc8), and index scoring fused with block selection for up to 2 requests (minimaxM3Tp8/fusedScoreSelect).The two targets are isolated. The TP8 target imports nothing from the TP4 target, owns copies of the MoE engine and MX GEMV it changes, and a drift test pins the files it copies unchanged. Outside the target, the TP8 part touches only
routing.py(the tp8 branch), the newminimaxM3Tp8kernels and their thop ops, and a two-line no-op hook infmha/flashinfer_trtllm_gen.pythat applies a layer's KV-split cap.Test Coverage
tests/unittest/_torch/modeling_v2/models/minimax_m3/minimax_m3_nvfp4__sm_103__tp4/: a torch-reference test for every catalog entry; dispatch tables vs certified cells; the require-mode raise; and exact-numerics tests of the verify and drafter against stock Eagle3. All 1156 pass on GB300.tests/unittest/_torch/(executor/,sampler/,speculative/,attention/sparse/msa/): all 548 pass on GB300.modeling_v2off):PR Checklist
Please review the following before submitting your PR:
PR description clearly explains what and why. If using CodeRabbit's summary, please make sure it makes sense.
PR Follows TRT-LLM CODING GUIDELINES to the best of your knowledge.
Test cases are provided for new code paths (see test instructions)
If PR introduces API changes, an appropriate PR label is added - either
api-compatibleorapi-breaking. Forapi-breaking, includeBREAKINGin the PR title.Any new dependencies have been scanned for license and vulnerabilities
CODEOWNERS updated if ownership changes
Documentation updated as needed
Update tava architecture diagram if there is a significant design change in PR.
The reviewers assigned automatically/manually are appropriate for the PR.
Please check this after reviewing the above items as appropriate for this PR.
GitHub Bot Help
To see a list of available CI bot commands, please comment
/bot help.🤖 Generated with Claude Code