Repository navigation
Experimental TPU implementation of DistributedDataParallel - #4193
Conversation
e9907a6 to
a94a815
Compare
| if not dist.is_initialized(): | ||
| rank, world_size = init_xla_backend() | ||
| else: | ||
| rank, world_size = xm.get_ordinal(), xm.xrt_world_size() |
There was a problem hiding this comment.
one customer asked if they can use torch.distributed to get the ordinal and world size, do you know if that will work if we init the xla backend?
There was a problem hiding this comment.
if I understand correctly
- if user use the upstream ddp, they need to manually
init_process_group - if user use our custom wrapper, they don't.
If this a fair understanding?
There was a problem hiding this comment.
Ordinal and world size will be correct in torch.distributed on TPU v4 if the process group is initialized with init_pjrt_process_group, but not on v2/v3, because we'll have two ordinals per rank on v2/v3.
I added the option to initialize the torch.distributed group through xmp.spawn for three reasons, in order of importance:
- The master IP is not predictable in a TPU slice.
- If on TPU v2/v3, only one thread can initialize the
torch.distributedgroup. It's easier to do it here than tell the user to manage that themselves. - It may be convenient for the PJRT process ID to match each process' rank so we have one fewer index to keep track of.
So, with either DDP implementation, the user can initialize the main process group themselves if they solve the three problems above.
The default is to not initialize the process group since we found that TCP process group initialization is flaky on large pod slices.
| else: | ||
| init_method = None | ||
|
|
||
| init_pjrt_process_group(init_method=init_method) |
There was a problem hiding this comment.
hmm, so user don't need to init the process group if they are using our wrapper?
ed03d91 to
0b7fe90
Compare
JackCaoG
left a comment
There was a problem hiding this comment.
Can we update README and add corresponding tests on xlml? I think we don't have either native ddp nor this new custom ddp e2e test running right now.
alanwaketan
left a comment
There was a problem hiding this comment.
LGTM. Thanks, Will. This looks awesome.
| def __init__(self, | ||
| module: nn.Module, | ||
| *, | ||
| broadcast_buffers: bool = True, |
There was a problem hiding this comment.
I guess we don't need to implement this logic?
There was a problem hiding this comment.
The broadcast_buffers option is implemented in forward
There was a problem hiding this comment.
I guess my confusion is like if the previous optimizer_step approach doesn't demand this, what's the benefits of providing such option here? And then it doesn't seem like you test this option.
|
Filed bugs to update documentation and add tests. |
torch.distributedinpjrt.spawn, since the master address and process ranks are not predictable on TPU.atolin DDP tests. The LR was so small that the parameter comparison always passed, even when I had errors in my code.Tested with PJRT and XRT: