| 9 | # For example if you have 2 gpus - one with 16GB and other with 24GB normal partitioning would throw OOM |
| 10 | # With this implementation you can set partition_split in config so that less layers is loaded onto 16GB GPU |
| 11 | class ManualPipelineModule(PipelineModule): |
| 12 | def __init__(self, *args, manual_partition_split=None, **kwargs): |
| 13 | self.manual_partition_split = manual_partition_split |
| 14 | super().__init__(*args, **kwargs) |
| 15 | |
| 16 | def _partition_layers(self, method='uniform'): |
| 17 | if method.lower() == 'manual' and self.manual_partition_split is not None: |
| 18 | num_stages = self._topo.get_dim('pipe') |
| 19 | stage_id = self._topo.get_coord(self.global_rank).pipe |
| 20 | num_partitions = len(self.manual_partition_split) |
| 21 | assert num_partitions == num_stages - 1, f'partition_split must be length {num_stages-1} (pipeline_stages-1), was actually {num_partitions}' |
| 22 | |
| 23 | total_layers = len(self._layer_specs) |
| 24 | boundaries = [0] + self.manual_partition_split + [total_layers] |
| 25 | self.parts = boundaries |
| 26 | |
| 27 | # Print some information on the partitioning. |
| 28 | if self.global_rank == 0: |
| 29 | for stage in range(num_stages): |
| 30 | start = self.parts[stage] |
| 31 | stop = self.parts[stage + 1] |
| 32 | print(f'stage={stage} layers={stop - start}') |
| 33 | for idx, layer in enumerate(self._layer_specs[start:stop]): |
| 34 | name = str(layer) |
| 35 | if isinstance(layer, LayerSpec): |
| 36 | name = layer.typename.__name__ |
| 37 | if isinstance(layer, nn.Module): |
| 38 | name = layer.__class__.__name__ |
| 39 | else: |
| 40 | try: |
| 41 | name = layer.__name__ |
| 42 | except AttributeError: |
| 43 | pass |
| 44 | print(f' {idx+start:2d}: {name}') |
| 45 | if self.loss_fn: |
| 46 | try: |
| 47 | print(f' loss: {self.loss_fn.__name__}') |
| 48 | except AttributeError: |
| 49 | print(f' loss: {self.loss_fn.__class__.__name__}') |
| 50 | |
| 51 | self._set_bounds(start=self.parts[stage_id], stop=self.parts[stage_id+1]) |
| 52 | else: |
| 53 | super()._partition_layers(method) |
no outgoing calls
no test coverage detected