r""" Context manager for training with uneven inputs across processes in DDP. This context manager will keep track of already-joined DDP processes, and "shadow" the forward and backward passes by inserting collective communication operations to match with the ones cr
(
self,
divide_by_initial_world_size: bool = True,
enable: bool = True,
throw_on_early_termination: bool = False,
)
| 1609 | self.process_group.allreduce(locally_used_param_map) |
| 1610 | |
| 1611 | def join( |
| 1612 | self, |
| 1613 | divide_by_initial_world_size: bool = True, |
| 1614 | enable: bool = True, |
| 1615 | throw_on_early_termination: bool = False, |
| 1616 | ): |
| 1617 | r""" |
| 1618 | Context manager for training with uneven inputs across processes in DDP. |
| 1619 | |
| 1620 | This context manager will keep track of already-joined DDP processes, |
| 1621 | and "shadow" the forward and backward passes by inserting collective |
| 1622 | communication operations to match with the ones created by non-joined |
| 1623 | DDP processes. This will ensure each collective call has a corresponding |
| 1624 | call by already-joined DDP processes, preventing hangs or errors that |
| 1625 | would otherwise happen when training with uneven inputs across |
| 1626 | processes. Alternatively, if the flag ``throw_on_early_termination`` is |
| 1627 | specified to be ``True``, all trainers will throw an error once one rank |
| 1628 | runs out of inputs, allowing these errors to be caught and handled |
| 1629 | according to application logic. |
| 1630 | |
| 1631 | Once all DDP processes have joined, the context manager will broadcast |
| 1632 | the model corresponding to the last joined process to all processes to |
| 1633 | ensure the model is the same across all processes |
| 1634 | (which is guaranteed by DDP). |
| 1635 | |
| 1636 | To use this to enable training with uneven inputs across processes, |
| 1637 | simply wrap this context manager around your training loop. No further |
| 1638 | modifications to the model or data loading is required. |
| 1639 | |
| 1640 | .. warning:: |
| 1641 | If the model or training loop this context manager is wrapped around |
| 1642 | has additional distributed collective operations, such as |
| 1643 | ``SyncBatchNorm`` in the model's forward pass, then the flag |
| 1644 | ``throw_on_early_termination`` must be enabled. This is because this |
| 1645 | context manager is not aware of non-DDP collective communication. |
| 1646 | This flag will cause all ranks to throw when any one rank |
| 1647 | exhausts inputs, allowing these errors to be caught and recovered |
| 1648 | from across all ranks. |
| 1649 | |
| 1650 | Args: |
| 1651 | divide_by_initial_world_size (bool): If ``True``, will divide |
| 1652 | gradients by the initial ``world_size`` DDP training was launched |
| 1653 | with. If ``False``, will compute the effective world size |
| 1654 | (number of ranks that have not depleted their inputs yet) and |
| 1655 | divide gradients by that during allreduce. Set |
| 1656 | ``divide_by_initial_world_size=True`` to ensure every input |
| 1657 | sample including the uneven inputs have equal weight in terms of |
| 1658 | how much they contribute to the global gradient. This is |
| 1659 | achieved by always dividing the gradient by the initial |
| 1660 | ``world_size`` even when we encounter uneven inputs. If you set |
| 1661 | this to ``False``, we divide the gradient by the remaining |
| 1662 | number of nodes. This ensures parity with training on a smaller |
| 1663 | ``world_size`` although it also means the uneven inputs would |
| 1664 | contribute more towards the global gradient. Typically, you |
| 1665 | would want to set this to ``True`` for cases where the last few |
| 1666 | inputs of your training job are uneven. In extreme cases, where |
| 1667 | there is a large discrepancy in the number of inputs, setting |
| 1668 | this to ``False`` might provide better results. |