Skip to content

[None][test] Replace disaggregated DWDP accuracy tests with aggregated coverage - #17546

Open
tianyuz-nv wants to merge 1 commit into
NVIDIA:mainfrom
tianyuz-nv:feat/dwdp-agg-accuracy
Open

[None][test] Replace disaggregated DWDP accuracy tests with aggregated coverage#17546
tianyuz-nv wants to merge 1 commit into
NVIDIA:mainfrom
tianyuz-nv:feat/dwdp-agg-accuracy

Conversation

@tianyuz-nv

@tianyuz-nv tianyuz-nv commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

DWDP accuracy is currently guarded only through disaggregated serving. That couples
the feature's CI signal to a much larger system: when disaggregated serving breaks
for reasons unrelated to DWDP — cluster transport configuration, KV cache
transceiver issues, and so on — the DWDP accuracy tests break with it. The result is
that all three disaggregated DWDP accuracy tests are currently waived on GB200 and
B200, so DWDP has no effective end-to-end accuracy coverage at all.

This PR decouples the two. DWDP accuracy is guarded by aggregated serving instead,
which exercises the same expert-sharing paths without depending on disaggregation.

What changed

  • Add tests/integration/defs/accuracy/test_dwdp_aggregated.py (3 cases, GSM8K on
    DeepSeek-V3-Lite, dwdp_size=4) and register it in the CI lists.
  • Relax the DWDP gate in create_py_executor so a single aggregated instance with
    attention DP is accepted. Aggregated attention DP satisfies the invariant DWDP
    relies on — every rank is a complete model replica owning one expert slice —
    because Mapping.dp_size == tp_size there and attention is replicated rather than
    tensor-sharded. Real tensor parallelism is still rejected, now with an explicit
    error instead of a bare assert. The change sits entirely inside the existing
    if llm_args.dwdp_config is not None: branch, so non-DWDP paths are untouched.
  • Remove the disaggregated DWDP tests from the CI lists and drop their now-dead
    waives. The file itself is kept in tree as a manual reproduction of the
    disaggregated path.

The disaggregated failures themselves are not fixed here; the related tracking bugs
(nvbugs 6276923 and 6525009) are being updated separately.

Test coverage

DeepSeek-V3-Lite has 72 routed experts and rank r stores
[r * num_prefetch_experts, r * num_prefetch_experts + num_experts_per_worker).

case experts per worker prefetch stride resulting layout
mode_a_uniform 18 18 4 x 18 = 72, no overlap
mode_b_overlap 24 16 each rank stores 8 redundant experts, adjacent ranges overlap
mode_a_uniform_contention_opt 18 18 as above, plus the batched prefetch path

dwdp_size=4 rather than the 2 the disaggregated tests used: aggregated serving has
no generation server, so the whole 4-GPU allocation goes to DWDP peers. Three remote
peers per rank is also what makes contention_opt meaningful, since it interleaves
prefetch slices across peers. Case count is unchanged (3 → 3).

Verification

Ran on GB200 (4 GPU) before opening this PR:

  • New aggregated tests: 3 passed, accuracy 64.556 / 63.268 / 63.457 against a
    63.710 reference.
  • Existing disaggregated DWDP accuracy test still passes with the relaxed gate
    (65.011 vs 64.740 reference), so disaggregated serving is unaffected.

Test Coverage

  • accuracy/test_dwdp_aggregated.py::TestDwdpAggDeepSeekV3Lite::test_dwdp_agg_accuracy[mode_a_uniform]
  • accuracy/test_dwdp_aggregated.py::TestDwdpAggDeepSeekV3Lite::test_dwdp_agg_accuracy[mode_b_overlap]
  • accuracy/test_dwdp_aggregated.py::TestDwdpAggDeepSeekV3Lite::test_dwdp_agg_accuracy[mode_a_uniform_contention_opt]

PR Checklist

  • PR title follows the required format
  • Commits signed off (DCO)
  • CI green (draft — pending /bot run)

…d coverage

DWDP accuracy was gated by three disaggregated-serving tests that are
currently waived on GB200 and B200, so the feature has no effective CI
coverage. Those tests exercise DWDP through the disaggregated KV cache
transceiver, which makes them sensitive to per-cluster UCX transport
configuration rather than to DWDP itself.

Add an aggregated equivalent instead. A single instance running attention
DP satisfies the invariant DWDP relies on -- every rank is a complete model
replica owning one expert slice -- because Mapping.dp_size == tp_size there
and attention is replicated rather than tensor-sharded. Relax the DWDP gate
in create_py_executor accordingly: tp_size > 1 is now accepted when
attention DP is enabled, and real tensor parallelism is still rejected with
an explicit error. Mapping already forces moe_tp = moe_ep = 1 whenever
dwdp_size > 1, so expert weights stay unsharded and ConfigurableMoE selects
no MoE communication strategy on this path.

The new tests run at dwdp_size=4 rather than the 2 the disaggregated tests
used: aggregated serving has no generation server, so the whole allocation
goes to DWDP peers. Three remote peers per rank also make contention_opt
meaningful, since it interleaves prefetch slices across peers -- with a
single remote peer that path was degenerate.

Retire the disaggregated tests from the CI lists and drop their now-dead
waives, but keep the file in tree as a manual reproduction of the
disaggregated DWDP path, with a note on the UCX_TLS setting to check first.

Signed-off-by: tianyuz-nv <tianyuz@nvidia.com>
@tianyuz-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

DWDP initialization now supports aggregated attention-DP layouts and validates incompatible configurations. New DeepSeek-V3-Lite aggregated accuracy tests cover three expert-partitioning modes. Test lists replace disaggregated entries, and manual disaggregated-test guidance is documented.

Changes

DWDP aggregated serving

Layer / File(s) Summary
DWDP layout validation
tensorrt_llm/_torch/pyexecutor/py_executor_creator.py
DWDP initialization validates dwdp_size and rejects tensor parallelism without attention data parallelism. The documentation describes supported disaggregated and aggregated layouts.
Aggregated accuracy coverage
tests/integration/defs/accuracy/test_dwdp_aggregated.py, tests/integration/test_lists/qa/llm_function_core.txt, tests/integration/test_lists/test-db/l0_gb200_multi_gpus.yml, tests/integration/test_lists/waives.txt
The DeepSeek-V3-Lite GSM8K test covers uniform, overlapping, and contention-optimized expert layouts. QA and pre-merge lists register these tests and remove the replaced waiver entries.
Disaggregated test guidance
tests/integration/defs/accuracy/test_dwdp_disaggregated_serving.py
The disaggregated DWDP tests now document manual execution, CI coverage, and required UCX_TLS checks.

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

Sequence Diagram(s)

sequenceDiagram
  participant TestDwdpAggDeepSeekV3Lite
  participant AttentionDP_LLM
  participant PyExecutor_DWDP
  participant GSM8K
  TestDwdpAggDeepSeekV3Lite->>AttentionDP_LLM: configure four-worker aggregated DWDP
  AttentionDP_LLM->>PyExecutor_DWDP: initialize DWDP layout
  PyExecutor_DWDP-->>AttentionDP_LLM: validate configuration
  AttentionDP_LLM->>GSM8K: evaluate prompts
  GSM8K-->>TestDwdpAggDeepSeekV3Lite: return accuracy results
Loading

Possibly related PRs

Suggested labels: ci: full pre-merge approved

