A trainer subclass that uses PyTorch FSDP to shard the model across multiple GPUs. This trainer will shard both the policy and reference model across all available GPUs. Models are sharded at the block level, where the block class name is provided in the config.
(self, policy: nn.Module, config: DictConfig, seed: int, run_dir: str, reference_model: Optional[nn.Module] = None, rank: int = 0, world_size: int = 1)
| 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...') |
| 488 | self.reference_model = FSDP(reference_model, **shared_fsdp_kwargs) |
no test coverage detected