| 218 | |
| 219 | |
| 220 | class ContextParallelGatherHook(ModelHook): |
| 221 | def __init__(self, metadata: ContextParallelModelPlan, parallel_config: ContextParallelConfig) -> None: |
| 222 | super().__init__() |
| 223 | self.metadata = metadata |
| 224 | self.parallel_config = parallel_config |
| 225 | |
| 226 | def post_forward(self, module, output): |
| 227 | is_tensor = isinstance(output, torch.Tensor) |
| 228 | |
| 229 | if is_tensor: |
| 230 | output = [output] |
| 231 | elif not (isinstance(output, (list, tuple)) and all(isinstance(x, torch.Tensor) for x in output)): |
| 232 | raise ValueError(f"Expected output to be a tensor or a list/tuple of tensors, but got {type(output)}.") |
| 233 | |
| 234 | output = list(output) |
| 235 | |
| 236 | if len(output) != len(self.metadata): |
| 237 | raise ValueError(f"Expected output to have {len(self.metadata)} elements, but got {len(output)}.") |
| 238 | |
| 239 | for i, cpm in enumerate(self.metadata): |
| 240 | if cpm is None: |
| 241 | continue |
| 242 | if self.parallel_config.ulysses_anything or self.parallel_config.ring_anything: |
| 243 | output[i] = PartitionAnythingSharder.unshard_anything( |
| 244 | output[i], cpm.gather_dim, self.parallel_config._flattened_mesh |
| 245 | ) |
| 246 | else: |
| 247 | output[i] = EquipartitionSharder.unshard( |
| 248 | output[i], cpm.gather_dim, self.parallel_config._flattened_mesh |
| 249 | ) |
| 250 | |
| 251 | return output[0] if is_tensor else tuple(output) |
| 252 | |
| 253 | |
| 254 | class AllGatherFunction(torch.autograd.Function): |
no outgoing calls
no test coverage detected
searching dependent graphs…