评价此页

FullyShardedDataParallel#

创建于: Feb 02, 2022 | 最后更新于: Jun 11, 2025

class torch.distributed.fsdp.FullyShardedDataParallel(module, process_group=None, sharding_strategy=None, cpu_offload=None, auto_wrap_policy=None, backward_prefetch=BackwardPrefetch.BACKWARD_PRE, mixed_precision=None, ignored_modules=None, param_init_fn=None, device_id=None, sync_module_states=False, forward_prefetch=False, limit_all_gathers=True, use_orig_params=False, ignored_states=None, device_mesh=None)[source]#

用于在数据并行工作节点之间分片模块参数的包装器。

这受到 Xu et al. 以及 DeepSpeed 的 ZeRO Stage 3 的启发。FullyShardedDataParallel 通常缩写为 FSDP。

示例

>>> import torch
>>> from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
>>> torch.cuda.set_device(device_id)
>>> sharded_module = FSDP(my_module)
>>> optim = torch.optim.Adam(sharded_module.parameters(), lr=0.0001)
>>> x = sharded_module(x, y=3, z=torch.Tensor([1]))
>>> loss = x.sum()
>>> loss.backward()
>>> optim.step()

使用 FSDP 需要包装您的模块,然后在初始化您的优化器。这是必需的,因为 FSDP 会更改参数变量。

设置 FSDP 时,您需要考虑目标 CUDA 设备。如果设备有 ID(dev_id),您有三种选择:

  • 将模块放置在该设备上

  • 使用 torch.cuda.set_device(dev_id) 设置设备

  • dev_id 传递给 device_id 构造函数参数。

这确保 FSDP 实例的计算设备是目标设备。对于选项 1 和 3,FSDP 初始化始终在 GPU 上进行。对于选项 2,FSDP 初始化发生在模块的当前设备上,这可能是 CPU。

如果您使用的是 sync_module_states=True 标志,您需要确保模块在 GPU 上,或者使用 device_id 参数指定一个 CUDA 设备,FSDP 将在 FSDP 构造函数中将模块移至该设备。这是必需的,因为 sync_module_states=True 需要 GPU 通信。

FSDP 还负责将输入张量移至前向方法,因此您无需手动将它们从 CPU 移出。

对于 use_orig_params=TrueShardingStrategy.SHARD_GRAD_OP 会暴露未分片(unsharded)的参数,而不是前向传播后的分片(sharded)参数,这与 ShardingStrategy.FULL_SHARD 不同。如果您想检查梯度,可以使用 summon_full_params 方法并设置 with_grads=True

使用 limit_all_gathers=True 时,您可能会在 FSDP 的前向传播之前看到 CPU 线程没有发出任何内核的间隙。这是故意的,它显示了限流器的效果。以这种方式同步 CPU 线程可防止为后续的 all-gather 分配过多的内存,并且实际上不会延迟 GPU 内核执行。

出于与 autograd 相关的原因,FSDP 在前向和后向计算期间会用 torch.Tensor 视图替换管理的模块参数。如果您的模块的前向传播依赖于保存的参数引用而不是每次迭代重新获取引用,那么它将看不到 FSDP 新创建的视图,并且 autograd 将无法正常工作。

最后,当使用 sharding_strategy=ShardingStrategy.HYBRID_SHARD 并将分片进程组设置为节点内(intra-node),并将复制进程组设置为节点间(inter-node)时,在某些集群设置下,设置 NCCL_CROSS_NIC=1 可以帮助提高复制进程组上的 all-reduce 时间。

限制

使用 FSDP 时,需要注意几个限制:

  • 在使用 CPU 卸载(offload)时,FSDP 目前不支持 no_sync() 之外的梯度累积。这是因为 FSDP 使用新近归约的梯度,而不是与现有梯度累积,这可能导致不正确的结果。

  • FSDP 不支持运行包含在 FSDP 实例中的子模块的前向传播。这是因为子模块的参数会被分片,但子模块本身不是 FSDP 实例,因此其前向传播不会适当地 all-gather 完整的参数。

  • 由于 FSDP 注册后向钩(backward hooks)的方式,它不适用于双后向(double backwards)。

  • FSDP 在冻结参数方面有一些限制。对于 use_orig_params=False,每个 FSDP 实例必须管理所有冻结的参数或所有未冻结的参数。对于 use_orig_params=True,FSDP 支持混合冻结和未冻结的参数,但建议避免这样做,以防止出现高于预期的梯度内存使用。

  • 截至 PyTorch 1.12,FSDP 对共享参数的支持有限。如果您的用例需要增强的共享参数支持,请在 此 issue 中发帖。

  • 您应该避免在前后向传播之间修改参数,除非使用 summon_full_params 上下文,否则修改可能不会保留。

