快捷键

torch.ao.quantization.fuse_modules 源代码

# mypy: 允许未类型化定义
导入 复制
from 打字 导入 可选

导入 torch.nn  神经网络

# 为向后兼容
from torch.ao.quantization.fuser_method_mappings 导入 (  # 无需检查:F401
    融合卷积归一化,
    融合卷积批量归一化 ReLU,
    获取用户方法,
)
from torch.nn.utils.parametrize 导入 type_before_parametrizations


全部 = [
    熔合已知模块,
    "融合模块",
    "融合模块_qat",
]


getattr 的一般化
定义 获取模块(模型, 子模块键):
    标记 = 子模块键.分割(“。”)
    当前模块 = 模型
    for s  令牌:
        当前模块 = getattr(当前模块, s)
    返回 当前模块


setattr 的一般化
定义 _set_module(模型, 子模块键, 模块):
    令牌 = 子模块键.分割(“。”)
    子令牌 = 令牌[-1]
    当前模块 = 模型
    for s  子词:
        当前模块 = getattr(当前模块, s)

    setattr(当前模块, 令牌[-1], 模块)


定义 合并已知模块(模块列表, 是否是 qat, 额外融合方法映射=):
    r返回已知融合模块的列表。

返回融合指定操作的模块列表。
在输入模块列表中。

仅融合以下模块序列:
    conv, bn
    conv, bn, relu
卷积,ReLU
线性,归一化
线性,ReLU
对于这些序列,输出模块列表中的第一个元素执行
混合操作。其余元素设置为 nn.Identity()
"文档"
    类型 = 元组(参数化前的类型(m) for m  模块列表)
    融合方法 = 获取_fuser 方法(类型, 额外_fuser 方法映射)
    如果 fuser 方法  :
        raise 不支持的操作异常(f无法融合模块:{类型}")
    新模块: 列表[可选[神经网络.模块]] = [] * 长度(模块列表)
    fused = 融合方法(是否启用 QAT, *mod_list)
    # 注意:在接下来的两个循环中未处理的 forward hooks 将在融合后丢失
    # 将基础模块的预 forward hooks 移动到结果融合模块
    for pre_hook_fn  模块列表[0]._前向预处理钩子.():
        融合.注册前向钩子(预钩子函数)
    模块列表[0]._前向预处理钩子.清晰()
    将最后一个模块的后置钩子移动到结果融合模块中
    for 钩子函数  模块列表[-1]._前向钩子.():
        融合.注册前向钩子(钩子函数)
    模块列表[-1]._前向钩子.清晰()
    新模块[0] = fused

    for i  范围(1, 长度(模块列表)):
        身份 = 神经网络.身份()
        身份.训练 = 模块列表[0].训练
        新模块[i] = 身份

    返回 新模块


定义 _融合模块助手(
    模型,
    要融合的模块,
    是否是 QAT,
    火焰函数=熔合已知模块,
    熔合自定义配置字典=,
):
    如果 熔合自定义配置字典  :
        熔合自定义配置字典 = {}
    额外熔合方法映射 = 熔合自定义配置字典.获取(
        "附加融合方法映射", {}
    )
    模块列表 = [_获取模块(模型, 项目) for 项目  模块融合列表]

    模块列表融合
    新模块列表 = 融合函数(模块列表, 是_qat, 附加的 fuser 方法映射)

    用融合的模块列表替换原始模块列表
    for i, 项目  列举(要融合的模块):
        设置模块(模型, 项目, 新模块列表[i])


定义 合并模块(
    模型,
    要合并的模块,
    是否是 QAT,
    内置=错误,
    火焰函数=熔合已知模块,
    熔合自定义配置字典=,
):
    如果  内置:
        模型 = 复制.深拷贝(模型)

    如果 所有(isinstance(模块元素, 字符串) for 模块元素  要融合的模块):
        # 处理 modules_to_fuse 为列表的情况
        混合模块助手(
            模型, 模块融合, 是否启用 QAT, 融合器函数, fuse_custom_config_dict
        )
    否则:
        处理 modules_to_fuse 为列表的列表的情况
        for 模块列表  要融合的模块:
            _模块辅助函数(
                模型, 模块列表, 是否启用 QAT, 融合器函数, 熔合自定义配置字典
            )
    返回 模型


[文档]定义 模块融合( 模型, 要融合的模块, 内置=错误, 将模块列表融合成一个单一模块。=已知的融合模块。, 自定义配置字典的融合。=, ): r将一系列模块融合成一个模块。 仅融合以下模块序列: conv, bn conv, bn, relu conv, relu 线性,ReLU 批标准化,ReLU 所有其他序列保持不变。 对于这些序列,替换列表中的第一个项目。 使用融合模块,替换其余模块 具有身份。 参数: 模型:包含要融合的模块的模型 modules_to_fuse:要融合的模块名称的列表。也可以是一个列表 如果只有一个模块列表要融合,则返回字符串。 inplace: 布尔值,指定融合是否在模型中就地发生,默认为 返回一个新的模型 fuser_func: 函数,接收一个模块列表作为输入,输出一个融合后的模块列表 长度相同。例如, fuser_func([convModule, BNModule]) 返回列表 [ConvBNModule, nn.Identity()] 默认为 torch.ao.quantization.fuse_known_modules `fuse_custom_config_dict`:融合的定制配置 .. 代码块 :: python # 熔合自定义配置字典示例 fuse_custom_config_dict = { # 其他 fuser_method 映射 "additional_fuser_method_mapping": { (torch.nn.Conv2d, torch.nn.BatchNorm2d): 熔合卷积和归一化层 }, } 返回: 具有熔合模块的模型。如果 inplace=True,则创建一个新的副本。 示例: >>> # xdoctest: +SKIP >>> m = M().eval() >>> # m 是包含以下子模块的模块 >>> modules_to_fuse = [ ['conv1', 'bn1', 'relu1'], ['submodule.conv', 'submodule.relu']] >>> fused_m = torch.ao.quantization.fuse_modules(m, modules_to_fuse) >>> output = fused_m(input) >>> m = M().eval() >>> # 交替提供要融合的单个模块列表 >>> modules_to_fuse = ['conv1', 'bn1', 'relu1'] >>> fused_m = torch.ao.quantization.fuse_modules(m, modules_to_fuse) >>> output = fused_m(input) "文档" 返回 合并模块( 模型, 要合并的模块, 是否启用 QAT=错误, 内置=内置, 合并函数=fuser_func, 熔断自定义配置字典=熔断自定义配置字典, )
定义 熔断模块 qat( 模型, 模块融合, 内置=错误, 融合函数=融合已知模块, 融合自定义配置字典=, ): `fuse_modules` 的 QAT 版本。 返回 _fuse_modules( 模型, 要融合的模块, 是否是 QAT=, 内置=内置, fuser_func=fuser_func, 熔断自定义配置字典=熔断自定义配置字典, )

© 版权所有 PyTorch 贡献者。

使用 Sphinx 构建,并使用 Read the Docs 提供的主题。

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

深入了解初学者和高级开发者的教程

查看教程

资源

查找开发资源,获取您的疑问解答

查看资源