Suggested reviewers: schetlur-nv

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states that disaggregated DWDP accuracy tests are replaced with aggregated coverage and follows the required format.
Description check ✅ Passed The description explains the motivation, implementation, test coverage, verification results, and checklist status in the required structure.
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 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tensorrt_llm/_torch/pyexecutor/py_executor_creator.py`:
- Around line 562-567: Extend the validation condition guarding the DWDP
complete-replica invariant to also reject mapping.pp_size > 1, while preserving
the existing tp_size and enable_attention_dp checks and error path. Update the
ValueError message to clearly identify the invalid pipeline-parallel
configuration and retain the valid configuration guidance.

In `@tests/integration/defs/accuracy/test_dwdp_aggregated.py`:
- Line 66: Update the test_dwdp_agg_accuracy method signature by annotating
num_experts_per_worker and num_prefetch_experts as int, contention_opt as bool,
and the return type as None.

In `@tests/integration/defs/accuracy/test_dwdp_disaggregated_serving.py`:
- Around line 13-18: Correct the manual-run guidance to reflect that
disaggregated workers use the value returned by get_ucx_tls(), assigned through
run_env["UCX_TLS"] in the test setup. Either document that effective policy and
its configuration source, or add and validate an override parameter that
controls the context and generation workers before describing manual UCX_TLS
overrides.
- Around line 6-11: Update the manual execution documentation in the test file’s
introductory NOTE to state that running it directly with pytest requires GPU
access, model weights, and LLM_MODELS_ROOT set to a valid model root (or an
available fallback directory), and include these prerequisites in the documented
command.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d6be1cd9-f2a6-4fcb-abe7-2653319ac949

📥 Commits

Reviewing files that changed from the base of the PR and between 07b3e82 and 42c5352.

📒 Files selected for processing (6)
  • tensorrt_llm/_torch/pyexecutor/py_executor_creator.py
  • tests/integration/defs/accuracy/test_dwdp_aggregated.py
  • tests/integration/defs/accuracy/test_dwdp_disaggregated_serving.py
  • tests/integration/test_lists/qa/llm_function_core.txt
  • tests/integration/test_lists/test-db/l0_gb200_multi_gpus.yml
  • tests/integration/test_lists/waives.txt
💤 Files with no reviewable changes (1)
  • tests/integration/test_lists/waives.txt

Comment on lines +562 to +567
if mapping.tp_size > 1 and not mapping.enable_attention_dp:
raise ValueError(
"DWDP requires each rank to be a complete model replica: use "
"tp_size=1 (disaggregated context worker) or "
"enable_attention_dp=True (aggregated serving), but got "
f"tp_size={mapping.tp_size} with enable_attention_dp=False.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Reject pipeline parallelism for DWDP.

These checks accept pp_size > 1 when tp_size == 1. Pipeline parallelism makes each rank a model shard, which violates the complete-replica invariant documented on Lines 540-555. Reject mapping.pp_size > 1 with the same validation path.

Proposed fix
-        if mapping.tp_size > 1 and not mapping.enable_attention_dp:
+        if (mapping.pp_size > 1
+                or (mapping.tp_size > 1
+                    and not mapping.enable_attention_dp)):
             raise ValueError(
                 "DWDP requires each rank to be a complete model replica: use "
-                "tp_size=1 (disaggregated context worker) or "
+                "tp_size=1 and pp_size=1 (disaggregated context worker) or "
                 "enable_attention_dp=True (aggregated serving), but got "
-                f"tp_size={mapping.tp_size} with enable_attention_dp=False.")
+                f"tp_size={mapping.tp_size}, pp_size={mapping.pp_size}, "
+                f"and enable_attention_dp={mapping.enable_attention_dp}.")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if mapping.tp_size > 1 and not mapping.enable_attention_dp:
raise ValueError(
"DWDP requires each rank to be a complete model replica: use "
"tp_size=1 (disaggregated context worker) or "
"enable_attention_dp=True (aggregated serving), but got "
f"tp_size={mapping.tp_size} with enable_attention_dp=False.")
if (mapping.pp_size > 1
or (mapping.tp_size > 1
and not mapping.enable_attention_dp)):
raise ValueError(
"DWDP requires each rank to be a complete model replica: use "
"tp_size=1 and pp_size=1 (disaggregated context worker) or "
"enable_attention_dp=True (aggregated serving), but got "
f"tp_size={mapping.tp_size}, pp_size={mapping.pp_size}, "
f"and enable_attention_dp={mapping.enable_attention_dp}.")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tensorrt_llm/_torch/pyexecutor/py_executor_creator.py` around lines 562 -
567, Extend the validation condition guarding the DWDP complete-replica
invariant to also reject mapping.pp_size > 1, while preserving the existing
tp_size and enable_attention_dp checks and error path. Update the ValueError
message to clearly identify the invalid pipeline-parallel configuration and
retain the valid configuration guidance.

],
ids=["mode_a_uniform", "mode_b_overlap", "mode_a_uniform_contention_opt"],
)
def test_dwdp_agg_accuracy(self, num_experts_per_worker, num_prefetch_experts, contention_opt):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add type annotations to the test method.

Annotate the three parameters as int, int, and bool. Add -> None to the method signature.

