fix(vllm): support BF16 TRTLLM NCCL reshard refit - #3659
Conversation
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit 707968a)
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit cbd4138)
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit bda8858)
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit 2aa1570)
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit 4aece4b)
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit 1292dbe)
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit 56e27a8)
Signed-off-by: seonjinn <sna@nvidia.com> (cherry picked from commit 0c33c30)
…e-refit-pr-20260807 Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
…e-refit-pr-20260807 Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
…e-refit-pr-20260807
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
|
/ok to test 9d5a10a |
Signed-off-by: seonjinn <sna@nvidia.com>
|
/ok to test 2844542 |
|
Self-review completed against the latest
No unresolved correctness findings remain in the NCCL reshard extension. The PR remains draft because it includes and depends on #3545. |
|
Latest-main end-to-end validation completed at
This verifies the implementation on the current |
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
|
Mixed-scope validation update on
The combined mixed-refit stack also completed two colocated sync CUDA IPC runs with CUDA Graph on:
These end-to-end runs include the dependent sync-refit changes and are compatibility evidence, not PR #3659-only performance results. Nano caveat: its forward |
Signed-off-by: seonjinn <sna@nvidia.com>
|
/ok to test 96101df |
Signed-off-by: seonjinn <sna@nvidia.com>
@seonjinn, there was an error processing your request: See the following link for more information: https://docs.gha-runners.nvidia.com/cpr/e/2/ |
|
/ok to test 8eddc45 |
Signed-off-by: seonjinn <sna@nvidia.com>
|
/ok to test f20709b |
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
Signed-off-by: seonjinn <sna@nvidia.com>
|
/ok to test eb7529f |
Signed-off-by: seonjinn <sna@nvidia.com>
…erify-20260906 Signed-off-by: seonjinn <sna@nvidia.com> # Conflicts: # tests/test_suites/disabled.txt
Signed-off-by: seonjinn <sna@nvidia.com>
|
/ok to test 014a305 |
What this PR does
Makes weight refit work for BF16 MoE models running on the FlashInfer TRTLLM backend when using
refit_transport=nccl_reshard.Without this fix, a refit silently corrupts the MoE expert weights and the model generates garbage. With this fix, expert weights load correctly, and any configuration we cannot handle is rejected with a clear error instead of corrupting anything.
#3545 already fixed this for the
ipcandcollectivetransports. This PR extends the fix tonccl_reshard, which needs a different approach.The problem in one picture
nccl_reshardstreams every received tensor directly into vLLM's live parameter buffers. That is fast, and it is correct as long as the buffer stores the weight in the same layout as the checkpoint.The FlashInfer TRTLLM MoE backend breaks that assumption: at model load time, vLLM repacks the grouped expert weights (
gate/up/downprojections) into a private layout its kernels need. Streaming checkpoint-layout bytes into a repacked buffer writes the right numbers into the wrong places — no error, just a corrupted model.Why we can't just reuse the #3545 fix
#3545 fixes
ipc/collectiveby reloading the whole model through vLLM's normal weight loader (which knows how to repack). Butnccl_reshardreceives most weights directly into live buffers. A whole-model reload would reset all buffers back to checkpoint layout — including the dense/attention buffers that direct receive depends on and that were never broken. The fix must be surgical: touch only the expert weights.How the fix works
Split the weights into two groups and treat them differently:
For the expert weights, concretely:
[num_experts, ...]weight.experts.<expert_start + local_idx>.<proj>.weight). vLLM repacks it exactly like it does at model load.finalize()at the end rebuilds the kernel layout.When we refuse to refit (on purpose)
Two layouts cannot be mapped to "one named load per expert", so we reject them loudly at setup instead of guessing:
ValueErrorwhen the refit map is built.expert_placement_strategy != "linear", e.g. round-robin) →RuntimeError, because "global expert ID =expert_start + local_idx" would be wrong.And if anything fails after the expert buffers have been invalidated mid-refit, the worker is marked permanently unusable rather than serving a half-updated model.
What is NOT affected
Everything else is untouched: other MoE backends, other transports, quantized (FP8/MXFP8) paths, dense models.
vLLM version compatibility
The backend detection touches three vLLM internals, verified byte-identical at v0.25.1 (our current pin) and v0.28.0:
UnquantizedMoeBackend.FLASHINFER_TRTLLM,UnquantizedFusedMoEMethod.unquantized_backend, andExpertMapManager.placement_strategy. If a future vLLM moves them, the guarded imports degrade to "backend not detected" and the placement check raises — there is no silent-corruption path.How it was validated
Policy generation refit completed successfully,moe_backend=flashinfer_trtllm.pre-commitpasses.Dependency
#3545 has merged and this branch is synced with latest
main, so the diff here is only thenccl_reshardextension.