Skip to content

(1/2) Implementing Compiler Pass for AutoTP - #8204

Open
therealnaveenkamal wants to merge 1 commit into
deepspeedai:masterfrom
therealnaveenkamal:feature/autotp
Open

(1/2) Implementing Compiler Pass for AutoTP#8204
therealnaveenkamal wants to merge 1 commit into
deepspeedai:masterfrom
therealnaveenkamal:feature/autotp

Conversation

@therealnaveenkamal

Copy link
Copy Markdown
Contributor

Working on #8104

  • Added support for AutoTP. Added two primitives: copy_to_tp and reduce_from_tp - the f and g nodes.
  • Identifies column/row-parallel matmuls by the injected layer type in nn_module_stack, reading back.
  • Wrote a test to verify correctness of module injection and compiler pass.

cc @tohtana

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3a2bb41dd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

# finding one here means this activation has been handled.
if activation.op == "call_function" and activation.target is COLUMN_PARALLEL_OP:
continue
_insert_after(gm, activation, COLUMN_PARALLEL_OP)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Skip gather-output column layers in AutoTP pass

When a LinearLayer has gather_output=True (for example the default/HF lm_head path), defer_collectives_to_compiler() intentionally leaves its module-level ColumnParallel/gather collectives enabled, but the graph pass still reaches this insertion because it only checks the layer type. That adds an extra copy_to_tp_region before the matmul, so the layer's input gradient is all-reduced once by the compiled op and once by the existing ColumnParallel.apply, silently scaling upstream gradients. Skip modules whose defer_collectives_to_compiler flag is false, or at least gather_output layers.

Useful? React with 👍 / 👎.

collective_node.meta["val"] = node.meta.get("val")
# Steal every consumer first, then hand the original back as this node's own input; doing it in
# the other order would leave the new node feeding itself.
node.replace_all_uses_with(collective_node)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restrict f insertion to column-parallel consumers

When the same activation also feeds any non-column consumer, this helper's replace_all_uses_with rewrites those consumers to read from copy_to_tp_region as well. Its forward is an identity, but its backward all-reduces the combined gradient from every rewritten consumer, whereas module-level AutoTP only all-reduces the gradient from column-parallel branches. This silently corrupts upstream gradients; only the matching column matmul users should be retargeted.

Useful? React with 👍 / 👎.

@tohtana tohtana 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.

Thank you @therealnaveenkamal, this is amazing!
I don't see any critical issue in the code. The approach that reuses existing AutoTP's patterns is great. It gives consistent results with non-DeepCompile AutoTP.

One remaining work is validating the correctness in a more realistic setting. I think it would be good to compare loss values from existing AutoTP and this one. I did similar work for AutoEP. The harness for the verification might be useful if you don't have such a script. We should check different configs like DP1/TP4 and DP2/TP2.

I left a few comments about details. Please consider addressing them. Also, please fix the commit to pass DCO check.

@@ -0,0 +1,72 @@
# Copyright (c) Microsoft Corporation.

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.

For new files, please show DeepSpeed's copyright. You can find an example in other files.


from unit.common import DistributedTest

pytestmark = pytest.mark.skipif(not required_torch_version(min_version=2.9),

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.

Can you clarify what limits this feature to v2.9+? Also, can we have the same check in the main code?

@tohtana

tohtana commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Can you also share your plan for the the next step as this PR has 1/2 in the title.
I think it would be good to start with the combination with ZeRO. Probably we could do further optimizations based on profiling.

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.

2 participants