As per coding guidelines, “Annotate every function, use None for procedures.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/defs/accuracy/test_dwdp_aggregated.py` at line 66, Update
the test_dwdp_agg_accuracy method signature by annotating num_experts_per_worker
and num_prefetch_experts as int, contention_opt as bool, and the return type as
None.

Source: Coding guidelines

Comment on lines +6 to +11
NOTE: these tests are intentionally not registered in any CI test list. DWDP
accuracy is gated in CI by test_dwdp_aggregated.py, which exercises the same
expert-sharing paths without the disaggregated KV cache transceiver and is
therefore not exposed to per-cluster transport configuration. This file is kept
as a manual reproduction of the disaggregated DWDP path; run it directly with
pytest.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Include the required model-root setup.

pytest alone is not sufficient for this integration test. tests/integration/defs/conftest.py:99-113 requires LLM_MODELS_ROOT or an available fallback model directory. The test also requires GPU access and model weights. Document these requirements in the manual command.

As per path instructions, integration tests require GPU access and model weights, and LLM_MODELS_ROOT must be set before execution.

Proposed documentation update
- pytest.
+ LLM_MODELS_ROOT=/path/to/llm-models pytest tests/integration/defs/accuracy/test_dwdp_disaggregated_serving.py
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
NOTE: these tests are intentionally not registered in any CI test list. DWDP
accuracy is gated in CI by test_dwdp_aggregated.py, which exercises the same
expert-sharing paths without the disaggregated KV cache transceiver and is
therefore not exposed to per-cluster transport configuration. This file is kept
as a manual reproduction of the disaggregated DWDP path; run it directly with
pytest.
NOTE: these tests are intentionally not registered in any CI test list. DWDP
accuracy is gated in CI by test_dwdp_aggregated.py, which exercises the same
expert-sharing paths without the disaggregated KV cache transceiver and is
therefore not exposed to per-cluster transport configuration. This file is kept
as a manual reproduction of the disaggregated DWDP path; run it directly with
LLM_MODELS_ROOT=/path/to/llm-models pytest tests/integration/defs/accuracy/test_dwdp_disaggregated_serving.py
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/defs/accuracy/test_dwdp_disaggregated_serving.py` around
lines 6 - 11, Update the manual execution documentation in the test file’s
introductory NOTE to state that running it directly with pytest requires GPU
access, model weights, and LLM_MODELS_ROOT set to a valid model root (or an
available fallback directory), and include these prerequisites in the documented
command.

Source: Path instructions

Comment on lines +13 to +18
When running it manually, check the launcher's UCX settings first: SLURM
enroot/pyxis injects ``UCX_TLS=tcp`` from the host MPI stack on some clusters,
which pins the KV cache transceiver to a transport that can fail there and hang
the run in ``check_gen_transfer_status``. Clear or pin ``UCX_TLS`` for the
cluster before running -- see jenkins/scripts/slurm_env_setup.sh and
examples/disaggregated/slurm/benchmark/start_worker_dwdp.sh.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the UCX override guidance.

tests/integration/defs/disaggregated/test_disaggregated.py:1000-1095 unconditionally sets run_env["UCX_TLS"] = get_ucx_tls() and propagates that value to the context and generation workers. Clearing or pinning inherited launcher UCX_TLS does not control those workers. Document the effective get_ucx_tls() policy, or add a validated override parameter before documenting manual overrides.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/defs/accuracy/test_dwdp_disaggregated_serving.py` around
lines 13 - 18, Correct the manual-run guidance to reflect that disaggregated
workers use the value returned by get_ucx_tls(), assigned through
run_env["UCX_TLS"] in the test setup. Either document that effective policy and
its configuration source, or add and validate an override parameter that
controls the context and generation workers before describing manual UCX_TLS
overrides.

@tianyuz-nv

Copy link
Copy Markdown
Collaborator Author

/bot run --disable-fail-fast

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #65553 [ run ] triggered by Bot. Commit: 42c5352 Link to invocation

@Shixiaowei02

Copy link
Copy Markdown
Collaborator

LGTM. Please address the bot comments above. Thanks!

@tensorrt-cicd

Copy link
Copy Markdown
Collaborator

PR_Github #65553 [ run ] completed with state SUCCESS. Commit: 42c5352
/LLM/main/L0_MergeRequest_PR pipeline #53290 completed with status: 'FAILURE'

CI Report

⚠️ Action Required:

  • Please check the failed tests and fix your PR
  • If you cannot view the failures, ask the CI triggerer to share details
  • Once fixed, request an NVIDIA team member to trigger CI again

CI Agent Failure Analysis

Link to invocation

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants