Repository navigation
[spmd_types] manual loss parallel CE - #3467
Conversation
[ghstack-poisoned]
[ghstack-poisoned]
| """ | ||
|
|
||
| @staticmethod | ||
| def typecheck_forward( |
There was a problem hiding this comment.
Is typecheck_forward an spmd types native solution for autograd function?
This sounds a partial solution.
- In torchtitan we shouldn't do partial mesh check, instead we should do full mesh check.
- There are more than one way to handle things, including
local_spmdfield in Module. Is there way to consolidate?
Is it worth it to introduce a Node(Configurable) which
Moduleinherits- can still have in / out placements
There was a problem hiding this comment.
Is typecheck_forward an spmd types native solution for autograd function?
yes, see spmd_types docs, the typechecker will look for this method
# Set of autograd.Function subclasses registered with a typecheck_forward
# staticmethod. When .apply() is intercepted by __torch_function__,
# typecheck_forward is called INSTEAD of .apply(). It should assert_type()
# on inputs, call .apply() to execute, and assert_type() on the output.
In torchtitan we shouldn't do partial mesh check, instead we should do full mesh check.
hmm, I feel this should be handled by earlier module boundaries where we declare activation placements, or the later lm_head sharding? (I should ensure that's explicit and asserted). This fn in theory shouldn't touch the DP/CP axes, so re-checking if DP/CP is on seems a bit messy.
There are more than one way to handle things, including local_spmd field in Module. Is there way to consolidate?
They should serve different purposes here - local_spmd regions are still transparent to typechecking, we just switch to local typecheck. With custom autograd typecheck the type propagation is opaque, so this is a black-box where typecheck_forward is trusted by the typechecker (no typecheck).
Node(Configurable)
this seems... useful for chunked loss, and maybe other contexts outside spmd types too. But I'm not sure about the scope of this - in MoE & VL there are some forward sections & functions that require local/no-typecheck - would the plan be to refactor all of them to Node
There was a problem hiding this comment.
OK that sounds convincing!
in MoE & VL there are some forward sections & functions that require local/no-typecheck - would the plan be to refactor all of them to Node
that seems a different topic, I think we should kill the non-DTensor code as much as possible, outside the modules that we apply local_spmd on.
@shuhuayu can also help on this.
| ) | ||
| output_type = dict(spmd.get_local_type(logits)) | ||
| output_type[tp_group] = spmd.I | ||
| spmd.assert_type(result, output_type) |
There was a problem hiding this comment.
My worry is that such autograd functions would not enforce typing on all mesh axes
tianyu-l
left a comment
There was a problem hiding this comment.
The only concern is that this code not being actually integrated, but I'll stamp.
| ) | ||
|
|
||
|
|
||
| def _vocab_shard_size_and_offset( |
There was a problem hiding this comment.
the file is already big, maybe make this inline if it's only used for loss parallel
| """ | ||
|
|
||
| @staticmethod | ||
| def typecheck_forward( |
There was a problem hiding this comment.
OK that sounds convincing!
in MoE & VL there are some forward sections & functions that require local/no-typecheck - would the plan be to refactor all of them to Node
that seems a different topic, I think we should kill the non-DTensor code as much as possible, outside the modules that we apply local_spmd on.
@shuhuayu can also help on this.
fegin
left a comment
There was a problem hiding this comment.
LGTM, some change requests but not critical.
| safetensors | ||
| einops | ||
| pillow | ||
| spmd_types==0.2.0 |
There was a problem hiding this comment.
The README.md still uses pip install -r requirements.txt. So we should also add this to the general requirements.txt
There was a problem hiding this comment.
I think it's just a symlink to this one?
| ctx, | ||
| logits: torch.Tensor, | ||
| labels: torch.Tensor, | ||
| tp_group: dist.ProcessGroup, |
There was a problem hiding this comment.
Can we take a DeviceMesh? Most places in trainer still take DeviceMesh. So it is better to be consistent. Or is there any blocker?
There was a problem hiding this comment.
I think once spmd infra lands we can just call current_mesh() and stop threading this. I wasn't planning to move full DTensor to this as part of the stack yet
| ``IGNORE_INDEX`` labels. Forward uses three TP all-reduces (max, sumexp, | ||
| gather); backward is fused (NLL + log-softmax) with zero collectives. |
There was a problem hiding this comment.
nit: use three TP all-reduce to reduce the results of three oerators.
| safe_labels >= vocab_start + local_vocab_size | ||
| ) | ||
| local_labels = safe_labels - vocab_start | ||
| local_labels = local_labels.clone() |
There was a problem hiding this comment.
Is this clone redundant? safe_labels - vocab_start creates a new tensor. So clone() seems to be redundant.
| local_labels[out_of_range] = 0 | ||
|
|
||
| local_result = torch.gather(log_probs, -1, local_labels.unsqueeze(-1)) | ||
| local_result = local_result.clone() |
| safe_labels >= ctx.vocab_start + ctx.local_vocab_size | ||
| ) | ||
| local_labels = safe_labels - ctx.vocab_start | ||
| local_labels = local_labels.clone() |
…tor still TODO Documents the 34-commit pull from upstream/main (27aa490..641b5f6, merge commit fb1c5a3, sitting in worktree ezpz-46th-47th-sync). Two structural refactors hit ezpz: - PR pytorch#3458 (RoPE refactor): REPLAYED in commit 02dd1e7, verified by importing + building all agpt + moe flavors under the torch 2.13 venv. Numerics smoke against baselines still pending. - PR pytorch#3269 (mixed-optimizer refactor): NOT YET STARTED. Affects OptimizersContainer.Config + 8 custom container subclasses in optimizer/containers.py + ~13 callsites in agpt/moe/competition config registries. Also documents that spmd_types==0.2.1 was installed into .venv (new upstream runtime dep from PR pytorch#3466/pytorch#3467/pytorch#3560) and notes the open follow-ups (replay PR pytorch#3269, smoke against baselines, audit RL). Doesn't update upstream-sync.md's "next-sync" reminder banner — this sync isn't complete yet (ezpz branch is not on the worktree HEAD).
Adds the spmd_types integration to titan part-by-part, starting from replacing the
torch.distributed.tensor.parallel.loss_parallel()DTensor-based context manager with a manually written_LossParallelCrossEntropycustom autograd function.Written to support uneven sharding (on last rank), IGNORE_INDEX, verified bitwise against loss_parallel() in test cases. The PR adds spmd_types requirement to titan, as it includes typecheck_forward & testing.
Not yet wired into the training path - the later stack will wire it for the spmd backend path, but likely leaves DTensor & plain-tensor on the loss_parallel() path for now.
Stack from ghstack (oldest at bottom):