FullyShardedDataParallel¶
- 类 torch.distributed.fsdp 中。FullyShardedDataParallel(module, process_group=无, sharding_strategy=无, cpu_offload=无, auto_wrap_policy=无,backward_prefetch=BackwardPrefetch.BACKWARD_PRE,mixed_precision=无,ignored_modules=无,param_init_fn=无、device_id=无、sync_module_states=False、forward_prefetch=False、limit_all_gathers=False、use_orig_params=False, ignored_parameters=None)[来源]¶
用于跨数据并行工作程序对 Module 参数进行分片的包装器。这 的灵感来自 Xu 等人以及 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 将就地分片参数,这将破坏任何 以前初始化的优化器。
警告
如果目标 CUDA 设备具有 ID ,则 (1) 应已放置在该设备上,(2) 设备 应该使用 , 进行设置,或者 (3) 应该传递到构造函数中 论点。此 FSDP 实例的计算设备将是该目标 装置。对于 (1) 和 (3),FSDP 初始化始终在 GPU 上进行。 对于 (2),FSDP 初始化发生在 的当前 device,可能是 CPU。
dev_id
module
torch.cuda.set_device(dev_id)
dev_id
device_id
module
警告
FSDP 目前不支持在使用 CPU 卸载时在外部进行梯度累积。尝试这样做会产生 结果不正确,因为 FSDP 将使用新降低的梯度 而不是与任何现有梯度累积。
no_sync()
警告
构造后更改原始参数变量名称将 导致未定义的行为。
警告
传入 sync_module_states=True 标志需要将 module 在 GPU 上,或使用参数指定 CUDA 设备 FSDP 将 move module to.这是因为需要 GPU 通信。
device_id
sync_module_states=True
警告
从 PyTorch 1.12 开始,FSDP 仅提供对共享参数的有限支持 (例如,将一个图层的权重设置为另一个图层的权重)。在 特别是,共享参数的模块必须包装为 相同的 FSDP 单元。如果您的 使用案例,请 ping https://github.com/pytorch/pytorch/issues/77724
Linear
注意
FSDP 函数的输入将移动到计算设备 (同一设备 FSDP 模块开启)之前,因此用户执行 不必手动从 CPU > GPU 移动输入。
forward
forward
- 参数
模块 (nn.Module) – 这是要使用 FSDP 包装的模块。
process_group (optional[Union[ProcessGroup, Tuple[ProcessGroup, ProcessGroup]]]) – 可选[Union[ProcessGroup, Tuple[ProcessGroup, ProcessGroup]]] 这是用于集体通信的进程组, 模型分片的那个。对于混合分片策略,例如 用户可以 传入一个进程组元组,这些进程组表示要分片和复制的组, 分别。
ShardingStrategy.HYBRID_SHARD
sharding_strategy (Optional[ShardingStrategy]) – 配置 FSDP 使用的分片策略,该策略可以交易 关闭内存节省和通信开销。有关详细信息,请参阅
。(默认:
FULL_SHARD
)cpu_offload (Optional[CPUOffload]) – 这将配置 CPU 卸载。如果此设置为 ,则 不会发生 CPU 卸载。有关详细信息,请参阅
。 (默认:
None
None
)auto_wrap_policy (可选[Union[Callable[[nn.模块, bool, int], bool], _FSDPPolicy]]) –
这是 、 、 或 的可调用 对象 固定签名。如果是 ,则 包装 只有一个顶级 FSDP 实例,没有任何嵌套包装。如果 它是一个 ,则换行遵循给定的 政策。 in 就是一个例子。如果它是一个可调用的,那么它应该接受三个 arguments , , 和 and 应返回一个指定的 传入的 Conf-In 是否应该被包装,如果遍历应该继续向下遍历 subtree 如果 .其他自定义参数可以是 添加到 callable 中。in 给出了一个 callable 示例, 如果模块的子树中的参数超过 100M numel,则包装模块。 一个好的做法是在包装后打印模型并调整为 需要。
None
_FSDPPolicy
None
module
_FSDPPolicy
ModuleWrapPolicy
torch.distributed.fsdp.wrap.py
module: nn.Module
recurse: bool
nonwrapped_numel: int
bool
module
recurse=False
recurse=True
size_based_auto_wrap_policy
torch.distributed.fsdp.wrap.py
例:
>>> 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]) – 这将配置所有收集的显式向后预取。有关详细信息,请参阅
。(默认:
BACKWARD_PRE
)mixed_precision (Optional[MixedPrecision]) – 这将为 FSDP 配置本机混合精度。如果设置为 ,则不使用混合精度。否则,参数 buffer 和 gradient reduction dtypes 的 d类型。有关详细信息,请参阅
。(默认:
None
None
)ignored_modules (Optional[Iterable[torch.nn.Module]]) – 其 自己的 parameters 和子模块的 parameters 和 buffer 是 被此实例忽略。直接进入的模块都不应该是
实例,并且任何已经构造
的子模块都不会被忽略,如果 它们嵌套在此实例下。此参数可用于 在使用 OR 参数的分片未由 FSDP.(默认:
ignored_modules
auto_wrap_policy
None
)param_init_fn (可选[Callable[[nn.模块],无]]) –
一个 指定当前位于 meta 设备上的模块应如何初始化 拖动到实际设备上。请注意,从 v1.12 开始,我们在 meta device 并应用默认初始化,该初始化在传入的 if 上调用方法,否则我们运行以初始化传入的 在。具体而言,这意味着如果对于任何 module 参数,则假定你的模块正确实现了 a,否则将引发错误。请注意,我们还提供对模块的支持 使用 torchdistX 的 (https://github.com/pytorch/torchdistX) API 初始化。在这种情况下,将初始化延迟的模块 通过调用 torchdistX 的默认初始化函数,如果不是,则调用传入的 。这同样适用于初始化所有 meta 模块。 请注意,此初始化函数在执行任何 FSDP 分片之前应用 逻辑。
Callable[torch.nn.Module] -> None
is_meta
reset_parameters
nn.Module
param_init_fn
param_init_fn
nn.Module
is_meta=True
param_init_fn
reset_parameters()
deferred_init
materialize_module
param_init_fn
None
Callable
例:
>>> module = MyModule(device="meta") >>> def my_init_fn(module): >>> # responsible for initializing a module, such as with reset_parameters >>> ... >>> 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]]) – 描述 FSDP 模块应移动到的 CUDA 设备的 或,以确定 FSDP 模块的位置 进行分片等初始化。如果未指定此参数 并且位于 CPU 上,我们会发出警告,指出此参数可以 指定以加快初始化速度。如果指定,则生成的 FSDP 实例 将驻留在此设备上,包括移动被忽略的模块的参数 需要。请注意,如果指定了 if 但已在 不同的 CUDA 设备,则会引发错误。(默认:
int
torch.device
module
device_id
module
None
)sync_module_states (bool) – 如果,每个单独包装的 FSDP 单元将广播 module 参数,以确保它们在 0 之后的所有等级中都相同 初始化。这有助于确保模型参数在不同等级之间相同 ,但至少会给 增加通信开销 每个单独包装的 FSDP 单元触发一次广播。 这也有助于以内存高效的方式加载 Takes Taken 和 To be loading 的 checkpoint。有关此示例,请参阅文档。(默认:
True
__init__
state_dict
load_state_dict
FullStateDictConfig
False
)forward_prefetch (bool) – 如果 ,则 FSDP 显式预取 在 forward pass 中执行时,下一个即将到来的 all-gather。 这可能会改善 CPU 的通信和计算重叠 绑定工作负载。这应该仅用于静态图形模型 由于正向顺序是根据第一次迭代的 执行。(默认:
True
False
)limit_all_gathers (bool) – 如果 ,则 FSDP 允许 CPU thread 来调度 all-gathers,而无需任何额外的同步。 如果 ,则 FSDP 将 CPU 线程显式同步到 防止过多的 In-Running All-Gathers。这只会影响 安排 All-Gather 的分片策略。启用此功能可以 帮助减少 CUDA malloc 重试次数。
False
True
bool
ignored_parameters (Optional[Iterable[torch.nn.Parameter]]) – 忽略 parameters 将不受此 FSDP 实例的管理, 这意味着这些参数不会被 FSDP 扁平化和分片, 它们的梯度也不会同步。有了这个新添加的 参数,可能很快就会被弃用。为了向后兼容, 两者都暂时保留, 但 FSDP 只允许将其中一个指定为 not 。
ignored_modules
ignored_parameters
ignored_modules
None
- apply(fn)[来源]¶
递归应用于每个子模块(由 ) 以及自我。典型用途包括初始化模型的参数 (另请参见 torch.nn.init)。
fn
.children()
与 相比,此版本还收集了 应用之前的完整参数。它不应从 在另一个上下文中。
torch.nn.Module.apply
fn
summon_full_params
- 参数
fn ( -> None) – 要应用于每个子模块的函数
Module
- 结果
自我
- 返回类型:
- clip_grad_norm_(max_norm, norm_type=2.0)[来源]¶
剪辑所有参数的渐变范数。范数是通过 所有参数的梯度都视为单个向量,并且 渐变是就地修改的。
- 参数
- 结果
参数的总范数(视为单个向量)。
- 返回类型:
注意
返回的总范数将具有“最大”的 dtype PyTorch 的类型提升定义的所有参数/梯度 语义学。例如,如果所有参数/梯度都使用低 precision dtype 的 vtype 中,则返回的 norm 的 dtype 将如此之低 precision dtype,但如果至少存在一个 parameter/ gradient 一起使用 FP32,则返回的 norm 的 dtype 将为 FP32。
警告
这需要在所有等级上调用,因为它使用 集体通信。
- static flatten_sharded_optim_state_dict(sharded_optim_state_dict, model, optim)[来源]¶
API 类似于
.唯一的 区别在于 input 应该是 从 返回。
因此,将 在每个等级上调用 All-gather 以收集 S。
sharded_optim_state_dict
ShardedTensor
- 参数
sharded_optim_state_dict (Dict[str, Any]) – 优化器状态 dict 对应于未展平的参数,并按住 sharded optimizer 状态。
model (torch.nn.Module) – 请参阅 :meth:。
shard_full_optim_state_dict
optim (torch.optim.Optimizer) – 的 Optimizer
model
参数。–
- 结果
- 返回类型:
- static fsdp_modules(module, root_only=False)[来源]¶
返回所有嵌套的 FSDP 实例,可能包括其自身 并且仅在 .
module
root_only=True
- 参数
module (torch.nn.Module) – 根模块,可以是模块,也可以是模块。
FSDP
root_only (bool) – 是否仅返回 FSDP 根模块。 (默认:
False
)
- 结果
嵌套在 输入 .
module
- 返回类型:
- static full_optim_state_dict(model, optim, optim_input=None, rank0_only=True, group=None)[来源]¶
合并排名 0 上的完整优化器状态并返回它
遵循 的约定
,即使用键和 。模块中扁平化的参数 包含在 中,则映射回其未拼合的参数。
"state"
"param_groups"
FSDP
model
警告
与 不同,此方法 使用完整的参数名称作为键,而不是参数 ID。
torch.optim.Optimizer.state_dict()
- 参数
model (torch.nn.Module) – 根模块 (可以是也可能不是
实例),其参数 传递到 Optimizer 中。
optim
optim (torch.optim.Optimizer) – 的 Optimizer 参数。
model
optim_input (Optional[Union[List[Dict[str, Any]], Iterable[torch.nn.Parameter]]]) – 传入优化器的输入,表示
of 参数组或参数的可迭代对象; 如果 ,则此方法假定输入为 。此参数已弃用,并且 无需再传入。(默认:
optim
None
model.parameters()
None
)rank0_only (bool) – 如果 ,则仅保存排名 0 上填充
的内容;if ,则将其保存在所有等级上。(默认:
True
False
True
)组 (dist.ProcessGroup) – 模型的进程组,或者如果使用 默认进程组。(默认:
None
None
)
- 结果
A
包含 的原始未拼合参数的优化器状态,并包含键 “state” 和 “param_groups” 遵循
.如果 则非零排名返回空
。
model
rank0_only=True
- 返回类型:
Dict[str, 任意]
- static load_optim_state_dict_pre_hook(model, optim, optim_state_dict, group=None)[来源]¶
此钩子旨在由 . 除了不同的参数外,函数性与 相同。
torch.distributed.NamedOptimizer
:meth:optim_state_dict_to_load
- 参数
model (torch.nn.Module) – 根模块 (可以是也可能不是
实例),其参数 传递到 Optimizer 中。
optim
optim (torch.optim.Optimizer) – 的 Optimizer 参数。
model
optim_state_dict (Dict[str, Any]) – 要加载的优化器状态。
组 (dist.ProcessGroup) – 模型的流程组,参数 分片,或者使用默认进程组。( 违约:
None
None
)
- 返回类型:
- named_buffers(*args, **kwargs)[来源]¶
用于拦截缓冲区名称的覆盖
,以及 删除所有出现的特定于 FSDP 的扁平化缓冲区前缀 当进入 Context Manager 中
时。
- named_parameters(*args, **kwargs)[来源]¶
用于拦截参数名称的 overrides
和 删除所有出现的特定于 FSDP 的扁平化参数前缀 当进入 Context Manager 中
时。
- no_sync()[来源]¶
用于禁用跨 FSDP 的梯度同步的上下文管理器 实例。在此上下文中,梯度将在 module 中累积 变量,稍后将在第一个 forward-backward 传递。这应该只是 在根 FSDP 实例上使用,并将递归地应用于所有 子 FSDP 实例。
注意
这可能会导致更高的内存使用率,因为 FSDP 会 累积完整的模型梯度(而不是梯度分片) 直到最终同步。
注意
当与 CPU 卸载一起使用时,梯度不会 在 Context Manager 中卸载到 CPU。相反,他们 只会在最终同步后立即卸载。
- 返回类型:
- static optim_state_dict(model, optim, group=None)[来源]¶
返回 的状态 dict 为 (部分) 由 FSDP 分片。状态可以分片、合并或合并 排名 0 仅取决于 或
的设置。
optim
model
state_dict_type
例:
>>> 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_checkponit() >>> 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( >>> optim_state_dict, model, optim >>> ) >>> optim.load_state_dict(optim_state_dict)
- 参数
model (torch.nn.Module) – 根模块 (可以是也可能不是
实例),其参数 传递到 Optimizer 中。
optim
optim (torch.optim.Optimizer) – 的 Optimizer 参数。
model
组 (dist.ProcessGroup) – 模型的流程组,参数 分片,或者使用默认进程组。( 违约:
None
None
)
- 结果
- 返回类型:
Dict[str, 任意]
- static optim_state_dict_post_hook(model, optim, optim_state_dict, group=None)[来源]¶
此钩子旨在由 . 函数性与 except 对于不同的参数。
torch.distributed.NamedOptimizer
:meth:optim_state_dict
- 参数
model (torch.nn.Module) – 根模块 (可以是也可能不是
实例),其参数 传递到 Optimizer 中。
optim
optim (torch.optim.Optimizer) – 的 Optimizer 参数。
model
(Dict[str (optim) – 要覆盖的optim_state_dict。价值 通常由 .
NamedOptimizer.state_dict()
Any]– 要覆盖的optim_state_dict。价值 通常由 .
NamedOptimizer.state_dict()
组 (dist.ProcessGroup) – 模型的流程组,参数 分片,或者使用默认进程组。( 违约:
None
None
)
- 结果
- 返回类型:
Dict[str, 任意]
- static optim_state_dict_to_load(optim_state_dict, model, optim, is_named_optimizer=False, group=None)[来源]¶
给定一个 saved ,将其转换为优化器 state_dict ,可以加载到 中,它是 的优化器。 由 FullyShardedDataParallel (部分) 分片。
optim_state_dict
optim
model
model
>>> 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_checkponit() >>> 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( >>> optim_state_dict, model, optim >>> ) >>> optim.load_state_dict(optim_state_dict)
- 参数
optim_state_dict (Dict[str, Any]) – 要加载的优化器状态。
model (torch.nn.Module) – 根模块 (可以是也可能不是
实例),其参数 传递到 Optimizer 中。
optim
optim (torch.optim.Optimizer) – 的 Optimizer 参数。
model
is_named_optimizer (bool) – 这个优化器是 NamedOptimizer 还是 KeyedOptimizer 的 API 中。仅当 TorchRec 的 KeyedOptimizer 或 torch.distributed 的 NamedOptimizer 的 NamedOptimizer 中。
optim
组 (dist.ProcessGroup) – 模型的流程组,参数 分片,或者使用默认进程组。( 违约:
None
None
)
- 返回类型:
- register_comm_hook(state, hook)[来源]¶
注册一个通信钩子,这是一个增强功能,它提供了一个 灵活的钩子,用户可以在其中指定 FSDP 如何聚合梯度 跨多个 worker。 这个钩子可以用来实现多种算法,比如 GossipGrad 和梯度压缩 其中涉及不同的沟通策略 参数
同步。
警告
在运行初始正向传递之前,应注册 FSDP 通信钩子 而且只有一次。
- 参数
状态 (对象) –
传递给 hook 以在训练过程中维护任何状态信息。 示例包括梯度压缩中的误差反馈、 peer 来与 gossipGrad 中的 next 通信,等等。 它由每个 worker 本地存储 并由 worker 上的所有梯度张量共享。
hook (Callable) – 可调用,具有以下签名之一: 1) : 此函数接受一个 Python 张量,该张量表示 相对于所有变量的完整、扁平化、未分片的梯度 对应于此 FSDP 单元正在包装的模型 (未被其他 FSDP 子单位包裹)。 然后,它执行所有必要的处理并返回 ; 2) : 此函数接受两个 Python 张量,第一个表示 相对于所有变量的完整、扁平化、未分片的梯度 对应于此 FSDP 单元正在包装的模型 (未被其他 FSDP 子单位包裹)。后者 表示一个预先调整大小的张量,用于在 减少。 在这两种情况下, callable 都会执行所有必要的处理并返回 。 签名为 1 的可调用对象应处理 NO_SHARD 情况下的梯度通信。 签名为 2 的可调用对象应处理分片案例的梯度通信。
hook: Callable[torch.Tensor] -> None
None
hook: Callable[torch.Tensor, torch.Tensor] -> None
None
- static rekey_optim_state_dict(optim_state_dict, optim_state_key_type, model, optim_input=None, optim=None)[来源]¶
重新对优化器 state dict 进行 key 操作以使用 key 类型。这可以用来实现 来自 FSDP 的模型的优化器 state dict 之间的兼容性 实例和没有的实例。
optim_state_dict
optim_state_key_type
要重新键入 FSDP 完整优化器状态 dict(即 from
)以使用参数 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)
要将普通优化器 state dict 从未包装模型重新生成密钥,请将其设置为 loadable to a wrapped model 的
>>> 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)
- 结果
优化器状态 dict 使用 由 指定的参数键。
optim_state_key_type
- 返回类型:
Dict[str, 任意]
- static scatter_full_optim_state_dict(full_optim_state_dict, model, optim_input=None, optim=None, group=None)[来源]¶
将完整的优化器状态字典从等级 0 分散到所有其他等级, 返回每个排名的分片优化器状态 dict。回归 value 与
相同,并且 rank 0,则第一个参数应为 的返回值
。
例:
>>> 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)
注意
Both
和
都可用于获取 分片优化器状态 dict 来加载。假设 full optimizer state dict 驻留在 CPU 内存中,前者需要 每个 rank 在 CPU 内存中拥有完整的 dict,其中每个 rank 单独对 dict 进行分片而不进行任何通信,而 后者只需要 rank 0 即可在 CPU 内存中拥有完整的 dict, 其中,排名 0 将每个分片移动到 GPU 内存(对于 NCCL),并且 适当地将其传达给 Rank。因此,前者具有 更高的总 CPU 内存成本,而后者具有更高的 通信成本。
- 参数
full_optim_state_dict (Optional[Dict[str, Any]]) – 优化器状态 dict 对应的未扁平化参数,并按住 如果处于 rank 0 上,则为完整的非分片优化器状态;参数 在非零等级上被忽略。
model (torch.nn.Module) – 根模块 (可以是也可能不是
实例),其参数 对应于 中的优化器状态。
full_optim_state_dict
optim_input (Optional[Union[List[Dict[str, Any]], Iterable[torch.nn.Parameter]]]) – 传入优化器的输入,表示
of 参数组或参数的可迭代对象; 如果 ,则此方法假定输入为 。此参数已弃用,并且 无需再传入。(默认:
None
model.parameters()
None
)optim (Optional[torch.optim.Optimizer]) – 将加载的优化器 此方法返回的 state dict。这是首选 参数以用于 。(默认:
optim_input
None
)组 (dist.ProcessGroup) – 模型的进程组,或者如果 使用默认进程组。(默认:
None
None
)
- 结果
完整的优化器状态 dict 现在重新映射到 展平参数而不是未展平参数,以及 restricted 以仅包含此 rank 的 Optimizer 状态部分。
- 返回类型:
Dict[str, 任意]
- static set_state_dict_type(module, state_dict_type, state_dict_config=None, optim_state_dict_config=None)[来源]¶
设置 和 相应的 (可选) 目标模块的所有后代 FSDP 模块的配置。 目标模块不必是 FSDP 模块。如果目标 module 是 FSDP 模块,它也会被更改。
state_dict_type
state_dict_type
注意
此 API 应仅针对顶级 (root) 调用 模块。
注意
此 API 使用户能够透明地使用传统 API 来获取模型检查点,在这种情况下, 根 FSDP 模块由另一个 .例如 以下内容将确保在所有非 FSDP 上调用 实例,同时分派到sharded_state_dict实现 对于 FSDP:
state_dict
nn.Module
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
- 结果
一个 StateDictSettings,其中包含前面的 state_dict 类型和 模块的配置。
- 返回类型:
StateDict设置
- static shard_full_optim_state_dict(full_optim_state_dict, model, optim_input=None, optim=None)[来源]¶
按以下方式对完整的优化器 state dict 进行分片 将状态重新映射到 flattened 参数,而不是 unflattened 参数 参数,并限制为仅优化器的此 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)
注意
Both
和
都可用于获取 分片优化器状态 dict 来加载。假设 full optimizer state dict 驻留在 CPU 内存中,前者需要 每个 rank 在 CPU 内存中拥有完整的 dict,其中每个 rank 单独对 dict 进行分片而不进行任何通信,而 后者只需要 rank 0 即可在 CPU 内存中拥有完整的 dict, 其中,排名 0 将每个分片移动到 GPU 内存(对于 NCCL),并且 适当地将其传达给 Rank。因此,前者具有 更高的总 CPU 内存成本,而后者具有更高的 通信成本。
- 参数
full_optim_state_dict (Dict[str, Any]) – 优化器状态 dict 对应于未展平的参数,并按住 full non-sharded optimizer 状态。
model (torch.nn.Module) – 根模块 (可以是也可能不是
实例),其参数 对应于 中的优化器状态。
full_optim_state_dict
optim_input (Optional[Union[List[Dict[str, Any]], Iterable[torch.nn.Parameter]]]) – 传入优化器的输入,表示
of 参数组或参数的可迭代对象; 如果 ,则此方法假定输入为 。此参数已弃用,并且 无需再传入。(默认:
None
model.parameters()
None
)optim (Optional[torch.optim.Optimizer]) – 将加载的优化器 此方法返回的 state dict。这是首选 参数以用于 。(默认:
optim_input
None
)
- 结果
完整的优化器状态 dict 现在重新映射到 展平参数而不是未展平参数,以及 restricted 以仅包含此 rank 的 Optimizer 状态部分。
- 返回类型:
Dict[str, 任意]
- static sharded_optim_state_dict(model, optim, group=None)[来源]¶
API 类似于
此 API 块 所有非零维状态以节省内存。 此 API 应仅在派生模型时使用 与 Context Manager 一起使用。
ShardedTensor
state_dict
with state_dict_type(SHARDED_STATE_DICT):
警告
返回的 state dict 包含 和 不能被常规 直接使用。
ShardedTensor
optim.load_state_dict
- static state_dict_type(module, state_dict_type, state_dict_config=None, optim_state_dict_config=None)[来源]¶
一个上下文管理器,用于设置所有 descendant 目标模块的 FSDP 模块。此上下文管理器具有相同的 函数设置为
.有关详细信息,请阅读 文档
。
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
- 返回类型:
- static summon_full_params(module, recurse=True, writeback=True, rank0_only=False, offload_to_cpu=False, with_grads=False)[来源]¶
一个上下文管理器,用于公开 FSDP 实例的完整参数。 在前进/后退后,模型可以得到 用于其他处理或检查的参数。它可以采用非 FSDP 模块,并将为所有包含的 FSDP 模块调用完整的参数作为 以及他们的孩子,这取决于争论。
recurse
注意
这可用于内部 FSDP。
注意
这不能在向前或向后传递中使用。也不 可以从此上下文中启动 forward 和 backward。
注意
参数将在上下文之后恢复为其本地分片 manager 退出时,存储行为与 forward 相同。
注意
可以修改 full 参数,但只能修改 portion 对应的本地参数分片将在 上下文管理器退出(除非 ,在这种情况下 更改将被丢弃)。在 FSDP 不分片的情况下 参数(当前仅在 、 或 config 时)保留修改,而不管 .
writeback=False
world_size == 1
NO_SHARD
writeback
注意
此方法适用于本身不是 FSDP 但 可能包含多个独立的 FSDP 商品。在这种情况下,给定的 参数将应用于所有包含的 FSDP 单位。
警告
请注意,目前不支持 with 结合使用,并且会引发 错误。这是因为模型参数形状会有所不同 在上下文中跨等级,并写入它们可能会导致 退出上下文时等级之间的不一致。
rank0_only=True
writeback=True
警告
请注意,和 will 导致完整参数被冗余复制到 CPU 内存 GPU 位于同一台计算机上,这可能会产生 CPU OOM 的 OOM 中。建议与 一起使用。
offload_to_cpu
rank0_only=False
offload_to_cpu
rank0_only=True
- 参数
recurse (bool, 可选) – 递归调用嵌套的所有参数 FSDP 实例 (默认值:True)。
writeback (bool, Optional) – 如果 ,对参数的修改是 在上下文管理器退出后丢弃; 禁用此选项可能会稍微更有效(默认值:True)
False
rank0_only (bool, 可选) – 如果 ,则完整参数为 仅在全局排名 0 上实现。这意味着,在 context,只有排名 0 才会有完整的参数,而其他 ranks 将具有分片参数。请注意,不支持 with 的设置, 因为模型参数形状会因等级而异 在上下文中,写入它们可能会导致 退出上下文时等级之间的不一致。
True
rank0_only=True
writeback=True
offload_to_cpu (bool, Optional) – 如果 ,则完整参数为 卸载到 CPU。请注意,此卸载目前仅 如果参数是分片的(但事实并非如此,则会出现 对于 world_size = 1 或 config)。推荐 与 to use 搭配 to avoid 模型参数的冗余副本被卸载到相同的 CPU 内存。
True
NO_SHARD
offload_to_cpu
rank0_only=True
with_grads (bool, Optional) – 如果 ,则梯度也是 unsharded 替换为参数。目前,这只是 传递到 FSDP 时受支持 constructor 和此方法。 (默认:
True
use_orig_params=True
offload_to_cpu=False
False
)
- 返回类型:
- 类 torch.distributed.fsdp 中。BackwardPrefetch(value)[来源]¶
这将配置显式向后预取,从而提高吞吐量 但可能会略微增加峰值内存使用量。
对于 NCCL 后端,任何 collective,即使是在不同的流中发布的, 争用相同的每个设备 NCCL 流,这就是为什么相对 集体的发布顺序是重叠的。这 不同的向后预取设置对应于不同的顺序。
BACKWARD_PRE
:这将预取 当前 set of parameter 的 gradient computation。这向后改进 通过重叠通信 (NEXT All-Gather) 传递吞吐量,以及 计算(当前梯度计算)。BACKWARD_POST
:这将预取 当前 set of parameter 的 gradient computation。这可能会有所改善 通过重叠通信实现的向后传递吞吐量(当前 reduce-scatter)和 computation(下一个梯度计算)。 具体来说,下一个 all-gather 将重新排序为在当前 reduce-scatter 的 Reduce-Scatter 中。
注意
如果预取导致的峰值内存使用量增加为 问题,您可以考虑传递给 FSDP 构造函数,这在某些情况下可能有助于减少峰值内存使用量。
limit_all_gathers=True
- 类 torch.distributed.fsdp 中。ShardingStrategy(value)[来源]¶
-
FULL_SHARD
:参数、梯度和优化器状态被分片。 对于参数,此策略在 forward,在 forward 之后重新分片,在 backward 之前取消分片 计算,并在向后计算后重新分片。对于渐变, 它会在 backward 计算。分片优化器状态按排名在本地更新。SHARD_GRAD_OP
:梯度和优化器状态在 计算,此外,参数在外部分片 计算。对于参数,此策略在 forward 的 Forward 函数,不会在 forward 之后重新分片它们,而只对它们进行重新分片 在反向计算之后。分片优化器状态已更新 本地每个等级。在 Inside 中,参数不会重新分片 在反向计算之后。no_sync()
NO_SHARD
:参数、梯度和优化器状态未分片 而是跨等级复制,类似于 PyTorch 的 API。对于梯度,此策略 在反向计算后同步它们(通过 all-reduce)。这 未分片的优化器状态按排名在本地更新。DistributedDataParallel
HYBRID_SHARD
:在节点内应用,并跨节点复制参数FULL_SHARD
节点。这会导致通信量减少,因为昂贵的 all-gathers 和 reduce-scatters 仅在节点内完成,这对于 medium 来说可能性能更高 -大小的模型。
_HYBRID_SHARD_ZERO2
:在节点内应用,并跨节点复制参数SHARD_GRAD_OP
节点。这与 类似,不同之处在于这可能会提供更高的吞吐量 由于未分片的参数在正向传递后不会释放,因此将 all-gathers 在 pre-backward 中。
HYBRID_SHARD
- 类 torch.distributed.fsdp 中。MixedPrecision(param_dtype=无, reduce_dtype=无, buffer_dtype=无, keep_low_precision_grads=False, cast_forward_inputs=False, cast_root_forward_inputs=True)[来源]¶
这将配置 FSDP 原生混合精度训练。
- 变量:
param_dtype (torch.dtype) – 这指定了 model 的 dtype parameters、inputs(when 或 )以及用于计算的 dtype 。 但是,在向前和向后传递之外,参数位于 全精度。模型检查点总是完全发生 精度。
cast_forward_inputs
cast_root_forward_inputs``is set to ``True
reduce_dtype (torch.dtype) – 指定梯度的 dtype reduction 的 intent 函数,该 URL 允许与 .
param_dtype
buffer_dtype (torch.dtype) – 指定缓冲区的 dtype。FSDP 不分片缓冲区,将它们强制转换到第一个 forward 传递,并在此后将它们保持在该 dtype 中。型 checkpointing 总是以完全精确的方式进行。
buffer_dtype
keep_low_precision_grads (bool) – 指定是否进行上转换 梯度返回到 backward 之后的完整参数精度 通过。如果使用自定义 可以执行 中的优化器步骤的优化器。 (默认:
False
reduce_dtype
False
)cast_forward_inputs (bool) – 在前向转换浮点张量 arguments 和 keyword arguments 设置为 . (默认:
param_dtype
False
)cast_root_forward_inputs (bool) – 在前向转换浮点张量 arguments 和 keyword arguments 的 URL。 它优先于根 FSDP 实例。 (默认:
param_dtype
cast_forward_inputs
True
)
注意
此 API 是实验性的,可能会发生更改。
注意
只有浮点张量才会强制转换为其指定的 dtype。
注意
在 中,参数被强制为 full 精度,但缓冲区不是。
summon_full_params
注意
state_dict
检查点参数和缓冲区完整 精度。对于缓冲区,仅支持 。StateDictType.FULL_STATE_DICT
注意
必须显式指定每个低精度 dtype。为 example,则仅指定 reduction dtype 设置为低精度,并且 FSDP 不会强制转换 参数或缓冲区。
MixedPrecision(reduce_dtype=torch.float16)
注意
如果未指定 a,则梯度缩减 发生在 if specified 或原始参数 dtype 中 否则。
reduce_dtype
param_dtype
注意
如果用户将带有模块的模型和 an 传递给 FSDP 构造函数,则 FSDP 将禁用 通过单独包装模块来混合精度 在他们自己的 FSDP 实例中禁用混合精度。这是由于 到一些缺失的低精度内核。如果用户执行 不使用 ,则用户必须注意不要 对包含模块的 FSDP 实例使用混合精度。
BatchNorm
auto_wrap_policy
BatchNorm
BatchNorm
auto_wrap_policy
BatchNorm
注意
MixedPrecision
has 和 default 的 。对于根 FSDP 实例, 它的优先级高于它的 。对于非根 FSDP 实例,将忽略其值。默认设置为 对于每个 FSDP 实例具有相同的 configuration 并且只需要在模型的 forward pass 开始时将 input 转换为 的典型情况来说就足够了。cast_root_forward_inputs=True
cast_forward_inputs=False
cast_root_forward_inputs
cast_forward_inputs
cast_root_forward_inputs
MixedPrecision
param_dtype
注意
对于具有不同配置的嵌套 FSDP 实例,我们建议在每个实例的 向前。在这种情况下,由于强制转换发生在每个 FSDP 之前 实例的转发,父 FSDP 实例应具有其非 FSDP 子模块在其 FSDP 子模块之前运行,以避免激活 dtype 由于配置不同而更改。
MixedPrecision
cast_forward_inputs
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), >>> )
上面显示了一个工作示例。另一方面,如果被替换为 ,这意味着使用 different 首先向前运行,然后会错误地看到 activations 而不是 activations。
model[1]
model[0]
MixedPrecision
model[1]
float16
bfloat16