| 428 | |
| 429 | |
| 430 | class FSDPTrainer(BasicTrainer): |
| 431 | def __init__(self, policy: nn.Module, config: DictConfig, seed: int, run_dir: str, reference_model: Optional[nn.Module] = None, rank: int = 0, world_size: int = 1): |
| 432 | """A trainer subclass that uses PyTorch FSDP to shard the model across multiple GPUs. |
| 433 | |
| 434 | This trainer will shard both the policy and reference model across all available GPUs. |
| 435 | Models are sharded at the block level, where the block class name is provided in the config. |
| 436 | """ |
| 437 | |
| 438 | super().__init__(policy, config, seed, run_dir, reference_model, rank, world_size) |
| 439 | assert config.model.block_name is not None, 'must specify model.block_name (e.g., GPT2Block or GPTNeoXLayer) for FSDP' |
| 440 | |
| 441 | wrap_class = get_block_class_from_model(policy, config.model.block_name) |
| 442 | model_auto_wrap_policy = functools.partial(transformer_auto_wrap_policy, transformer_layer_cls={wrap_class},) |
| 443 | |
| 444 | shared_fsdp_kwargs = dict( |
| 445 | auto_wrap_policy=model_auto_wrap_policy, |
| 446 | sharding_strategy=ShardingStrategy.FULL_SHARD, |
| 447 | cpu_offload=CPUOffload(offload_params=False), |
| 448 | backward_prefetch=BackwardPrefetch.BACKWARD_PRE, |
| 449 | device_id=rank, |
| 450 | ignored_modules=None, |
| 451 | limit_all_gathers=False, |
| 452 | use_orig_params=False, |
| 453 | sync_module_states=False |
| 454 | ) |
| 455 | |
| 456 | rank0_print('Sharding policy...') |
| 457 | mp_dtype = getattr(torch, config.model.fsdp_policy_mp) if config.model.fsdp_policy_mp is not None else None |
| 458 | policy_mp_policy = MixedPrecision(param_dtype=mp_dtype, reduce_dtype=mp_dtype, buffer_dtype=mp_dtype) |
| 459 | self.policy = FSDP(policy, **shared_fsdp_kwargs, mixed_precision=policy_mp_policy) |
| 460 | |
| 461 | if config.activation_checkpointing: |
| 462 | rank0_print('Attempting to enable activation checkpointing...') |
| 463 | try: |
| 464 | # use activation checkpointing, according to: |
| 465 | # https://pytorch.org/blog/scaling-multimodal-foundation-models-in-torchmultimodal-with-pytorch-distributed/ |
| 466 | # |
| 467 | # first, verify we have FSDP activation support ready by importing: |
| 468 | from torch.distributed.algorithms._checkpoint.checkpoint_wrapper import ( |
| 469 | checkpoint_wrapper, |
| 470 | apply_activation_checkpointing, |
| 471 | CheckpointImpl, |
| 472 | ) |
| 473 | non_reentrant_wrapper = functools.partial( |
| 474 | checkpoint_wrapper, |
| 475 | offload_to_cpu=False, |
| 476 | checkpoint_impl=CheckpointImpl.NO_REENTRANT, |
| 477 | ) |
| 478 | except Exception as e: |
| 479 | rank0_print('FSDP activation checkpointing not available:', e) |
| 480 | else: |
| 481 | check_fn = lambda submodule: isinstance(submodule, wrap_class) |
| 482 | rank0_print('Applying activation checkpointing wrapper to policy...') |
| 483 | apply_activation_checkpointing(self.policy, checkpoint_wrapper_fn=non_reentrant_wrapper, check_fn=check_fn) |
| 484 | rank0_print('FSDP activation checkpointing enabled!') |
| 485 | |
| 486 | if config.loss.name in {'dpo', 'ipo'}: |
| 487 | rank0_print('Sharding reference model...') |
nothing calls this directly
no outgoing calls
no test coverage detected