Skip to content

fix(profiler): make parallel label injective across (tp, pp, dp, moe_tp, moe_ep) - #10086

Merged
tedzhouhk merged 6 commits into
ai-dynamo:mainfrom
jooe0824:jooe0824/profiler-parallel-label
Jun 17, 2026
Merged

fix(profiler): make parallel label injective across (tp, pp, dp, moe_tp, moe_ep)#10086
tedzhouhk merged 6 commits into
ai-dynamo:mainfrom
jooe0824:jooe0824/profiler-parallel-label

Conversation

@jooe0824

@jooe0824 jooe0824 commented May 28, 2026

Copy link
Copy Markdown
Contributor

Overview:

'PickedParallelConfig.label()' in 'parallelization.py' (and its mirror 'make_parallel_label()' in 'aic_dataframe.py') used a 3-way bucket — 'dep{moe_ep}' / 'tep{moe_tp}' / 'tp{tp}' — that collapsed distinct '(tp, pp, dp, moe_tp, moe_ep)' 5-tuples to the same string.
Two unrelated topologies could share a label, which silently corrupted 'thorough.py' sweep 'work_dir' naming and 'aiconfigurator.sdk.picking' 'groupby(parallel)' dedup downstream of the picker.

Details:

The legacy encoding

def label(self) -> str:
    if self.moe_ep > 1:
        return f"dep{self.moe_ep}"     # drops tp, pp, dp, moe_tp
    elif self.moe_tp > 1:
        return f"tep{self.moe_tp}"     # drops tp, pp, dp
    return f"tp{self.tp}"               # drops pp, dp  ← non-MoE collisions

Each branch drops every dimension it doesn't name, producing three independent collision classes — not all MoE-related:

Branch Dropped dims Example collision (all yield the same label)
dep{moe_ep} (MoE-EP) tp, pp, dp, moe_tp (tp=2, moe_ep=2) vs (tp=1, dp=2, moe_ep=2) → both "dep2"
tep{moe_tp} (MoE-TP) tp, pp, dp (tp=2, moe_tp=2) vs (tp=1, pp=2, moe_tp=2) → both "tep2"
tp{tp} (dense, non-MoE) pp, dp (tp=2) vs (tp=2, pp=2) vs (tp=2, dp=2) → all "tp2"

The dense class is reachable any time the picker emits a non-MoE config with pp > 1 (multi-stage large dense) or dp > 1 (attention-DP without MoE), so the bug is not MoE-specific.

How the bug manifests downstream:

  1. thorough.py sweep work_dir naming — the per-config directory is <work_dir>/. Two distinct picks sharing a label overwrite each other's profiling outputs, silently masking one of them entirely.
  2. aiconfigurator.sdk.picking's groupby("parallel") dedup — distinct topologies merge into a single group, so the Pareto frontier picker drops one and attributes the survivor's seq/s/gpu to a topology it didn't actually measure.

Both failures are silent: no exception, no log warning. The pick proceeds with corrupted data, and the downstream planner uses a perf model bootstrapped from the wrong row.

The fix:

label() now emits every dimension whose value is > 1.
make_parallel_label() mirrors the same encoding so the profiler and the planner agree.

(tp=2, dp=1, moe_tp=2, moe_ep=1) -> "tp2-moetp2"
(tp=2, dp=1, moe_tp=1, moe_ep=2) -> "tp2-moeep2"
(tp=1, dp=2, moe_tp=1, moe_ep=2) -> "tp1-dp2-moeep2" # was "dep2"
(tp=2, pp=2, dp=1, moe_tp=1, moe_ep=1) -> "tp2-pp2" # was "tp2" (dense+PP)
(tp=2, pp=1, dp=2, moe_tp=1, moe_ep=1) -> "tp2-dp2" # was "tp2" (dense+DP)

Test:

Added two unit-test files.

File Tests
components/src/dynamo/planner/tests/unit/test_parallelization_label.py test_label_unique_per_tuple (parametrized cross-producer agreement) · test_label_distinct_across_all_enumerated_tuples (function-wide injectivity) ·test_regression_dep2_collision (explicit pin of the historical MoE-EP collision pair) · test_label_format_pin (parametrized format pins — docstring examples, default-1 omission, dense+pp/dp cases)
components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py test_label_distinct_across_all_enumerated_tuples (function-level injectivity) · test_groupby_does_not_merge_distinct_topologies (consumer-shape regression against df.groupby("parallel")) · test_make_parallel_label_format_pin (parametrized format pins)

Where should the reviewer start?

  • components/src/dynamo/planner/config/parallelization.py — source of truth for PickedParallelConfig.label()
  • components/src/dynamo/profiler/utils/aic_dataframe.py — mirror make_parallel_label() consumed by thorough.py
  • components/src/dynamo/planner/tests/unit/test_parallelization_label.py
  • components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py

Related Issues: (use one of the action keywords Closes / Fixes / Resolves / Relates to)

  • feat(planner): own AIC interpolation; fix MoE-DEP bugs in rapid mode #8335 — feat(planner): own AIC interpolation; fix MoE-DEP bugs in rapid mode → introduce parallelization.py
    The actual production-code change is small — about a dozen lines across two functions (PickedParallelConfig.label() and make_parallel_label()). For that reason no separate issue was filed — the bug manifestation is documented inline below.

Open in Devin Review

Summary by CodeRabbit

  • Bug Fixes

    • Parallelism labels now uniquely identify distinct topologies, preventing prior label collisions.
  • Tests

    • Added comprehensive regression and parametric tests to verify label uniqueness, stability, and exact format pins across representative configuration sets.
  • Documentation

    • Updated docstrings to describe the new injective label format and its behavior.

Review Change Stack

…tp, moe_ep)

'PickedParallelConfig.label()' in 'parallelization.py' (and its mirror 'make_parallel_label()' in 'aic_dataframe.py') used a 3-way bucket — 'dep{moe_ep}' / 'tep{moe_tp}' / 'tp{tp}' — that collapsed distinct '(tp, pp, dp, moe_tp, moe_ep)' 5-tuples to the same string. Two unrelated topologies could share a label, which silently corrupted 'thorough.py' sweep 'work_dir' naming and 'aiconfigurator.sdk.picking' 'groupby(parallel)' dedup downstream of the picker.

Signed-off-by: jooe0824 <jooe0824@sk.com>
@jooe0824
jooe0824 requested review from a team as code owners May 28, 2026 10:18
@copy-pr-bot

copy-pr-bot Bot commented May 28, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown
Contributor

👋 Hi jooe0824! Thank you for contributing to ai-dynamo/dynamo.

Just a reminder: The NVIDIA Test Github Validation CI runs an essential subset of the testing framework to quickly catch errors.Your PR reviewers may elect to test the changes comprehensively before approving your changes.

🚀

@github-actions github-actions Bot added external-contribution Pull request is from an external contributor planner labels May 28, 2026
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b1311d06-0b26-408e-8d59-b44742072049

📥 Commits

Reviewing files that changed from the base of the PR and between ec8b5d3 and e50f477.

📒 Files selected for processing (2)
  • components/src/dynamo/planner/tests/unit/test_parallelization_label.py
  • components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • components/src/dynamo/planner/tests/unit/test_parallelization_label.py
  • components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py

Walkthrough

This PR fixes label collisions in parallel configuration encoding by rewriting PickedParallelConfig.label() and make_parallel_label() to use an injective hyphen-joined format over the full 5-tuple (tp, pp, dp, moe_tp, moe_ep), replacing prior single-token logic, and adds comprehensive regression tests validating both functions produce unique, stable labels.

Changes

Injective Parallel Label Encoding

Layer / File(s) Summary
Label generation implementations
components/src/dynamo/planner/config/parallelization.py, components/src/dynamo/profiler/utils/aic_dataframe.py
PickedParallelConfig.label() and make_parallel_label() are rewritten to assemble hyphen-joined labels from (tp, pp, dp, moe_tp, moe_ep), omitting dimensions equal to 1; docstrings updated to document the new injective behavior and prior collision issue.
Planner-side regression tests
components/src/dynamo/planner/tests/unit/test_parallelization_label.py
Tests validate PickedParallelConfig.label() produces unique labels, agrees with make_parallel_label() across enumerated topologies, includes a regression test for the historical "dep2" collision case, and pins exact label format expectations for selected configurations.
Profiler-side regression tests
components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py
Tests validate make_parallel_label() produces collision-free labels, verify that pandas DataFrame groupby("parallel") does not merge distinct topologies, and pin exact label format expectations for representative tuples.

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: making the parallel label injective across all five parallelization dimensions, directly addressing the core bug fix.
Description check ✅ Passed The description is comprehensive and well-structured, following the template with Overview, Details, Where to start, and Related Issues sections. It thoroughly explains the bug, its downstream impacts, the fix, and test coverage.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@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: 2

🤖 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 `@components/src/dynamo/planner/tests/unit/test_parallelization_label.py`:
- Around line 14-25: Add a module-level pytestmark list in
test_parallelization_label.py by defining the variable pytestmark and assigning
it a list containing the markers pytest.mark.gpu_0, pytest.mark.pre_merge (with
a TODO comment about reverting to post_merge), pytest.mark.unit, and
pytest.mark.planner so the test module is properly tagged for CI scheduling and
component categorization.

In `@components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py`:
- Around line 12-21: Add a module-level pytestmark list to
components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py to ensure the
module is picked up by pre-merge CI: create a Python list named pytestmark at
top-level that includes pytest.mark.pre_merge (and any existing project markers
you follow in sibling tests), and attach a TODO comment indicating this
promotion is temporary and should be reverted; you can place this near the
existing imports that reference make_parallel_label and _NUM_GPUS so the whole
module is marked without adding per-test decorators.
🪄 Autofix (Beta)

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: Pro

Run ID: 2c4a7e3d-9c82-432e-9436-d86b0daffc56

📥 Commits

Reviewing files that changed from the base of the PR and between 60969cb and ec8b5d3.

📒 Files selected for processing (4)
  • components/src/dynamo/planner/config/parallelization.py
  • components/src/dynamo/planner/tests/unit/test_parallelization_label.py
  • components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py
  • components/src/dynamo/profiler/utils/aic_dataframe.py

Comment thread components/src/dynamo/profiler/tests/unit/test_aic_dataframe.py
Signed-off-by: jooe0824 <jooe0824@sk.com>
@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Actionable comments posted: 0

@tedzhouhk

Copy link
Copy Markdown
Contributor

/ok to test 69e3775

@tedzhouhk
tedzhouhk merged commit d1ec9b9 into ai-dynamo:main Jun 17, 2026
81 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external-contribution Pull request is from an external contributor fix planner size/L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants