重要提示
您正在查看 NeMo 2.0 文档。此版本引入了对 API 和新库 NeMo Run 的重大更改。我们目前正在将 NeMo 1.0 的所有功能移植到 2.0。有关先前版本或 2.0 中尚不可用的功能的文档,请参阅 NeMo 24.07 文档。
Adapters API#
核心#
- class nemo.core.adapter_mixins.AdapterModuleMixin
基类:
ABC
通用适配器 Mixin,可以为任何 torch.nn.Module 增强适配器模块支持。
此 mixin 类添加了一种分层方式,可以将任何类型的适配器模块添加到预先存在的模块。由于模型本质上也是 nn.Module,因此此 mixin 可以附加到任何模型或模块。此 mixin 类添加了几个实用程序方法,这些方法根据需要被使用或覆盖。
适配器模块是任何 Pytorch nn.Module,它具有以下几个属性
它的输入和输出维度相同,而隐藏维度不必相同。
- 适配器模块的最后一层被零初始化,以便到适配器的残差连接
产生原始输出。
此 mixin 将以下实例变量添加到继承它的类中
- adapter_layer:一个 torch.nn.ModuleDict(),其键是适配器的名称(全局唯一),
值是 Adapter nn.Module()。
adapter_cfg:一个 OmegaConf DictConfig 对象,它保存已初始化的适配器的配置。
- adapter_name:一个 str 解析名称,它是全局唯一的键,但多个模块可以共享
此名称。
- adapter_global_cfg_key:一个 str,表示模型配置中的一个键,用户可以提供该键。
该值解析为 global_cfg,可以通过 model.cfg.adapters.global_cfg.* 覆盖。
- adapter_metadata_cfg_key:一个 str,表示模型配置中的一个键,用于保留
适配器配置的元数据。
注意
此模块 不 负责维护其配置。子类必须确保根据需要更新或保留配置。子类有责任将最新的配置传播到较低层。
- adapter_global_cfg_key = 'global_cfg'
- adapter_metadata_cfg_key = 'adapter_meta_cfg'
- add_adapter(
- name: str,
- cfg: omegaconf.DictConfig | AdapterConfig,
- **kwargs,
向此模块添加适配器模块。
- 参数:
name – 适配器的全局唯一名称。将用于访问、启用和禁用适配器。
cfg – 一个 DictConfig 或 Dataclass,至少包含 __target__ 以实例化新的适配器模块。
- is_adapter_available() bool
检查是否已实例化任何适配器模块。
- 返回:
bool,确定是否已实例化任何适配器模块。即使适配器已启用或禁用,也返回 true;仅当不存在适配器时才返回 false。
- set_enabled_adapters(
- name: str | None = None,
- enabled: bool = True,
更新内部适配器配置,确定是否启用或禁用适配器(或所有适配器)。
常见的用户模式是禁用所有适配器(在添加它们之后,或恢复具有预先存在的适配器的模型之后),然后简单地启用其中一个适配器。
module.set_enabled_adapters(enabled=False) module.set_enabled_adapters(name=<some adapter name>, enabled=True)
- 参数:
name – 可选 str。如果给定 str 名称,则配置将更新为 enabled 的值。如果未给定名称,则将启用/禁用所有适配器。
enabled – Bool,确定是否启用/禁用适配器。
- get_enabled_adapters() List[str]
返回所有已启用适配器名称的列表。名称将始终是解析的名称,没有模块信息。
- 返回:
已启用适配器名称的 str 名称列表。
- get_adapter_module(name: str)
如果可能,按名称获取适配器模块,否则返回 None。
- 参数:
name – 与适配器对应的 str 名称(已解析或未解析)。
- 返回:
如果名称可以解析和匹配,则为 nn.Module,否则为 None。
- get_adapter_cfg(name: str)
与 get_adapter_module 相同的逻辑,但用于获取配置
- set_accepted_adapter_types(
- adapter_types: List[type | str],
具有此 mixin 的模块可以定义它将接受的适配器名称列表。此方法应在模块的 init 方法中调用,并设置模块期望添加的适配器名称。
- 参数:
adapter_types – 与类对应的 str 路径列表。类路径将被实例化以确保类路径正确。
- get_accepted_adapter_types() Set[type]
实用程序函数,用于获取模块接受的所有类的集合。
- 返回:
返回接受的适配器类型作为类的集合,否则返回空集。
- unfreeze_enabled_adapters(
- freeze_batchnorm: bool = True,
实用程序方法,用于仅解冻已启用的适配器模块。
常见的用户模式是冻结所有模块(包括所有适配器),然后仅解冻所需的适配器。
module.freeze() # only available to nemo.core.NeuralModule ! module.unfreeze_enabled_adapters()
- 参数:
freeze_batchnorm – 冻结任何和所有 BatchNorm*D 层的移动平均缓冲区更新的可选(且推荐)做法。这对于确保禁用所有适配器将精确产生原始(基础)模型的输出是必要的。
- forward_enabled_adapters(input: torch.Tensor)
使用提供的输入逐个转发所有活动适配器,并将每个适配器层的输出链接到下一个适配器。
在计算适配器的输出以及该输出如何与原始输入合并时,利用每个适配器的隐式合并策略。
- 参数:
input – 调用模块的输出张量是第一个适配器的输入,其输出然后链接到下一个适配器,直到消耗完所有适配器。
- 返回:
结果张量,在所有活动适配器完成其前向传递后。
- resolve_adapter_module_name_(
- name: str,
实用程序方法,用于将给定的全局/模块适配器名称解析为其组件。“:” 用作分隔符,用于表示模块名称与适配器名称。
如果元数据配置存在以供访问,则还将尝试将给定的适配器名称单独解析回 (module_name, adapter_name)。
- 参数:
name – 全局适配器或模块适配器名称(结构为 module_name:adapter_name)。
- 返回:
表示 (module_name, adapter_name) 的元组。如果提供全局适配器,则 module_name 设置为 ''。
- forward_single_enabled_adapter_(
- input: torch.Tensor,
- adapter_module: torch.nn.Module,
- *,
- adapter_name: str,
- adapter_strategy: nemo.core.classes.mixins.adapter_mixin_strategies.AbstractAdapterStrategy,
对某些输入数据执行单个适配器模块的前向步骤。
注意
子类可以覆盖此方法以适应更复杂的适配器前向步骤。
- 参数:
input – 输入:调用模块的输出张量是第一个适配器的输入,其输出然后链接到下一个适配器,直到消耗完所有适配器。
adapter_module – 当前需要执行前向传递的适配器模块。
adapter_name – 正在进行当前前向传递的适配器的解析名称。
adapter_strategy – AbstractAdapterStrategy 的子类,它确定适配器的输出应如何与输入合并,或者是否应完全合并。
- 返回:
结果张量,在当前活动适配器完成其前向传递后。
- check_supported_adapter_type_(
- adapter_cfg: omegaconf.DictConfig,
- supported_adapter_types: Iterable[type] | None = None,
实用程序方法,用于检查适配器模块是否是模块支持的类型。
子类应调用此方法以确保适配器模块是支持的类型。
- class nemo.core.adapter_mixins.AdapterModelPTMixin
-
适配器 Mixin,可以为 ModelPT 子类增强适配器支持。
此 mixin 类应仅与顶层 ModelPT 子类一起使用。此 mixin 类添加了几个实用程序方法,这些方法应被子类化和覆盖,以便根据需要传播到子模块。
适配器模块是任何 Pytorch nn.Module,它具有以下几个属性
它的输入和输出维度相同,而隐藏维度不必相同。
- 适配器模块的最后一层被零初始化,以便到适配器的残差连接
产生原始输出。
此 mixin 将以下实例变量添加到继承它的类中
- adapter_layer:一个 torch.nn.ModuleDict(),其键是适配器的名称(全局唯一),
值是 Adapter nn.Module()。
adapter_cfg:一个 OmegaConf DictConfig 对象,它保存已初始化的适配器的配置。
adapter_global_cfg_key:一个 str,表示模型配置中的一个键,用户可以提供该键。该值解析为 global_cfg,可以通过 model.cfg.adapters.global_cfg.* 覆盖。
注意
此模块 负责 维护其配置。在 ModelPT 级别,它将访问适配器配置信息并将其写入 self.cfg.adapters。
- setup_adapters()
实用程序方法,在 ASR ModelPT 实现构造函数中调用,以便恢复先前添加的任何适配器。
应由子类覆盖以进行所需的其他设置步骤。
此方法应在构造函数时仅调用一次。
- add_adapter(
- name: str,
- cfg: omegaconf.DictConfig | AdapterConfig,
向此模型添加适配器模块。
应由子类覆盖,并且必须使用 super() 调用 - 这将设置配置。在调用 super() 后,将此调用转发到实现 mixin 的模块。
- 参数:
name – 适配器的全局唯一名称。将用于访问、启用和禁用适配器。
cfg – 一个 DictConfig,至少包含 __target__ 以实例化新的适配器模块。
- is_adapter_available() bool
检查是否已实例化任何适配器模块。
应由子类覆盖。
- 返回:
bool,确定是否已实例化任何适配器模块。即使适配器已启用或禁用,也返回 true;仅当不存在适配器时才返回 false。
- set_enabled_adapters(
- name: str | None = None,
- enabled: bool = True,
更新内部适配器配置,确定是否启用或禁用适配器(或所有适配器)。
常见的用户模式是禁用所有适配器(在添加它们之后,或恢复具有预先存在的适配器的模型之后),然后简单地启用其中一个适配器。
应由子类覆盖,并且必须使用 super() 调用 - 这将设置配置。在调用 super() 后,将此调用转发到实现 mixin 的模块。
model.set_enabled_adapters(enabled=False) model.set_enabled_adapters(name=<some adapter name>, enabled=True)
- 参数:
name – 可选 str。如果给定 str 名称,则配置将更新为 enabled 的值。如果未给定名称,则将启用/禁用所有适配器。
enabled – Bool,确定是否启用/禁用适配器。
- get_enabled_adapters() List[str]
返回所有已启用适配器的列表。
应由子类实现。
- 返回:
每个已启用适配器的 str 名称列表。
- check_valid_model_with_adapter_support_()
实用程序方法,用于测试此 mixin 的子类本身是否是 ModelPT 的适当子类。
应由子类实现。
- save_adapters(
- filepath: str,
- name: str | None = None,
实用程序方法,仅保存适配器模块,而不保存整个模型本身。这允许共享适配器,适配器通常只是完整模型大小的一小部分,从而更容易交付。
注意
保存的文件是 pytorch 兼容的 pickle 文件,其中包含适配器的状态字典以及适配器配置的二进制表示。
- 参数:
filepath – 将包含适配器状态字典的 .pt 文件的 str 文件路径。
name – 将保存到此文件的适配器的可选名称。如果传递 None,则所有适配器都将保存到该文件。名称可以是全局名称 (adapter_name) 或模块级别名称 (module:adapter_name)。
- load_adapters(
- filepath: str,
- name: str | None = None,
- map_location: str | None = None,
- strict: bool = True,
实用程序方法,仅恢复适配器模块,而不恢复整个模型本身。这允许共享适配器,适配器通常只是完整模型大小的一小部分,从而更容易交付。
注意
在恢复期间,假定模型当前尚不具有具有该名称(如果提供)的适配器,或者任何与状态字典的模块共享名称的适配器(如果未提供名称)。这是为了确保每个适配器名称在模型中都是全局唯一的。
- 参数:
filepath – .pt 文件的文件路径。
name – 将保存到此文件的适配器的可选名称。如果传递 None,则所有适配器都将保存到该文件。名称必须是全局名称 (adapter_name) 或模块级别名称 (module:adapter_name),以完全匹配状态字典。
map_location – Pytorch 标志,用于放置适配器状态字典。
strict – Pytorch 标志,指示是否严格加载适配器的权重。
- update_adapter_cfg(cfg: omegaconf.DictConfig)
实用程序方法,用于使用提供的配置递归更新所有适配器模块配置。
注意
它不是(深)复制,而是引用复制。对配置所做的更改将反映到适配器子模块,但仍然建议使用此方法显式更新 adapter_cfg。
- 参数:
cfg – 包含 model.cfg.adapters 值的 DictConfig。
- replace_adapter_compatible_modules(
- update_config: bool = True,
- verbose: bool = True,
实用程序方法,用于替换所有具有适配器变体的子模块(如果存在)。不递归遍历子模块的子模块(仅限直系子模块)。
- 参数:
update_config – 一个标志,用于确定是否应更新配置。
verbose – 一个标志,用于确定该方法是否应记录所做的更改。
- property adapter_module_names: List[str]
模型支持的有效适配器模块列表。
注意
子类应覆盖此属性并返回 str 名称列表,其中包含它们支持的所有模块,这将使用户能够确定在何处放置适配器模块。
- 返回:
str 列表,每个列表对应一个受支持的适配器模块。默认情况下,子类应支持“默认适配器”('')。
- property default_adapter_module_name: str | None
如果提供 '' 名称,则用作“默认”的适配器模块的名称。
注意
子类应覆盖此属性并返回它们希望表示为默认值的模块的 str 名称。
- 返回:
表示为“默认”适配器的模块的 str 名称,或 None。如果为 None,则不支持默认适配器。
适配器网络#
- class nemo.collections.common.parts.adapter_modules.AdapterModuleUtil
基类:
AccessMixin
适配器模块的基类,为所有适配器模块提供通用功能。
- setup_adapter_strategy(
- adapter_strategy: AbstractAdapterStrategy | None,
设置此类的适配器策略,从而可以动态更改适配器输出与输入合并的方式。
成功调用后,将变量 adapter_strategy 分配给模块。
- 参数:
adapter_strategy – 可以是 None 或 AbstractAdapterStrategy 的实现。
- get_default_strategy_config() dataclass
返回默认适配器模块策略。
- adapter_unfreeze()
将适配器中所有参数的 requires_grad 设置为 True。对于所需的任何自定义解冻行为,应覆盖此方法。例如,如果并非适配器的所有参数都应解冻。
- class nemo.collections.common.parts.adapter_modules.LinearAdapter(*args: Any, **kwargs: Any)
Bases:
Module
,AdapterModuleUtil
带有 LayerNorm 和单隐藏层以及激活函数的简单线性前馈适配器模块。注意:适配器显式地将其最后一层初始化为全零,以避免在禁用所有适配器时影响原始模型。
- 参数:
in_features – 模块的输入维度。请注意,对于适配器,input_dim == output_dim。
dim – 前馈网络的隐藏维度。
activation – 激活函数的字符串名称。
norm_position – 字符串,可以是 pre 或 post。默认为 pre。 确定归一化是在第一层还是最后一层进行。 某些架构可能更喜欢其中一种。
dropout – 浮点值,是否对适配器最后一层的输出执行 dropout。
adapter_strategy – 默认情况下为 ResidualAddAdapterStrategyConfig。 适配器组合函数对象。
适配器策略#
- class nemo.core.classes.mixins.adapter_mixin_strategies.AbstractAdapterStrategy
基类:
ABC
- forward(
- input: torch.Tensor,
- adapter: torch.nn.Module,
- *,
- module: AdapterModuleMixin,
定义适配器的输出应如何与输入合并的前向方法,或者是否应合并。
还提供了调用此策略的模块 - 从而允许访问调用模块中的所有其他适配器。 如果一个适配器是元适配器,它组合了各种适配器的输出,这将非常有用。 在这种情况下,输入可以跨所有其他适配器转发,收集它们的输出,然后可以通过某种策略合并这些输出。 例如,请参阅
[AdapterFusion: Non-Destructive Task Composition for Transfer Learning](https://arxiv.org/abs/2005.00247)
[Exploiting Adapters for Cross-lingual Low-resource Speech Recognition](https://arxiv.org/abs/2105.11905)
- 参数:
input – 模块的原始输出张量,或先前适配器的输出(如果启用了多个适配器)。
adapter – 当前需要执行前向传递的适配器模块。
module – 调用模块的整体。 它是实现 AdapterModuleMixin 的模块,因此策略可以通过 module.adapter_layer 访问此模块中的所有其他适配器。
- 返回:
结果张量,在一个活动的适配器完成其前向传递之后。
- class nemo.core.classes.mixins.adapter_mixin_strategies.ReturnResultAdapterStrategy
Bases:
AbstractAdapterStrategy
一种适配器策略的实现,该策略仅返回适配器的结果。 支持随机性
- forward(
- input: torch.Tensor,
- adapter: torch.nn.Module,
- *,
- module: AdapterModuleMixin,
一个基本策略,它仅返回适配器计算的结果作为输出。
- 参数:
input – 模块的原始输出张量,或先前适配器的输出(如果启用了多个适配器)。
adapter – 当前需要执行前向传递的适配器模块。
module – 调用模块的整体。 它是实现 AdapterModuleMixin 的模块,因此策略可以通过 module.adapter_layer 访问此模块中的所有其他适配器。
- 返回:
结果张量,在一个活动的适配器完成其前向传递之后。
- compute_output(
- input: torch.Tensor | List[torch.Tensor] | Tuple[torch.Tensor] | Dict[str, Any],
- adapter: torch.nn.Module,
- *,
- module: AdapterModuleMixin,
计算单个适配器对某些输入的输出。
- 参数:
input – 模块的原始输出张量,或先前适配器的输出(如果启用了多个适配器)。
adapter – 当前需要执行前向传递的适配器模块。
module – 调用模块的整体。 它是实现 AdapterModuleMixin 的模块,因此策略可以通过 module.adapter_layer 访问此模块中的所有其他适配器。
- 返回:
结果张量,在一个活动的适配器完成其前向传递之后。
- class nemo.core.classes.mixins.adapter_mixin_strategies.ResidualAddAdapterStrategy(
- stochastic_depth: float = 0.0,
- l2_lambda: float = 0.0,
Bases:
AbstractAdapterStrategy
一种将适配器模块与其输入进行残差加法的实现。 支持随机深度正则化。
- forward(
- input: torch.Tensor,
- adapter: torch.nn.Module,
- *,
- module: AdapterModuleMixin,
一个基本策略,包括在输入上建立残差连接,在底层适配器进行前向传递之后。
- 参数:
input – 模块的原始输出张量,或先前适配器的输出(如果启用了多个适配器)。
adapter – 当前需要执行前向传递的适配器模块。
module – 调用模块的整体。 它是实现 AdapterModuleMixin 的模块,因此策略可以通过 module.adapter_layer 访问此模块中的所有其他适配器。
- 返回:
结果张量,在一个活动的适配器完成其前向传递之后。
- compute_output(
- input: torch.Tensor,
- adapter: torch.nn.Module,
- *,
- module: AdapterModuleMixin,
计算单个适配器对某些输入的输出。
- 参数:
input – 模块的原始输出张量,或先前适配器的输出(如果启用了多个适配器)。
adapter – 当前需要执行前向传递的适配器模块。
module – 调用模块的整体。 它是实现 AdapterModuleMixin 的模块,因此策略可以通过 module.adapter_layer 访问此模块中的所有其他适配器。
- 返回:
结果张量,在一个活动的适配器完成其前向传递之后。
- apply_stochastic_depth(
- output: torch.Tensor,
- input: torch.Tensor,
- adapter: torch.nn.Module,
- *,
- module: AdapterModuleMixin,
如果概率大于 0,则计算并应用随机深度。
- 参数:
output – 结果张量,在一个活动的适配器完成其前向传递之后。
input – 模块的原始输出张量,或先前适配器的输出(如果启用了多个适配器)。
adapter – 当前需要执行前向传递的适配器模块。
module – 调用模块的整体。 它是实现 AdapterModuleMixin 的模块,因此策略可以通过 module.adapter_layer 访问此模块中的所有其他适配器。
- 返回:
结果张量,在可能对其应用随机深度之后。
- compute_auxiliary_losses(
- output: torch.Tensor,
- input: torch.Tensor,
- adapter: torch.nn.Module,
- *,
- module: AdapterModuleMixin,
计算任何辅助损失并将其保存在张量注册表中。
- 参数:
output – 结果张量,在一个活动的适配器完成其前向传递之后。
input – 模块的原始输出张量,或先前适配器的输出(如果启用了多个适配器)。
adapter – 当前需要执行前向传递的适配器模块。
module – 调用模块的整体。 它是实现 AdapterModuleMixin 的模块,因此策略可以通过 module.adapter_layer 访问此模块中的所有其他适配器。