• 文档 >
  • 模块代码 >
  • torch >
  • torch.ao.nn.quantized.dynamic.modules.rnn
快捷键

torch.ao.nn.quantized.dynamic.modules.rnn 的源代码

# mypy: 允许未类型化装饰器
# mypy: 允许未类型化定义
导入 数字
导入 警告
来自 typing_extensions 导入 已弃用

导入 火炬
导入 torch.nn 作为 然后
来自 火炬 导入 张量  # noqa: F401
来自 torch._jit_internal 导入 字典, 列表, 可选, 元组, 联合  # noqa: F401
来自 torch.ao.nn.quantized.modules.utils 导入 _quantize_weight
来自 torch.nn.utils.rnn 导入 PackedSequence


__all__ = [
    pack_weight_bias,
    PackedParameter,
    RNNBase,
    "长短期记忆网络",
    "门控循环单元",
    "RNNCellBase",
    RNN 单元,
    LSTM 单元,
    GRU 单元,
    应用置换,
]


定义 应用置换(张量: 张量, 置换: 张量, 暗淡: 整型 = 1) -> 张量:
    返回 张量.索引选择(暗淡, 置换)


@deprecated(
    "`apply_permutation` 已弃用,请使用 `tensor.index_select(dim, permutation)` 代替",
    分类=未来警告,
)
定义 apply_permutation(张量: 张量, 置换: 张量, 暗淡: 整型 = 1) -> 张量:
    返回 应用置换(张量, 置换, 暗淡)