参数:
  • module (nn.Module) – 这是要用 FSDP 包装的模块。

  • process_group (Optional[Union[ProcessGroup, Tuple[ProcessGroup, ProcessGroup]]]) – 这是模型被分片的进程组,因此是 FSDP 的 all-gather 和 reduce-scatter 集合通信使用的进程组。如果为 None,则 FSDP 使用默认进程组。对于混合分片策略,如 ShardingStrategy.HYBRID_SHARD,用户可以传递一个进程组元组,分别表示用于分片和复制的组。如果为 None,则 FSDP 会为用户构建进程组,用于节点内分片和节点间复制。(默认:None

  • sharding_strategy (Optional[ShardingStrategy]) – 这配置了分片策略,可能会在内存节省和通信开销之间权衡。有关详细信息,请参阅 ShardingStrategy。(默认:FULL_SHARD

  • cpu_offload (Optional[CPUOffload]) – 这配置了 CPU 卸载。如果设置为 None,则不发生 CPU 卸载。有关详细信息,请参阅 CPUOffload。(默认:None

  • auto_wrap_policy (Optional[Union[Callable[[nn.Module, bool, int], bool], ModuleWrapPolicy, CustomPolicy]]) –

    这指定了一个策略,用于将 FSDP 应用于 module 的子模块,这对于通信和计算重叠是必需的,因此会影响性能。如果为 None,则 FSDP 仅应用于 module,用户应手动将 FSDP 应用于父模块(自底向上进行)。为了方便起见,它直接接受 ModuleWrapPolicy,允许用户指定要包装的模块类(例如 Transformer 块)。否则,它应该是一个可调用对象,接受三个参数 module: nn.Modulerecurse: bool,和 nonwrapped_numel: int,并返回一个 bool,指定是否应将 FSDP 应用于传入的 module(如果 recurse=False),或者如果遍历应该继续到模块的子树(如果 recurse=True)。用户可以向可调用对象添加其他参数。torch.distributed.fsdp.wrap.py 中的 size_based_auto_wrap_policy 提供了一个示例可调用对象,如果其子树中的参数超过 1 亿个 numel,则将 FSDP 应用于模块。我们建议在应用 FSDP 后打印模型并根据需要进行调整。

    示例

    >>> def custom_auto_wrap_policy(
    >>>     module: nn.Module,
    >>>     recurse: bool,
    >>>     nonwrapped_numel: int,
    >>>     # Additional custom arguments
    >>>     min_num_params: int = int(1e8),
    >>> ) -> bool:
    >>>     return nonwrapped_numel >= min_num_params
    >>> # Configure a custom `min_num_params`
    >>> my_auto_wrap_policy = functools.partial(custom_auto_wrap_policy, min_num_params=int(1e5))
    

  • backward_prefetch (Optional[BackwardPrefetch]) – 这配置了显式的后向 all-gather 预取。如果为 None,则 FSDP 不进行后向预取,后向传播中没有通信和计算重叠。有关详细信息,请参阅 BackwardPrefetch。(默认:BACKWARD_PRE

  • mixed_precision (Optional[MixedPrecision]) – 这配置了 FSDP 的原生混合精度。如果设置为 None,则不使用混合精度。否则,可以设置参数、缓冲区和梯度归约的数据类型。有关详细信息,请参阅 MixedPrecision。(默认:None

  • ignored_modules (Optional[Iterable[torch.nn.Module]]) – 该实例忽略的模块,其自身参数和子模块的参数及缓冲区将被忽略。 ignored_modules 中的任何模块不应该是 FullyShardedDataParallel 实例,并且作为子模块的已构造的 FullyShardedDataParallel 实例如果嵌套在此实例下,也不会被忽略。使用 auto_wrap_policy 时,或者当参数的分片不由 FSDP 管理时,此参数可用于避免按模块粒度分片特定参数。(默认:None

  • param_init_fn (Optional[Callable[[nn.Module], None]]) –

    一个 Callable[torch.nn.Module] -> None,它指定了如何在实际设备上初始化当前位于元设备(meta device)上的模块。从 v1.12 开始,FSDP 通过 is_meta 检测具有元设备参数或缓冲区的模块,并在指定 param_init_fn 时应用它,否则调用 nn.Module.reset_parameters()。在这两种情况下,实现应*仅*初始化模块的参数/缓冲区,而不初始化其子模块的参数/缓冲区。这是为了避免重复初始化。此外,FSDP 还支持通过 torchdistX(pytorch/torchdistX)的 deferred_init() API 进行延迟初始化,其中延迟的模块通过调用 param_init_fn(如果指定)或 torchdistX 的默认 materialize_module() 来初始化。如果指定了 param_init_fn,则它将应用于所有元设备模块,这意味着它可能需要根据模块类型进行情况处理。FSDP 在参数展平(flattening)和分片之前调用初始化函数。

    示例

    >>> module = MyModule(device="meta")
    >>> def my_init_fn(module: nn.Module):
    >>>     # E.g. initialize depending on the module type
    >>>     ...
    >>> fsdp_model = FSDP(module, param_init_fn=my_init_fn, auto_wrap_policy=size_based_auto_wrap_policy)
    >>> print(next(fsdp_model.parameters()).device) # current CUDA device
    >>> # With torchdistX
    >>> module = deferred_init.deferred_init(MyModule, device="cuda")
    >>> # Will initialize via deferred_init.materialize_module().
    >>> fsdp_model = FSDP(module, auto_wrap_policy=size_based_auto_wrap_policy)
    

  • device_id (Optional[Union[int, torch.device]]) – 一个 inttorch.device,指定 FSDP 初始化发生的 CUDA 设备,包括必要的模块初始化和参数分片。如果 module 在 CPU 上,则应指定此参数以提高初始化速度。如果设置了默认 CUDA 设备(例如通过 torch.cuda.set_device),则用户可以传递 torch.cuda.current_device 给此参数。(默认:None

  • sync_module_states (bool) – 如果为 True,则每个 FSDP 模块将从 rank 0 广播模块参数和缓冲区,以确保它们在各个 rank 之间是复制的(这会增加构造函数的通信开销)。这有助于以内存高效的方式通过 load_state_dict 加载 state_dict 检查点。有关示例,请参阅 FullStateDictConfig。(默认:False

  • forward_prefetch (bool) – 如果为 True,则 FSDP 在当前前向计算*之前*显式预取下一个前向 all-gather。这仅对 CPU 密集型工作负载有用,在这种情况下,更早地发出下一个 all-gather 可以改善重叠。这应该只用于静态图模型,因为预取遵循第一次迭代的执行顺序。(默认:False

  • limit_all_gathers (bool) – 如果为 True,则 FSDP 显式同步 CPU 线程,以确保 GPU 内存使用仅限于*两个*连续的 FSDP 实例(当前运行计算的实例和预取 all-gather 的下一个实例)。如果为 False,则 FSDP 允许 CPU 线程在没有任何额外同步的情况下发出 all-gather。 (默认:True)我们通常将此功能称为“速率限制器”。此标志应仅为低内存压力的特定 CPU 密集型工作负载设置为 False,在这种情况下,CPU 线程可以积极地发出所有内核,而无需担心 GPU 内存使用。

  • use_orig_params (bool) – 将此设置为 True 时,FSDP 会使用 module 的原始参数。FSDP 通过 nn.Module.named_parameters() 向用户公开这些原始参数,而不是 FSDP 内部的 FlatParameter。这意味着优化器步骤在原始参数上运行,从而支持每个原始参数的超参数。FSDP 保留原始参数变量,并在未分片(unsharded)和分片(sharded)形式之间操作它们的数据,其中它们总是指向底层未分片或分片 FlatParameter 的视图。对于当前算法,分片形式始终是 1D 的,会丢失原始张量结构。一个原始参数在给定 rank 上可能具有其数据的全部、部分或全部不存在。在不存在的情况下,其数据将类似于大小为 0 的空张量。用户不应编写依赖于给定原始参数在分片形式中存在的任何数据的程序。True 是使用 torch.compile() 所必需的。将此设置为 False 时,FSDP 会通过 nn.Module.named_parameters() 向用户公开 FSDP 内部的 FlatParameter。(默认:False

  • ignored_states (Optional[Iterable[torch.nn.Parameter]], Optional[Iterable[torch.nn.Module]]) – 被忽略的参数或模块,它们不会被此 FSDP 实例管理,这意味着参数不会被分片,并且它们的梯度不会在 rank 之间进行归约。此参数与现有的 ignored_modules 参数统一,我们可能会很快弃用 ignored_modules。为了向后兼容,我们保留 ignored_statesignored_modules,但 FSDP 只允许其中一个被指定为非 None

  • device_mesh (Optional[DeviceMesh]) – DeviceMesh 可以作为 process_group 的替代品。当传递 device_mesh 时,FSDP 将使用底层进程组进行 all-gather 和 reduce-scatter 集合通信。因此,这两个参数需要互斥。对于混合分片策略,如 ShardingStrategy.HYBRID_SHARD,用户可以传递一个二维 DeviceMesh 而不是进程组元组。对于二维 FSDP + TP,用户必须传递 device_mesh 而不是 process_group。有关 DeviceMesh 的更多信息,请访问:https://pytorch.ac.cn/tutorials/recipes/distributed_device_mesh.html

apply(fn)[source]#

fn 递归应用于每个子模块(由 .children() 返回)以及自身。

典型用法包括初始化模型的参数(另请参阅 torch.nn.init)。

torch.nn.Module.apply 相比,此版本会额外收集完整参数后再应用 fn。不应在另一个 summon_full_params 上下文内部调用它。

参数:

fn (Module -> None) – 要应用于每个子模块的函数

返回:

self

返回类型:

模块

check_is_root()[source]#

检查此实例是否为根 FSDP 模块。

返回类型:

布尔值

clip_grad_norm_(max_norm, norm_type=2.0)[source]#

裁剪所有参数的梯度范数。

范数是在所有参数的梯度上计算的,将它们视为单个向量,并且梯度被原地修改。

参数:
  • max_norm (float or int) – 梯度的最大范数

  • norm_type (float or int) – 使用的 p-范数的类型。可以是 'inf' 用于无穷范数。

返回:

参数的总范数(视为单个向量)。

返回类型:

张量

如果每个 FSDP 实例都使用 NO_SHARD,这意味着没有梯度在 rank 之间分片,那么您可以直接使用 torch.nn.utils.clip_grad_norm_()

如果至少有一个 FSDP 实例使用分片策略(即非 NO_SHARD 的策略),那么您应该使用此方法而不是 torch.nn.utils.clip_grad_norm_(),因为此方法处理了梯度在 rank 之间分片的事实。

返回的总范数将具有所有参数/梯度的“最大”数据类型,根据 PyTorch 的类型提升语义定义。例如,如果*所有*参数/梯度都使用低精度数据类型,则返回的范数数据类型将是该低精度数据类型,但如果存在至少一个使用 FP32 的参数/梯度,则返回的范数数据类型将是 FP32。

警告

这需要在所有 rank 上调用,因为它使用了集合通信。

static flatten_sharded_optim_state_dict(sharded_optim_state_dict, model, optim)[source]#

展平分片优化器状态字典。

该 API 与 shard_full_optim_state_dict() 类似。唯一的区别是,输入 sharded_optim_state_dict 应该由 sharded_optim_state_dict() 返回。因此,每个 rank 都会进行 all-gather 调用来收集 ShardedTensor

参数:
返回:

参考 shard_full_optim_state_dict()

返回类型:

dict[str, Any]

forward(*args, **kwargs)[source]#

运行包装模块的前向传播,插入 FSDP 特定的前向和后向分片逻辑。

返回类型:

任何

static fsdp_modules(module, root_only=False)[source]#

返回所有嵌套的 FSDP 实例。

如果 root_only=True,这可能包括 module 本身,并且只包含 FSDP 根模块。

参数:
  • module (torch.nn.Module) – 根模块,它可能是一个 FSDP 模块,也可能不是。

  • root_only (bool) – 是否只返回 FSDP 根模块。(默认:False

返回:

嵌套在输入 module 中的 FSDP 模块。

返回类型:

List[FullyShardedDataParallel]

static full_optim_state_dict(model, optim, optim_input=None, rank0_only=True, group=None)[source]#

返回完整的优化器状态字典。

将完整的优化器状态合并到 rank 0,并以 dict 的形式返回,遵循 torch.optim.Optimizer.state_dict() 的约定,即包含 "state""param_groups" 键。在 FSDP 模块中包含的展平参数将被映射回其未展平的参数。

由于使用了集体通信,因此需要在所有 rank 上调用此方法。但是,如果 rank0_only=True,则只有 rank 0 会填充状态字典,而所有其他 rank 会返回一个空的 dict

torch.optim.Optimizer.state_dict() 不同,此方法使用完整的参数名称作为键,而不是参数 ID。

torch.optim.Optimizer.state_dict() 中的情况一样,优化器状态字典中包含的张量不会被克隆,因此可能会出现别名问题。为最佳实践,请考虑立即保存返回的优化器状态字典,例如使用 torch.save()

参数:
  • model (torch.nn.Module) – 根模块(可能是或不是 FullyShardedDataParallel 实例),其参数已传递给优化器 optim

  • optim (torch.optim.Optimizer) – model 参数的优化器。

  • optim_input (Optional[Union[List[Dict[str, Any]], Iterable[torch.nn.Parameter]]]) – 传递给优化器 optim 的输入,表示参数组的 list 或参数的可迭代对象;如果为 None,则此方法假定输入为 model.parameters()。此参数已弃用,不再需要传递。(默认:None

  • rank0_only (bool) – 如果为 True,则仅在 rank 0 上保存填充的 dict;如果为 False,则在所有 rank 上保存。(默认:True

  • group (dist.ProcessGroup) – 模型的进程组,或者如果使用默认进程组则为 None。(默认:None

返回:

一个 dict,其中包含 model 的原始未展平参数的优化器状态,并包含遵循 torch.optim.Optimizer.state_dict() 约定的“state”和“param_groups”键。如果 rank0_only=True,则非零 rank 返回一个空的 dict

返回类型:

Dict[str, Any]

static get_state_dict_type(module)[source]#

获取 FSDP 模块(以 module 为根)的状态字典类型以及相应的配置。

目标模块不一定是 FSDP 模块。

返回:

一个 StateDictSettings 对象,其中包含当前设置的状态字典类型以及状态字典/优化器状态字典配置。

抛出:
  • AssertionError` if the StateDictSettings for differen

  • FSDP submodules differ.

返回类型:

StateDictSettings

property module: Module#

返回包装的模块。

named_buffers(*args, **kwargs)[source]#

返回一个模块缓冲区迭代器,同时生成缓冲区的名称和缓冲区本身。

summon_full_params() 上下文管理器内部,拦截缓冲区名称并移除 FSDP 特定的展平缓冲区前缀的所有出现。

返回类型:

Iterator[tuple[str, Tensor]]

named_parameters(*args, **kwargs)[source]#

返回一个模块参数迭代器,同时生成参数的名称和参数本身。

summon_full_params() 上下文管理器内部,拦截参数名称并移除 FSDP 特定的展平参数前缀的所有出现。

返回类型:

Iterator[tuple[str, Parameter]]

no_sync()[source]#

禁用 FSDP 实例之间的梯度同步。

在此上下文中,梯度将累积在模块变量中,稍后将在退出上下文后的第一个前向-后向传递中同步。这应该只在根 FSDP 实例上使用,并将递归应用于所有子 FSDP 实例。

注意

这可能会导致更高的内存使用量,因为 FSDP 将累积完整的模型梯度(而不是梯度分片),直到最终同步。

注意

与 CPU 卸载一起使用时,梯度在上下文中不会卸载到 CPU。相反,它们将在最终同步后立即卸载。

返回类型:

生成器

static optim_state_dict(model, optim, optim_state_dict=None, group=None)[source]#

转换分片模型的优化器状态字典。

给定的状态字典可以转换为以下三种类型之一:1) 完整的优化器状态字典,2) 分片优化器状态字典,3) 本地优化器状态字典。

对于完整的优化器状态字典,所有状态都未展平且未分片。可以通过 state_dict_type() 指定仅 rank0 和仅 CPU,以避免 OOM。

对于分片优化器状态字典,所有状态都未展平但已分片。可以通过 state_dict_type() 指定仅 CPU,以进一步节省内存。

对于本地状态字典,不进行任何转换。但状态将从 nn.Tensor 转换为 ShardedTensor 以表示其分片性质(此功能尚不支持)。

示例

>>> from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
>>> from torch.distributed.fsdp import StateDictType
>>> from torch.distributed.fsdp import FullStateDictConfig
>>> from torch.distributed.fsdp import FullOptimStateDictConfig
>>> # Save a checkpoint
>>> model, optim = ...
>>> FSDP.set_state_dict_type(
>>>     model,
>>>     StateDictType.FULL_STATE_DICT,
>>>     FullStateDictConfig(rank0_only=False),
>>>     FullOptimStateDictConfig(rank0_only=False),
>>> )
>>> state_dict = model.state_dict()
>>> optim_state_dict = FSDP.optim_state_dict(model, optim)
>>> save_a_checkpoint(state_dict, optim_state_dict)
>>> # Load a checkpoint
>>> model, optim = ...
>>> state_dict, optim_state_dict = load_a_checkpoint()
>>> FSDP.set_state_dict_type(
>>>     model,
>>>     StateDictType.FULL_STATE_DICT,
>>>     FullStateDictConfig(rank0_only=False),
>>>     FullOptimStateDictConfig(rank0_only=False),
>>> )
>>> model.load_state_dict(state_dict)
>>> optim_state_dict = FSDP.optim_state_dict_to_load(
>>>     model, optim, optim_state_dict
>>> )
>>> optim.load_state_dict(optim_state_dict)
参数:
  • model (torch.nn.Module) – 根模块(可能是或不是 FullyShardedDataParallel 实例),其参数已传递给优化器 optim

  • optim (torch.optim.Optimizer) – model 参数的优化器。

  • optim_state_dict (Dict[str, Any]) – 要转换的目标优化器状态字典。如果值为 None,则使用 optim.state_dict()。(默认:None

  • group (dist.ProcessGroup) – 模型在其中分片参数的模型进程组,或者如果使用默认进程组则为 None。(默认:None

返回:

一个 dict,其中包含 model 的优化器状态。优化器状态的分片基于 state_dict_type

返回类型:

Dict[str, Any]

static optim_state_dict_to_load(model, optim, optim_state_dict, is_named_optimizer=False, load_directly=False, group=None)[source]#

转换优化器状态字典,以便它可以被加载到与 FSDP 模型关联的优化器中。

给定一个通过 optim_state_dict() 转换的 optim_state_dict,它将被转换为可加载到 optim(它是 model 的优化器)的展平优化器状态字典。model 必须由 FullyShardedDataParallel 进行分片。

>>> from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
>>> from torch.distributed.fsdp import StateDictType
>>> from torch.distributed.fsdp import FullStateDictConfig
>>> from torch.distributed.fsdp import FullOptimStateDictConfig
>>> # Save a checkpoint
>>> model, optim = ...
>>> FSDP.set_state_dict_type(
>>>     model,
>>>     StateDictType.FULL_STATE_DICT,
>>>     FullStateDictConfig(rank0_only=False),
>>>     FullOptimStateDictConfig(rank0_only=False),
>>> )
>>> state_dict = model.state_dict()
>>> original_osd = optim.state_dict()
>>> optim_state_dict = FSDP.optim_state_dict(
>>>     model,
>>>     optim,
>>>     optim_state_dict=original_osd
>>> )
>>> save_a_checkpoint(state_dict, optim_state_dict)
>>> # Load a checkpoint
>>> model, optim = ...
>>> state_dict, optim_state_dict = load_a_checkpoint()
>>> FSDP.set_state_dict_type(
>>>     model,
>>>     StateDictType.FULL_STATE_DICT,
>>>     FullStateDictConfig(rank0_only=False),
>>>     FullOptimStateDictConfig(rank0_only=False),
>>> )
>>> model.load_state_dict(state_dict)
>>> optim_state_dict = FSDP.optim_state_dict_to_load(
>>>     model, optim, optim_state_dict
>>> )
>>> optim.load_state_dict(optim_state_dict)
参数:
  • model (torch.nn.Module) – 根模块(可能是或不是 FullyShardedDataParallel 实例),其参数已传递给优化器 optim

  • optim (torch.optim.Optimizer) – model 参数的优化器。

  • optim_state_dict (Dict[str, Any]) – 要加载的优化器状态。

  • is_named_optimizer (bool) – 此优化器是 NamedOptimizer 还是 KeyedOptimizer。仅当 optim 是 TorchRec 的 KeyedOptimizer 或 torch.distributed 的 NamedOptimizer 时才设置为 True。

  • load_directly (bool) – 如果设置为 True,此 API 还将在返回结果之前调用 optim.load_state_dict(result)。否则,用户负责调用 optim.load_state_dict()。(默认:False

  • group (dist.ProcessGroup) – 模型在其中分片参数的模型进程组,或者如果使用默认进程组则为 None。(默认:None

返回类型:

dict[str, Any]

register_comm_hook(state, hook)[source]#

注册通信钩子。

这是一个增强功能,为用户提供了一个灵活的钩子,他们可以在其中指定 FSDP 如何在多个工作节点之间聚合梯度。此钩子可用于实现几种算法,例如 GossipGrad 和梯度压缩,这些算法在与 FullyShardedDataParallel 进行训练时涉及不同的参数同步通信策略。

警告

FSDP 通信钩子应在运行初始前向传递之前注册,并且只能注册一次。

参数:
  • state (object) –

    传递给钩子,用于在训练过程中维护任何状态信息。例如,梯度压缩中的错误反馈、GossipGrad 中下一个要通信的对等节点等。它由每个工作节点本地存储,并由该节点上的所有梯度张量共享。

  • hook (Callable) – 可调用对象,具有以下签名之一:1) hook: Callable[torch.Tensor] -> None:此函数接受一个 Python 张量,该张量代表与此 FSDP 单元包装的模型(未被其他 FSDP 子单元包装)对应的所有变量的完整、展平、未分片梯度。然后执行所有必要的处理并返回 None;2) hook: Callable[torch.Tensor, torch.Tensor] -> None:此函数接受两个 Python 张量,第一个张量代表与此 FSDP 单元包装的模型(未被其他 FSDP 子单元包装)对应的所有变量的完整、展平、未分片梯度。第二个张量代表一个预先调整大小的张量,用于存储约简后分片梯度的块。在两种情况下,可调用对象都会执行所有必要的处理并返回 None。具有签名 1 的可调用对象应处理 NO_SHARD 情况下的梯度通信。具有签名 2 的可调用对象应处理分片情况下的梯度通信。

static rekey_optim_state_dict(optim_state_dict, optim_state_key_type, model, optim_input=None, optim=None)[source]#

将优化器状态字典 optim_state_dict 重新键合,以便使用 optim_state_key_type 键类型。

这可以用来实现 FSDP 实例模型的状态字典与未包装模型的状态字典之间的兼容性。

将 FSDP 完整优化器状态字典(即来自 full_optim_state_dict())重新键合,以使用参数 ID 并可加载到未包装的模型

>>> wrapped_model, wrapped_optim = ...
>>> full_osd = FSDP.full_optim_state_dict(wrapped_model, wrapped_optim)
>>> nonwrapped_model, nonwrapped_optim = ...
>>> rekeyed_osd = FSDP.rekey_optim_state_dict(full_osd, OptimStateKeyType.PARAM_ID, nonwrapped_model)
>>> nonwrapped_optim.load_state_dict(rekeyed_osd)

将来自未包装模型的普通优化器状态字典重新键合,以便可加载到已包装的模型

>>> nonwrapped_model, nonwrapped_optim = ...
>>> osd = nonwrapped_optim.state_dict()
>>> rekeyed_osd = FSDP.rekey_optim_state_dict(osd, OptimStateKeyType.PARAM_NAME, nonwrapped_model)
>>> wrapped_model, wrapped_optim = ...
>>> sharded_osd = FSDP.shard_full_optim_state_dict(rekeyed_osd, wrapped_model)
>>> wrapped_optim.load_state_dict(sharded_osd)
返回:

使用 optim_state_key_type 指定的参数键重新键合的优化器状态字典。

返回类型:

Dict[str, Any]

static scatter_full_optim_state_dict(full_optim_state_dict, model, optim_input=None, optim=None, group=None)[source]#

将完整的优化器状态字典从 rank 0 散射到所有其他 rank。

在每个 rank 上返回分片优化器状态字典。返回值与 shard_full_optim_state_dict() 相同,并且在 rank 0 上,第一个参数应该是 full_optim_state_dict() 的返回值。

示例

>>> from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
>>> model, optim = ...
>>> full_osd = FSDP.full_optim_state_dict(model, optim)  # only non-empty on rank 0
>>> # Define new model with possibly different world size
>>> new_model, new_optim, new_group = ...
>>> sharded_osd = FSDP.scatter_full_optim_state_dict(full_osd, new_model, group=new_group)
>>> new_optim.load_state_dict(sharded_osd)

注意

可以使用 shard_full_optim_state_dict()scatter_full_optim_state_dict() 来获取要加载的分片优化器状态字典。假设完整的优化器状态字典位于 CPU 内存中,前者要求每个 rank 在 CPU 内存中都有完整的字典,每个 rank 单独分片字典而无需通信;而后者要求只有 rank 0 在 CPU 内存中拥有完整的字典,其中 rank 0 将每个分片移动到 GPU 内存(用于 NCCL)并将其适当地传达给 rank。因此,前者具有更高的聚合 CPU 内存成本,而后者具有更高的通信成本。

参数:
  • full_optim_state_dict (Optional[Dict[str, Any]]) – 对应于未展平参数的优化器状态字典,并在 rank 0 上持有完整的非分片优化器状态;该参数在非零 rank 上被忽略。

  • model (torch.nn.Module) – 根模块(可能是或不是 FullyShardedDataParallel 实例),其参数对应于 full_optim_state_dict 中的优化器状态。

  • optim_input (Optional[Union[List[Dict[str, Any]], Iterable[torch.nn.Parameter]]]) – 传递给优化器的输入,表示参数组的 list 或参数的可迭代对象;如果为 None,则此方法假定输入为 model.parameters()。此参数已弃用,不再需要传递。(默认值:None

  • optim (Optional[torch.optim.Optimizer]) – 加载此方法返回的状态字典的优化器。这是优于 optim_input 的首选参数。(默认值:None

  • group (dist.ProcessGroup) – 模型的进程组,或者如果使用默认进程组则为 None。(默认:None

返回:

完整的优化器状态字典现在已重新映射到展平的参数,而不是未展平的参数,并且仅限于包含此 rank 的优化器状态部分。

返回类型:

Dict[str, Any]

static set_state_dict_type(module, state_dict_type, state_dict_config=None, optim_state_dict_config=None)[source]#

设置目标模块的所有后代 FSDP 模块的 state_dict_type

还接受模型和优化器状态字典的可选配置。目标模块不一定是 FSDP 模块。如果目标模块是 FSDP 模块,其 state_dict_type 也将被更改。

注意

此 API 应仅用于顶级(根)模块。

注意

此 API 允许用户在根 FSDP 模块被另一个 nn.Module 包装的情况下,透明地使用传统的 state_dict API 来获取模型检查点。例如,以下将确保 state_dict 被应用于所有非 FSDP 实例,同时将 FSDP 的实现分派到 sharded_state_dict

示例

>>> model = DDP(FSDP(...))
>>> FSDP.set_state_dict_type(
>>>     model,
>>>     StateDictType.SHARDED_STATE_DICT,
>>>     state_dict_config = ShardedStateDictConfig(offload_to_cpu=True),
>>>     optim_state_dict_config = OptimStateDictConfig(offload_to_cpu=True),
>>> )
>>> param_state_dict = model.state_dict()
>>> optim_state_dict = FSDP.optim_state_dict(model, optim)
参数:
  • module (torch.nn.Module) – 根模块。

  • state_dict_type (StateDictType) – 要设置的期望的 state_dict_type

  • state_dict_config (Optional[StateDictConfig]) – 目标 state_dict_type 的配置。

  • optim_state_dict_config (Optional[OptimStateDictConfig]) – 优化器状态字典的配置。

返回:

一个 StateDictSettings,包含先前的 state_dict 类型和模块的配置。

返回类型:

StateDictSettings

static shard_full_optim_state_dict(full_optim_state_dict, model, optim_input=None, optim=None)[source]#

分片完整的优化器状态字典。

full_optim_state_dict 中的状态重新映射到展平的参数而不是未展平的参数,并限制为仅此 rank 的优化器状态部分。第一个参数应该是 full_optim_state_dict() 的返回值。

示例

>>> from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
>>> model, optim = ...
>>> full_osd = FSDP.full_optim_state_dict(model, optim)
>>> torch.save(full_osd, PATH)
>>> # Define new model with possibly different world size
>>> new_model, new_optim = ...
>>> full_osd = torch.load(PATH)
>>> sharded_osd = FSDP.shard_full_optim_state_dict(full_osd, new_model)
>>> new_optim.load_state_dict(sharded_osd)

注意

可以使用 shard_full_optim_state_dict()scatter_full_optim_state_dict() 来获取要加载的分片优化器状态字典。假设完整的优化器状态字典位于 CPU 内存中,前者要求每个 rank 在 CPU 内存中都有完整的字典,每个 rank 单独分片字典而无需通信;而后者要求只有 rank 0 在 CPU 内存中拥有完整的字典,其中 rank 0 将每个分片移动到 GPU 内存(用于 NCCL)并将其适当地传达给 rank。因此,前者具有更高的聚合 CPU 内存成本,而后者具有更高的通信成本。

参数:
  • full_optim_state_dict (Dict[str, Any]) – 对应于未展平参数的优化器状态字典,并包含完整的非分片优化器状态。

  • model (torch.nn.Module) – 根模块(可能是或不是 FullyShardedDataParallel 实例),其参数对应于 full_optim_state_dict 中的优化器状态。

  • optim_input (Optional[Union[List[Dict[str, Any]], Iterable[torch.nn.Parameter]]]) – 传递给优化器的输入,表示参数组的 list 或参数的可迭代对象;如果为 None,则此方法假定输入为 model.parameters()。此参数已弃用,不再需要传递。(默认值:None

  • optim (Optional[torch.optim.Optimizer]) – 加载此方法返回的状态字典的优化器。这是优于 optim_input 的首选参数。(默认值:None

返回:

完整的优化器状态字典现在已重新映射到展平的参数,而不是未展平的参数,并且仅限于包含此 rank 的优化器状态部分。

返回类型:

Dict[str, Any]

static sharded_optim_state_dict(model, optim, group=None)[source]#

以分片形式返回优化器状态字典。

此 API 与 full_optim_state_dict() 类似,但此 API 将所有非零维度状态分块为 ShardedTensor 以节省内存。此 API 应仅在模型 state_dict 是使用上下文管理器 with state_dict_type(SHARDED_STATE_DICT): 派生的时使用。

有关详细用法,请参阅 full_optim_state_dict()

警告

返回的状态字典包含 ShardedTensor,无法被常规 optim.load_state_dict 直接使用。

返回类型:

dict[str, Any]

static state_dict_type(module, state_dict_type, state_dict_config=None, optim_state_dict_config=None)[source]#

设置目标模块的所有后代 FSDP 模块的 state_dict_type

此上下文管理器与 set_state_dict_type() 具有相同的功能。有关详细信息,请阅读 set_state_dict_type() 的文档。

示例

>>> model = DDP(FSDP(...))
>>> with FSDP.state_dict_type(
>>>     model,
>>>     StateDictType.SHARDED_STATE_DICT,
>>> ):
>>>     checkpoint = model.state_dict()
参数:
  • module (torch.nn.Module) – 根模块。

  • state_dict_type (StateDictType) – 要设置的期望的 state_dict_type

  • state_dict_config (Optional[StateDictConfig]) – 目标 state_dict_type 的模型 state_dict 配置。

  • optim_state_dict_config (Optional[OptimStateDictConfig]) – 目标 state_dict_type 的优化器 state_dict 配置。

返回类型:

生成器

static summon_full_params(module, recurse=True, writeback=True, rank0_only=False, offload_to_cpu=False, with_grads=False)[source]#

使用此上下文管理器公开 FSDP 实例的完整参数。

在模型进行前向/后向计算 *之后* 可能很有用,用于获取参数以进行其他处理或检查。它可以接受一个非 FSDP 模块,并根据 recurse 参数,为所有包含的 FSDP 模块及其子模块获取完整的参数。

注意

这可以用于内部 FSDP。

注意

此 API *不能* 在前向或后向传递中使用。也不能在此上下文内启动前向和后向传递。

注意

退出上下文管理器后,参数将恢复为其局部分片,存储行为与前向传递相同。

注意

可以修改完整参数,但只有与局部参数分片对应的部分将在退出上下文管理器后保留(除非 writeback=False,在这种情况下,更改将被丢弃)。在 FSDP 未分片参数的情况下,目前仅当 world_size == 1NO_SHARD 配置时,修改才会保留,而与 writeback 无关。

注意

此方法作用于本身不是 FSDP 的模块,但可能包含多个独立的 FSDP 单元。在这种情况下,给定的参数将应用于所有包含的 FSDP 单元。

警告

请注意,目前不支持将 rank0_only=Truewriteback=True 结合使用,否则将引发错误。这是因为在上下文内,模型参数形状在不同的 rank 之间会有所不同,并且写入这些参数可能导致在退出上下文时跨 rank 不一致。

警告

请注意,offload_to_cpurank0_only=False 将导致完整的参数被冗余地复制到位于同一机器上的 GPU 的 CPU 内存中,这可能会带来 CPU OOM 的风险。建议将 offload_to_cpurank0_only=True 一起使用。

参数:
  • recurse (bool, Optional) – 递归地获取嵌套 FSDP 实例的所有参数(默认值:True)。

  • writeback (bool, Optional) – 如果为 False,则在上下文管理器退出后,对参数的修改将被丢弃;禁用此选项可以稍微提高效率(默认值:True)。

  • rank0_only (bool, Optional) – 如果为 True,则完整的参数仅在全局 rank 0 上物化。这意味着在上下文中,只有 rank 0 拥有完整的参数,而其他 rank 拥有分片的参数。请注意,将 rank0_only=Truewriteback=True 结合使用是不支持的,因为在上下文中模型参数的形状在不同的 rank 之间会有所不同,并且写入这些参数可能导致在退出上下文时跨 rank 不一致。

  • offload_to_cpu (bool, Optional) – 如果为 True,则完整的参数将卸载到 CPU。请注意,此卸载目前仅在参数被分片时发生(仅在 world_size = 1 或 NO_SHARD 配置时才不发生)。建议将 offload_to_cpurank0_only=True 一起使用,以避免将模型参数冗余地卸载到相同的 CPU 内存中。

  • with_grads (bool, Optional) – 如果为 True,则梯度也与参数一起取消分片。目前,这仅在将 use_orig_params=True 传递给 FSDP 构造函数并且将 offload_to_cpu=False 传递给此方法时才受支持。(默认值:False

返回类型:

生成器

class torch.distributed.fsdp.BackwardPrefetch(value)[source]#

此配置允许显式的后向预取,通过在后向传递中重叠通信和计算来提高吞吐量,但会略微增加内存使用。

  • BACKWARD_PRE:这提供了最多的重叠,但增加了最多的内存使用。它会在当前参数集梯度计算 *之前* 预取下一组参数。这会重叠 *下一次 all-gather* 和 *当前梯度计算*,在高峰时,它会在内存中同时持有当前参数集、下一组参数和当前梯度集。

  • BACKWARD_POST:这提供了较少的重叠,但需要较少的内存使用。它会在当前参数集梯度计算 *之后* 预取下一组参数。这会重叠 *当前 reduce-scatter* 和 *下一次梯度计算*,并且它会在分配下一组参数的内存之前释放当前参数集,在高峰时仅在内存中持有下一组参数和当前梯度集。

  • FSDP 的 backward_prefetch 参数接受 None,这将完全禁用后向预取。这没有重叠,也不会增加内存使用。总的来说,我们不推荐此设置,因为它可能会显著降低吞吐量。

有关更多技术背景:对于使用 NCCL 后端的单个进程组,任何集体通信(即使是从不同的流发出的)都会争夺相同的每个设备的 NCCL 流,这意味着集体通信发出的相对顺序对于重叠很重要。两个后向预取值对应于不同的发出顺序。

class torch.distributed.fsdp.ShardingStrategy(value)[source]#

这指定了 FullyShardedDataParallel 用于分布式训练的分片策略。

  • FULL_SHARD:参数、梯度和优化器状态被分片。对于参数,此策略在前向传递之前取消分片(通过 all-gather),在前向传递之后重新分片,在后向计算之前取消分片,并在后向计算之后重新分片。对于梯度,它在后向计算之后同步并分片它们(通过 reduce-scatter)。分片优化器状态在每个 rank 上本地更新。

  • SHARD_GRAD_OP:梯度和优化器状态在计算过程中被分片,此外,参数在计算外部被分片。对于参数,此策略在前向传递之前取消分片,在前向传递之后不重新分片,仅在后向计算之后重新分片。分片优化器状态在每个 rank 上本地更新。在 no_sync() 内部,参数在后向计算之后不会被重新分片。

  • NO_SHARD:参数、梯度和优化器状态不被分片,而是像 PyTorch 的 DistributedDataParallel API 一样在 rank 之间复制。对于梯度,此策略在后向计算之后同步它们(通过 all-reduce)。未分片的优化器状态在每个 rank 上本地更新。

  • HYBRID_SHARD:在节点内应用 FULL_SHARD,并在节点之间复制参数。这会减少通信量,因为昂贵的 all-gather 和 reduce-scatter 操作仅在节点内进行,这对于中等规模的模型可能更有效。

  • _HYBRID_SHARD_ZERO2:在节点内应用 SHARD_GRAD_OP,并在节点之间复制参数。这类似于 HYBRID_SHARD,但可能提供更高的吞吐量,因为未分片的参数在后向传递之后不会被释放,从而节省了预后向传递中的 all-gather 操作。

class torch.distributed.fsdp.MixedPrecision(param_dtype=None, reduce_dtype=None, buffer_dtype=None, keep_low_precision_grads=False, cast_forward_inputs=False, cast_root_forward_inputs=True, _module_classes_to_ignore=(<class 'torch.nn.modules.batchnorm._BatchNorm'>, ))[source]#

此配置用于 FSDP 原生混合精度训练。

变量:
  • param_dtype (Optional[torch.dtype]) – 指定模型参数在前向和后向传递期间的 dtype,因此也是前向和后向计算的 dtype。在前向和后向传递之外,*分片* 的参数将保留为全精度(例如,用于优化器步骤),并且在模型检查点时,参数始终以全精度保存。(默认值:None

  • reduce_dtype (Optional[torch.dtype]) – 指定梯度归约(即 reduce-scatter 或 all-reduce)的 dtype。如果此项为 None,但 param_dtype 不为 None,则它将采用 param_dtype 的值,梯度归约仍以低精度运行。这可以与 param_dtype 不同,例如,强制梯度归约以全精度运行。(默认值:None

  • buffer_dtype (Optional[torch.dtype]) – 指定缓冲区(buffers)的 dtype。FSDP 不分片缓冲区。相反,FSDP 在第一次前向传递时将它们转换为 buffer_dtype,然后一直保持该 dtype。对于模型检查点,缓冲区将以全精度保存,但 LOCAL_STATE_DICT 除外。(默认值:None

  • keep_low_precision_grads (bool) – 如果为 False,则 FSDP 在后向传递后将梯度上溯到全精度,以准备优化器步骤。如果为 True,则 FSDP 将梯度保留在用于梯度归约的 dtype 中,如果使用支持低精度运行的自定义优化器,这可以节省内存。(默认值:False

  • cast_forward_inputs (bool) – 如果为 True,则此 FSDP 模块将其前向参数和关键字参数转换为 param_dtype。这是为了确保参数和输入的 dtype 在前向计算时匹配,因为许多操作都需要匹配。当仅对部分 FSDP 模块应用混合精度而不是全部时,可能需要将其设置为 True,在这种情况下,混合精度 FSDP 子模块需要重新转换其输入。(默认值:False

  • cast_root_forward_inputs (bool) – 如果为 True,则根 FSDP 模块将其前向参数和关键字参数转换为 param_dtype,这将覆盖 cast_forward_inputs 的值。对于非根 FSDP 模块,此设置无效。(默认值:True

  • _module_classes_to_ignore (collections.abc.Sequence[type[torch.nn.modules.module.Module]]) – (Sequence[Type[nn.Module]]): 此参数指定在使用 auto_wrap_policy 时要忽略混合精度的模块类别:这些类别的模块将单独应用 FSDP,并禁用混合精度(这意味着最终的 FSDP 构建将偏离指定的策略)。如果未指定 auto_wrap_policy,则此参数无效。此 API 是实验性的,可能会发生更改。(默认值:(_BatchNorm,)

注意

此 API 是实验性的,可能会发生更改。

注意

仅浮点张量会被转换为指定的 dtype。

注意

summon_full_params 中,参数被强制转换为全精度,但缓冲区不会。

注意

层归一化(Layer norm)和批归一化(batch norm)会在 float32 中累积,即使它们的输入是低精度(如 float16bfloat16)。禁用这些归一化模块的 FSDP 混合精度仅意味着仿射参数以 float32 保存。然而,这会为这些归一化模块带来单独的 all-gather 和 reduce-scatter 操作,这可能效率不高,因此如果工作负载允许,用户应优先考虑仍对这些模块应用混合精度。

注意

默认情况下,如果用户传入的包含任何 _BatchNorm 模块的模型并指定了 auto_wrap_policy,则批归一化模块将单独应用 FSDP,并禁用混合精度。请参阅 _module_classes_to_ignore 参数。

注意

MixedPrecision 默认具有 cast_root_forward_inputs=Truecast_forward_inputs=False。对于根 FSDP 实例,其 cast_root_forward_inputs 优先于其 cast_forward_inputs。对于非根 FSDP 实例,其 cast_root_forward_inputs 值将被忽略。默认设置对于每个 FSDP 实例具有相同的 MixedPrecision 配置,并且仅需要在模型前向传递开始时转换输入的典型情况已经足够。

注意

对于具有不同 MixedPrecision 配置的嵌套 FSDP 实例,我们建议设置单个 cast_forward_inputs 值来配置是否在每个实例的前向传递之前转换输入。在这种情况下,由于转换发生在每个 FSDP 实例的前向传递之前,父 FSDP 实例应在其非 FSDP 子模块运行之后再运行其 FSDP 子模块,以避免激活 dtype 因不同的 MixedPrecision 配置而改变。

示例

>>> model = nn.Sequential(nn.Linear(3, 3), nn.Linear(3, 3))
>>> model[1] = FSDP(
>>>     model[1],
>>>     mixed_precision=MixedPrecision(param_dtype=torch.float16, cast_forward_inputs=True),
>>> )
>>> model = FSDP(
>>>     model,
>>>     mixed_precision=MixedPrecision(param_dtype=torch.bfloat16, cast_forward_inputs=True),
>>> )

以上展示了一个工作示例。另一方面,如果 model[1] 被替换为 model[0],意味着使用不同 MixedPrecision 的子模块先运行其前向传递,那么 model[1] 将错误地看到 float16 激活而不是 bfloat16 激活。

class torch.distributed.fsdp.CPUOffload(offload_params=False)[source]#

此配置用于 CPU 卸载。

变量:

offload_params (bool) – 指定在参数不参与计算时是否卸载到 CPU。如果为 True,则也卸载梯度到 CPU,这意味着优化器步骤在 CPU 上运行。

class torch.distributed.fsdp.StateDictConfig(offload_to_cpu=False)[源代码]#

StateDictConfig 是所有 state_dict 配置类的基类。用户应实例化一个子类(例如 FullStateDictConfig),以便配置 FSDP 支持的相应 state_dict 类型的设置。

变量:

offload_to_cpu (bool) – 如果为 True,则 FSDP 将 state_dict 值卸载到 CPU,如果为 False,则 FSDP 将其保留在 GPU 上。(默认:False

class torch.distributed.fsdp.FullStateDictConfig(offload_to_cpu=False, rank0_only=False)[源代码]#

FullStateDictConfig 是用于 StateDictType.FULL_STATE_DICT 的配置类。我们建议在保存完整的 state_dict 时同时启用 offload_to_cpu=Truerank0_only=True,分别节省 GPU 内存和 CPU 内存。此配置类旨在通过 state_dict_type() 上下文管理器使用,如下所示:

>>> from torch.distributed.fsdp import FullyShardedDataParallel as FSDP
>>> fsdp = FSDP(model, auto_wrap_policy=...)
>>> cfg = FullStateDictConfig(offload_to_cpu=True, rank0_only=True)
>>> with FSDP.state_dict_type(fsdp, StateDictType.FULL_STATE_DICT, cfg):
>>>     state = fsdp.state_dict()
>>> # `state` will be empty on non rank 0 and contain CPU tensors on rank 0.
>>> # To reload checkpoint for inference, finetuning, transfer learning, etc:
>>> model = model_fn()  # Initialize model in preparation for wrapping with FSDP
>>> if dist.get_rank() == 0:
>>> # Load checkpoint only on rank 0 to avoid memory redundancy
>>>     state_dict = torch.load("my_checkpoint.pt")
>>>     model.load_state_dict(state_dict)
>>> # All ranks initialize FSDP module as usual. `sync_module_states` argument
>>> # communicates loaded checkpoint states from rank 0 to rest of the world.
>>> fsdp = FSDP(
...     model,
...     device_id=torch.cuda.current_device(),
...     auto_wrap_policy=...,
...     sync_module_states=True,
... )
>>> # After this point, all ranks have FSDP model with loaded checkpoint.
变量:

rank0_only (bool) – 如果为 True,则只有 rank 0 保存完整的 state_dict,非零 rank 保存一个空字典。如果为 False,则所有 rank 保存完整的 state_dict。(默认:False

class torch.distributed.fsdp.ShardedStateDictConfig(offload_to_cpu=False, _use_dtensor=False)[源代码]#

ShardedStateDictConfig 是用于 StateDictType.SHARDED_STATE_DICT 的配置类。

变量:

_use_dtensor (bool) – 如果为 True,则 FSDP 将 state_dict 的值保存为 DTensor,如果为 False,则 FSDP 将其保存为 ShardedTensor。(默认:False

警告

_use_dtensorShardedStateDictConfig 的私有字段,FSDP 使用它来确定 state_dict 值的类型。用户不应手动修改 _use_dtensor

class torch.distributed.fsdp.LocalStateDictConfig(offload_to_cpu: bool = False)[源代码]#
class torch.distributed.fsdp.OptimStateDictConfig(offload_to_cpu=True)[源代码]#

OptimStateDictConfig 是所有 optim_state_dict 配置类的基类。用户应实例化一个子类(例如 FullOptimStateDictConfig),以便配置 FSDP 支持的相应 optim_state_dict 类型的设置。

变量:

offload_to_cpu (bool) – 如果为 True,则 FSDP 将 state_dict 的张量值卸载到 CPU,如果为 False,则 FSDP 将其保留在原始设备上(除非启用了参数 CPU 卸载,否则为 GPU)。(默认:True

class torch.distributed.fsdp.FullOptimStateDictConfig(offload_to_cpu=True, rank0_only=False)[源代码]#
变量:

rank0_only (bool) – 如果为 True,则只有 rank 0 保存完整的 state_dict,非零 rank 保存一个空字典。如果为 False,则所有 rank 保存完整的 state_dict。(默认:False

class torch.distributed.fsdp.ShardedOptimStateDictConfig(offload_to_cpu=True, _use_dtensor=False)[源代码]#

ShardedOptimStateDictConfig 是用于 StateDictType.SHARDED_STATE_DICT 的配置类。

变量:

_use_dtensor (bool) – 如果为 True,则 FSDP 将 state_dict 的值保存为 DTensor,如果为 False,则 FSDP 将其保存为 ShardedTensor。(默认:False

警告

_use_dtensorShardedOptimStateDictConfig 的私有字段,FSDP 使用它来确定 state_dict 值的类型。用户不应手动修改 _use_dtensor

class torch.distributed.fsdp.LocalOptimStateDictConfig(offload_to_cpu: bool = False)[源代码]#
class torch.distributed.fsdp.StateDictSettings(state_dict_type: torch.distributed.fsdp.api.StateDictType, state_dict_config: torch.distributed.fsdp.api.StateDictConfig, optim_state_dict_config: torch.distributed.fsdp.api.OptimStateDictConfig)[源代码]#