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: |
|
|
||
| } // namespace | ||
|
|
||
| void invokeStepInputsScatter(uint8_t const* stage, cudaStream_t stream) |
There was a problem hiding this comment.
shall these 2 also be put into minimaxM3 folder?
There was a problem hiding this comment.
Done in dcdbd8c: stepInputsScatter.{cu,h} are now in kernels/minimaxM3/.
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 |
There was a problem hiding this comment.
I am wondering shall we put these m3 specific torch ops into thop/minimaxM3?
Easy to manage the review rules and changed based testing.
There was a problem hiding this comment.
Done in dcdbd8c: all MiniMax-M3 torch ops, including stepInputsScatterOp.cpp, are now in thop/minimaxM3/, which adds them to th_common_attention from its own CMakeLists.txt (like thop/moe/).
|
|
||
|
|
||
| @dataclass(frozen=True) | ||
| class RuntimeFacts: |
There was a problem hiding this comment.
@WeiHaocheng could you help to take a look at this one?
There was a problem hiding this comment.
We can directly use the 'def route(pretrained_config, mapping, compute_capability, spec_config, kv_cache_quant_algo)' function interface here.
| @@ -418,6 +418,60 @@ def _( | |||
| return scores.new_empty((scores.shape[2], scores.shape[0], topk), | |||
| dtype=torch.int32) | |||
|
|
|||
| @torch.library.register_fake("trtllm::step_inputs_scatter") | |||
There was a problem hiding this comment.
I think we should register these under the modeling_v2 m3 speficif folder since its only used there.
There was a problem hiding this comment.
Done in dcdbd8c: the fake impls moved to modeling_v2/models/minimax_m3/fake_ops.py, imported by the M3 package, pyexecutor/step_inputs.py and the fake-registration test.
|
PR_Github #78786 [ run ] completed with state
|
|
PR_Github #79048 [ run ] completed with state
|
…ares is_spec_decode DecoderRunner reads DecoderRunnerConfig.is_spec_decode at construction (the spec step fold binds the engine buffers). The compiled-body validation test builds the runner from a SimpleNamespace config; give it the field the real config always has. Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
Resolve the modeling_v2 router against NVIDIA#20267: route() now takes the resolver's KV-cache algorithm as its fifth argument for every routing module, and modules that set ROUTES_ON_RUNTIME (MiniMax-M3) still receive runtime=RuntimeFacts; the MiniMax-M3 route() accepts the new argument. Keep both sides' new helpers (RuntimeFacts / resolved_mode and tp_reaches_across_nodes) and both test-list additions. Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #79124 [ run ] triggered by Bot. Commit: |
|
PR_Github #79124 [ run ] completed with state
|
|
For the new Minimax M3 kernels, please move them to the Minimax directory under modeling_v2 (you can add a csrc/ folder for the C++/CUDA sources). Shared kernels for TP4/TP8 belong in models/minimax_m3, while target-specific kernels should reside in their respective target folders. In short, new ops should be scoped to the level where they take effect rather than dumped into generic modules. |
Resolve the MiniMax-M3 index-score kernels against NVIDIA#19275 (c146094), which split cute_dsl_kernels/ into the domain kernel trees: the TP4 and TP8 m3_index_score imports now take cute_ptx_utils and utils from tensorrt_llm._torch.kernels.blackwell, and the docstring points at attention/kernels/blackwell/minimax_m3_index_decode_score.py. Both moved modules are unchanged (pure renames). Signed-off-by: peihengh <259410613+peihu-nv@users.noreply.github.com>
|
/bot run --disable-fail-fast |
|
PR_Github #79261 [ run ] triggered by Bot. Commit: |
| alpha: Optional[float], | ||
| beta: Optional[float], | ||
| ) -> torch.Tensor: | ||
| return torch.ops.trtllm.silu_and_mul( |
There was a problem hiding this comment.
For model-specific ops implemented in C++/CUDA, a simple pybind is sufficient; they don't necessarily need to be bound as 'torch.ops.trtllm.x'.
| """Fixed M3 H6144 gather/raw residual/RMS, reusing pinned K3 norm kernel. | ||
|
|
||
| 128 threads x 8 BF16 x 6 iterations covers the row. Unlike the original | ||
| K3 wrapper this target does not promise FlashInfer's bit-identical reduction. |
There was a problem hiding this comment.
Please move the code under 'tensorrt_llm/_torch/_experimental/modeling_v2/models/minimax_m3/minimax_m3_nvfp4__sm_103__tp4/kernels/' to the 'ops' directory at the same level.
| captured = getattr(spec_config, "eagle3_layers_to_capture", None) | ||
| checks = ( | ||
| ( | ||
| cfg.get("num_hidden_layers") == 1, |
There was a problem hiding this comment.
Adding so many model architecture checks in the routing logic is unnecessary. The fact that this interface is invoked already guarantees that the model architecture is Minimax M3. These checks are essentially guarding against scenarios that will never happen.
| checkpoint's config, the parallel mapping, the GPU's compute capability and | ||
| the speculative-decoding config. It returns the target class, or raises | ||
| the speculative-decoding config (and, for a module that sets | ||
| ``ROUTES_ON_RUNTIME``, the engine arguments in :class:`RuntimeFacts`). It |
There was a problem hiding this comment.
This line is also can be deleted.
|
PR_Github #79261 [ run ] completed with state
|
|
/bot run --disable-fail-fast |
|
PR_Github #79375 [ run ] triggered by Bot. Commit: |
|
PR_Github #79375 [ run ] completed with state
|
|
/bot run --disable-fail-fast |
|
PR_Github #79618 [ run ] triggered by Bot. Commit: |
@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