定义 打包权重偏差(权重, 偏置, 数据类型):
    如果 dtype == 火炬.qint8:
        # 对于每一层,对于每个方向,我们需要进行量化和打包
        # 按此顺序打包权重和参数:
        #
        #   w_ih, w_hh
        包装重量 = 火炬.操作.量化.线性预打包(权重, 偏置)

        返回 包装重量
    否则:
        # 对于每一层,对于每个方向,我们需要进行量化和打包
        权重和打包参数的顺序如下:
        #
        打包的输入隐藏层权重、打包的隐藏层隐藏层权重、输入隐藏层偏置、隐藏层隐藏层偏置
        打包的权重 = 火炬.操作.量化.线性预打包 fp16(权重, 偏置)

        返回 打包的权重


 PackedParameter(火炬.nn.模块):
    定义 初始化(自身, 参数):
        超级().初始化()
        自身.参数 = 参数

    定义 保存到状态字典(自身, 目的地, 前缀, 保留变量):
        超级().保存到状态字典(目的地, 前缀, 保留变量)
        目的地[前缀 + 参数] = 自身.参数

    定义 从状态字典加载(
        自身,
        state_dict,
        前缀,
        本地元数据,
        严格的,
        缺少键,
        预期之外的键,
        错误信息,
    ):
        自身.参数 = state_dict[前缀 + 参数]
        超级().从状态字典加载(
            state_dict,
            前缀,
            本地元数据,
            错误,
            缺少键,
            预期之外的键,
            错误信息,
        )


 RNNBase(火炬.nn.模块):
    浮点模块 = nn.RNNBase

    _version = 2

    定义 初始化(
        自身,
        模式,
        输入大小,
        隐藏层大小,
        层数=1,
        偏置=True,
        批量优先=错误,
        dropout=0.0,
        双向的=错误,
        数据类型=火炬.qint8,
    ):
        超级().初始化()

        自身.模式 = 模式
        自身.输入大小 = 输入大小
        自身.hidden_size = hidden_size
        自身.层数 = 层数
        自身.偏差 = 偏差
        自身.批量优先 = 批量优先
        自身.dropout = float(dropout)
        自身.双向 = 双向
        自身.dtype = dtype
        自身.版本 = 2
        自身.训练 = 
        方向数量 = 2 如果 双向 否则 1

        # "type: ignore" 是必需的,因为整数和数字不完全可比较
        # https://github.com/python/mypy/issues/8566
        如果 (
            not isinstance(dropout, 数字.数字)
             not 0  dropout  1  # type: ignore[operator]
             isinstance(dropout, 布尔)
        ):
            抛出异常 ValueError(
                "dropout 应该是一个在 [0, 1] 范围内的数字"
                表示一个元素被置零的概率
                零化
            )
        如果 dropout > 0  层数 == 1:  # type: ignore[operator]
            warnings.警告(
                "dropout 选项在所有层之后添加 dropout,但最后一个层除外,因此非零 dropout 期望"
                "循环层之后,所以非零 dropout 期望"
                f"num_layers 的值大于 1,但得到了 dropout="{dropout}
                f"num_layers="{层数}"
            )

        如果 模式 == "长短期记忆网络":
            网格大小 = 4 * hidden_size
        elif 模式 == "门控循环单元":
            网格大小 = 3 * hidden_size
        否则:
            抛出异常 ValueError(识别不到的 RNN 模式: + 模式)

        所有权重值 = []
           范围(层数):
             _  范围(方向数量):
                层输入大小 = (
                    输入大小 如果  == 0 否则 hidden_size * 方向数量
                )

                w_ih = 火炬.randn(网格大小, 层输入大小).(火炬.float)
                网格_hh = 火炬.randn(网格大小, 隐藏层大小).(火炬.float)
                b_ih = 火炬.randn(网格大小).(火炬.float)
                b_hh = 火炬.randn(网格大小).(火炬.float)
                如果 dtype == 火炬.qint8:
                    w_ih = 火炬.按张量量化(
                        我_ih, 比例=0.1, 零点=0, 数据类型=火炬.qint8
                    )
                    网格_hh = 火炬.按张量量化(
                        我_hh, 比例=0.1, 零点=0, 数据类型=火炬.qint8
                    )
                    包装输入高度 = 火炬.操作.量化.线性预打包(我_ih, 你_ih)
                    打包_hh = 火炬.操作.量化.线性预打包(我_hh, 你_hh)
                    如果 自身.版本  None  自身.版本 < 2:
                        单元参数 = (
                            火炬.操作.量化.使量化单元参数动态化(
                                压缩输入隐藏状态, 压缩隐藏状态, 你_ih, b_hh
                            )
                        )
                    否则:
                        单元参数 = (
                            火炬.操作.量化.使量化单元参数动态化(
                                压缩输入隐藏状态, 压缩隐藏状态, 你_ih, 你_hh, 真实
                            )
                        )
                否则:
                    packed_ih = 火炬.操作.量化.线性预打包 fp16(我_ih, 你_ih)
                    packed_hh = 火炬.操作.量化.线性预打包 fp16(我_hh, 你_hh)
                    cell_params = 火炬.操作.量化.make_quantized_cell_params_fp16(
                        压缩输入隐藏状态, 打包_hh
                    )

                所有重量值.追加(打包参数(单元参数))
        自身.所有权重值 = 火炬.nn.模块列表(所有权重值)

    定义 _获取名称(自身):
        返回 动态量化 RNN

    定义 额外表示(自身):
        s = "{输入大小}, {隐藏层大小}"
        如果 自身.层数 != 1:
            s += ", num_layers="{层数}"
        如果 自身.偏差  not True:
            s += ", 偏置="{偏置}"
        如果 自身.批量优先  not 错误:
            s += ", batch_first="{batch_first}"
        如果 自身.dropout != 0:
            s += ", dropout="{dropout}"
        如果 自身.双向  not 错误:
            s += ", 双向="{双向}"
        返回 s.格式(**自身.字典)

    定义 __repr__(自身):
        # 我们不想显示`ModuleList`子项,因此自定义
        `__repr__`。这与 nn.Module.__repr__相同,除了检查
        `PackedParameter`和`nn.ModuleList`。
        你仍然应该重写`extra_repr`来添加更多信息。
        额外行 = []
        额外表示 = 自身.额外表示()
        # 空字符串将被分割成列表 ['']
        如果 额外表示:
            额外行 = 额外表示.分割("输入文本翻译为简体中文为:\n")
        子行 = []
         , 模块  自身.模块.项目():
            如果 isinstance(模块, (PackedParameter, nn.模块列表)):
                继续
            mod_str = 表示(模块)
            mod_str = nn.模块.模块._addindent(mod_str, 2)
            子行.追加(“(” + key + "): " + mod_str)
         = 额外行 + 子行

        主字符串 = 自身._获取名称() + “(”
        如果 :
            # 简单的一行信息,大多数内置模块都会使用
            如果 长度(额外行) == 1  not 子行:
                主字符串 += 额外行[0]
            否则:
                主字符串 += "输入文本翻译为简体中文为:\n  " + "输入文本翻译为简体中文为:\n  ".加入() + "输入文本翻译为简体中文为:\n"

        主字符串 += )"
        返回 主字符串

    定义 检查输入(自身, 输入: 张量, batch_sizes: 可选[张量]) -> :
        预期输入维度 = 2 如果 批大小  not None 否则 3
        如果 输入.暗淡() != 期望的输入维度:
            抛出异常 运行时错误(
                f"输入必须具有"{期望的输入维度}维度,实际得到{输入.暗淡()}"
            )
        如果 自身.输入大小 != 输入.尺寸(-1):
            抛出异常 运行时错误(
                f"input.size(-1)必须等于 input_size。期望"{自身.输入大小},获得{输入.尺寸(-1)}"
            )

    定义 获取期望的隐藏尺寸(
        自身, 输入: 张量, batch_sizes: 可选[张量]
    ) -> 元组[int, int, int]
        如果 批大小  not :
            小批量 = int(batch_sizes[0])
        否则:
            小批量 = 输入.尺寸(0) 如果 自身.批量优先 否则 输入.尺寸(1)
        方向数量 = 2 如果 自身.双向 否则 1
        预期隐藏大小 = (
            自身.层数 * 方向数量,
            微批,
            自身.隐藏层大小,
        )
        返回 预期隐藏大小

    定义 检查隐藏层大小(
        自身,
        hx: 张量,
        预期隐藏大小: 元组[int, int, int]
        信息: 字符串 = 预期隐藏大小{},获得{}",
    ) -> :
        如果 hx.尺寸() != 预期隐藏大小:
            抛出异常 运行时错误(信息.格式(预期隐藏大小, 列表(hx.尺寸())))

    定义 检查前向参数(
        自身, 输入: 张量, 隐藏: 张量, batch_sizes: 可选[张量]
    ) -> :
        自身.检查输入(输入, batch_sizes)
        预期隐藏大小 = 自身.获取期望的隐藏尺寸(输入, batch_sizes)
        自身.检查隐藏层大小(
            隐藏, 预期隐藏大小, 信息=预期隐藏大小{},获得{}"
        )

    定义 打乱隐藏状态(自身, hx: 张量, 置换: 可选[张量]) -> 张量:
        如果 排列  :
            返回 hx
        返回 应用置换(hx, 置换)

    定义 从状态字典加载(
        自身,
        state_dict,
        前缀,
        本地元数据,
        严格的,
        缺少键,
        预期之外的键,
        错误信息,
    ):
        版本 = 本地元数据.获取(版本, )
        自身.版本 = 版本
        超级().从状态字典加载(
            state_dict,
            前缀,
            本地元数据,
            错误,
            缺少键,
            预期之外的键,
            错误信息,
        )

    定义 设置权重偏差(自身, 权重偏差字典):
        定义 权重偏差名称(ihhh, , 后缀):
            权重名称 = f重量{呜呜}下划线{}{后缀}"
            偏置名称 = f偏差_{ihhh}_l{}{后缀}"
            返回 权重名称, 偏差名称

        方向数量 = 2 如果 自身.双向 否则 1
        # TODO: 在 RNNBase 的__init__中去重
        所有权重值 = []
           范围(自身.层数):
             方向  范围(方向数量):
                后缀 = "_reverse" 如果 方向 == 1 否则 请提供需要翻译的文本
                w_ih 名称, b_ih_name = weight_bias_name("ih", , 后缀)
                w_hh_name, b_hh_name = weight_bias_name(hh, , 后缀)
                w_ih = weight_bias_dict[网络层名称]
                b_ih = 权重偏置字典[隐藏层名称]
                网格_hh = 权重偏置字典[系统名称]
                b_hh = 权重偏差字典[b_hh 名称]
                如果 我_ih.dtype == 火炬.qint8:
                    紧凑的 ih = 火炬.操作.量化.线性预打包(我_ih, 你_ih)
                    压缩_hh = 火炬.操作.量化.线性预打包(我_hh, 你_hh)
                    如果 自身.版本  None  自身.版本 < 2:
                        单元参数 = (
                            火炬.操作.量化.使量化单元参数动态化(
                                压缩输入隐藏状态, 压缩隐藏状态, 你_ih, b_hh
                            )
                        )
                    否则:
                        单元参数 = (
                            火炬.操作.量化.动态化量化单元参数(
                                压缩输入隐藏状态, 压缩隐藏状态, 你_ih, 你_hh, 真实
                            )
                        )
                否则:
                    紧凑输入门 = 火炬.操作.量化.线性预打包 fp16(我_ih, 你_ih)
                    紧凑隐藏门 = 火炬.操作.量化.线性预打包 fp16(我_hh, 你_hh)
                    单元参数 = 火炬.操作.量化.make_quantized_cell_params_fp16(
                        压缩输入隐藏状态, packed_hh
                    )

                _all_weight_values.追加(PackedParameter(单元参数))
        自身._所有权重值 = 火炬.nn.模块列表(_所有权重值)

    @classmethod
    定义 从浮点数(, mod, 使用预计算的假量化=错误):
        断言 类型(mod)  {
            火炬.nn.长短期记忆网络,
            火炬.nn.GRU,
        }, "nn.quantized.dynamic.RNNBase.from_float 仅适用于 nn.LSTM 和 nn.GRU"
        断言 有属性(mod, qconfig), 输入浮点模块必须定义 qconfig

        如果 mod.qconfig  not None  mod.qconfig.权重  not :
            weight_observer_method = mod.qconfig.权重
        否则:
            如果我们在文件开头导入 qconfig,将出现循环导入问题:
            # https://github.com/pytorch/pytorch/pull/24231. 当前的解决方案是推迟导入,直到需要它。
            #
            来自 torch.ao.quantization.qconfig 导入 default_dynamic_qconfig

            权重观察者方法 = 默认动态 Q 配置.权重

        dtype = 权重观察者方法().dtype
        支持的标量类型 = [火炬.qint8, 火炬.float16]
        如果 dtype not  支持的标量类型:
            抛出异常 运行时错误(
                f不支持动态 RNN 量化的数据类型:{数据类型}"
            )
        RNNBase 可以是 LSTM 或 GRU
        qRNNBase: 联盟[长短期记忆网络, GRU]
        如果 mod.模式 == "长短期记忆网络":
            qRNNBase = 长短期记忆网络(
                mod.输入大小,
                mod.隐藏层大小,
                mod.层数,
                mod.偏置,
                mod.批量优先,
                mod.dropout,
                mod.双向的,
                数据类型,
            )
        elif mod.模式 == "门控循环单元":
            qRNNBase = GRU(
                mod.输入大小,
                mod.隐藏层大小,
                mod.层数,
                mod.偏置,
                mod.批量优先,
                mod.dropout,
                mod.双向的,
                数据类型,
            )
        否则:
            抛出异常 不支持的操作异常(
                目前仅支持 LSTM/GRU 进行 QuantizedRNN 量化
            )

        方向数量 = 2 如果 mod.双向 否则 1

        断言 mod.偏差

        _所有权重值 = []
           范围(qRNNBase.层数):
             方向  范围(方向数量):
                后缀 = "_reverse" 如果 方向 == 1 否则 请提供需要翻译的文本

                定义 检索权重偏差(ihhh):
                    权重名称 = f"权重_{ihhh}__l{}{后缀}"
                    偏差名称 = f"偏差_"{嗡嗡嗡}下划线{}{后缀}"
                    权重 = getattr(mod, 重量名称)
                    偏差 = getattr(mod, 偏差名称)
                    返回 重量, 偏差

                输入层权重, 偏置_ih = 检索权重偏差(ih)
                weight_hh, 偏置_hh = 检索权重偏差(hh)

                如果 dtype == 火炬.qint8:

                    定义 量化打包(w, b):
                        重量观察者 = 权重观察者方法()
                        重量观察者(w)
                        权重 = _quantize_weight(w.float(), 重量观察者)
                        打包权重 = 火炬.操作.量化.线性预打包(权重, b)
                        返回 包装重量

                    包装输入高度 = 量化打包(输入层权重, 偏差_ih)
                    包装高度高度 = 量化打包(weight_hh, 隐藏层偏置)
                    如果 qRNNBase.版本  None  qRNNBase.版本 < 2:
                        单元参数 = (
                            火炬.操作.量化.动态化量化单元参数(
                                压缩输入隐藏状态, 压缩隐藏状态, 偏差_ih, 偏置_hh
                            )
                        )
                    否则:
                        单元参数 = (
                            火炬.操作.量化.动态化量化单元参数(
                                压缩输入隐藏状态, 压缩隐藏状态, 偏差_ih, 隐藏层偏置, 真实
                            )
                        )

                elif dtype == 火炬.float16:
                    紧凑的输入隐藏层 = 火炬.操作.量化.线性预打包 fp16(
                        输入层权重.float(), 偏置_ih
                    )
                    packed_hh = 火炬.操作.量化.线性预打包 fp16(
                        weight_hh.float(), 偏置_hh
                    )

                    单元参数 = 火炬.操作.量化.创建量化单元参数 fp16(
                        压缩输入隐藏状态, packed_hh
                    )
                否则:
                    抛出异常 运行时错误(
                        "指定的动态量化 LSTM 数据类型不受支持!"
                    )

                _所有权重值.追加(打包参数(单元参数))
        qRNNBase._all_weight_values = 火炬.nn.模块列表(_all_weight_values)

        返回 qRNNBase

    定义 权重偏置(自身):
        返回权重和偏差的字典
        weight_bias_dict: 字典[字符串, 字典] = {权重: {}, 偏置: {}}
        计算 = 0
        方向数量 = 2 如果 自身.双向 否则 1
           范围(自身.层数):
             方向  范围(方向数量):
                后缀 = "_reverse" 如果 方向 == 1 否则 请提供需要翻译的文本
                key_name1 = fweight_ih_l{}{后缀}"
                key_name2 = fweight_hh_l{}{后缀}"
                # 紧凑权重是 torchbind 类中的 CellParamsSerializationType 的一部分
                # 在紧凑权重类中,权重和偏置可以作为 Tensors 访问
                压缩权重偏差 = 自身._所有权重值[  忽略索引
                    计算
                ].参数.__getstate__()[0]
[4]
                权重偏差字典[权重]
[键名 1] = 压缩权重偏差[
                    0
                ].__getstate__()[0]
[0]
                权重偏差字典[权重]
[键名 2] = 压缩权重偏差[
                    1
                ].__getstate__()[0]
[0]
                key_name1 = fbias_ih_l{}{后缀}"
                key_name2 = fbias_hh_l{}{后缀}"
                weight_bias_dict[偏置]
[key_name1] = 压缩权重偏差[
                    0
                ].__getstate__()[0]
[1]
                权重偏差字典[偏置]
[键名 2] = 压缩权重偏差[
                    1
                ].__getstate__()[0]
[1]
                计算 = 计算 + 1
        返回 权重偏差字典

    定义 获取权重(自身):
        返回 自身.权重偏置()[权重]

    定义 获取偏差(自身):
        返回 自身.权重偏置()[偏置]


[文档] 长短期记忆网络(RNNBase): r"" 一种动态量化 LSTM 模块,输入和输出为浮点张量。 我们采用与 `torch.nn.LSTM` 相同的接口,请参阅 https://pytorch.org/docs/stable/nn.html#torch.nn.LSTM 以获取文档。 示例: >>> # xdoctest: +SKIP >>> rnn = nn.LSTM(10, 20, 2) >>> input = torch.randn(5, 3, 10) >>> h0 = torch.randn(2, 3, 20) >>> c0 = torch.randn(2, 3, 20) 输出,(hn,cn) = rnn(input, (h0,c0)) ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 浮点模块 = nn.LSTM __重载__ = {前进: ["forward_packed", 前向张量]} 定义 初始化(自身, *参数, **kwargs): 超级().初始化("长短期记忆网络", *参数, **kwargs) 定义 _获取名称(自身): 返回 动态量化 LSTM 定义 forward_impl( 自身, 输入: 张量, hx: 可选[元组[张量, 张量]], batch_sizes: 可选[张量] 最大批量大小: int, 排序索引: 可选[张量] ) -> 元组[张量, 元组[张量, 张量]] 如果 hx : 方向数量 = 2 如果 自身.双向 否则 1 零值 = 火炬.( 自身.层数 * 方向数量, 最大批量大小, 自身.隐藏层大小, 数据类型=输入.数据类型, 设备=输入.设备, ) hx = (, ) 否则: 每个隐藏状态的批次应与用户认为他/她正在传递的输入序列相匹配。 用户认为他/她正在传递的输入序列。 hx = 自身.打乱隐藏状态(hx, 排序索引) 自身.检查前向参数(输入, hx, batch_sizes) 所有参数 = [m.参数 m 自身.所有权重值] 如果 批大小 : 结果 = 火炬.量化 LSTM( 输入, hx, _所有参数, 自身.偏置, 自身.层数, float(自身.dropout), 自身.训练, 自身.双向的, 自身.批量优先, 数据类型=自身.数据类型, 使用动态=True, ) 否则: 结果 = 火炬.量化 LSTM( 输入, batch_sizes, hx, _所有参数, 自身.偏置, 自身.层数, float(自身.dropout), 自身.训练, 自身.双向的, 数据类型=自身.数据类型, 使用动态=True, ) 输出 = 结果[0] 隐藏 = 结果[1] 返回 输出, 隐藏 @torch.算子.导出 定义 前向张量( 自身, 输入: 张量, hx: 可选[元组[张量, 张量]] = None ) -> 元组[张量, 元组[张量, 张量]] 批大小 = None 最大批量大小 = 输入.尺寸(0) 如果 自身.批量优先 否则 输入.尺寸(1) 排序索引 = None 未排序索引 = None 输出, 隐藏 = 自身.forward_impl( 输入, hx, batch_sizes, 最大批量大小, 排序索引 ) 返回 输出, 自身.打乱隐藏状态(隐藏, 未排序的索引) @torch.算子.导出 定义 forward_packed( 自身, 输入: PackedSequence, hx: 可选[元组[张量, 张量]] = None ) -> 元组[PackedSequence, 元组[张量, 张量]] 输入_, batch_sizes, 排序索引, 未排序索引 = 输入 最大批量大小 = int(batch_sizes[0]) 输出_, 隐藏 = 自身.forward_impl( 输入_, hx, batch_sizes, 最大批量大小, 排序索引 ) 输出 = PackedSequence(输出_, batch_sizes, 排序索引, 未排序的索引) 返回 输出, 自身.打乱隐藏状态(隐藏, 未排序的索引) 由于问题 #43072 需要 "type: ignore" 定义 打乱隐藏状态( # 类型:忽略[覆盖] 自身, hx: 元组[张量, 张量] 置换: 可选[张量] ) -> 元组[张量, 张量]: 如果 排列 : 返回 hx 返回 应用置换(hx[0] 置换), 应用置换( hx[1] 排列 ) # "type: ignore" 由于问题 #43072 需要忽略类型检查 定义 检查前向参数( # 类型:忽略[覆盖] 自身, 输入: 张量, 隐藏: 元组[张量, 张量] batch_sizes: 可选[张量] ) -> : 自身.检查输入(输入, batch_sizes) 预期隐藏大小 = 自身.获取期望的隐藏尺寸(输入, batch_sizes) 自身.检查隐藏层大小( 隐藏[0] 预期隐藏大小, 预期隐藏层[0]大小{},获得{}" ) 自身.检查隐藏层大小( 隐藏[1] 预期隐藏大小, 预期隐藏[1]大小{},获得{}" ) @torch.算子.忽略 定义 前向(自身, 输入, hx=): 如果 isinstance(输入, PackedSequence): 返回 自身.forward_packed(输入, hx) 否则: 返回 自身.前向张量(输入, hx) @classmethod 定义 从浮点数(, mod, 使用预计算的假量化=错误): 返回 超级().从浮点数( mod, 使用预计算的假量化=使用预计算的假量化 ) @classmethod 定义 来自参考(, ref_mod): 断言 有属性(ref_mod, "weight_ih_l0_dtype"), "我们假设 weight_ih_l0" "存在于 LSTM 中,可能需要放宽假设以支持该用例" qmod = ( ref_mod.输入大小, ref_mod.隐藏层大小, ref_mod.层数, ref_mod.偏置, ref_mod.批量优先, ref_mod.dropout, ref_mod.双向的, # 假设存在层 0,这应该没问题 ref_mod.weight_ih_l0_dtype, ) qmod.设置权重偏差(ref_mod.get_quantized_weight_bias_dict()) 返回 qmod
[文档] GRU(RNNBase): r将多层门控循环单元(GRU)RNN 应用于输入序列。 对于输入序列中的每个元素,每一层计算以下函数: 函数: .. math:: \begin{array}{ll} r_t = σ(W_{ir} x_t + b_{ir} + W_{hr} h_{(t-1)} + b_{hr}) z_t = σ(W_{iz} x_t + b_{iz} + W_{hz} h_{(t-1)} + b_{hz}) n_t = tanh(W_{in} x_t + b_{in} + r_t ⊙ (W_{hn} h_{(t-1)}+ b_{hn})) h_t = (1 - z_t) ⊙ n_t + z_t ⊙ h_{(t-1)} \end{array} 在时间`t`,:math:`h_t`是隐藏状态,:math:`x_t`是输入 在时间`t`,:math:`h_{(t-1)}`是层的隐藏状态 在时间`t-1`或时间`0`的初始隐藏状态,以及:math:`r_t`, math:`z_t`,:math:`n_t`分别是重置、更新和新门 σ是 Sigmoid 函数,而⊙是 Hadamard 积。 在多层 GRU 中,第 l 层的输入 x^(l)_t (:math:`l >= 2`) 是前一层隐藏状态 :math:`h^{(l-1)}_t` 乘以 dropout :math:`\delta^{(l-1)}_t` 其中每个 :math:`\delta^{(l-1)}_t` 是一个伯努利随机变量 变量以概率:attr:`dropout`取值为:math:`0`。 参数: input_size: 输入 `x` 预期特征的数量 hidden_size: 隐藏状态 `h` 中的特征数量 num_layers: 循环层的数量。例如,设置 ``num_layers=2`` 这意味着将两个 GRU 堆叠起来形成一个`堆叠 GRU`, 第二个 GRU 接收第一个 GRU 的输出并 计算最终结果。默认:1 如果为 ``False``,则该层不使用偏置权重 `b_ih` 和 `b_hh`。 默认:``True`` batch_first:如果为 ``True``,则输入和输出张量以(batch,seq,feature)的形式提供。 作为 (batch, seq, feature)。默认:``False`` dropout:如果非零,则在每个输出的基础上引入一个`Dropout`层 GRU 层除了最后一层,dropout 概率相等 :attr:`dropout`. 默认值:0 bidirectional:如果为 True,则变为双向 GRU。默认值:`False` 输入:input,h_0 - **输入** 形状为 `(seq_len, batch, input_size)`:包含特征的张量 输入序列的特征。输入也可以是打包的可变长度变量 序列。请参阅:func:`torch.nn.utils.rnn.pack_padded_sequence` 了解详情。 - **h_0** 形状为 `(num_layers * num_directions, batch, hidden_size)` 的张量: 包含每个批次中每个元素的初始隐藏状态。 默认为零,如果没有提供。如果 RNN 是双向的, 则 num_directions 应为 2,否则应为 1。 输出:输出,h_n - **输出**的形状为`(seq_len, batch, num_directions * hidden_size)`:张量 包含来自 GRU 最后一层的输出特征 h_t。 对于每个`t`。如果输入的是`:class:`torch.nn.utils.rnn.PackedSequence`,则输出也将是一个打包序列。 如果给定的是打包序列作为输入,输出也将是一个打包序列。 对于未打包的情况,可以使用`output.view(seq_len, batch, num_directions, hidden_size)`来分离方向。 使用`output.view(seq_len, batch, num_directions, hidden_size)`可以分离输出。 前进和后退的方向分别为 `0` 和 `1`。 类似地,方向可以在打包的情况下进行分隔。 - **h_n** 的形状为 `(num_layers * num_directions, batch, hidden_size)`:张量 包含 `t = seq_len` 的隐藏状态 如*输出*,层可以通过以下方式分离: ``h_n.view(num_layers, num_directions, batch, hidden_size)``。 形状: - 输入 1: :math:`(L, N, H_{in})` 张量包含输入特征,其中 math:`H_{in}=\text{input\_size}` 且 `L` 表示序列长度。 - 输入 2::math:`(S, N, H_{out})` 张量 包含每个批处理元素中的初始隐藏状态。 math:`H_{out}=\text{hidden\_size}` 默认为零,如果未提供。其中 :math:`S=\text{num\_layers} * \text{num\_directions}` 如果 RNN 是双向的,则 num_directions 应为 2,否则应为 1。 - 输出 1: :math:`(L, N, H_{all})` 其中 :math:`H_{all}=\text{num\_directions} * \text{hidden\_size}` - 输出 2: :math:`(S, N, H_{out})` 包含下一个隐藏状态的张量 批量中的每个元素 属性: weight_ih_l[k]:第 k 层的可学习输入-隐藏权重。 (W_ir|W_iz|W_in),形状为 `(3*hidden_size, input_size)`,对于 `k = 0` 。 否则,形状为 `(3*hidden_size, num_directions * hidden_size)` weight_hh_l[k]:第 :math:`\text{k}^{th}` 层的可学习隐藏-隐藏权重 (W_hr|W_hz|W_hn),形状为 `(3*hidden_size, hidden_size)` bias_ih_l[k]:第 :math:`\text{k}^{th}` 层的可学习输入-隐藏偏置 (b_ir|b_iz|b_in),形状为 `(3*hidden_size)` bias_hh_l[k]:第 :math:`\text{k}^{th}` 层的可学习隐藏-隐藏偏置 (b_hr|b_hz|b_hn),形状为 `(3*hidden_size)` .. 注意:: 所有权重和偏置都初始化为:math:`\mathcal{U}(-\sqrt{k}, \sqrt{k})` 其中:math:`k = \frac{1}{\text{hidden\_size}}` .. 注意:: 新门 :math:`n_t` 的计算与原始论文和其他框架略有不同。 在原始实现中,在乘以权重矩阵之前,先进行 :math:`r_t` 和前一个隐藏状态 :math:`h_{(t-1)}` 的 Hadamard 积 :math:`(\odot)`。 在原始实现中,在乘以权重矩阵之前,先进行 :math:`r_t` 和前一个隐藏状态 :math:`h_{(t-1)}` 的 Hadamard 积 :math:`(\odot)`。 `W` 和偏置项的添加: .. math:: \begin{aligned} n_t = tanh(W_{in} x_t + b_{in} + W_{hn} ( r_t \odot h_{(t-1)} ) + b_{hn}) \end{aligned} 这与 PyTorch 实现不同,PyTorch 是在 :math:`W_{hn} h_{(t-1)}` 之后进行的 .. math:: \begin{aligned} n_t = tanh(W_{in} x_t + b_{in} + r_t \odot (W_{hn} h_{(t-1)}+ b_{hn})) \end{aligned} 故意这样实现以提高效率。 .. 包含 :: ../cudnn_persistent_rnn.rst 示例: >>> # xdoctest: +SKIP >>> rnn = nn.GRU(10, 20, 2) >>> input = torch.randn(5, 3, 10) >>> h0 = torch.randn(2, 3, 20) 输出,hn = rnn(input, h0) ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 浮点模块 = nn.GRU __重载__ = {前进: ["前向打包", "前向张量"]} 定义 初始化(自身, *参数, **kwargs): 超级().初始化("门控循环单元", *参数, **kwargs) 定义 _获取名称(自身): 返回 "动态量化 GRU" 定义 检查前向参数( 自身, 输入: 张量, 隐藏: 张量, batch_sizes: 可选[张量] ) -> : 自身.检查输入(输入, batch_sizes) 预期隐藏大小 = 自身.获取期望的隐藏尺寸(输入, batch_sizes) 自身.检查隐藏层大小( 隐藏, 预期隐藏大小, 预期隐藏大小{},获得{}" ) 定义 forward_impl( 自身, 输入: 张量, hx: 可选[张量] batch_sizes: 可选[张量] 最大批量大小: int, 排序索引: 可选[张量] ) -> 元组[张量, 张量]: 如果 hx : 方向数量 = 2 如果 自身.双向 否则 1 零值 = 火炬.( 自身.层数 * 方向数量, 最大批量大小, 自身.隐藏层大小, 数据类型=输入.数据类型, 设备=输入.设备, ) hx = 零值 否则: 每个隐藏状态的批次应与用户认为他/她正在传递的输入序列相匹配。 用户认为他/她正在传递的输入序列。 hx = 自身.打乱隐藏状态(hx, 排序索引) 自身.检查前向参数(输入, hx, batch_sizes) 所有参数 = [m.参数 m 自身.所有权重值] 如果 批大小 : 结果 = 火炬.量化 GRU( 输入, hx, _所有参数, 自身.偏置, 自身.层数, 自身.dropout, 自身.训练, 自身.双向的, 自身.批量优先, ) 否则: 结果 = 火炬.量化 GRU( 输入, batch_sizes, hx, _所有参数, 自身.偏置, 自身.层数, 自身.dropout, 自身.训练, 自身.双向的, ) 输出 = 结果[0] 隐藏 = 结果[1] 返回 输出, 隐藏 @torch.算子.导出 定义 前向张量( 自身, 输入: 张量, hx: 可选[张量] = None ) -> 元组[张量, 张量]: 批大小 = None 最大批量大小 = 输入.尺寸(0) 如果 自身.批量优先 否则 输入.尺寸(1) 排序索引 = None 未排序索引 = None 输出, 隐藏 = 自身.forward_impl( 输入, hx, batch_sizes, 最大批量大小, 排序索引 ) 返回 输出, 自身.打乱隐藏状态(隐藏, 未排序的索引) @torch.算子.导出 定义 forward_packed( 自身, 输入: PackedSequence, hx: 可选[张量] = None ) -> 元组[PackedSequence, 张量]: 输入_, batch_sizes, 排序索引, 未排序索引 = 输入 最大批量大小 = int(batch_sizes[0]) 输出_, 隐藏 = 自身.forward_impl( 输入_, hx, batch_sizes, 最大批量大小, 排序索引 ) 输出 = PackedSequence(输出_, batch_sizes, 排序索引, 未排序的索引) 返回 输出, 自身.打乱隐藏状态(隐藏, 未排序的索引) 定义 打乱隐藏状态(自身, hx: 张量, 置换: 可选[张量]) -> 张量: 如果 排列 : 返回 hx 返回 应用置换(hx, 置换) @torch.算子.忽略 定义 前向(自身, 输入, hx=): 如果 isinstance(输入, PackedSequence): 返回 自身.forward_packed(输入, hx) 否则: 返回 自身.前向张量(输入, hx) @classmethod 定义 从浮点数(, mod, 使用预计算的假量化=错误): 返回 超级().从浮点数( mod, 使用预计算的假量化=使用预计算的假量化 ) @classmethod 定义 来自参考(, ref_mod): 断言 有属性(ref_mod, "weight_ih_l0_dtype"), "我们假设 weight_ih_l0 " 存在 LSTM 中,可能需要放宽假设以支持用例 qmod = ( ref_mod.输入大小, ref_mod.隐藏层大小, ref_mod.层数, ref_mod.偏置, ref_mod.批量优先, ref_mod.dropout, ref_mod.双向的, # 层 0,应该没问题 ref_mod.weight_ih_l0_dtype, ) qmod.设置权重偏差(ref_mod.获取量化权重偏差字典()) 返回 qmod
RNNCellBase(火炬.nn.模块): # _FLOAT_MODULE = nn.CellRNNBase 常量 = [输入大小, 隐藏层大小, 偏置] 定义 初始化( 自身, 输入大小, 隐藏层大小, 偏置=True, num_chunks=4, 数据类型=火炬.qint8 ): 超级().初始化() 自身.输入大小 = 输入大小 自身.hidden_size = hidden_size 自身.偏差 = 偏差 自身.权重数据类型 = dtype 如果 偏置: 自身.偏置_ih = 火炬.randn(num_chunks: 分块数量 * 隐藏层大小).(数据类型=火炬.float) 自身.偏置_hh = 火炬.randn(num_chunks: 分块数量 * 隐藏层大小).(数据类型=火炬.float) 否则: 自身.注册参数("偏置_ih", ) 自身.注册参数("偏差_hh", ) weight_ih = 火炬.randn(num_chunks: 分块数量 * 隐藏层大小, 输入大小).(火炬.float) 权重_hh = 火炬.randn(num_chunks: 分块数量 * 隐藏层大小, 隐藏层大小).(火炬.float) 如果 dtype == 火炬.qint8: weight_ih = 火炬.按张量量化( 输入层权重, 比例=1, 零点=0, 数据类型=火炬.qint8 ) 权重_hh = 火炬.按张量量化( weight_hh, 比例=1, 零点=0, 数据类型=火炬.qint8 ) 如果 dtype == 火炬.qint8: 每层每个方向都需要进行量化打包 按此顺序打包权重和打包参数: # w_ih, w_hh 打包权重_ih = 火炬.操作.量化.线性预打包( 输入层权重, 自身.偏置_ih ) 打包重量高高位 = 火炬.操作.量化.线性预打包( weight_hh, 自身.偏置_hh ) 否则: 每层每个方向都需要进行量化打包 按此顺序打包权重和打包参数: # 按顺序打包 packed_ih、packed_hh、b_ih、b_hh 打包权重 packed_weight_ih = 火炬.操作.量化.线性预打包 fp16( 输入层权重, 自身.偏置_ih ) 包装重量_hh = 火炬.操作.量化.线性预打包 fp16( weight_hh, 自身.偏置_hh ) 自身._包装重量_ih = 包装重量_ih 自身._包装重量_hh = 包装重量 定义 _获取名称(自身): 返回 动态量化 RNN 基 定义 额外表示(自身): s = "{输入大小}, {隐藏层大小}" 如果 偏差 自身.字典 自身.偏差 not True: s += ", 偏置="{偏置}" 如果 "非线性" 自身.字典 自身.非线性 != 双曲正切: s += 非线性={非线性}" 返回 s.格式(**自身.字典) 定义 检查前向输入(自身, 输入): 如果 输入.尺寸(1) != 自身.输入大小: 抛出异常 运行时错误( f输入存在不一致的 input_size: 获取{输入.尺寸(1)},预期{自身.输入大小}" ) 定义 检查前向隐藏( 自身, 输入: 张量, hx: 张量, 隐藏标签: 字符串 = 请提供需要翻译的文本 ) -> : 如果 输入.尺寸(0) != hx.尺寸(0): 抛出异常 运行时错误( f"输入批次大小"{输入.尺寸(0)}不匹配隐藏{隐藏标签}批量大小{hx.尺寸(0)}" ) 如果 hx.尺寸(1) != 自身.隐藏层大小: 抛出异常 运行时错误( f隐藏{隐藏标签}存在不一致的隐藏大小:获取{hx.尺寸(1)},预期{自身.隐藏层大小}" ) @classmethod 定义 从浮点数(, mod, 使用预计算的假量化=错误): 断言 类型(mod) { 火炬.nn.LSTMCell, 火炬.nn.GRU 单元, 火炬.nn.RNN 单元, }, nn.quantized.dynamic.RNNCellBase.from_float\ 仅适用于 nn.LSTMCell、nn.GRUCell 和 nn.RNNCell 断言 有属性(mod, qconfig), 输入浮点模块必须定义 qconfig 如果 mod.qconfig not None mod.qconfig.权重 not : 权重观察者方法 = mod.qconfig.权重 否则: # 如果在文件开头导入 qconfig,我们将遇到循环导入问题: # https://github.com/pytorch/pytorch/pull/24231。当前的解决方案是推迟导入: 导入直到我们需要它。 来自 torch.ao.quantization.qconfig 导入 default_dynamic_qconfig 权重观察者方法 = 默认动态 Q 配置.权重 dtype = 权重观察者方法().dtype 支持的标量类型 = [火炬.qint8, 火炬.float16] 如果 dtype not 支持的标量类型: 抛出异常 运行时错误( f不支持动态 RNN 量化的数据类型:{数据类型}" ) qRNNCellBase: 联盟[LSTMCell, GRU 单元, RNN 单元] 如果 类型(mod) == 火炬.nn.LSTMCell: qRNNCellBase = LSTMCell( mod.输入大小, mod.隐藏层大小, 偏置=mod.偏置, 数据类型=dtype ) elif 类型(mod) == 火炬.nn.GRU 单元: qRNNCellBase = GRU 单元( mod.输入大小, mod.隐藏层大小, 偏置=mod.偏置, 数据类型=dtype ) elif 类型(mod) == 火炬.nn.RNN 单元: qRNNCellBase = RNN 单元( mod.输入大小, mod.隐藏层大小, 偏置=mod.偏置, 非线性=mod.非线性, 数据类型=数据类型, ) 否则: 抛出异常 不支持的操作异常( 目前只支持 LSTMCell、GRUCell 和 RNNCell\ 用于 QuantizedRNN ) 断言 mod.偏差 定义 _观察和量化权重(重量): 如果 dtype == 火炬.qint8: 重量观察者 = 权重观察者方法() 重量观察者(重量) 权重 = _quantize_weight(重量.float(), 重量观察者) 返回 权重 否则: 返回 重量.float() qRNNCellBase._packed_weight_ih = pack_weight_bias( _observe_and_quantize_weight(mod.输入层权重), mod.偏差_ih, dtype ) qRNNCellBase._packed_weight_hh = pack_weight_bias( _observe_and_quantize_weight(mod.weight_hh), mod.隐藏层偏置, dtype ) 返回 qRNNCellBase @classmethod 定义 来自参考(, ref_mod): 断言 有属性(ref_mod, "weight_ih_dtype"), "我们假设 weight_ih " "存在于参考模块中,可能需要放宽假设以支持用例" 如果 有属性(ref_mod, 非线性): qmod = ( ref_mod.输入大小, ref_mod.隐藏层大小, ref_mod.偏置, ref_mod.非线性, 数据类型=ref_mod.权重_ih 数据类型, ) 否则: qmod = ( ref_mod.输入大小, ref_mod.隐藏层大小, ref_mod.偏置, 数据类型=ref_mod.权重_ih 数据类型, ) 权重偏置字典 = { 权重: { weight_ih: ref_mod.获取量化输入隐藏层权重(), "隐藏层权重": ref_mod.获取量化隐藏层权重(), }, 偏置: { "偏置_ih": ref_mod.偏差_ih, "偏差_hh": ref_mod.隐藏层偏置, }, } qmod.设置权重偏差(权重偏差字典) 返回 qmod 定义 权重偏置(自身): # 返回权重和偏置的字典 权重偏差字典: 字典[字符串, 字典] = {权重: {}, 偏置: {}} w1, b1 = 自身._packed_weight_ih.__getstate__()[0] w2, b2 = 自身._包装重量_hh.__getstate__()[0] # TODO:这些可以简化为一级?例如使用 weight_ih 作为键 # 直接 权重偏差字典[权重] ["权重_ih"] = w1 权重偏差字典[权重] ["权重_hh"] = w2 权重偏差字典[偏置] ["偏置_ih"] = b1 权重偏差字典[偏置] ["偏差_hh"] = b2 返回 权重偏差字典 定义 获取权重(自身): 返回 自身.权重偏置()[权重] 定义 获取偏置(自身): 返回 自身.权重偏置()[偏置] 定义 设置权重偏差(自身, 权重偏差字典): # TODO: 这些可以简化为一级,例如使用 weight_ih 作为键 直接 自身._packed_weight_ih = 包装权重偏差( 权重偏差字典[权重] ["权重_ih"] 权重偏差字典[偏置] ["偏置_ih"] 自身.权重数据类型, ) 自身._打包权重_hh = 包装权重偏差( 权重偏差字典[权重] ["重量_hh"] 权重偏差字典[偏置] ["偏差_hh"] 自身.权重数据类型, ) 定义 保存到状态字典(自身, 目的地, 前缀, 保留变量): 超级().保存到状态字典(目的地, 前缀, 保留变量) 目的地[前缀 + "_打包重量_ih"] = 自身._打包权重_ih 目的地[前缀 + "_打包权重_hh"] = 自身._打包权重_hh 定义 从状态字典加载( 自身, state_dict, 前缀, 本地元数据, 严格的, 缺少键, 预期之外的键, 错误信息, ): 自身._打包权重_ih = state_dict.弹出(前缀 + "_packed_weight_ih") 自身._packed_weight_hh = state_dict.弹出(前缀 + "_packed_weight_hh") 超级().从状态字典加载( state_dict, 前缀, 本地元数据, 错误, 缺少键, 预期之外的键, 错误信息, )
[文档] RNN 单元(RNNCellBase): r一个具有 tanh 或 ReLU 非线性函数的 Elman RNN 单元。 动态量化 RNNCell 模块,输入输出为浮点张量。 权重被量化为 8 位。我们采用与`torch.nn.RNNCell`相同的接口, 请参阅 https://pytorch.org/docs/stable/nn.html#torch.nn.RNNCell 以获取文档。 示例: >>> # xdoctest: +SKIP >>> rnn = nn.RNNCell(10, 20) >>> input = torch.randn(6, 3, 10) >>> hx = torch.randn(3, 20) >>> output = [] >>> for i in range(6): ... hx = rnn(input[i], hx) ... output.append(hx) ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 常量 = [输入大小, 隐藏层大小, 偏置, 非线性] 定义 初始化( 自身, 输入大小, 隐藏层大小, 偏置=True, 非线性=双曲正切, 数据类型=火炬.qint8 ): 超级().初始化(输入大小, 隐藏层大小, 偏置, num_chunks=1, 数据类型=数据类型) 自身.非线性 = 非线性 定义 _获取名称(自身): 返回 动态量化 RNN 单元 定义 前向(自身, 输入: 张量, hx: 可选[张量] = ) -> 张量: 自身.检查前向输入(输入) 如果 hx : hx = 火炬.( 输入.尺寸(0), 自身.隐藏层大小, 数据类型=输入.数据类型, 设备=输入.设备 ) 自身.检查前向隐藏状态(输入, hx, "") 如果 自身.非线性 == 双曲正切: 返回 = 火炬.操作.量化.动态量化 tanh 单元量化 RNN( 输入, hx, 自身._packed_weight_ih, 自身._packed_weight_hh, 自身.偏差_ih, 自身.隐藏层偏置, ) elif 自身.非线性 == ReLU: 返回 = 火炬.操作.量化.量化 RNN-ReLU 单元动态( 输入, hx, 自身._packed_weight_ih, 自身._包装重量_hh, 自身.偏差_ih, 自身.隐藏层偏置, ) 否则: 返回 = 输入 # TODO: 当 jit 支持异常流程时删除 抛出异常 运行时错误(f"未知非线性:"{自身.非线性}") 返回 返回 @classmethod 定义 从浮点数(, mod, 使用预计算的假量化=错误): 返回 超级().从浮点数( mod, 使用预计算的假量化=使用预计算的假量化 )
[文档] LSTMCell(RNNCellBase): r"一个长短期记忆(LSTM)单元。" 一种动态量化 LSTMCell 模块,输入和输出为浮点张量。 权重量化为 8 位。我们采用与`torch.nn.LSTMCell`相同的接口, 请参阅 https://pytorch.org/docs/stable/nn.html#torch.nn.LSTMCell 获取文档。 示例: >>> # xdoctest: +SKIP >>> rnn = nn.LSTMCell(10, 20) >>> input = torch.randn(6, 3, 10) >>> hx = torch.randn(3, 20) >>> cx = torch.randn(3, 20) >>> output = [] >>> for i in range(6): ... hx, cx = rnn(input[i], (hx, cx)) ... output.append(hx) ```python # 假设输入文本为: input_text = '"""' # 翻译函数(此处仅为示例,实际翻译功能需要调用真实的翻译 API) def translate_to_simplified_chinese(text): # 这里应该调用真实的翻译 API 进行翻译 # 由于示例中不使用真实的 API,以下为模拟翻译结果 return text # 输出翻译结果 translated_text = translate_to_simplified_chinese(input_text) print(translated_text) ``` 定义 初始化(自身, *参数, **kwargs): 超级().初始化(*参数, num_chunks=4, **kwargs) # 类型:忽略[杂项] 定义 _获取名称(自身): 返回 "DynamicQuantizedLSTMCell" 定义 前向( 自身, 输入: 张量, hx: 可选[元组[张量, 张量]] = None ) -> 元组[张量, 张量]: 自身.检查前向输入(输入) 如果 hx : 零值 = 火炬.( 输入.尺寸(0), 自身.隐藏层大小, 数据类型=输入.数据类型, 设备=输入.设备 ) hx = (, ) 自身.检查前向隐藏状态(输入, hx[0] "[0]") 自身.检查隐藏的前向(输入, hx[1] "[1]") 返回 火炬.操作.量化.量化 LSTM 单元动态( 输入, hx, 自身._packed_weight_ih, 自身._packed_weight_hh, 自身.偏差_ih, 自身.隐藏层偏置, ) @classmethod 定义 从浮点数(, mod, 使用预计算的假量化=错误): 返回 超级().从浮点数( mod, 使用预计算的假量化=使用预计算的假量化 )
[文档]class GRUCell(RNNCellBase): r"""一个门控循环单元(GRU)单元 一个动态量化 GRUCell 模块,输入和输出为浮点张量。 权重量化为 8 位。我们采用与`torch.nn.GRUCell`相同的接口, 请参阅 https://pytorch.org/docs/stable/nn.html#torch.nn.GRUCell 以获取文档说明。 示例:: >>> # xdoctest: +SKIP >>> rnn = nn.GRUCell(10, 20) >>> input = torch.randn(6, 3, 10) >>> hx = torch.randn(3, 20) >>> output = [] >>> for i in range(6): ... hx = rnn(input[i], hx) ... output.append(hx) """ def __init__(self, 输入大小, 隐藏大小, 偏置=True, 数据类型=torch.qint8): super().__init__(input_size, hidden_size, bias, num_chunks=3, dtype=dtype) def _get_name(self): return "DynamicQuantizedGRUCell" def forward(self, input: Tensor, hx: Optional[Tensor] = None) -> Tensor: self.check_forward_input(input) if hx is None: hx = torch.zeros( input.size(0), self.hidden_size, dtype=input.dtype, device=input.device ) self.check_forward_hidden(input, hx, "") return torch.ops.quantized.quantized_gru_cell_dynamic( input, hx, self._packed_weight_ih, self._packed_weight_hh, self.bias_ih, self.bias_hh, ) @classmethod def from_float(cls, mod, use_precomputed_fake_quant=False): return super().from_float( mod, 使用预计算的假量化=use_precomputed_fake_quant )

© 版权所有 PyTorch 贡献者。

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

文档

查看 PyTorch 的全面开发者文档

查看文档

教程

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

查看教程

资源

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

查看资源