Skip to content

[https://nvbugs/6483369][fix] Keep the engineer-confirmed one-line stale-waiver removal, and add a… - #17438

Open
trtllm-agent wants to merge 2 commits into
NVIDIA:mainfrom
tensorrt-cicd:repair-bot-bug6483369
Open

[https://nvbugs/6483369][fix] Keep the engineer-confirmed one-line stale-waiver removal, and add a…#17438
trtllm-agent wants to merge 2 commits into
NVIDIA:mainfrom
tensorrt-cicd:repair-bot-bug6483369

Conversation

@trtllm-agent

@trtllm-agent trtllm-agent commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Root cause: The deferred MoEAllReduce finalize kernel accumulated the top-k weighted expert sum in bf16, rounding after every one of the top_k terms, biasing DeepSeek-V3.2 routed-MoE hidden states (MMLU 87.2 → 61.866); already fixed in tree, but no test pinned the fp32-accumulation contract.
  • Fix: Keep the engineer-confirmed one-line stale-waiver removal, and add a self-calibrating regression test that asserts the kernel is closer to an fp32 reference than to a bf16-accumulating one.
  • Original test: pytest tests/integration/defs/accuracy/test_llm_api_pytorch.py::TestDeepSeekV32::test_nvfp4_multi_gpus_chunked_prefill[latency] -v
  • Automated fix generated by repair-bot

Test plan

  • Verify fix on the same GPU type as the original failure
  • Check for regressions in related tests

Links

Dev Engineer Review

  • Removed only the stale B300 DeepSeek-V3.2 chunked-prefill latency waiver for bug 6483369.
  • Added deterministic deferred-MoE inputs and a parameterized accumulation-precision regression test for top_k values 8 and 32.
  • The test checks that kernel output is closer to fp32 accumulation than dtype-rounded accumulation.
  • The existing deferred-MoE pattern test now uses the shared input helper.
  • No unintended public API changes or neighboring waiver changes were identified.

QA Engineer Review

  • Added test_moe_finalize_allreduce_accumulation_precision.
  • Added and reused make_moe_finalize_inputs.
  • Added run_moe_finalize_allreduce_accumulation_precision_op.
  • Removed the B300 DeepSeek-V3.2 chunked-prefill waiver from tests/integration/test_lists/waives.txt.
  • The new test is not listed in test-db/ or qa/.
  • Verdict: insufficient.

…cy] on B300

The MMLU drop (87.2 -> 61.866) came from the deferred MoEAllReduce finalize
kernel accumulating the top-k weighted expert sum in bf16, rounding after
every top_k term. Across DeepSeek-V3.2's routed MoE layers that rounding bias
drifts the hidden states far enough to lose accuracy without any crash.

That numerics bug was fixed upstream by 2801e94 ("[TRTLLM-14575][fix]
MoE: fp32 accumulation in deferred MoEAllReduce finalize", NVIDIA#16778), which is
already an ancestor of this branch, so no product-code change is needed here.
The failing QA run used branch tip 5d8a786, which predates that commit.
The assigned engineer reached the same conclusion on the bug ("already fixed
by 2801e94... It is no longer reproducible in TOT now. V2C.").

The [latency] config does reach the fixed kernel: modeling_deepseekv3.py
selects the deferred finalize path (do_finalize=False) when POST_MOE_FUSION is
on with moe_backend="TRTLLM", nvfp4 experts and tokens <= 128 -- all true for
tp8/ep8, attention_dp=False, max_batch_size=1.

Confirmed by a full run of this exact test on B300 (tp8/ep8,
DeepSeek-V3.2-Exp-FP4-v2) at this branch's product tree:

  MMLU weighted average accuracy: 87.99 (4104)   reference 87.200 -> PASS
  gsm8k average accuracy:         96.25          reference 95.600 -> PASS
  1 passed, 2 warnings in 6281.09s (1:44:41)

The 1:44:41 wall-clock is why this case cannot be validated inside a short CI
timeout; it needs the full B300 QA budget, which unwaiving restores.

Only the waiver line for this bug id is removed; the neighbouring B300
DeepSeekV32 entries belong to 6423845 and 6423866 and are left in place.

Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com>
The deferred MoEAllReduce finalize kernel used to accumulate the top-k
weighted expert sum in bf16, rounding after every one of the top_k terms.
That biased DeepSeek-V3.2 routed-MoE hidden states and dropped MMLU from
87.2 to 61.9 on B300 without any crash. It was fixed upstream by
2801e94, which accumulates into a local fp32 facc[] and rounds to
DType once; that commit is an ancestor of HEAD but not of the QA tree
5d8a786 that reported this failure, which is why the test now passes.

Nothing in CI pins that contract. The existing pattern tests exercise
this exact kernel but assert at rtol/atol=0.2, which a bf16 accumulator
satisfies just as easily as an fp32 one, so a regression would land
silently and only surface as a multi-hour accuracy test on one platform.

Add a test that compares the kernel against both candidate reference
implementations -- fp32 accumulation rounded once, and DType accumulation
rounded per term -- and asserts it is measurably closer to the fp32 one.
The two references bracket the kernel, so the check calibrates itself
instead of hardcoding a hardware-dependent error bound. Measured
separation in relative RMS error is 2.4x at top_k=8 and 4.2x at top_k=32,
against a required 1.5x margin; substituting a bf16 accumulator makes the
assertion fire for every top_k/seed combination tried.

The file is already collected wholesale by l0_dgx_h100.yml, so no
test-list change is needed.

Signed-off-by: trtllm-agent <296075020+trtllm-agent@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 61c2b330-8925-44e1-a391-9cfb47821d0b

📥 Commits

Reviewing files that changed from the base of the PR and between 937bacc and 58a73fb.

📒 Files selected for processing (2)
  • tests/integration/test_lists/waives.txt
  • tests/unittest/_torch/multi_gpu/test_allreduce.py
💤 Files with no reviewable changes (1)
  • tests/integration/test_lists/waives.txt

Walkthrough

The pull request adds deferred-MoE accumulation-precision coverage for top_k values 8 and 32, reuses deterministic test inputs, and removes a waiver for the DeepSeekV32 chunked-prefill latency test.

Changes

Deferred MoE precision validation

Layer / File(s) Summary
Deterministic inputs and precision tests
tests/unittest/_torch/multi_gpu/test_allreduce.py
Adds shared deferred-MoE input generation, fp32 and dtype-rounded reference comparisons, MPI coverage for top_k 8 and 32, and helper reuse in the existing pattern test.

DeepSeek latency coverage

Layer / File(s) Summary
Remove DeepSeek latency waiver
tests/integration/test_lists/waives.txt
Removes the waiver for TestDeepSeekV32::test_nvfp4_multi_gpus_chunked_prefill[latency].

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: brnguyen2

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the required NVBugs and fix format and clearly identifies the waiver removal and regression test.
Description check ✅ Passed The description explains the root cause, fix, regression test, test plan, and linked bug, although it does not use every template heading.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@brnguyen2 brnguyen2 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving — the comments below are optional touch-ups, not blockers.

The waiver removal checks out: 6483369 was bisected to the in-tree fp32-accumulation fix and confirmed non-reproducible at TOT, so this isn't a speculative unwaive. I also verified the new test's "reference B" against the pre-fix kernel source — the old code cast the fp32 product to bf16 and +='d in bf16, which is exactly what permuted[:, k] * scale[:, k] followed by a bf16 add reproduces. So the test really would have caught the regression, and the bracketing trick is a good answer to "an absolute tolerance here would be shape- and hardware-dependent".

On CI registration: no test-db change is needed. tests/integration/test_lists/test-db/l0_dgx_h100.yml:20 lists unittest/_torch/multi_gpu -m "not post_merge" as a directory, so the new test is collected automatically. Worth noting in the description that the coverage lands on the 2-GPU H100 stage rather than B300 — fine here since the kernel path is architecture-independent, but it's the kind of thing a future reader will ask.

Description hygiene: the PR title ("Keep the engineer-confirmed one-line stale-waiver removal, and add a…") describes the bot's decision process rather than the change. The branch's own commit subject — "[nvbugs/6483369][test] Pin fp32 accumulation in deferred MoE finalize" — is a much better title; please use it. It would also help to state up front that the kernel fix is already in main (2801e94) and this PR is unwaive + regression coverage only, since "Root cause / Fix" phrasing reads as if the kernel change is in here.

Test-only change, so no docs or release-note obligation.

err_vs_fp32 = rel_rms_vs(acc_fp32)
err_vs_dtype = rel_rms_vs(acc_dtype)

# The two references differ by ~2.4x (top_k=8) up to ~8x (top_k=128) in

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment quotes a ~2.4x reference separation at top_k=8 and ~8x at top_k=128, but the parameterization only runs 8 and 32. That leaves the weakest case (8) with ~1.6x headroom over the 1.5x threshold, and cites a data point for a shape the test never exercises.

Two concrete options: record the measured ratios for the values actually parameterized (8 and 32) so a future reader can judge the margin, or add a larger top_k to the parameter list if you want the 8x case covered. Either way, please drop the top_k=128 number from the comment unless it's in the list — it reads as if the test has more margin than it does.

output_hidden_states, _ = moe_allreduce(
fc2_output, all_reduce_params=moe_all_reduce_params)

permuted = fc2_output[expanded_idx_to_permuted_idx]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kernel skips slots where expanded_idx_to_permuted_idx == -1 (moeAllReduceFusionKernels.cu:582), but make_moe_finalize_inputs draws indices from [0, seq_len * top_k), so no test in this file ever reaches that branch — the pre-existing pattern tests have the same gap.

Note also that this fancy-index reference cannot simply be reused if sentinels are added: -1 wraps to the last row of fc2_output and silently contributes a bogus expert term rather than being skipped. A follow-up variant that plants a few -1s and zeroes the corresponding scale entries in the reference would close both holes.

assert r is True


def make_moe_finalize_inputs(seq_len, hidden_size, top_k, dtype):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test_moe_finalize_allreduce_no_residual (line 796) still builds the same tensors inline with the same shapes. It can't reuse this helper verbatim (it doesn't draw residual, so the RNG sequence differs), but leaving one of the three call sites hand-rolled means the next shape change has to be made in two places. Consider a with_residual=False flag on the helper, or a comment noting why that one is intentionally separate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants